diff --git a/.clang-format b/.clang-format index c722d050c..3be90d0bf 100644 --- a/.clang-format +++ b/.clang-format @@ -75,7 +75,7 @@ IndentWidth: 2 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 diff --git a/.travis.yml b/.travis.yml index 09f1003aa..e53a2a7db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ script: fi - mkdir build - cd build - - cmake -DENABLE_5GNR=True -DENABLE_TTCN3=True -DRF_FOUND=True -G Ninja .. + - cmake -DENABLE_TTCN3=True -DRF_FOUND=True -G Ninja .. - ninja - ninja test - sudo ninja install \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6db26c7e5..f03cc15c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,6 @@ configure_file( option(ENABLE_SRSUE "Build srsUE application" ON) option(ENABLE_SRSENB "Build srsENB application" ON) option(ENABLE_SRSEPC "Build srsEPC application" ON) -option(ENABLE_5GNR "Build with 5G-NR components" OFF) option(DISABLE_SIMD "Disable SIMD instructions" OFF) option(AUTO_DETECT_ISA "Autodetect supported ISA extensions" ON) @@ -106,9 +105,6 @@ else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") -if (ENABLE_5GNR) - add_definitions(-DHAVE_5GNR) -endif (ENABLE_5GNR) ######################################################################## # Find dependencies @@ -281,6 +277,17 @@ if (ENABLE_TTCN3) message(STATUS "Building with TTCN3 binaries") endif (ENABLE_TTCN3) +# Backward-cpp +find_package(Backward) +if(Backward_FOUND) + if(BACKWARD_HAS_EXTERNAL_LIBRARIES) + add_definitions(-DHAVE_BACKWARD) + message(STATUS "Building with backward-cpp support") + else (BACKWARD_HAS_EXTERNAL_LIBRARIES) + message(STATUS "Backward-cpp found, but external libraries are missing.") + endif() +endif() + ######################################################################## # Install Dirs ######################################################################## @@ -541,6 +548,28 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") message(STATUS "Building for version: ${VERSION}") +######################################################################## +# Ctest function helpers +######################################################################## + +function(add_lte_test) + add_test(${ARGN}) + set(TNAME ${ARGV0}) + if(${TNAME} STREQUAL NAME) + set(TNAME ${ARGV1}) + endif() + set_tests_properties(${TNAME} PROPERTIES LABELS "lte;${CTEST_LABELS}") +endfunction() + +function(add_nr_test) + add_test(${ARGN}) + set(TNAME ${ARGV0}) + if(${TNAME} STREQUAL NAME) + set(TNAME ${ARGV1}) + endif() + set_tests_properties(${TNAME} PROPERTIES LABELS "nr;${CTEST_LABELS}") +endfunction() + ######################################################################## # Add general includes and dependencies ######################################################################## diff --git a/COPYRIGHT b/COPYRIGHT index f7a6d34ae..54c126fd5 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -46,6 +46,10 @@ Files: lib/include/srslte/srslog/bundled/fmt/chrono.h Copyright: 2012-2020, Victor Zverovich License: MIT +Files: lib/include/srslte/common/backward.hpp + cmake/modules/FindBackward.cmake +Copyright: 2013, Google Inc. +License: MIT License: AGPL-3+ This program is free software: you can redistribute it and/or modify diff --git a/README.md b/README.md index e7962241e..5da4bd793 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Build Instructions For example, on Ubuntu, one can install the mandatory build dependencies with: ``` -sudo apt-get install cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev +sudo apt-get install build-essential cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev ``` or on Fedora: ``` @@ -132,6 +132,7 @@ Note that depending on your flavor and version of Linux, the actual package name * Optional requirements: * srsgui: https://github.com/srslte/srsgui - for real-time plotting. * libpcsclite-dev: https://pcsclite.apdu.fr/ - for accessing smart card readers + * libdw-dev libdw - for truly informative backtraces using backward-cpp * RF front-end driver: * UHD: https://github.com/EttusResearch/uhd diff --git a/cmake/modules/FindBackward.cmake b/cmake/modules/FindBackward.cmake new file mode 100644 index 000000000..3e5cf7dca --- /dev/null +++ b/cmake/modules/FindBackward.cmake @@ -0,0 +1,243 @@ +# +# BackwardMacros.cmake +# Copyright 2013 Google Inc. All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +############################################################################### +# OPTIONS +############################################################################### + +if(POLICY CMP0011) + cmake_policy(SET CMP0011 NEW) + cmake_policy(SET CMP0012 NEW) +endif() + +set(STACK_WALKING_UNWIND TRUE CACHE BOOL + "Use compiler's unwind API") +set(STACK_WALKING_BACKTRACE FALSE CACHE BOOL + "Use backtrace from (e)glibc for stack walking") +set(STACK_WALKING_LIBUNWIND FALSE CACHE BOOL + "Use libunwind for stack walking") + +set(STACK_DETAILS_AUTO_DETECT TRUE CACHE BOOL + "Auto detect backward's stack details dependencies") + +set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE CACHE BOOL + "Use backtrace from (e)glibc for symbols resolution") +set(STACK_DETAILS_DW FALSE CACHE BOOL + "Use libdw to read debug info") +set(STACK_DETAILS_BFD FALSE CACHE BOOL + "Use libbfd to read debug info") +set(STACK_DETAILS_DWARF FALSE CACHE BOOL + "Use libdwarf/libelf to read debug info") + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT DEFINED BACKWARD_TESTS) + # If this is a top level CMake project, we most lixely want the tests + set(BACKWARD_TESTS ON CACHE BOOL "Enable tests") +else() + set(BACKWARD_TESTS OFF CACHE BOOL "Enable tests") +endif() +############################################################################### +# CONFIGS +############################################################################### +include(FindPackageHandleStandardArgs) + +if (STACK_WALKING_LIBUNWIND) + # libunwind works on the macOS without having to add special include + # paths or libraries + if (NOT APPLE) + find_path(LIBUNWIND_INCLUDE_DIR NAMES "libunwind.h") + find_library(LIBUNWIND_LIBRARY unwind) + + if (LIBUNWIND_LIBRARY) + include(CheckSymbolExists) + check_symbol_exists(UNW_INIT_SIGNAL_FRAME libunwind.h HAVE_UNW_INIT_SIGNAL_FRAME) + if (NOT HAVE_UNW_INIT_SIGNAL_FRAME) + message(STATUS "libunwind does not support unwinding from signal handler frames") + endif() + endif() + + set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR}) + set(LIBDWARF_LIBRARIES ${LIBUNWIND_LIBRARY}) + find_package_handle_standard_args(libunwind DEFAULT_MSG + LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR) + mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY) + list(APPEND _BACKWARD_LIBRARIES ${LIBUNWIND_LIBRARY}) + endif() + + # Disable other unwinders if libunwind is found + set(STACK_WALKING_UNWIND FALSE) + set(STACK_WALKING_BACKTRACE FALSE) +endif() + +if (${STACK_DETAILS_AUTO_DETECT}) + # find libdw + find_path(LIBDW_INCLUDE_DIR NAMES "elfutils/libdw.h" "elfutils/libdwfl.h") + find_library(LIBDW_LIBRARY dw) + set(LIBDW_INCLUDE_DIRS ${LIBDW_INCLUDE_DIR} ) + set(LIBDW_LIBRARIES ${LIBDW_LIBRARY} ) + find_package_handle_standard_args(libdw DEFAULT_MSG + LIBDW_LIBRARY LIBDW_INCLUDE_DIR) + mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARY) + + # find libbfd + find_path(LIBBFD_INCLUDE_DIR NAMES "bfd.h") + find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h") + find_library(LIBBFD_LIBRARY bfd) + find_library(LIBDL_LIBRARY dl) + set(LIBBFD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR}) + set(LIBBFD_LIBRARIES ${LIBBFD_LIBRARY} ${LIBDL_LIBRARY}) + find_package_handle_standard_args(libbfd DEFAULT_MSG + LIBBFD_LIBRARY LIBBFD_INCLUDE_DIR + LIBDL_LIBRARY LIBDL_INCLUDE_DIR) + mark_as_advanced(LIBBFD_INCLUDE_DIR LIBBFD_LIBRARY + LIBDL_INCLUDE_DIR LIBDL_LIBRARY) + + # find libdwarf + find_path(LIBDWARF_INCLUDE_DIR NAMES "libdwarf.h" PATH_SUFFIXES libdwarf) + find_path(LIBELF_INCLUDE_DIR NAMES "libelf.h") + find_path(LIBDL_INCLUDE_DIR NAMES "dlfcn.h") + find_library(LIBDWARF_LIBRARY dwarf) + find_library(LIBELF_LIBRARY elf) + find_library(LIBDL_LIBRARY dl) + set(LIBDWARF_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} ${LIBDL_INCLUDE_DIR}) + set(LIBDWARF_LIBRARIES ${LIBDWARF_LIBRARY} ${LIBELF_LIBRARY} ${LIBDL_LIBRARY}) + find_package_handle_standard_args(libdwarf DEFAULT_MSG + LIBDWARF_LIBRARY LIBDWARF_INCLUDE_DIR + LIBELF_LIBRARY LIBELF_INCLUDE_DIR + LIBDL_LIBRARY LIBDL_INCLUDE_DIR) + mark_as_advanced(LIBDWARF_INCLUDE_DIR LIBDWARF_LIBRARY + LIBELF_INCLUDE_DIR LIBELF_LIBRARY + LIBDL_INCLUDE_DIR LIBDL_LIBRARY) + + if (LIBDW_FOUND) + LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDW_INCLUDE_DIRS}) + LIST(APPEND _BACKWARD_LIBRARIES ${LIBDW_LIBRARIES}) + set(STACK_DETAILS_DW TRUE) + set(STACK_DETAILS_BFD FALSE) + set(STACK_DETAILS_DWARF FALSE) + set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE) + elseif(LIBBFD_FOUND) + LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBBFD_INCLUDE_DIRS}) + LIST(APPEND _BACKWARD_LIBRARIES ${LIBBFD_LIBRARIES}) + + # If we attempt to link against static bfd, make sure to link its dependencies, too + get_filename_component(bfd_lib_ext "${LIBBFD_LIBRARY}" EXT) + if (bfd_lib_ext STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}") + list(APPEND _BACKWARD_LIBRARIES iberty z) + endif() + + set(STACK_DETAILS_DW FALSE) + set(STACK_DETAILS_BFD TRUE) + set(STACK_DETAILS_DWARF FALSE) + set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE) + elseif(LIBDWARF_FOUND) + LIST(APPEND _BACKWARD_INCLUDE_DIRS ${LIBDWARF_INCLUDE_DIRS}) + LIST(APPEND _BACKWARD_LIBRARIES ${LIBDWARF_LIBRARIES}) + + set(STACK_DETAILS_DW FALSE) + set(STACK_DETAILS_BFD FALSE) + set(STACK_DETAILS_DWARF TRUE) + set(STACK_DETAILS_BACKTRACE_SYMBOL FALSE) + else() + set(STACK_DETAILS_DW FALSE) + set(STACK_DETAILS_BFD FALSE) + set(STACK_DETAILS_DWARF FALSE) + set(STACK_DETAILS_BACKTRACE_SYMBOL TRUE) + endif() +else() + if (STACK_DETAILS_DW) + LIST(APPEND _BACKWARD_LIBRARIES dw) + endif() + + if (STACK_DETAILS_BFD) + LIST(APPEND _BACKWARD_LIBRARIES bfd dl) + endif() + + if (STACK_DETAILS_DWARF) + LIST(APPEND _BACKWARD_LIBRARIES dwarf elf) + endif() +endif() + +macro(map_definitions var_prefix define_prefix) + foreach(def ${ARGN}) + if (${${var_prefix}${def}}) + LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=1") + else() + LIST(APPEND _BACKWARD_DEFINITIONS "${define_prefix}${def}=0") + endif() + endforeach() +endmacro() + +if (NOT _BACKWARD_DEFINITIONS) + map_definitions("STACK_WALKING_" "BACKWARD_HAS_" UNWIND LIBUNWIND BACKTRACE) + map_definitions("STACK_DETAILS_" "BACKWARD_HAS_" BACKTRACE_SYMBOL DW BFD DWARF) +endif() + +set(BACKWARD_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}") + +set(BACKWARD_HAS_EXTERNAL_LIBRARIES FALSE) +set(FIND_PACKAGE_REQUIRED_VARS BACKWARD_INCLUDE_DIR) +if(DEFINED _BACKWARD_LIBRARIES) + set(BACKWARD_HAS_EXTERNAL_LIBRARIES TRUE) + list(APPEND FIND_PACKAGE_REQUIRED_VARS _BACKWARD_LIBRARIES) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Backward + REQUIRED_VARS ${FIND_PACKAGE_REQUIRED_VARS} +) +list(APPEND _BACKWARD_INCLUDE_DIRS ${BACKWARD_INCLUDE_DIR}) + +macro(add_backward target) + target_include_directories(${target} PRIVATE ${BACKWARD_INCLUDE_DIRS}) + set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS ${BACKWARD_DEFINITIONS}) + set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES ${BACKWARD_LIBRARIES}) +endmacro() + +set(BACKWARD_INCLUDE_DIRS ${_BACKWARD_INCLUDE_DIRS} CACHE INTERNAL "_BACKWARD_INCLUDE_DIRS") +set(BACKWARD_DEFINITIONS ${_BACKWARD_DEFINITIONS} CACHE INTERNAL "BACKWARD_DEFINITIONS") +set(BACKWARD_LIBRARIES ${_BACKWARD_LIBRARIES} CACHE INTERNAL "BACKWARD_LIBRARIES") +mark_as_advanced(BACKWARD_INCLUDE_DIRS BACKWARD_DEFINITIONS BACKWARD_LIBRARIES) + +# Expand each definition in BACKWARD_DEFINITIONS to its own cmake var and export +# to outer scope +foreach(var ${BACKWARD_DEFINITIONS}) + string(REPLACE "=" ";" var_as_list ${var}) + list(GET var_as_list 0 var_name) + list(GET var_as_list 1 var_value) + set(${var_name} ${var_value}) + mark_as_advanced(${var_name}) + #message(STATUS "${var_name}=${var_value}") +endforeach() + +# Disabled for older CMake version (CentOS) +#if (NOT TARGET Backward::Backward) +# add_library(Backward::Backward INTERFACE IMPORTED) +# set_target_properties(Backward::Backward PROPERTIES +# INTERFACE_INCLUDE_DIRECTORIES "${BACKWARD_INCLUDE_DIRS}" +# INTERFACE_COMPILE_DEFINITIONS "${BACKWARD_DEFINITIONS}" +# ) +# if(BACKWARD_HAS_EXTERNAL_LIBRARIES) +# set_target_properties(Backward::Backward PROPERTIES +# INTERFACE_LINK_LIBRARIES "${BACKWARD_LIBRARIES}" +# ) +# endif() +#endif() diff --git a/debian/copyright b/debian/copyright index 1da7298c9..9f52b0d58 100644 --- a/debian/copyright +++ b/debian/copyright @@ -53,6 +53,11 @@ Files: lib/include/srslte/srslog/bundled/fmt/chrono.h Copyright: 2012-2020, Victor Zverovich License: MIT +Files: lib/include/srslte/common/backward.hpp + cmake/modules/FindBackward.cmake +Copyright: 2013, Google Inc. +License: MIT + License: AGPL-3+ This program is free software: you can redistribute it and/or modify diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d55bb3f20..dd46892cb 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -31,4 +31,4 @@ add_subdirectory(test) ######################################################################## INSTALL( DIRECTORY include/ DESTINATION "${INCLUDE_DIR}" - FILES_MATCHING PATTERN "*.h" ) + FILES_MATCHING PATTERN "*.h" ) \ No newline at end of file diff --git a/lib/examples/cell_search.c b/lib/examples/cell_search.c index e2c44acda..683cec028 100644 --- a/lib/examples/cell_search.c +++ b/lib/examples/cell_search.c @@ -116,7 +116,7 @@ void parse_args(int argc, char** argv) int srslte_rf_recv_wrapper(void* h, void* data, uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ---- ", nsamples); return srslte_rf_recv_with_time((srslte_rf_t*)h, data, nsamples, 1, NULL, NULL); } @@ -152,7 +152,7 @@ int main(int argc, char** argv) printf("Opening RF device...\n"); if (srslte_rf_open(&rf, rf_args)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } if (!cell_detect_config.init_agc) { @@ -160,7 +160,7 @@ int main(int argc, char** argv) } else { printf("Starting AGC thread...\n"); if (srslte_rf_start_gain_thread(&rf, false)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } srslte_rf_set_rx_gain(&rf, 50); @@ -171,7 +171,7 @@ int main(int argc, char** argv) nof_freqs = srslte_band_get_fd_band(band, channels, earfcn_start, earfcn_end, MAX_EARFCN); if (nof_freqs < 0) { - ERROR("Error getting EARFCN list\n"); + ERROR("Error getting EARFCN list"); exit(-1); } @@ -182,7 +182,7 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, (void*)&rf)) { - ERROR("Error initiating UE cell detect\n"); + ERROR("Error initiating UE cell detect"); exit(-1); } @@ -199,10 +199,9 @@ int main(int argc, char** argv) } for (freq = 0; freq < nof_freqs && !go_exit; freq++) { - /* set rf_freq */ srslte_rf_set_rx_freq(&rf, 0, (double)channels[freq].fd * MHZ); - INFO("Set rf_freq to %.3f MHz\n", (double)channels[freq].fd * MHZ / 1000000); + INFO("Set rf_freq to %.3f MHz", (double)channels[freq].fd * MHZ / 1000000); printf( "[%3d/%d]: EARFCN %d Freq. %.2f MHz looking for PSS.\n", freq, nof_freqs, channels[freq].id, channels[freq].fd); @@ -214,14 +213,14 @@ int main(int argc, char** argv) bzero(found_cells, 3 * sizeof(srslte_ue_cellsearch_result_t)); - INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ / 1000000); + INFO("Setting sampling frequency %.2f MHz for PSS search", SRSLTE_CS_SAMP_FREQ / 1000000); srslte_rf_set_rx_srate(&rf, SRSLTE_CS_SAMP_FREQ); - INFO("Starting receiver...\n"); + INFO("Starting receiver..."); srslte_rf_start_rx_stream(&rf, false); n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL); if (n < 0) { - ERROR("Error searching cell\n"); + ERROR("Error searching cell"); exit(-1); } else if (n > 0) { for (int i = 0; i < 3; i++) { @@ -231,7 +230,7 @@ int main(int argc, char** argv) cell.cp = found_cells[i].cp; int ret = rf_mib_decoder(&rf, 1, &cell_detect_config, &cell, NULL); if (ret < 0) { - ERROR("Error decoding MIB\n"); + ERROR("Error decoding MIB"); exit(-1); } if (ret == SRSLTE_UE_MIB_FOUND) { diff --git a/lib/examples/cell_search_nbiot.c b/lib/examples/cell_search_nbiot.c index f6d5a7ad9..7cff45db8 100644 --- a/lib/examples/cell_search_nbiot.c +++ b/lib/examples/cell_search_nbiot.c @@ -121,7 +121,7 @@ void parse_args(int argc, char** argv) int srslte_rf_recv_wrapper(void* h, cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); void* ptr[SRSLTE_MAX_PORTS]; for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { ptr[i] = data[i]; @@ -193,7 +193,7 @@ int main(int argc, char** argv) // set rf_freq double rf_freq = channels[freq].fd * MHZ + raster_offset[i]; srslte_rf_set_rx_freq(&rf, 0, rf_freq); - INFO("Set rf_freq to %.3f Hz\n", rf_freq); + INFO("Set rf_freq to %.3f Hz", rf_freq); printf("[%3d/%d]: EARFCN %d, %.2f MHz looking for NPSS.\n", freq, nof_freqs, channels[freq].id, rf_freq / 1e6); fflush(stdout); @@ -216,9 +216,9 @@ int main(int argc, char** argv) srslte_ue_sync_nbiot_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_wrapper, cell_detect_config.init_agc); } - INFO("Setting sampling frequency %.2f MHz for NPSS search\n", SRSLTE_CS_SAMP_FREQ / 1000000); + INFO("Setting sampling frequency %.2f MHz for NPSS search", SRSLTE_CS_SAMP_FREQ / 1000000); srslte_rf_set_rx_srate(&rf, SRSLTE_CS_SAMP_FREQ); - INFO("Starting receiver...\n"); + INFO("Starting receiver..."); srslte_rf_start_rx_stream(&rf, false); n = srslte_ue_cellsearch_nbiot_scan(&cs); diff --git a/lib/examples/npdsch_enodeb.c b/lib/examples/npdsch_enodeb.c index 548e4f5e1..a996212f4 100644 --- a/lib/examples/npdsch_enodeb.c +++ b/lib/examples/npdsch_enodeb.c @@ -498,7 +498,6 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (!output_file_name) { - int srate = srslte_sampling_freq_hz(cell.base.nof_prb); if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); @@ -564,7 +563,7 @@ int main(int argc, char** argv) srslte_nsss_put_subframe(&nsss_sync, nsss_signal, sf_buffer, sfn, cell.base.nof_prb, cell.nbiot_prb); } else { // NRS in all other subframes (using CSR signal intentionally) - // DEBUG("%d.%d: Putting %d NRS pilots\n", sfn, sf_idx, SRSLTE_REFSIGNAL_NUM_SF(1, cell.nof_ports)); + // DEBUG("%d.%d: Putting %d NRS pilots", sfn, sf_idx, SRSLTE_REFSIGNAL_NUM_SF(1, cell.nof_ports)); srslte_refsignal_nrs_put_sf(cell, 0, ch_est.nrs_signal.pilots[0][sf_idx], sf_buffer); } @@ -600,14 +599,13 @@ int main(int argc, char** argv) } if (srslte_nbiot_ue_dl_is_sib1_sf(&ue_dl, sfn, sf_idx)) { - INFO("%d.%d: Transmitting SIB1-NB.\n", sfn, sf_idx); + INFO("%d.%d: Transmitting SIB1-NB.", sfn, sf_idx); assert(send_data == false); // configure DL grant for SIB1-NB transmission if (sib1_npdsch_cfg.sf_idx == 0) { srslte_ra_nbiot_dl_grant_t grant; - srslte_ra_nbiot_dl_dci_to_grant( - &ra_dl_sib1, &grant, sfn, sf_idx, DUMMY_R_MAX, true, cell.mode); + srslte_ra_nbiot_dl_dci_to_grant(&ra_dl_sib1, &grant, sfn, sf_idx, DUMMY_R_MAX, true, cell.mode); if (srslte_npdsch_cfg(&sib1_npdsch_cfg, cell, &grant, sf_idx)) { fprintf(stderr, "Error configuring NPDSCH\n"); exit(-1); @@ -635,7 +633,7 @@ int main(int argc, char** argv) // always transmit NPDCCH on fixed positions if no transmission is going on if (sf_idx == NPDCCH_SF_IDX && !npdsch_active) { // Encode NPDCCH - INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L); + INFO("Putting DCI to location: n=%d, L=%d", locations[sf_idx][0].ncce, locations[sf_idx][0].L); srslte_dci_msg_pack_npdsch(&ra_dl, SRSLTE_DCI_FORMATN1, &dci_msg, false); if (srslte_npdcch_encode(&npdcch, &dci_msg, locations[sf_idx][0], UE_CRNTI, sf_re_symbols, sf_idx)) { fprintf(stderr, "Error encoding DCI message\n"); @@ -654,7 +652,7 @@ int main(int argc, char** argv) // catch start of "user" NPDSCH if (!npdsch_active && (sf_idx == npdsch_cfg.grant.start_sfidx && sfn == npdsch_cfg.grant.start_sfn)) { // generate data only in first sf - INFO("%d.%d: Generating %d random bits\n", sfn, sf_idx, npdsch_cfg.grant.mcs[0].tbs); + INFO("%d.%d: Generating %d random bits", sfn, sf_idx, npdsch_cfg.grant.mcs[0].tbs); for (int i = 0; i < npdsch_cfg.grant.mcs[0].tbs / 8; i++) { data[i] = srslte_random_uniform_int_dist(random_gen, 0, 255); } @@ -666,7 +664,7 @@ int main(int argc, char** argv) } if (npdsch_active) { - DEBUG("Current sf_idx=%d, Encoding npdsch.sf_idx=%d start=%d, nof=%d\n", + DEBUG("Current sf_idx=%d, Encoding npdsch.sf_idx=%d start=%d, nof=%d", sf_idx, npdsch_cfg.sf_idx, npdsch_cfg.grant.start_sfidx, @@ -677,7 +675,7 @@ int main(int argc, char** argv) exit(-1); } if (npdsch_cfg.num_sf == npdsch_cfg.grant.nof_sf * npdsch_cfg.grant.nof_rep) { - INFO("Deactive current NPDSCH\n"); + INFO("Deactive current NPDSCH"); npdsch_active = false; } } diff --git a/lib/examples/npdsch_ue.c b/lib/examples/npdsch_ue.c index 237cd30ca..fad96e76f 100644 --- a/lib/examples/npdsch_ue.c +++ b/lib/examples/npdsch_ue.c @@ -283,7 +283,7 @@ void pcap_pack_and_write(FILE* pcap_file, #ifndef DISABLE_RF int srslte_rf_recv_wrapper(void* h, void* data, uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); return srslte_rf_recv_with_time(h, data, nsamples, true, &t->full_secs, &t->frac_secs); } @@ -355,7 +355,6 @@ int main(int argc, char** argv) #ifndef DISABLE_RF if (!prog_args.input_file_name) { - printf("Opening RF device...\n"); if (srslte_rf_open_devname(&rf, prog_args.rf_dev, prog_args.rf_args, 1)) { fprintf(stderr, "Error opening rf\n"); @@ -520,9 +519,8 @@ int main(int argc, char** argv) srslte_npbch_decode_reset(&ue_mib.npbch); - INFO("\nEntering main loop...\n\n"); + INFO("\nEntering main loop..."); while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { - ret = srslte_ue_sync_nbiot_zerocopy_multi(&ue_sync, buff_ptrs); if (ret < 0) { fprintf(stderr, "Error calling srslte_nbiot_ue_sync_zerocopy_multi()\n"); @@ -551,7 +549,7 @@ int main(int argc, char** argv) // update SFN and set deployment mode system_frame_number = (mib.sfn + sfn_offset) % 1024; - cell.mode = mib.mode; + cell.mode = mib.mode; // set number of ports of base cell to that of NB-IoT cell (FIXME: read eutra-NumCRS-Ports-r13) cell.base.nof_ports = cell.nof_ports; @@ -713,7 +711,7 @@ int main(int argc, char** argv) srslte_ue_sync_nbiot_get_sfidx(&ue_sync), prog_args.rnti); if (n == SRSLTE_SUCCESS) { - INFO("NPDSCH decoded ok.\n"); + INFO("NPDSCH decoded ok."); } } else { // decode NPDCCH @@ -725,7 +723,7 @@ int main(int argc, char** argv) prog_args.rnti, &dci_msg); if (n == SRSLTE_NBIOT_UE_DL_FOUND_DCI) { - INFO("DCI found for rnti=%d\n", prog_args.rnti); + INFO("DCI found for rnti=%d", prog_args.rnti); // convert DCI to grant srslte_ra_nbiot_dl_dci_t dci_unpacked; srslte_ra_nbiot_dl_grant_t grant; @@ -916,9 +914,9 @@ float tmp_plot2[110 * 15 * 2048]; void* plot_thread_run(void* arg) { - uint32_t nof_re = SRSLTE_SF_LEN_RE(ue_dl.cell.base.nof_prb, ue_dl.cell.base.cp); + uint32_t nof_re = SRSLTE_SF_LEN_RE(ue_dl.cell.base.nof_prb, ue_dl.cell.base.cp); #if HAVE_RSRP_PLOT - float rsrp_lin = 0; + float rsrp_lin = 0; #endif sdrgui_init_title("Software Radio Systems NB-IoT Receiver"); diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 75bbd9d72..0fcddf3ec 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -75,7 +75,7 @@ static int mbsfn_area_id = -1; static char* rf_args = ""; static char* rf_dev = ""; static float rf_amp = 0.8, rf_gain = 60.0, rf_freq = 2400000000; -static bool enable_256qam = false; +static bool enable_256qam = false; static float output_file_snr = +INFINITY; static bool use_standard_lte_rate = false; @@ -151,7 +151,6 @@ static void parse_args(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "IadglfmoncpqvutxbwMsBQ")) != -1) { - switch (opt) { case 'I': rf_dev = argv[optind]; @@ -241,7 +240,7 @@ static void base_init() cell.nof_ports = 2; break; default: - ERROR("Transmission mode %d not implemented or invalid\n", transmission_mode); + ERROR("Transmission mode %d not implemented or invalid", transmission_mode); exit(-1); } @@ -278,7 +277,7 @@ static void base_init() if (output_file_name) { if (strcmp(output_file_name, "NULL")) { if (srslte_filesink_init(&fsink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", output_file_name); + ERROR("Error opening file %s", output_file_name); exit(-1); } null_file_sink = false; @@ -300,12 +299,12 @@ static void base_init() if (net_port > 0) { if (srslte_netsource_init(&net_source, "127.0.0.1", net_port, SRSLTE_NETSOURCE_UDP)) { - ERROR("Error creating input UDP socket at port %d\n", net_port); + ERROR("Error creating input UDP socket at port %d", net_port); exit(-1); } if (null_file_sink) { if (srslte_netsink_init(&net_sink, "127.0.0.1", net_port + 1, SRSLTE_NETSINK_TCP)) { - ERROR("Error sink\n"); + ERROR("Error sink"); exit(-1); } } @@ -318,7 +317,7 @@ static void base_init() /* create ifft object */ for (i = 0; i < cell.nof_ports; i++) { if (srslte_ofdm_tx_init(&ifft[i], SRSLTE_CP_NORM, sf_buffer[i], output_buffer[i], cell.nof_prb)) { - ERROR("Error creating iFFT object\n"); + ERROR("Error creating iFFT object"); exit(-1); } @@ -326,49 +325,49 @@ static void base_init() } if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSLTE_CP_EXT, sf_buffer[0], output_buffer[0], cell.nof_prb)) { - ERROR("Error creating iFFT object\n"); + ERROR("Error creating iFFT object"); exit(-1); } srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn, 2); srslte_ofdm_set_normalize(&ifft_mbsfn, true); if (srslte_pbch_init(&pbch)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } if (srslte_pbch_set_cell(&pbch, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating regs\n"); + ERROR("Error initiating regs"); exit(-1); } if (srslte_pcfich_init(&pcfich, 1)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } if (srslte_pcfich_set_cell(&pcfich, ®s, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } if (srslte_pdcch_init_enb(&pdcch, cell.nof_prb)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch, ®s, cell)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); exit(-1); } if (srslte_pdsch_init_enb(&pdsch, cell.nof_prb)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } if (srslte_pdsch_set_cell(&pdsch, cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } @@ -376,7 +375,7 @@ static void base_init() if (mbsfn_area_id > -1) { if (srslte_pmch_init(&pmch, cell.nof_prb, 1)) { - ERROR("Error creating PMCH object\n"); + ERROR("Error creating PMCH object"); } srslte_pmch_set_area_id(&pmch, mbsfn_area_id); } @@ -384,12 +383,12 @@ static void base_init() for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffers[i]) { - ERROR("Error allocating soft buffer\n"); + ERROR("Error allocating soft buffer"); exit(-1); } if (srslte_softbuffer_tx_init(softbuffers[i], cell.nof_prb)) { - ERROR("Error initiating soft buffer\n"); + ERROR("Error initiating soft buffer"); exit(-1); } } @@ -481,7 +480,6 @@ static uint32_t prbset_to_bitmask() static int update_radl() { - ZERO_OBJECT(dci_dl); /* Configure cell and PDSCH in function of the transmission mode */ @@ -675,7 +673,7 @@ static void* net_thread_fnc(void* arg) 1) / 8; rpm += n; - INFO("received %d bytes. rpm=%d/%d\n", n, rpm, nbytes); + INFO("received %d bytes. rpm=%d/%d", n, rpm, nbytes); wpm = 0; while (rpm >= nbytes) { // wait for packet to be transmitted @@ -686,19 +684,19 @@ static void* net_thread_fnc(void* arg) memcpy(data[0], &data2[wpm], nbytes / (size_t)2); memcpy(data[1], &data2[wpm], nbytes / (size_t)2); } - INFO("Sent %d/%d bytes ready\n", nbytes, rpm); + INFO("Sent %d/%d bytes ready", nbytes, rpm); rpm -= nbytes; wpm += nbytes; net_packet_ready = true; } if (wpm > 0) { - INFO("%d bytes left in buffer for next packet\n", rpm); + INFO("%d bytes left in buffer for next packet", rpm); memcpy(data2, &data2[wpm], rpm * sizeof(uint8_t)); } } else if (n == 0) { rpm = 0; } else { - ERROR("Error receiving from network\n"); + ERROR("Error receiving from network"); exit(-1); } } while (true); @@ -757,22 +755,22 @@ int main(int argc, char** argv) /* Generate reference signals */ if (srslte_refsignal_cs_init(&csr_refs, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); exit(-1); } if (mbsfn_area_id > -1) { if (srslte_refsignal_mbsfn_init(&mbsfn_refs, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); exit(-1); } if (srslte_refsignal_mbsfn_set_cell(&mbsfn_refs, cell, mbsfn_area_id)) { - ERROR("Error initializing MBSFNR signal\n"); + ERROR("Error initializing MBSFNR signal"); exit(-1); } } if (srslte_refsignal_cs_set_cell(&csr_refs, cell)) { - ERROR("Error setting cell\n"); + ERROR("Error setting cell"); exit(-1); } @@ -789,17 +787,16 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (!output_file_name) { - int srate = srslte_sampling_freq_hz(cell.nof_prb); if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srslte_rf_set_tx_srate(&radio, (double)srate); if (srate_rf != srate) { - ERROR("Could not set sampling rate\n"); + ERROR("Could not set sampling rate"); exit(-1); } } else { - ERROR("Invalid number of PRB %d\n", cell.nof_prb); + ERROR("Invalid number of PRB %d", cell.nof_prb); exit(-1); } srslte_rf_set_tx_gain(&radio, rf_gain); @@ -885,17 +882,17 @@ int main(int argc, char** argv) /* Update DL resource allocation from control port */ if (update_control()) { - ERROR("Error updating parameters from control port\n"); + ERROR("Error updating parameters from control port"); } /* Transmit PDCCH + PDSCH only when there is data to send */ if ((net_port > 0) && (mch_table[sf_idx] == 1 && mbsfn_area_id > -1)) { send_data = net_packet_ready; if (net_packet_ready) { - INFO("Transmitting packet from port\n"); + INFO("Transmitting packet from port"); } } else { - INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.tb[0].tbs + pdsch_cfg.grant.tb[1].tbs); + INFO("SF: %d, Generating %d random bits", sf_idx, pdsch_cfg.grant.tb[0].tbs + pdsch_cfg.grant.tb[1].tbs); for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { if (pdsch_cfg.grant.tb[tb].enabled) { for (i = 0; i < pdsch_cfg.grant.tb[tb].tbs / 8; i++) { @@ -915,24 +912,24 @@ int main(int argc, char** argv) dl_sf.sf_type = SRSLTE_SF_NORM; /* Encode PDCCH */ - INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L); + INFO("Putting DCI to location: n=%d, L=%d", locations[sf_idx][0].ncce, locations[sf_idx][0].L); srslte_dci_msg_pack_pdsch(&cell, &dl_sf, NULL, &dci_dl, &dci_msg); dci_msg.location = locations[sf_idx][0]; if (srslte_pdcch_encode(&pdcch, &dl_sf, &dci_msg, sf_symbols)) { - ERROR("Error encoding DCI message\n"); + ERROR("Error encoding DCI message"); exit(-1); } /* Configure pdsch_cfg parameters */ if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, transmission_mode, enable_256qam, &dci_dl, &pdsch_cfg.grant)) { - ERROR("Error configuring PDSCH\n"); + ERROR("Error configuring PDSCH"); exit(-1); } /* Encode PDSCH */ if (srslte_pdsch_encode(&pdsch, &dl_sf, &pdsch_cfg, data, sf_symbols)) { - ERROR("Error encoding PDSCH\n"); + ERROR("Error encoding PDSCH"); exit(-1); } if (net_port > 0 && net_packet_ready) { @@ -940,7 +937,7 @@ int main(int argc, char** argv) for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { srslte_bit_pack_vector(data[tb], data_tmp, pdsch_cfg.grant.tb[tb].tbs); if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pdsch_cfg.grant.tb[tb].tbs - 1) / 8) < 0) { - ERROR("Error sending data through UDP socket\n"); + ERROR("Error sending data through UDP socket"); } } } @@ -961,7 +958,7 @@ int main(int argc, char** argv) /* Configure pdsch_cfg parameters */ if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, enable_256qam, &dci_dl, &pmch_cfg.pdsch_cfg.grant)) { - ERROR("Error configuring PDSCH\n"); + ERROR("Error configuring PDSCH"); exit(-1); } @@ -973,14 +970,14 @@ int main(int argc, char** argv) /* Encode PMCH */ if (srslte_pmch_encode(&pmch, &dl_sf, &pmch_cfg, data_mbms, sf_symbols)) { - ERROR("Error encoding PDSCH\n"); + ERROR("Error encoding PDSCH"); exit(-1); } if (net_port > 0 && net_packet_ready) { if (null_file_sink) { srslte_bit_pack_vector(data[0], data_tmp, pmch_cfg.pdsch_cfg.grant.tb[0].tbs); if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pmch_cfg.pdsch_cfg.grant.tb[0].tbs - 1) / 8) < 0) { - ERROR("Error sending data through UDP socket\n"); + ERROR("Error sending data through UDP socket"); } } net_packet_ready = false; diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 805b0ff75..44fc497d5 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -346,7 +346,7 @@ cf_t* sf_buffer[SRSLTE_MAX_PORTS] = {NULL}; int srslte_rf_recv_wrapper(void* h, cf_t* data_[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); void* ptr[SRSLTE_MAX_PORTS]; for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { ptr[i] = data_[i]; @@ -424,7 +424,6 @@ int main(int argc, char** argv) generate_mcch_table(mch_table, prog_args.mbsfn_sf_mask); } if (prog_args.cpu_affinity > -1) { - cpu_set_t cpuset; pthread_t thread; @@ -435,7 +434,7 @@ int main(int argc, char** argv) CPU_SET((size_t)i, &cpuset); } if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset)) { - ERROR("Error setting main thread affinity to %d \n", prog_args.cpu_affinity); + ERROR("Error setting main thread affinity to %d", prog_args.cpu_affinity); exit(-1); } } @@ -443,7 +442,7 @@ int main(int argc, char** argv) if (prog_args.net_port > 0) { if (srslte_netsink_init(&net_sink, prog_args.net_address, prog_args.net_port, SRSLTE_NETSINK_UDP)) { - ERROR("Error initiating UDP socket to %s:%d\n", prog_args.net_address, prog_args.net_port); + ERROR("Error initiating UDP socket to %s:%d", prog_args.net_address, prog_args.net_port); exit(-1); } srslte_netsink_set_nonblocking(&net_sink); @@ -451,7 +450,7 @@ int main(int argc, char** argv) if (prog_args.net_port_signal > 0) { if (srslte_netsink_init( &net_sink_signal, prog_args.net_address_signal, prog_args.net_port_signal, SRSLTE_NETSINK_UDP)) { - ERROR("Error initiating UDP socket to %s:%d\n", prog_args.net_address_signal, prog_args.net_port_signal); + ERROR("Error initiating UDP socket to %s:%d", prog_args.net_address_signal, prog_args.net_port_signal); exit(-1); } srslte_netsink_set_nonblocking(&net_sink_signal); @@ -461,7 +460,6 @@ int main(int argc, char** argv) #ifndef DISABLE_RF if (!prog_args.input_file_name) { - printf("Opening RF device with %d RX antennas...\n", prog_args.rf_nof_rx_ant); if (srslte_rf_open_devname(&rf, prog_args.rf_dev, prog_args.rf_args, prog_args.rf_nof_rx_ant)) { fprintf(stderr, "Error opening rf\n"); @@ -473,7 +471,7 @@ int main(int argc, char** argv) } else { printf("Starting AGC thread...\n"); if (srslte_rf_start_gain_thread(&rf, false)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } srslte_rf_set_rx_gain(&rf, srslte_rf_get_rx_gain(&rf)); @@ -495,7 +493,7 @@ int main(int argc, char** argv) ret = rf_search_and_decode_mib( &rf, prog_args.rf_nof_rx_ant, &cell_detect_config, prog_args.force_N_id_2, &cell, &search_cell_cfo); if (ret < 0) { - ERROR("Error searching for cell\n"); + ERROR("Error searching for cell"); exit(-1); } else if (ret == 0 && !go_exit) { printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++); @@ -513,11 +511,11 @@ int main(int argc, char** argv) printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srslte_rf_set_rx_srate(&rf, (double)srate); if (srate_rf != srate) { - ERROR("Could not set sampling rate\n"); + ERROR("Could not set sampling rate"); exit(-1); } } else { - ERROR("Invalid number of PRB %d\n", cell.nof_prb); + ERROR("Invalid number of PRB %d", cell.nof_prb); exit(-1); } @@ -541,7 +539,7 @@ int main(int argc, char** argv) prog_args.file_offset_time, prog_args.file_offset_freq, prog_args.rf_nof_rx_ant)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); exit(-1); } @@ -562,11 +560,11 @@ int main(int argc, char** argv) prog_args.rf_nof_rx_ant, (void*)&rf, decimate)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); exit(-1); } if (srslte_ue_sync_set_cell(&ue_sync, cell)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); exit(-1); } #endif @@ -578,20 +576,20 @@ int main(int argc, char** argv) } srslte_ue_mib_t ue_mib; if (srslte_ue_mib_init(&ue_mib, sf_buffer[0], cell.nof_prb)) { - ERROR("Error initaiting UE MIB decoder\n"); + ERROR("Error initaiting UE MIB decoder"); exit(-1); } if (srslte_ue_mib_set_cell(&ue_mib, cell)) { - ERROR("Error initaiting UE MIB decoder\n"); + ERROR("Error initaiting UE MIB decoder"); exit(-1); } if (srslte_ue_dl_init(&ue_dl, sf_buffer, cell.nof_prb, prog_args.rf_nof_rx_ant)) { - ERROR("Error initiating UE downlink processing module\n"); + ERROR("Error initiating UE downlink processing module"); exit(-1); } if (srslte_ue_dl_set_cell(&ue_dl, cell)) { - ERROR("Error initiating UE downlink processing module\n"); + ERROR("Error initiating UE downlink processing module"); exit(-1); } @@ -676,7 +674,7 @@ int main(int argc, char** argv) srslte_pbch_decode_reset(&ue_mib.pbch); - INFO("\nEntering main loop...\n\n"); + INFO("\nEntering main loop..."); // Variables for measurements uint32_t nframes = 0; @@ -724,7 +722,7 @@ int main(int argc, char** argv) } ret = srslte_ue_sync_zerocopy(&ue_sync, buffers, max_num_samples); if (ret < 0) { - ERROR("Error calling srslte_ue_sync_work()\n"); + ERROR("Error calling srslte_ue_sync_work()"); } #ifdef CORRECT_SAMPLE_OFFSET @@ -735,7 +733,6 @@ int main(int argc, char** argv) /* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */ if (ret == 1) { - bool acks[SRSLTE_MAX_CODEWORDS] = {false}; struct timeval t[3]; @@ -748,7 +745,7 @@ int main(int argc, char** argv) int sfn_offset; n = srslte_ue_mib_decode(&ue_mib, bch_payload, NULL, &sfn_offset); if (n < 0) { - ERROR("Error decoding UE MIB\n"); + ERROR("Error decoding UE MIB"); exit(-1); } else if (n == SRSLTE_UE_MIB_FOUND) { srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); @@ -833,7 +830,6 @@ int main(int argc, char** argv) get_time_interval(t); if (n > 0) { - /* Send data if socket active */ if (prog_args.net_port > 0) { if (sf_idx == 1) { @@ -1143,7 +1139,6 @@ void* plot_thread_run(void* arg) void init_plots() { - if (sem_init(&plot_sem, 0, 0)) { perror("sem_init"); exit(-1); diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index e08b219ba..c29b9540f 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -210,7 +210,7 @@ void parse_args(prog_args_t* args, int argc, char** argv) #ifndef DISABLE_RF int srslte_rf_recv_wrapper(void* h, cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); void* ptr[SRSLTE_MAX_PORTS]; for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { ptr[i] = data[i]; @@ -238,7 +238,7 @@ int main(int argc, char** argv) srslte_sl_comm_resource_pool_t sl_comm_resource_pool; if (srslte_sl_comm_resource_pool_get_default_config(&sl_comm_resource_pool, cell_sl) != SRSLTE_SUCCESS) { - ERROR("Error initializing sl_comm_resource_pool\n"); + ERROR("Error initializing sl_comm_resource_pool"); return SRSLTE_ERROR; } @@ -254,7 +254,7 @@ int main(int argc, char** argv) printf("Opening RF device...\n"); if (srslte_rf_open_multi(&radio, prog_args.rf_args, prog_args.nof_rx_antennas)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } @@ -269,11 +269,11 @@ int main(int argc, char** argv) printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srslte_rf_set_rx_srate(&radio, (double)srate); if (srate_rf != srate) { - ERROR("Could not set sampling rate\n"); + ERROR("Could not set sampling rate"); exit(-1); } } else { - ERROR("Invalid number of PRB %d\n", cell_sl.nof_prb); + ERROR("Invalid number of PRB %d", cell_sl.nof_prb); exit(-1); } } @@ -316,7 +316,7 @@ int main(int argc, char** argv) ofdm_cfg.out_buffer = sf_buffer[0]; if (srslte_ofdm_rx_init_cfg(&fft[i], &ofdm_cfg)) { - ERROR("Error initiating FFT\n"); + ERROR("Error initiating FFT"); goto clean_exit; } } @@ -329,12 +329,12 @@ int main(int argc, char** argv) // init PSCCH object if (srslte_pscch_init(&pscch, SRSLTE_MAX_PRB) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH init\n"); + ERROR("Error in PSCCH init"); return SRSLTE_ERROR; } if (srslte_pscch_set_cell(&pscch, cell_sl) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH set cell\n"); + ERROR("Error in PSCCH set cell"); return SRSLTE_ERROR; } @@ -342,19 +342,19 @@ int main(int argc, char** argv) srslte_chest_sl_cfg_t pscch_chest_sl_cfg = {}; srslte_chest_sl_t pscch_chest = {}; if (srslte_chest_sl_init(&pscch_chest, SRSLTE_SIDELINK_PSCCH, cell_sl, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error in chest PSCCH init\n"); + ERROR("Error in chest PSCCH init"); return SRSLTE_ERROR; } if (srslte_pssch_init(&pssch, cell_sl, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error initializing PSSCH\n"); + ERROR("Error initializing PSSCH"); return SRSLTE_ERROR; } srslte_chest_sl_cfg_t pssch_chest_sl_cfg = {}; srslte_chest_sl_t pssch_chest = {}; if (srslte_chest_sl_init(&pssch_chest, SRSLTE_SIDELINK_PSSCH, cell_sl, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error in chest PSSCH init\n"); + ERROR("Error in chest PSSCH init"); return SRSLTE_ERROR; } @@ -382,7 +382,7 @@ int main(int argc, char** argv) } if (srslte_ue_sync_set_cell(&ue_sync, cell)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); exit(-1); } @@ -423,7 +423,7 @@ int main(int argc, char** argv) // receive subframe from radio int ret = srslte_ue_sync_zerocopy(&ue_sync, rx_buffer, sf_len); if (ret < 0) { - ERROR("Error calling srslte_ue_sync_work()\n"); + ERROR("Error calling srslte_ue_sync_work()"); } // update SF index @@ -438,7 +438,6 @@ int main(int argc, char** argv) pscch_prb_start_idx = sub_channel_idx * sl_comm_resource_pool.size_sub_channel; for (uint32_t cyclic_shift = 0; cyclic_shift <= 9; cyclic_shift += 3) { - // PSCCH Channel estimation pscch_chest_sl_cfg.cyclic_shift = cyclic_shift; pscch_chest_sl_cfg.prb_start_idx = pscch_prb_start_idx; diff --git a/lib/examples/synch_file.c b/lib/examples/synch_file.c index 2c73ba71d..c8ada96f2 100644 --- a/lib/examples/synch_file.c +++ b/lib/examples/synch_file.c @@ -127,11 +127,11 @@ int main(int argc, char** argv) fflush(stdout); if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } if (srslte_filesink_init(&fsink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", output_file_name); + ERROR("Error opening file %s", output_file_name); exit(-1); } @@ -152,7 +152,7 @@ int main(int argc, char** argv) } if (srslte_cfo_init(&cfocorr, frame_length)) { - ERROR("Error initiating CFO\n"); + ERROR("Error initiating CFO"); return -1; } @@ -163,19 +163,19 @@ int main(int argc, char** argv) */ for (N_id_2 = 0; N_id_2 < 3; N_id_2++) { if (srslte_pss_init_fft(&pss[N_id_2], frame_length, symbol_sz)) { - ERROR("Error initializing PSS object\n"); + ERROR("Error initializing PSS object"); exit(-1); } if (srslte_pss_set_N_id_2(&pss[N_id_2], N_id_2)) { - ERROR("Error initializing N_id_2\n"); + ERROR("Error initializing N_id_2"); exit(-1); } if (srslte_sss_init(&sss[N_id_2], symbol_sz)) { - ERROR("Error initializing SSS object\n"); + ERROR("Error initializing SSS object"); exit(-1); } if (srslte_sss_set_N_id_2(&sss[N_id_2], N_id_2)) { - ERROR("Error initializing N_id_2\n"); + ERROR("Error initializing N_id_2"); exit(-1); } } @@ -189,7 +189,6 @@ int main(int argc, char** argv) /* read all file or nof_frames */ frame_cnt = 0; while (frame_length == srslte_filesource_read(&fsrc, input, frame_length) && frame_cnt < nof_frames) { - gettimeofday(&tdata[1], NULL); if (force_cfo != CFO_AUTO) { srslte_cfo_correct(&cfocorr, input, input, force_cfo / 128); @@ -215,7 +214,6 @@ int main(int argc, char** argv) /* If peak detected */ if (peak_value[N_id_2] > corr_peak_threshold) { - sss_idx = peak_pos[N_id_2] - 2 * (symbol_sz + SRSLTE_CP_LEN(symbol_sz, SRSLTE_CP_NORM_LEN)); if (sss_idx >= 0) { srslte_sss_m0m1_diff(&sss[N_id_2], &input[sss_idx], &m0, &m0_value, &m1, &m1_value); diff --git a/lib/examples/usrp_capture.c b/lib/examples/usrp_capture.c index c410c6e5c..a755eeb86 100644 --- a/lib/examples/usrp_capture.c +++ b/lib/examples/usrp_capture.c @@ -122,9 +122,9 @@ int main(int argc, char** argv) srslte_filesink_init(&sink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN); - printf("Opening RF device...\n"); + printf("Opening RF device..."); if (srslte_rf_open_multi(&rf, rf_args, nof_rx_antennas)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } @@ -141,7 +141,7 @@ int main(int argc, char** argv) if (srate != rf_rate) { srate = srslte_rf_set_rx_srate(&rf, rf_rate); if (srate != rf_rate) { - ERROR("Error setting samplign frequency %.2f MHz\n", rf_rate * 1e-6); + ERROR("Error setting samplign frequency %.2f MHz", rf_rate * 1e-6); exit(-1); } } @@ -152,7 +152,7 @@ int main(int argc, char** argv) while ((sample_count < nof_samples || nof_samples == -1) && keep_running) { n = srslte_rf_recv_with_time_multi(&rf, (void**)buffer, buflen, true, NULL, NULL); if (n < 0) { - ERROR("Error receiving samples\n"); + ERROR("Error receiving samples"); exit(-1); } diff --git a/lib/examples/usrp_capture_sync.c b/lib/examples/usrp_capture_sync.c index 5c790c750..92e76c1ad 100644 --- a/lib/examples/usrp_capture_sync.c +++ b/lib/examples/usrp_capture_sync.c @@ -120,7 +120,7 @@ void parse_args(int argc, char** argv) int srslte_rf_recv_wrapper(void* h, cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); void* ptr[SRSLTE_MAX_PORTS]; for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { ptr[i] = data[i]; @@ -147,7 +147,7 @@ int main(int argc, char** argv) printf("Opening RF device...\n"); if (srslte_rf_open_multi(&rf, rf_args, nof_rx_antennas)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } @@ -169,11 +169,11 @@ int main(int argc, char** argv) printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srslte_rf_set_rx_srate(&rf, (double)srate); if (srate_rf != srate) { - ERROR("Could not set sampling rate\n"); + ERROR("Could not set sampling rate"); exit(-1); } } else { - ERROR("Invalid number of PRB %d\n", nof_prb); + ERROR("Invalid number of PRB %d", nof_prb); exit(-1); } srslte_rf_start_rx_stream(&rf, false); @@ -189,7 +189,7 @@ int main(int argc, char** argv) exit(-1); } if (srslte_ue_sync_set_cell(&ue_sync, cell)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); exit(-1); } @@ -200,7 +200,7 @@ int main(int argc, char** argv) while ((subframe_count < nof_subframes || nof_subframes == -1) && !stop_capture) { n = srslte_ue_sync_zerocopy(&ue_sync, buffer, max_num_samples); if (n < 0) { - ERROR("Error receiving samples\n"); + ERROR("Error receiving samples"); exit(-1); } if (n == 1) { diff --git a/lib/examples/usrp_capture_sync_nbiot.c b/lib/examples/usrp_capture_sync_nbiot.c index 220e91860..b6f4b98f5 100644 --- a/lib/examples/usrp_capture_sync_nbiot.c +++ b/lib/examples/usrp_capture_sync_nbiot.c @@ -92,7 +92,7 @@ void parse_args(int argc, char** argv) int srslte_rf_recv_wrapper(void* h, void* data, uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); return srslte_rf_recv(h, data, nsamples, 1); } diff --git a/lib/examples/usrp_txrx.c b/lib/examples/usrp_txrx.c index 33d9212f5..2d3d17f5e 100644 --- a/lib/examples/usrp_txrx.c +++ b/lib/examples/usrp_txrx.c @@ -85,7 +85,7 @@ void parse_args(int argc, char** argv) case 'p': nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); if (!srslte_nofprb_isvalid(nof_prb)) { - ERROR("Invalid number of UL RB %d\n", nof_prb); + ERROR("Invalid number of UL RB %d", nof_prb); exit(-1); } break; @@ -137,7 +137,7 @@ int main(int argc, char** argv) srslte_rf_t rf; printf("Opening RF device...\n"); if (srslte_rf_open(&rf, rf_args)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } diff --git a/lib/examples/zmq_remote_rx.c b/lib/examples/zmq_remote_rx.c index c41610299..cd8c90999 100644 --- a/lib/examples/zmq_remote_rx.c +++ b/lib/examples/zmq_remote_rx.c @@ -96,12 +96,12 @@ int main(int argc, char** argv) // Initializes ZMQ if (init_zmq()) { - ERROR("Initializing ZMQ\n"); + ERROR("Initializing ZMQ"); exit(-1); } if (init_radio(&buflen)) { - ERROR("Initializing Radio\n"); + ERROR("Initializing Radio"); exit(-1); } @@ -120,7 +120,7 @@ int main(int argc, char** argv) while (keep_running) { n = rx_radio(buffer, buflen); if (n < 0) { - ERROR("Error receiving samples\n"); + ERROR("Error receiving samples"); exit(-1); } if (srslte_verbose == SRSLTE_VERBOSE_INFO) { @@ -166,7 +166,7 @@ static int init_radio(uint32_t* buffer_len) // Uses srsLTE RF API to open a device, could use other code here printf("Opening RF device...\n"); if (srslte_rf_open_multi(&radio, rf_args, nof_rx_antennas)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); return -1; } srslte_rf_set_rx_gain(&radio, rf_gain); @@ -176,7 +176,7 @@ static int init_radio(uint32_t* buffer_len) printf("Set RX gain: %.2f dB\n", rf_gain); float srate = srslte_rf_set_rx_srate(&radio, rf_rate); if (srate != rf_rate) { - ERROR("Error setting samplign frequency %.2f MHz\n", rf_rate * 1e-6); + ERROR("Error setting samplign frequency %.2f MHz", rf_rate * 1e-6); return -1; } diff --git a/lib/include/srslte/adt/circular_array.h b/lib/include/srslte/adt/circular_array.h index 8e5874448..c47a3f23f 100644 --- a/lib/include/srslte/adt/circular_array.h +++ b/lib/include/srslte/adt/circular_array.h @@ -44,6 +44,9 @@ class circular_array std::array data{}; public: + using iterator = T*; + using const_iterator = const T*; + T& operator[](std::size_t pos) { return data[pos % N]; } const T& operator[](std::size_t pos) const { return data[pos % N]; } @@ -52,6 +55,8 @@ public: T* end() { return data.end(); } const T* end() const { return data.end(); } + + size_t size() const { return N; } }; } // namespace srslte diff --git a/lib/include/srslte/adt/span.h b/lib/include/srslte/adt/span.h index e3c000c0a..ff2fb7543 100644 --- a/lib/include/srslte/adt/span.h +++ b/lib/include/srslte/adt/span.h @@ -241,6 +241,9 @@ inline bool operator!=(span lhs, span rhs) return not lhs.equals(rhs); } +template +using const_span = span; + } // namespace srslte #endif // SRSLTE_SPAN_H diff --git a/lib/include/srslte/asn1/asn1_utils.h b/lib/include/srslte/asn1/asn1_utils.h index af64e7047..2327c1ba4 100644 --- a/lib/include/srslte/asn1/asn1_utils.h +++ b/lib/include/srslte/asn1/asn1_utils.h @@ -22,14 +22,14 @@ #ifndef SRSASN_COMMON_UTILS_H #define SRSASN_COMMON_UTILS_H -#include "srslte/srslog/bundled/fmt/format.h" +#include "srslte/srslog/srslog.h" #include #include #include +#include #include #include #include -#include #include #include @@ -62,10 +62,29 @@ struct static_max { logging ************************/ -void log_error(const char* format, ...); -void log_warning(const char* format, ...); -void log_info(const char* format, ...); -void log_debug(const char* format, ...); +template +void log_error(const char* format, Args&&... args) +{ + srslog::fetch_basic_logger("ASN1").error(format, std::forward(args)...); +} + +template +void log_warning(const char* format, Args&&... args) +{ + srslog::fetch_basic_logger("ASN1").warning(format, std::forward(args)...); +} + +template +void log_info(const char* format, Args&&... args) +{ + srslog::fetch_basic_logger("ASN1").info(format, std::forward(args)...); +} + +template +void log_debug(const char* format, Args&&... args) +{ + srslog::fetch_basic_logger("ASN1").debug(format, std::forward(args)...); +} void warn_assert(bool cond, const char* filename, int lineno); void log_invalid_access_choice_id(uint32_t val, uint32_t choice_id); @@ -226,7 +245,7 @@ public: iterator erase(iterator it) { if (it < begin() or it >= end()) { - log_warning("Trying to access out-of-bounds iterator.\n"); + log_warning("Trying to access out-of-bounds iterator."); return end(); } @@ -281,7 +300,7 @@ public: void push_back(const T& elem) { if (current_size >= MAX_N) { - log_error("Maximum size %d achieved for bounded_array.\n", MAX_N); + log_error("Maximum size %d achieved for bounded_array.", MAX_N); return; } data_[current_size++] = elem; @@ -645,7 +664,7 @@ public: fixed_octstring& from_string(const std::string& hexstr) { if (hexstr.size() != 2 * N) { - log_error("The provided hex string size is not valid (%zd!=2*%zd).\n", hexstr.size(), (size_t)N); + log_error("The provided hex string size is not valid (%zd!=2*%zd).", hexstr.size(), (size_t)N); } else { string_to_octstring(&octets_[0], hexstr); } @@ -716,7 +735,7 @@ public: bounded_octstring& from_string(const std::string& hexstr) { if (hexstr.size() > 2 * UB) { - log_error("The provided hex string size is not valid (%zd>2*%zd).\n", hexstr.size(), (size_t)UB); + log_error("The provided hex string size is not valid (%zd>2*%zd).", hexstr.size(), (size_t)UB); } else { resize(hexstr.size() / 2); string_to_octstring(&octets_[0], hexstr); @@ -877,7 +896,8 @@ public: this_type& from_string(const std::string& s) { if (s.size() < lb or s.size() > ub) { - log_error("The provided string size=%zd is not withing the bounds [%d, %d]\n", s.size(), lb, ub); + log_error( + "The provided string size=%zd is not withing the bounds [%d, %d]", s.size(), uint32_t(lb), uint32_t(ub)); } else { resize(s.size()); for (uint32_t i = 0; i < s.size(); ++i) { @@ -893,7 +913,7 @@ public: { auto nof_bits_ = std::max((uint32_t)ceilf(log2(std::max(val, (uint64_t)1u))), LB); if (nof_bits_ > UB) { - log_error("The provided bitstring value %ld does not fit the bounds [%d, %d]\n", val, lb, ub); + log_error("The provided bitstring value %ld does not fit the bounds [%d, %d]", val, uint32_t(lb), uint32_t(ub)); return *this; } resize(nof_bits_); @@ -1366,17 +1386,17 @@ int test_pack_unpack_consistency(const Msg& msg) // unpack and last pack done for the same number of bits if (bref3.distance() != bref2.distance()) { - log_error("[%s][%d] .\n", __FILE__, __LINE__); + log_error("[%s][%d] .", __FILE__, __LINE__); return -1; } // ensure packed messages are the same if (bref3.distance() != bref.distance()) { - log_error("[%s][%d] .\n", __FILE__, __LINE__); + log_error("[%s][%d] .", __FILE__, __LINE__); return -1; } if (memcmp(buf, buf2, bref.distance_bytes()) != 0) { - log_error("[%s][%d] .\n", __FILE__, __LINE__); + log_error("[%s][%d] .", __FILE__, __LINE__); return -1; } return SRSASN_SUCCESS; diff --git a/lib/include/srslte/asn1/liblte_common.h b/lib/include/srslte/asn1/liblte_common.h index ea46ceb36..30cd73bd2 100644 --- a/lib/include/srslte/asn1/liblte_common.h +++ b/lib/include/srslte/asn1/liblte_common.h @@ -31,7 +31,7 @@ // Caution these values must match SRSLTE_ ones in common.h #define LIBLTE_MAX_MSG_SIZE_BITS 102048 -#define LIBLTE_MAX_MSG_SIZE_BYTES 12756 +#define LIBLTE_MAX_MSG_SIZE_BYTES 12237 #define LIBLTE_MSG_HEADER_OFFSET 1020 // Macro to make it easier to convert defines into strings @@ -86,11 +86,12 @@ typedef struct { uint8 msg[LIBLTE_MAX_MSG_SIZE_BITS]; } LIBLTE_BIT_MSG_STRUCT __attribute__((aligned(8))); -typedef struct { +struct alignas(8) LIBLTE_BYTE_MSG_STRUCT +{ uint32 N_bytes; uint8 header[LIBLTE_MSG_HEADER_OFFSET]; uint8 msg[LIBLTE_MAX_MSG_SIZE_BYTES]; -} LIBLTE_BYTE_MSG_STRUCT; +}; /******************************************************************************* DECLARATIONS diff --git a/lib/include/srslte/asn1/rrc_nr.h b/lib/include/srslte/asn1/rrc_nr.h index 4ee70cdeb..85abafa95 100644 --- a/lib/include/srslte/asn1/rrc_nr.h +++ b/lib/include/srslte/asn1/rrc_nr.h @@ -2467,6 +2467,15 @@ private: elem_type_paramT_ c; }; + +template +std::string setup_release_c::types_opts::to_string() const +{ + static const char* options[] = {"release", "setup"}; + return convert_enum_idx(options, 2, value, "setup_release_c::types"); +} + + // UAC-BarringPerCat ::= SEQUENCE struct uac_barr_per_cat_s { uint8_t access_category = 1; diff --git a/lib/include/srslte/asn1/rrc_nr_utils.h b/lib/include/srslte/asn1/rrc_nr_utils.h index 0f021c8e5..41ba46bce 100644 --- a/lib/include/srslte/asn1/rrc_nr_utils.h +++ b/lib/include/srslte/asn1/rrc_nr_utils.h @@ -39,6 +39,7 @@ struct sib1_s; struct rlc_cfg_c; struct pdcp_cfg_s; struct lc_ch_cfg_s; +struct rach_cfg_common_s; } // namespace rrc_nr } // namespace asn1 @@ -55,6 +56,7 @@ void to_asn1(asn1::rrc_nr::plmn_id_s* asn1_type, const plmn_id_t& cfg); * MAC Config **************************/ logical_channel_config_t make_mac_logical_channel_cfg_t(uint8_t lcid, const asn1::rrc_nr::lc_ch_cfg_s& asn1_type); +rach_nr_cfg_t make_mac_rach_cfg(const asn1::rrc_nr::rach_cfg_common_s& asn1_type); /*************************** * RLC Config **************************/ diff --git a/lib/include/srslte/asn1/rrc_utils.h b/lib/include/srslte/asn1/rrc_utils.h index f60096641..671d4c077 100644 --- a/lib/include/srslte/asn1/rrc_utils.h +++ b/lib/include/srslte/asn1/rrc_utils.h @@ -84,7 +84,6 @@ struct ue_eutra_cap_s; * Conversion Helpers ***********************/ namespace srslte { - plmn_id_t make_plmn_id_t(const asn1::rrc::plmn_id_s& asn1_type); void to_asn1(asn1::rrc::plmn_id_s* asn1_type, const plmn_id_t& cfg); plmn_id_t make_plmn_id_t(const asn1::fixed_octstring<3, true>& asn1_type); @@ -105,6 +104,7 @@ void to_asn1(asn1::rrc::rlc_cfg_c* asn1_type, const rlc_config_t& cfg); **************************/ srslte::pdcp_config_t make_srb_pdcp_config_t(const uint8_t bearer_id, bool is_ue); srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue); +uint8_t get_pdcp_drb_sn_len(const asn1::rrc::pdcp_cfg_s& pdcp_cfg); srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const asn1::rrc::pdcp_cfg_s& pdcp_cfg); diff --git a/lib/include/srslte/asn1/s1ap_utils.h b/lib/include/srslte/asn1/s1ap_utils.h index 1de5292a4..ab15da539 100644 --- a/lib/include/srslte/asn1/s1ap_utils.h +++ b/lib/include/srslte/asn1/s1ap_utils.h @@ -45,6 +45,8 @@ struct rrc_establishment_cause_opts; struct cause_radio_network_opts; struct bearers_subject_to_status_transfer_item_ies_o; struct erab_level_qos_params_s; +struct ho_cmd_s; +struct erab_admitted_item_s; template struct protocol_ie_single_container_s; diff --git a/lib/include/srslte/common/backward.hpp b/lib/include/srslte/common/backward.hpp new file mode 100644 index 000000000..e79e2622d --- /dev/null +++ b/lib/include/srslte/common/backward.hpp @@ -0,0 +1,4406 @@ +/* + * backward.hpp + * Copyright 2013 Google Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef H_6B9572DA_A64B_49E6_B234_051480991C89 +#define H_6B9572DA_A64B_49E6_B234_051480991C89 + +#ifndef __cplusplus +#error "It's not going to compile without a C++ compiler..." +#endif + +#if defined(BACKWARD_CXX11) +#elif defined(BACKWARD_CXX98) +#else +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) +#define BACKWARD_CXX11 +#define BACKWARD_ATLEAST_CXX11 +#define BACKWARD_ATLEAST_CXX98 +#else +#define BACKWARD_CXX98 +#define BACKWARD_ATLEAST_CXX98 +#endif +#endif + +// You can define one of the following (or leave it to the auto-detection): +// +// #define BACKWARD_SYSTEM_LINUX +// - specialization for linux +// +// #define BACKWARD_SYSTEM_DARWIN +// - specialization for Mac OS X 10.5 and later. +// +// #define BACKWARD_SYSTEM_WINDOWS +// - specialization for Windows (Clang 9 and MSVC2017) +// +// #define BACKWARD_SYSTEM_UNKNOWN +// - placebo implementation, does nothing. +// +#if defined(BACKWARD_SYSTEM_LINUX) +#elif defined(BACKWARD_SYSTEM_DARWIN) +#elif defined(BACKWARD_SYSTEM_UNKNOWN) +#elif defined(BACKWARD_SYSTEM_WINDOWS) +#else +#if defined(__linux) || defined(__linux__) +#define BACKWARD_SYSTEM_LINUX +#elif defined(__APPLE__) +#define BACKWARD_SYSTEM_DARWIN +#elif defined(_WIN32) +#define BACKWARD_SYSTEM_WINDOWS +#else +#define BACKWARD_SYSTEM_UNKNOWN +#endif +#endif + +#define NOINLINE __attribute__((noinline)) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BACKWARD_SYSTEM_LINUX) + +// On linux, backtrace can back-trace or "walk" the stack using the following +// libraries: +// +// #define BACKWARD_HAS_UNWIND 1 +// - unwind comes from libgcc, but I saw an equivalent inside clang itself. +// - with unwind, the stacktrace is as accurate as it can possibly be, since +// this is used by the C++ runtine in gcc/clang for stack unwinding on +// exception. +// - normally libgcc is already linked to your program by default. +// +// #define BACKWARD_HAS_LIBUNWIND 1 +// - libunwind provides, in some cases, a more accurate stacktrace as it knows +// to decode signal handler frames and lets us edit the context registers when +// unwinding, allowing stack traces over bad function references. +// +// #define BACKWARD_HAS_BACKTRACE == 1 +// - backtrace seems to be a little bit more portable than libunwind, but on +// linux, it uses unwind anyway, but abstract away a tiny information that is +// sadly really important in order to get perfectly accurate stack traces. +// - backtrace is part of the (e)glib library. +// +// The default is: +// #define BACKWARD_HAS_UNWIND == 1 +// +// Note that only one of the define should be set to 1 at a time. +// +#if BACKWARD_HAS_UNWIND == 1 +#elif BACKWARD_HAS_LIBUNWIND == 1 +#elif BACKWARD_HAS_BACKTRACE == 1 +#else +#undef BACKWARD_HAS_UNWIND +#define BACKWARD_HAS_UNWIND 1 +#undef BACKWARD_HAS_LIBUNWIND +#define BACKWARD_HAS_LIBUNWIND 0 +#undef BACKWARD_HAS_BACKTRACE +#define BACKWARD_HAS_BACKTRACE 0 +#endif + +// On linux, backward can extract detailed information about a stack trace +// using one of the following libraries: +// +// #define BACKWARD_HAS_DW 1 +// - libdw gives you the most juicy details out of your stack traces: +// - object filename +// - function name +// - source filename +// - line and column numbers +// - source code snippet (assuming the file is accessible) +// - variables name and values (if not optimized out) +// - You need to link with the lib "dw": +// - apt-get install libdw-dev +// - g++/clang++ -ldw ... +// +// #define BACKWARD_HAS_BFD 1 +// - With libbfd, you get a fair amount of details: +// - object filename +// - function name +// - source filename +// - line numbers +// - source code snippet (assuming the file is accessible) +// - You need to link with the lib "bfd": +// - apt-get install binutils-dev +// - g++/clang++ -lbfd ... +// +// #define BACKWARD_HAS_DWARF 1 +// - libdwarf gives you the most juicy details out of your stack traces: +// - object filename +// - function name +// - source filename +// - line and column numbers +// - source code snippet (assuming the file is accessible) +// - variables name and values (if not optimized out) +// - You need to link with the lib "dwarf": +// - apt-get install libdwarf-dev +// - g++/clang++ -ldwarf ... +// +// #define BACKWARD_HAS_BACKTRACE_SYMBOL 1 +// - backtrace provides minimal details for a stack trace: +// - object filename +// - function name +// - backtrace is part of the (e)glib library. +// +// The default is: +// #define BACKWARD_HAS_BACKTRACE_SYMBOL == 1 +// +// Note that only one of the define should be set to 1 at a time. +// +#if BACKWARD_HAS_DW == 1 +#elif BACKWARD_HAS_BFD == 1 +#elif BACKWARD_HAS_DWARF == 1 +#elif BACKWARD_HAS_BACKTRACE_SYMBOL == 1 +#else +#undef BACKWARD_HAS_DW +#define BACKWARD_HAS_DW 0 +#undef BACKWARD_HAS_BFD +#define BACKWARD_HAS_BFD 0 +#undef BACKWARD_HAS_DWARF +#define BACKWARD_HAS_DWARF 0 +#undef BACKWARD_HAS_BACKTRACE_SYMBOL +#define BACKWARD_HAS_BACKTRACE_SYMBOL 1 +#endif + +#include +#include +#ifdef __ANDROID__ +// Old Android API levels define _Unwind_Ptr in both link.h and +// unwind.h Rename the one in link.h as we are not going to be using +// it +#define _Unwind_Ptr _Unwind_Ptr_Custom +#include +#undef _Unwind_Ptr +#else +#include +#endif +#include +#include +#include +#include + +#if BACKWARD_HAS_BFD == 1 +// NOTE: defining PACKAGE{,_VERSION} is required before including +// bfd.h on some platforms, see also: +// https://sourceware.org/bugzilla/show_bug.cgi?id=14243 +#ifndef PACKAGE +#define PACKAGE +#endif +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION +#endif +#include +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#else +#include +#endif +#endif + +#if BACKWARD_HAS_DW == 1 +#include +#include +#include +#endif + +#if BACKWARD_HAS_DWARF == 1 +#include +#include +#include +#include +#include +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#else +#include +#endif +#endif + +#if (BACKWARD_HAS_BACKTRACE == 1) || (BACKWARD_HAS_BACKTRACE_SYMBOL == 1) +// then we shall rely on backtrace +#include +#endif + +#endif // defined(BACKWARD_SYSTEM_LINUX) + +#if defined(BACKWARD_SYSTEM_DARWIN) +// On Darwin, backtrace can back-trace or "walk" the stack using the following +// libraries: +// +// #define BACKWARD_HAS_UNWIND 1 +// - unwind comes from libgcc, but I saw an equivalent inside clang itself. +// - with unwind, the stacktrace is as accurate as it can possibly be, since +// this is used by the C++ runtine in gcc/clang for stack unwinding on +// exception. +// - normally libgcc is already linked to your program by default. +// +// #define BACKWARD_HAS_LIBUNWIND 1 +// - libunwind comes from clang, which implements an API compatible version. +// - libunwind provides, in some cases, a more accurate stacktrace as it knows +// to decode signal handler frames and lets us edit the context registers when +// unwinding, allowing stack traces over bad function references. +// +// #define BACKWARD_HAS_BACKTRACE == 1 +// - backtrace is available by default, though it does not produce as much +// information as another library might. +// +// The default is: +// #define BACKWARD_HAS_UNWIND == 1 +// +// Note that only one of the define should be set to 1 at a time. +// +#if BACKWARD_HAS_UNWIND == 1 +#elif BACKWARD_HAS_BACKTRACE == 1 +#elif BACKWARD_HAS_LIBUNWIND == 1 +#else +#undef BACKWARD_HAS_UNWIND +#define BACKWARD_HAS_UNWIND 1 +#undef BACKWARD_HAS_BACKTRACE +#define BACKWARD_HAS_BACKTRACE 0 +#undef BACKWARD_HAS_LIBUNWIND +#define BACKWARD_HAS_LIBUNWIND 0 +#endif + +// On Darwin, backward can extract detailed information about a stack trace +// using one of the following libraries: +// +// #define BACKWARD_HAS_BACKTRACE_SYMBOL 1 +// - backtrace provides minimal details for a stack trace: +// - object filename +// - function name +// +// The default is: +// #define BACKWARD_HAS_BACKTRACE_SYMBOL == 1 +// +#if BACKWARD_HAS_BACKTRACE_SYMBOL == 1 +#else +#undef BACKWARD_HAS_BACKTRACE_SYMBOL +#define BACKWARD_HAS_BACKTRACE_SYMBOL 1 +#endif + +#include +#include +#include +#include +#include +#include + +#if (BACKWARD_HAS_BACKTRACE == 1) || (BACKWARD_HAS_BACKTRACE_SYMBOL == 1) +#include +#endif +#endif // defined(BACKWARD_SYSTEM_DARWIN) + +#if defined(BACKWARD_SYSTEM_WINDOWS) + +#include +#include +#include + +#include +typedef SSIZE_T ssize_t; + +#define NOMINMAX +#include +#include + +#include +#include + +#ifndef __clang__ +#undef NOINLINE +#define NOINLINE __declspec(noinline) +#endif + +#pragma comment(lib, "psapi.lib") +#pragma comment(lib, "dbghelp.lib") + +// Comment / packing is from stackoverflow: +// https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app/28276227#28276227 +// Some versions of imagehlp.dll lack the proper packing directives themselves +// so we need to do it. +#pragma pack(push, before_imagehlp, 8) +#include +#pragma pack(pop, before_imagehlp) + +// TODO maybe these should be undefined somewhere else? +#undef BACKWARD_HAS_UNWIND +#undef BACKWARD_HAS_BACKTRACE +#if BACKWARD_HAS_PDB_SYMBOL == 1 +#else +#undef BACKWARD_HAS_PDB_SYMBOL +#define BACKWARD_HAS_PDB_SYMBOL 1 +#endif + +#endif + +#if BACKWARD_HAS_UNWIND == 1 + +#include +// while gcc's unwind.h defines something like that: +// extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +// extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); +// +// clang's unwind.h defines something like this: +// uintptr_t _Unwind_GetIP(struct _Unwind_Context* __context); +// +// Even if the _Unwind_GetIPInfo can be linked to, it is not declared, worse we +// cannot just redeclare it because clang's unwind.h doesn't define _Unwind_Ptr +// anyway. +// +// Luckily we can play on the fact that the guard macros have a different name: +#ifdef __CLANG_UNWIND_H +// In fact, this function still comes from libgcc (on my different linux boxes, +// clang links against libgcc). +#include +extern "C" uintptr_t _Unwind_GetIPInfo(_Unwind_Context *, int *); +#endif + +#endif // BACKWARD_HAS_UNWIND == 1 + +#if BACKWARD_HAS_LIBUNWIND == 1 +#define UNW_LOCAL_ONLY +#include +#endif // BACKWARD_HAS_LIBUNWIND == 1 + +#ifdef BACKWARD_ATLEAST_CXX11 +#include +#include // for std::swap +namespace backward { +namespace details { +template struct hashtable { + typedef std::unordered_map type; +}; +using std::move; +} // namespace details +} // namespace backward +#else // NOT BACKWARD_ATLEAST_CXX11 +#define nullptr NULL +#define override +#include +namespace backward { +namespace details { +template struct hashtable { + typedef std::map type; +}; +template const T &move(const T &v) { return v; } +template T &move(T &v) { return v; } +} // namespace details +} // namespace backward +#endif // BACKWARD_ATLEAST_CXX11 + +namespace backward { +namespace details { +#if defined(BACKWARD_SYSTEM_WINDOWS) +const char kBackwardPathDelimiter[] = ";"; +#else +const char kBackwardPathDelimiter[] = ":"; +#endif +} // namespace details +} // namespace backward + +namespace backward { + +namespace system_tag { +struct linux_tag; // seems that I cannot call that "linux" because the name +// is already defined... so I am adding _tag everywhere. +struct darwin_tag; +struct windows_tag; +struct unknown_tag; + +#if defined(BACKWARD_SYSTEM_LINUX) +typedef linux_tag current_tag; +#elif defined(BACKWARD_SYSTEM_DARWIN) +typedef darwin_tag current_tag; +#elif defined(BACKWARD_SYSTEM_WINDOWS) +typedef windows_tag current_tag; +#elif defined(BACKWARD_SYSTEM_UNKNOWN) +typedef unknown_tag current_tag; +#else +#error "May I please get my system defines?" +#endif +} // namespace system_tag + +namespace trace_resolver_tag { +#if defined(BACKWARD_SYSTEM_LINUX) +struct libdw; +struct libbfd; +struct libdwarf; +struct backtrace_symbol; + +#if BACKWARD_HAS_DW == 1 +typedef libdw current; +#elif BACKWARD_HAS_BFD == 1 +typedef libbfd current; +#elif BACKWARD_HAS_DWARF == 1 +typedef libdwarf current; +#elif BACKWARD_HAS_BACKTRACE_SYMBOL == 1 +typedef backtrace_symbol current; +#else +#error "You shall not pass, until you know what you want." +#endif +#elif defined(BACKWARD_SYSTEM_DARWIN) +struct backtrace_symbol; + +#if BACKWARD_HAS_BACKTRACE_SYMBOL == 1 +typedef backtrace_symbol current; +#else +#error "You shall not pass, until you know what you want." +#endif +#elif defined(BACKWARD_SYSTEM_WINDOWS) +struct pdb_symbol; +#if BACKWARD_HAS_PDB_SYMBOL == 1 +typedef pdb_symbol current; +#else +#error "You shall not pass, until you know what you want." +#endif +#endif +} // namespace trace_resolver_tag + +namespace details { + +template struct rm_ptr { typedef T type; }; + +template struct rm_ptr { typedef T type; }; + +template struct rm_ptr { typedef const T type; }; + +template struct deleter { + template void operator()(U &ptr) const { (*F)(ptr); } +}; + +template struct default_delete { + void operator()(T &ptr) const { delete ptr; } +}; + +template > +class handle { + struct dummy; + T _val; + bool _empty; + +#ifdef BACKWARD_ATLEAST_CXX11 + handle(const handle &) = delete; + handle &operator=(const handle &) = delete; +#endif + +public: + ~handle() { + if (!_empty) { + Deleter()(_val); + } + } + + explicit handle() : _val(), _empty(true) {} + explicit handle(T val) : _val(val), _empty(false) { + if (!_val) + _empty = true; + } + +#ifdef BACKWARD_ATLEAST_CXX11 + handle(handle &&from) : _empty(true) { swap(from); } + handle &operator=(handle &&from) { + swap(from); + return *this; + } +#else + explicit handle(const handle &from) : _empty(true) { + // some sort of poor man's move semantic. + swap(const_cast(from)); + } + handle &operator=(const handle &from) { + // some sort of poor man's move semantic. + swap(const_cast(from)); + return *this; + } +#endif + + void reset(T new_val) { + handle tmp(new_val); + swap(tmp); + } + + void update(T new_val) { + _val = new_val; + _empty = !static_cast(new_val); + } + + operator const dummy *() const { + if (_empty) { + return nullptr; + } + return reinterpret_cast(_val); + } + T get() { return _val; } + T release() { + _empty = true; + return _val; + } + void swap(handle &b) { + using std::swap; + swap(b._val, _val); // can throw, we are safe here. + swap(b._empty, _empty); // should not throw: if you cannot swap two + // bools without throwing... It's a lost cause anyway! + } + + T &operator->() { return _val; } + const T &operator->() const { return _val; } + + typedef typename rm_ptr::type &ref_t; + typedef const typename rm_ptr::type &const_ref_t; + ref_t operator*() { return *_val; } + const_ref_t operator*() const { return *_val; } + ref_t operator[](size_t idx) { return _val[idx]; } + + // Watch out, we've got a badass over here + T *operator&() { + _empty = false; + return &_val; + } +}; + +// Default demangler implementation (do nothing). +template struct demangler_impl { + static std::string demangle(const char *funcname) { return funcname; } +}; + +#if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_DARWIN) + +template <> struct demangler_impl { + demangler_impl() : _demangle_buffer_length(0) {} + + std::string demangle(const char *funcname) { + using namespace details; + char *result = abi::__cxa_demangle(funcname, _demangle_buffer.get(), + &_demangle_buffer_length, nullptr); + if (result) { + _demangle_buffer.update(result); + return result; + } + return funcname; + } + +private: + details::handle _demangle_buffer; + size_t _demangle_buffer_length; +}; + +#endif // BACKWARD_SYSTEM_LINUX || BACKWARD_SYSTEM_DARWIN + +struct demangler : public demangler_impl {}; + +// Split a string on the platform's PATH delimiter. Example: if delimiter +// is ":" then: +// "" --> [] +// ":" --> ["",""] +// "::" --> ["","",""] +// "/a/b/c" --> ["/a/b/c"] +// "/a/b/c:/d/e/f" --> ["/a/b/c","/d/e/f"] +// etc. +inline std::vector split_source_prefixes(const std::string &s) { + std::vector out; + size_t last = 0; + size_t next = 0; + size_t delimiter_size = sizeof(kBackwardPathDelimiter) - 1; + while ((next = s.find(kBackwardPathDelimiter, last)) != std::string::npos) { + out.push_back(s.substr(last, next - last)); + last = next + delimiter_size; + } + if (last <= s.length()) { + out.push_back(s.substr(last)); + } + return out; +} + +} // namespace details + +/*************** A TRACE ***************/ + +struct Trace { + void *addr; + size_t idx; + + Trace() : addr(nullptr), idx(0) {} + + explicit Trace(void *_addr, size_t _idx) : addr(_addr), idx(_idx) {} +}; + +struct ResolvedTrace : public Trace { + + struct SourceLoc { + std::string function; + std::string filename; + unsigned line; + unsigned col; + + SourceLoc() : line(0), col(0) {} + + bool operator==(const SourceLoc &b) const { + return function == b.function && filename == b.filename && + line == b.line && col == b.col; + } + + bool operator!=(const SourceLoc &b) const { return !(*this == b); } + }; + + // In which binary object this trace is located. + std::string object_filename; + + // The function in the object that contain the trace. This is not the same + // as source.function which can be an function inlined in object_function. + std::string object_function; + + // The source location of this trace. It is possible for filename to be + // empty and for line/col to be invalid (value 0) if this information + // couldn't be deduced, for example if there is no debug information in the + // binary object. + SourceLoc source; + + // An optionals list of "inliners". All the successive sources location + // from where the source location of the trace (the attribute right above) + // is inlined. It is especially useful when you compiled with optimization. + typedef std::vector source_locs_t; + source_locs_t inliners; + + ResolvedTrace() : Trace() {} + ResolvedTrace(const Trace &mini_trace) : Trace(mini_trace) {} +}; + +/*************** STACK TRACE ***************/ + +// default implemention. +template class StackTraceImpl { +public: + size_t size() const { return 0; } + Trace operator[](size_t) const { return Trace(); } + size_t load_here(size_t = 0) { return 0; } + size_t load_from(void *, size_t = 0, void * = nullptr, void * = nullptr) { + return 0; + } + size_t thread_id() const { return 0; } + void skip_n_firsts(size_t) {} +}; + +class StackTraceImplBase { +public: + StackTraceImplBase() + : _thread_id(0), _skip(0), _context(nullptr), _error_addr(nullptr) {} + + size_t thread_id() const { return _thread_id; } + + void skip_n_firsts(size_t n) { _skip = n; } + +protected: + void load_thread_info() { +#ifdef BACKWARD_SYSTEM_LINUX +#ifndef __ANDROID__ + _thread_id = static_cast(syscall(SYS_gettid)); +#else + _thread_id = static_cast(gettid()); +#endif + if (_thread_id == static_cast(getpid())) { + // If the thread is the main one, let's hide that. + // I like to keep little secret sometimes. + _thread_id = 0; + } +#elif defined(BACKWARD_SYSTEM_DARWIN) + _thread_id = reinterpret_cast(pthread_self()); + if (pthread_main_np() == 1) { + // If the thread is the main one, let's hide that. + _thread_id = 0; + } +#endif + } + + void set_context(void *context) { _context = context; } + void *context() const { return _context; } + + void set_error_addr(void *error_addr) { _error_addr = error_addr; } + void *error_addr() const { return _error_addr; } + + size_t skip_n_firsts() const { return _skip; } + +private: + size_t _thread_id; + size_t _skip; + void *_context; + void *_error_addr; +}; + +class StackTraceImplHolder : public StackTraceImplBase { +public: + size_t size() const { + return (_stacktrace.size() >= skip_n_firsts()) + ? _stacktrace.size() - skip_n_firsts() + : 0; + } + Trace operator[](size_t idx) const { + if (idx >= size()) { + return Trace(); + } + return Trace(_stacktrace[idx + skip_n_firsts()], idx); + } + void *const *begin() const { + if (size()) { + return &_stacktrace[skip_n_firsts()]; + } + return nullptr; + } + +protected: + std::vector _stacktrace; +}; + +#if BACKWARD_HAS_UNWIND == 1 + +namespace details { + +template class Unwinder { +public: + size_t operator()(F &f, size_t depth) { + _f = &f; + _index = -1; + _depth = depth; + _Unwind_Backtrace(&this->backtrace_trampoline, this); + return static_cast(_index); + } + +private: + F *_f; + ssize_t _index; + size_t _depth; + + static _Unwind_Reason_Code backtrace_trampoline(_Unwind_Context *ctx, + void *self) { + return (static_cast(self))->backtrace(ctx); + } + + _Unwind_Reason_Code backtrace(_Unwind_Context *ctx) { + if (_index >= 0 && static_cast(_index) >= _depth) + return _URC_END_OF_STACK; + + int ip_before_instruction = 0; + uintptr_t ip = _Unwind_GetIPInfo(ctx, &ip_before_instruction); + + if (!ip_before_instruction) { + // calculating 0-1 for unsigned, looks like a possible bug to sanitiziers, + // so let's do it explicitly: + if (ip == 0) { + ip = std::numeric_limits::max(); // set it to 0xffff... (as + // from casting 0-1) + } else { + ip -= 1; // else just normally decrement it (no overflow/underflow will + // happen) + } + } + + if (_index >= 0) { // ignore first frame. + (*_f)(static_cast(_index), reinterpret_cast(ip)); + } + _index += 1; + return _URC_NO_REASON; + } +}; + +template size_t unwind(F f, size_t depth) { + Unwinder unwinder; + return unwinder(f, depth); +} + +} // namespace details + +template <> +class StackTraceImpl : public StackTraceImplHolder { +public: + NOINLINE + size_t load_here(size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + load_thread_info(); + set_context(context); + set_error_addr(error_addr); + if (depth == 0) { + return 0; + } + _stacktrace.resize(depth); + size_t trace_cnt = details::unwind(callback(*this), depth); + _stacktrace.resize(trace_cnt); + skip_n_firsts(0); + return size(); + } + size_t load_from(void *addr, size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + load_here(depth + 8, context, error_addr); + + for (size_t i = 0; i < _stacktrace.size(); ++i) { + if (_stacktrace[i] == addr) { + skip_n_firsts(i); + break; + } + } + + _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth)); + return size(); + } + +private: + struct callback { + StackTraceImpl &self; + callback(StackTraceImpl &_self) : self(_self) {} + + void operator()(size_t idx, void *addr) { self._stacktrace[idx] = addr; } + }; +}; + +#elif BACKWARD_HAS_LIBUNWIND == 1 + +template <> +class StackTraceImpl : public StackTraceImplHolder { +public: + __attribute__((noinline)) size_t load_here(size_t depth = 32, + void *_context = nullptr, + void *_error_addr = nullptr) { + set_context(_context); + set_error_addr(_error_addr); + load_thread_info(); + if (depth == 0) { + return 0; + } + _stacktrace.resize(depth + 1); + + int result = 0; + + unw_context_t ctx; + size_t index = 0; + + // Add the tail call. If the Instruction Pointer is the crash address it + // means we got a bad function pointer dereference, so we "unwind" the + // bad pointer manually by using the return address pointed to by the + // Stack Pointer as the Instruction Pointer and letting libunwind do + // the rest + + if (context()) { + ucontext_t *uctx = reinterpret_cast(context()); +#ifdef REG_RIP // x86_64 + if (uctx->uc_mcontext.gregs[REG_RIP] == + reinterpret_cast(error_addr())) { + uctx->uc_mcontext.gregs[REG_RIP] = + *reinterpret_cast(uctx->uc_mcontext.gregs[REG_RSP]); + } + _stacktrace[index] = + reinterpret_cast(uctx->uc_mcontext.gregs[REG_RIP]); + ++index; + ctx = *reinterpret_cast(uctx); +#elif defined(REG_EIP) // x86_32 + if (uctx->uc_mcontext.gregs[REG_EIP] == + reinterpret_cast(error_addr())) { + uctx->uc_mcontext.gregs[REG_EIP] = + *reinterpret_cast(uctx->uc_mcontext.gregs[REG_ESP]); + } + _stacktrace[index] = + reinterpret_cast(uctx->uc_mcontext.gregs[REG_EIP]); + ++index; + ctx = *reinterpret_cast(uctx); +#elif defined(__arm__) + // libunwind uses its own context type for ARM unwinding. + // Copy the registers from the signal handler's context so we can + // unwind + unw_getcontext(&ctx); + ctx.regs[UNW_ARM_R0] = uctx->uc_mcontext.arm_r0; + ctx.regs[UNW_ARM_R1] = uctx->uc_mcontext.arm_r1; + ctx.regs[UNW_ARM_R2] = uctx->uc_mcontext.arm_r2; + ctx.regs[UNW_ARM_R3] = uctx->uc_mcontext.arm_r3; + ctx.regs[UNW_ARM_R4] = uctx->uc_mcontext.arm_r4; + ctx.regs[UNW_ARM_R5] = uctx->uc_mcontext.arm_r5; + ctx.regs[UNW_ARM_R6] = uctx->uc_mcontext.arm_r6; + ctx.regs[UNW_ARM_R7] = uctx->uc_mcontext.arm_r7; + ctx.regs[UNW_ARM_R8] = uctx->uc_mcontext.arm_r8; + ctx.regs[UNW_ARM_R9] = uctx->uc_mcontext.arm_r9; + ctx.regs[UNW_ARM_R10] = uctx->uc_mcontext.arm_r10; + ctx.regs[UNW_ARM_R11] = uctx->uc_mcontext.arm_fp; + ctx.regs[UNW_ARM_R12] = uctx->uc_mcontext.arm_ip; + ctx.regs[UNW_ARM_R13] = uctx->uc_mcontext.arm_sp; + ctx.regs[UNW_ARM_R14] = uctx->uc_mcontext.arm_lr; + ctx.regs[UNW_ARM_R15] = uctx->uc_mcontext.arm_pc; + + // If we have crashed in the PC use the LR instead, as this was + // a bad function dereference + if (reinterpret_cast(error_addr()) == + uctx->uc_mcontext.arm_pc) { + ctx.regs[UNW_ARM_R15] = + uctx->uc_mcontext.arm_lr - sizeof(unsigned long); + } + _stacktrace[index] = reinterpret_cast(ctx.regs[UNW_ARM_R15]); + ++index; +#elif defined(__APPLE__) && defined(__x86_64__) + unw_getcontext(&ctx); + // OS X's implementation of libunwind uses its own context object + // so we need to convert the passed context to libunwind's format + // (information about the data layout taken from unw_getcontext.s + // in Apple's libunwind source + ctx.data[0] = uctx->uc_mcontext->__ss.__rax; + ctx.data[1] = uctx->uc_mcontext->__ss.__rbx; + ctx.data[2] = uctx->uc_mcontext->__ss.__rcx; + ctx.data[3] = uctx->uc_mcontext->__ss.__rdx; + ctx.data[4] = uctx->uc_mcontext->__ss.__rdi; + ctx.data[5] = uctx->uc_mcontext->__ss.__rsi; + ctx.data[6] = uctx->uc_mcontext->__ss.__rbp; + ctx.data[7] = uctx->uc_mcontext->__ss.__rsp; + ctx.data[8] = uctx->uc_mcontext->__ss.__r8; + ctx.data[9] = uctx->uc_mcontext->__ss.__r9; + ctx.data[10] = uctx->uc_mcontext->__ss.__r10; + ctx.data[11] = uctx->uc_mcontext->__ss.__r11; + ctx.data[12] = uctx->uc_mcontext->__ss.__r12; + ctx.data[13] = uctx->uc_mcontext->__ss.__r13; + ctx.data[14] = uctx->uc_mcontext->__ss.__r14; + ctx.data[15] = uctx->uc_mcontext->__ss.__r15; + ctx.data[16] = uctx->uc_mcontext->__ss.__rip; + + // If the IP is the same as the crash address we have a bad function + // dereference The caller's address is pointed to by %rsp, so we + // dereference that value and set it to be the next frame's IP. + if (uctx->uc_mcontext->__ss.__rip == + reinterpret_cast<__uint64_t>(error_addr())) { + ctx.data[16] = + *reinterpret_cast<__uint64_t *>(uctx->uc_mcontext->__ss.__rsp); + } + _stacktrace[index] = reinterpret_cast(ctx.data[16]); + ++index; +#elif defined(__APPLE__) + unw_getcontext(&ctx) + // TODO: Convert the ucontext_t to libunwind's unw_context_t like + // we do in 64 bits + if (ctx.uc_mcontext->__ss.__eip == + reinterpret_cast(error_addr())) { + ctx.uc_mcontext->__ss.__eip = ctx.uc_mcontext->__ss.__esp; + } + _stacktrace[index] = + reinterpret_cast(ctx.uc_mcontext->__ss.__eip); + ++index; +#endif + } + + unw_cursor_t cursor; + if (context()) { +#if defined(UNW_INIT_SIGNAL_FRAME) + result = unw_init_local2(&cursor, &ctx, UNW_INIT_SIGNAL_FRAME); +#else + result = unw_init_local(&cursor, &ctx); +#endif + } else { + unw_getcontext(&ctx); + ; + result = unw_init_local(&cursor, &ctx); + } + + if (result != 0) + return 1; + + unw_word_t ip = 0; + + while (index <= depth && unw_step(&cursor) > 0) { + result = unw_get_reg(&cursor, UNW_REG_IP, &ip); + if (result == 0) { + _stacktrace[index] = reinterpret_cast(--ip); + ++index; + } + } + --index; + + _stacktrace.resize(index + 1); + skip_n_firsts(0); + return size(); + } + + size_t load_from(void *addr, size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + load_here(depth + 8, context, error_addr); + + for (size_t i = 0; i < _stacktrace.size(); ++i) { + if (_stacktrace[i] == addr) { + skip_n_firsts(i); + _stacktrace[i] = (void *)((uintptr_t)_stacktrace[i]); + break; + } + } + + _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth)); + return size(); + } +}; + +#elif defined(BACKWARD_HAS_BACKTRACE) + +template <> +class StackTraceImpl : public StackTraceImplHolder { +public: + NOINLINE + size_t load_here(size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + set_context(context); + set_error_addr(error_addr); + load_thread_info(); + if (depth == 0) { + return 0; + } + _stacktrace.resize(depth + 1); + size_t trace_cnt = backtrace(&_stacktrace[0], _stacktrace.size()); + _stacktrace.resize(trace_cnt); + skip_n_firsts(1); + return size(); + } + + size_t load_from(void *addr, size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + load_here(depth + 8, contxt, error_addr); + + for (size_t i = 0; i < _stacktrace.size(); ++i) { + if (_stacktrace[i] == addr) { + skip_n_firsts(i); + _stacktrace[i] = (void *)((uintptr_t)_stacktrace[i] + 1); + break; + } + } + + _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth)); + return size(); + } +}; + +#elif defined(BACKWARD_SYSTEM_WINDOWS) + +template <> +class StackTraceImpl : public StackTraceImplHolder { +public: + // We have to load the machine type from the image info + // So we first initialize the resolver, and it tells us this info + void set_machine_type(DWORD machine_type) { machine_type_ = machine_type; } + void set_context(CONTEXT *ctx) { ctx_ = ctx; } + void set_thread_handle(HANDLE handle) { thd_ = handle; } + + NOINLINE + size_t load_here(size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + set_context(static_cast(context)); + set_error_addr(error_addr); + CONTEXT localCtx; // used when no context is provided + + if (depth == 0) { + return 0; + } + + if (!ctx_) { + ctx_ = &localCtx; + RtlCaptureContext(ctx_); + } + + if (!thd_) { + thd_ = GetCurrentThread(); + } + + HANDLE process = GetCurrentProcess(); + + STACKFRAME64 s; + memset(&s, 0, sizeof(STACKFRAME64)); + + // TODO: 32 bit context capture + s.AddrStack.Mode = AddrModeFlat; + s.AddrFrame.Mode = AddrModeFlat; + s.AddrPC.Mode = AddrModeFlat; +#ifdef _M_X64 + s.AddrPC.Offset = ctx_->Rip; + s.AddrStack.Offset = ctx_->Rsp; + s.AddrFrame.Offset = ctx_->Rbp; +#else + s.AddrPC.Offset = ctx_->Eip; + s.AddrStack.Offset = ctx_->Esp; + s.AddrFrame.Offset = ctx_->Ebp; +#endif + + if (!machine_type_) { +#ifdef _M_X64 + machine_type_ = IMAGE_FILE_MACHINE_AMD64; +#else + machine_type_ = IMAGE_FILE_MACHINE_I386; +#endif + } + + for (;;) { + // NOTE: this only works if PDBs are already loaded! + SetLastError(0); + if (!StackWalk64(machine_type_, process, thd_, &s, ctx_, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL)) + break; + + if (s.AddrReturn.Offset == 0) + break; + + _stacktrace.push_back(reinterpret_cast(s.AddrPC.Offset)); + + if (size() >= depth) + break; + } + + return size(); + } + + size_t load_from(void *addr, size_t depth = 32, void *context = nullptr, + void *error_addr = nullptr) { + load_here(depth + 8, context, error_addr); + + for (size_t i = 0; i < _stacktrace.size(); ++i) { + if (_stacktrace[i] == addr) { + skip_n_firsts(i); + break; + } + } + + _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth)); + return size(); + } + +private: + DWORD machine_type_ = 0; + HANDLE thd_ = 0; + CONTEXT *ctx_ = nullptr; +}; + +#endif + +class StackTrace : public StackTraceImpl {}; + +/*************** TRACE RESOLVER ***************/ + +template class TraceResolverImpl; + +#ifdef BACKWARD_SYSTEM_UNKNOWN + +template <> class TraceResolverImpl { +public: + template void load_stacktrace(ST &) {} + ResolvedTrace resolve(ResolvedTrace t) { return t; } +}; + +#endif + +class TraceResolverImplBase { +protected: + std::string demangle(const char *funcname) { + return _demangler.demangle(funcname); + } + +private: + details::demangler _demangler; +}; + +#ifdef BACKWARD_SYSTEM_LINUX + +class TraceResolverLinuxBase : public TraceResolverImplBase { +public: + TraceResolverLinuxBase() + : argv0_(get_argv0()), exec_path_(read_symlink("/proc/self/exe")) {} + std::string resolve_exec_path(Dl_info &symbol_info) const { + // mutates symbol_info.dli_fname to be filename to open and returns filename + // to display + if (symbol_info.dli_fname == argv0_) { + // dladdr returns argv[0] in dli_fname for symbols contained in + // the main executable, which is not a valid path if the + // executable was found by a search of the PATH environment + // variable; In that case, we actually open /proc/self/exe, which + // is always the actual executable (even if it was deleted/replaced!) + // but display the path that /proc/self/exe links to. + symbol_info.dli_fname = "/proc/self/exe"; + return exec_path_; + } else { + return symbol_info.dli_fname; + } + } + +private: + std::string argv0_; + std::string exec_path_; + + static std::string get_argv0() { + std::string argv0; + std::ifstream ifs("/proc/self/cmdline"); + std::getline(ifs, argv0, '\0'); + return argv0; + } + + static std::string read_symlink(std::string const &symlink_path) { + std::string path; + path.resize(100); + + while (true) { + ssize_t len = + ::readlink(symlink_path.c_str(), &*path.begin(), path.size()); + if (len < 0) { + return ""; + } + if (static_cast(len) == path.size()) { + path.resize(path.size() * 2); + } else { + path.resize(static_cast(len)); + break; + } + } + + return path; + } +}; + +template class TraceResolverLinuxImpl; + +#if BACKWARD_HAS_BACKTRACE_SYMBOL == 1 + +template <> +class TraceResolverLinuxImpl + : public TraceResolverLinuxBase { +public: + template void load_stacktrace(ST &st) { + using namespace details; + if (st.size() == 0) { + return; + } + _symbols.reset(backtrace_symbols(st.begin(), (int)st.size())); + } + + ResolvedTrace resolve(ResolvedTrace trace) { + char *filename = _symbols[trace.idx]; + char *funcname = filename; + while (*funcname && *funcname != '(') { + funcname += 1; + } + trace.object_filename.assign(filename, + funcname); // ok even if funcname is the ending + // \0 (then we assign entire string) + + if (*funcname) { // if it's not end of string (e.g. from last frame ip==0) + funcname += 1; + char *funcname_end = funcname; + while (*funcname_end && *funcname_end != ')' && *funcname_end != '+') { + funcname_end += 1; + } + *funcname_end = '\0'; + trace.object_function = this->demangle(funcname); + trace.source.function = trace.object_function; // we cannot do better. + } + return trace; + } + +private: + details::handle _symbols; +}; + +#endif // BACKWARD_HAS_BACKTRACE_SYMBOL == 1 + +#if BACKWARD_HAS_BFD == 1 + +template <> +class TraceResolverLinuxImpl + : public TraceResolverLinuxBase { +public: + TraceResolverLinuxImpl() : _bfd_loaded(false) {} + + template void load_stacktrace(ST &) {} + + ResolvedTrace resolve(ResolvedTrace trace) { + Dl_info symbol_info; + + // trace.addr is a virtual address in memory pointing to some code. + // Let's try to find from which loaded object it comes from. + // The loaded object can be yourself btw. + if (!dladdr(trace.addr, &symbol_info)) { + return trace; // dat broken trace... + } + + // Now we get in symbol_info: + // .dli_fname: + // pathname of the shared object that contains the address. + // .dli_fbase: + // where the object is loaded in memory. + // .dli_sname: + // the name of the nearest symbol to trace.addr, we expect a + // function name. + // .dli_saddr: + // the exact address corresponding to .dli_sname. + + if (symbol_info.dli_sname) { + trace.object_function = demangle(symbol_info.dli_sname); + } + + if (!symbol_info.dli_fname) { + return trace; + } + + trace.object_filename = resolve_exec_path(symbol_info); + bfd_fileobject &fobj = load_object_with_bfd(symbol_info.dli_fname); + if (!fobj.handle) { + return trace; // sad, we couldn't load the object :( + } + + find_sym_result *details_selected; // to be filled. + + // trace.addr is the next instruction to be executed after returning + // from the nested stack frame. In C++ this usually relate to the next + // statement right after the function call that leaded to a new stack + // frame. This is not usually what you want to see when printing out a + // stacktrace... + find_sym_result details_call_site = + find_symbol_details(fobj, trace.addr, symbol_info.dli_fbase); + details_selected = &details_call_site; + +#if BACKWARD_HAS_UNWIND == 0 + // ...this is why we also try to resolve the symbol that is right + // before the return address. If we are lucky enough, we will get the + // line of the function that was called. But if the code is optimized, + // we might get something absolutely not related since the compiler + // can reschedule the return address with inline functions and + // tail-call optimisation (among other things that I don't even know + // or cannot even dream about with my tiny limited brain). + find_sym_result details_adjusted_call_site = find_symbol_details( + fobj, (void *)(uintptr_t(trace.addr) - 1), symbol_info.dli_fbase); + + // In debug mode, we should always get the right thing(TM). + if (details_call_site.found && details_adjusted_call_site.found) { + // Ok, we assume that details_adjusted_call_site is a better estimation. + details_selected = &details_adjusted_call_site; + trace.addr = (void *)(uintptr_t(trace.addr) - 1); + } + + if (details_selected == &details_call_site && details_call_site.found) { + // we have to re-resolve the symbol in order to reset some + // internal state in BFD... so we can call backtrace_inliners + // thereafter... + details_call_site = + find_symbol_details(fobj, trace.addr, symbol_info.dli_fbase); + } +#endif // BACKWARD_HAS_UNWIND + + if (details_selected->found) { + if (details_selected->filename) { + trace.source.filename = details_selected->filename; + } + trace.source.line = details_selected->line; + + if (details_selected->funcname) { + // this time we get the name of the function where the code is + // located, instead of the function were the address is + // located. In short, if the code was inlined, we get the + // function correspoding to the code. Else we already got in + // trace.function. + trace.source.function = demangle(details_selected->funcname); + + if (!symbol_info.dli_sname) { + // for the case dladdr failed to find the symbol name of + // the function, we might as well try to put something + // here. + trace.object_function = trace.source.function; + } + } + + // Maybe the source of the trace got inlined inside the function + // (trace.source.function). Let's see if we can get all the inlined + // calls along the way up to the initial call site. + trace.inliners = backtrace_inliners(fobj, *details_selected); + +#if 0 + if (trace.inliners.size() == 0) { + // Maybe the trace was not inlined... or maybe it was and we + // are lacking the debug information. Let's try to make the + // world better and see if we can get the line number of the + // function (trace.source.function) now. + // + // We will get the location of where the function start (to be + // exact: the first instruction that really start the + // function), not where the name of the function is defined. + // This can be quite far away from the name of the function + // btw. + // + // If the source of the function is the same as the source of + // the trace, we cannot say if the trace was really inlined or + // not. However, if the filename of the source is different + // between the function and the trace... we can declare it as + // an inliner. This is not 100% accurate, but better than + // nothing. + + if (symbol_info.dli_saddr) { + find_sym_result details = find_symbol_details(fobj, + symbol_info.dli_saddr, + symbol_info.dli_fbase); + + if (details.found) { + ResolvedTrace::SourceLoc diy_inliner; + diy_inliner.line = details.line; + if (details.filename) { + diy_inliner.filename = details.filename; + } + if (details.funcname) { + diy_inliner.function = demangle(details.funcname); + } else { + diy_inliner.function = trace.source.function; + } + if (diy_inliner != trace.source) { + trace.inliners.push_back(diy_inliner); + } + } + } + } +#endif + } + + return trace; + } + +private: + bool _bfd_loaded; + + typedef details::handle> + bfd_handle_t; + + typedef details::handle bfd_symtab_t; + + struct bfd_fileobject { + bfd_handle_t handle; + bfd_vma base_addr; + bfd_symtab_t symtab; + bfd_symtab_t dynamic_symtab; + }; + + typedef details::hashtable::type fobj_bfd_map_t; + fobj_bfd_map_t _fobj_bfd_map; + + bfd_fileobject &load_object_with_bfd(const std::string &filename_object) { + using namespace details; + + if (!_bfd_loaded) { + using namespace details; + bfd_init(); + _bfd_loaded = true; + } + + fobj_bfd_map_t::iterator it = _fobj_bfd_map.find(filename_object); + if (it != _fobj_bfd_map.end()) { + return it->second; + } + + // this new object is empty for now. + bfd_fileobject &r = _fobj_bfd_map[filename_object]; + + // we do the work temporary in this one; + bfd_handle_t bfd_handle; + + int fd = open(filename_object.c_str(), O_RDONLY); + bfd_handle.reset(bfd_fdopenr(filename_object.c_str(), "default", fd)); + if (!bfd_handle) { + close(fd); + return r; + } + + if (!bfd_check_format(bfd_handle.get(), bfd_object)) { + return r; // not an object? You lose. + } + + if ((bfd_get_file_flags(bfd_handle.get()) & HAS_SYMS) == 0) { + return r; // that's what happen when you forget to compile in debug. + } + + ssize_t symtab_storage_size = bfd_get_symtab_upper_bound(bfd_handle.get()); + + ssize_t dyn_symtab_storage_size = + bfd_get_dynamic_symtab_upper_bound(bfd_handle.get()); + + if (symtab_storage_size <= 0 && dyn_symtab_storage_size <= 0) { + return r; // weird, is the file is corrupted? + } + + bfd_symtab_t symtab, dynamic_symtab; + ssize_t symcount = 0, dyn_symcount = 0; + + if (symtab_storage_size > 0) { + symtab.reset(static_cast( + malloc(static_cast(symtab_storage_size)))); + symcount = bfd_canonicalize_symtab(bfd_handle.get(), symtab.get()); + } + + if (dyn_symtab_storage_size > 0) { + dynamic_symtab.reset(static_cast( + malloc(static_cast(dyn_symtab_storage_size)))); + dyn_symcount = bfd_canonicalize_dynamic_symtab(bfd_handle.get(), + dynamic_symtab.get()); + } + + if (symcount <= 0 && dyn_symcount <= 0) { + return r; // damned, that's a stripped file that you got there! + } + + r.handle = move(bfd_handle); + r.symtab = move(symtab); + r.dynamic_symtab = move(dynamic_symtab); + return r; + } + + struct find_sym_result { + bool found; + const char *filename; + const char *funcname; + unsigned int line; + }; + + struct find_sym_context { + TraceResolverLinuxImpl *self; + bfd_fileobject *fobj; + void *addr; + void *base_addr; + find_sym_result result; + }; + + find_sym_result find_symbol_details(bfd_fileobject &fobj, void *addr, + void *base_addr) { + find_sym_context context; + context.self = this; + context.fobj = &fobj; + context.addr = addr; + context.base_addr = base_addr; + context.result.found = false; + bfd_map_over_sections(fobj.handle.get(), &find_in_section_trampoline, + static_cast(&context)); + return context.result; + } + + static void find_in_section_trampoline(bfd *, asection *section, void *data) { + find_sym_context *context = static_cast(data); + context->self->find_in_section( + reinterpret_cast(context->addr), + reinterpret_cast(context->base_addr), *context->fobj, section, + context->result); + } + + void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject &fobj, + asection *section, find_sym_result &result) { + if (result.found) + return; + +#ifdef bfd_get_section_flags + if ((bfd_get_section_flags(fobj.handle.get(), section) & SEC_ALLOC) == 0) +#else + if ((bfd_section_flags(section) & SEC_ALLOC) == 0) +#endif + return; // a debug section is never loaded automatically. + +#ifdef bfd_get_section_vma + bfd_vma sec_addr = bfd_get_section_vma(fobj.handle.get(), section); +#else + bfd_vma sec_addr = bfd_section_vma(section); +#endif +#ifdef bfd_get_section_size + bfd_size_type size = bfd_get_section_size(section); +#else + bfd_size_type size = bfd_section_size(section); +#endif + + // are we in the boundaries of the section? + if (addr < sec_addr || addr >= sec_addr + size) { + addr -= base_addr; // oups, a relocated object, lets try again... + if (addr < sec_addr || addr >= sec_addr + size) { + return; + } + } + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + if (!result.found && fobj.symtab) { + result.found = bfd_find_nearest_line( + fobj.handle.get(), section, fobj.symtab.get(), addr - sec_addr, + &result.filename, &result.funcname, &result.line); + } + + if (!result.found && fobj.dynamic_symtab) { + result.found = bfd_find_nearest_line( + fobj.handle.get(), section, fobj.dynamic_symtab.get(), + addr - sec_addr, &result.filename, &result.funcname, &result.line); + } +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + } + + ResolvedTrace::source_locs_t + backtrace_inliners(bfd_fileobject &fobj, find_sym_result previous_result) { + // This function can be called ONLY after a SUCCESSFUL call to + // find_symbol_details. The state is global to the bfd_handle. + ResolvedTrace::source_locs_t results; + while (previous_result.found) { + find_sym_result result; + result.found = bfd_find_inliner_info(fobj.handle.get(), &result.filename, + &result.funcname, &result.line); + + if (result + .found) /* and not ( + cstrings_eq(previous_result.filename, + result.filename) and + cstrings_eq(previous_result.funcname, result.funcname) + and result.line == previous_result.line + )) */ + { + ResolvedTrace::SourceLoc src_loc; + src_loc.line = result.line; + if (result.filename) { + src_loc.filename = result.filename; + } + if (result.funcname) { + src_loc.function = demangle(result.funcname); + } + results.push_back(src_loc); + } + previous_result = result; + } + return results; + } + + bool cstrings_eq(const char *a, const char *b) { + if (!a || !b) { + return false; + } + return strcmp(a, b) == 0; + } +}; +#endif // BACKWARD_HAS_BFD == 1 + +#if BACKWARD_HAS_DW == 1 + +template <> +class TraceResolverLinuxImpl + : public TraceResolverLinuxBase { +public: + TraceResolverLinuxImpl() : _dwfl_handle_initialized(false) {} + + template void load_stacktrace(ST &) {} + + ResolvedTrace resolve(ResolvedTrace trace) { + using namespace details; + + Dwarf_Addr trace_addr = (Dwarf_Addr)trace.addr; + + if (!_dwfl_handle_initialized) { + // initialize dwfl... + _dwfl_cb.reset(new Dwfl_Callbacks); + _dwfl_cb->find_elf = &dwfl_linux_proc_find_elf; + _dwfl_cb->find_debuginfo = &dwfl_standard_find_debuginfo; + _dwfl_cb->debuginfo_path = 0; + + _dwfl_handle.reset(dwfl_begin(_dwfl_cb.get())); + _dwfl_handle_initialized = true; + + if (!_dwfl_handle) { + return trace; + } + + // ...from the current process. + dwfl_report_begin(_dwfl_handle.get()); + int r = dwfl_linux_proc_report(_dwfl_handle.get(), getpid()); + dwfl_report_end(_dwfl_handle.get(), NULL, NULL); + if (r < 0) { + return trace; + } + } + + if (!_dwfl_handle) { + return trace; + } + + // find the module (binary object) that contains the trace's address. + // This is not using any debug information, but the addresses ranges of + // all the currently loaded binary object. + Dwfl_Module *mod = dwfl_addrmodule(_dwfl_handle.get(), trace_addr); + if (mod) { + // now that we found it, lets get the name of it, this will be the + // full path to the running binary or one of the loaded library. + const char *module_name = dwfl_module_info(mod, 0, 0, 0, 0, 0, 0, 0); + if (module_name) { + trace.object_filename = module_name; + } + // We also look after the name of the symbol, equal or before this + // address. This is found by walking the symtab. We should get the + // symbol corresponding to the function (mangled) containing the + // address. If the code corresponding to the address was inlined, + // this is the name of the out-most inliner function. + const char *sym_name = dwfl_module_addrname(mod, trace_addr); + if (sym_name) { + trace.object_function = demangle(sym_name); + } + } + + // now let's get serious, and find out the source location (file and + // line number) of the address. + + // This function will look in .debug_aranges for the address and map it + // to the location of the compilation unit DIE in .debug_info and + // return it. + Dwarf_Addr mod_bias = 0; + Dwarf_Die *cudie = dwfl_module_addrdie(mod, trace_addr, &mod_bias); + +#if 1 + if (!cudie) { + // Sadly clang does not generate the section .debug_aranges, thus + // dwfl_module_addrdie will fail early. Clang doesn't either set + // the lowpc/highpc/range info for every compilation unit. + // + // So in order to save the world: + // for every compilation unit, we will iterate over every single + // DIEs. Normally functions should have a lowpc/highpc/range, which + // we will use to infer the compilation unit. + + // note that this is probably badly inefficient. + while ((cudie = dwfl_module_nextcu(mod, cudie, &mod_bias))) { + Dwarf_Die die_mem; + Dwarf_Die *fundie = + find_fundie_by_pc(cudie, trace_addr - mod_bias, &die_mem); + if (fundie) { + break; + } + } + } +#endif + +//#define BACKWARD_I_DO_NOT_RECOMMEND_TO_ENABLE_THIS_HORRIBLE_PIECE_OF_CODE +#ifdef BACKWARD_I_DO_NOT_RECOMMEND_TO_ENABLE_THIS_HORRIBLE_PIECE_OF_CODE + if (!cudie) { + // If it's still not enough, lets dive deeper in the shit, and try + // to save the world again: for every compilation unit, we will + // load the corresponding .debug_line section, and see if we can + // find our address in it. + + Dwarf_Addr cfi_bias; + Dwarf_CFI *cfi_cache = dwfl_module_eh_cfi(mod, &cfi_bias); + + Dwarf_Addr bias; + while ((cudie = dwfl_module_nextcu(mod, cudie, &bias))) { + if (dwarf_getsrc_die(cudie, trace_addr - bias)) { + + // ...but if we get a match, it might be a false positive + // because our (address - bias) might as well be valid in a + // different compilation unit. So we throw our last card on + // the table and lookup for the address into the .eh_frame + // section. + + handle frame; + dwarf_cfi_addrframe(cfi_cache, trace_addr - cfi_bias, &frame); + if (frame) { + break; + } + } + } + } +#endif + + if (!cudie) { + return trace; // this time we lost the game :/ + } + + // Now that we have a compilation unit DIE, this function will be able + // to load the corresponding section in .debug_line (if not already + // loaded) and hopefully find the source location mapped to our + // address. + Dwarf_Line *srcloc = dwarf_getsrc_die(cudie, trace_addr - mod_bias); + + if (srcloc) { + const char *srcfile = dwarf_linesrc(srcloc, 0, 0); + if (srcfile) { + trace.source.filename = srcfile; + } + int line = 0, col = 0; + dwarf_lineno(srcloc, &line); + dwarf_linecol(srcloc, &col); + trace.source.line = line; + trace.source.col = col; + } + + deep_first_search_by_pc(cudie, trace_addr - mod_bias, + inliners_search_cb(trace)); + if (trace.source.function.size() == 0) { + // fallback. + trace.source.function = trace.object_function; + } + + return trace; + } + +private: + typedef details::handle> + dwfl_handle_t; + details::handle> + _dwfl_cb; + dwfl_handle_t _dwfl_handle; + bool _dwfl_handle_initialized; + + // defined here because in C++98, template function cannot take locally + // defined types... grrr. + struct inliners_search_cb { + void operator()(Dwarf_Die *die) { + switch (dwarf_tag(die)) { + const char *name; + case DW_TAG_subprogram: + if ((name = dwarf_diename(die))) { + trace.source.function = name; + } + break; + + case DW_TAG_inlined_subroutine: + ResolvedTrace::SourceLoc sloc; + Dwarf_Attribute attr_mem; + + if ((name = dwarf_diename(die))) { + sloc.function = name; + } + if ((name = die_call_file(die))) { + sloc.filename = name; + } + + Dwarf_Word line = 0, col = 0; + dwarf_formudata(dwarf_attr(die, DW_AT_call_line, &attr_mem), &line); + dwarf_formudata(dwarf_attr(die, DW_AT_call_column, &attr_mem), &col); + sloc.line = (unsigned)line; + sloc.col = (unsigned)col; + + trace.inliners.push_back(sloc); + break; + }; + } + ResolvedTrace &trace; + inliners_search_cb(ResolvedTrace &t) : trace(t) {} + }; + + static bool die_has_pc(Dwarf_Die *die, Dwarf_Addr pc) { + Dwarf_Addr low, high; + + // continuous range + if (dwarf_hasattr(die, DW_AT_low_pc) && dwarf_hasattr(die, DW_AT_high_pc)) { + if (dwarf_lowpc(die, &low) != 0) { + return false; + } + if (dwarf_highpc(die, &high) != 0) { + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = dwarf_attr(die, DW_AT_high_pc, &attr_mem); + Dwarf_Word value; + if (dwarf_formudata(attr, &value) != 0) { + return false; + } + high = low + value; + } + return pc >= low && pc < high; + } + + // non-continuous range. + Dwarf_Addr base; + ptrdiff_t offset = 0; + while ((offset = dwarf_ranges(die, offset, &base, &low, &high)) > 0) { + if (pc >= low && pc < high) { + return true; + } + } + return false; + } + + static Dwarf_Die *find_fundie_by_pc(Dwarf_Die *parent_die, Dwarf_Addr pc, + Dwarf_Die *result) { + if (dwarf_child(parent_die, result) != 0) { + return 0; + } + + Dwarf_Die *die = result; + do { + switch (dwarf_tag(die)) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + if (die_has_pc(die, pc)) { + return result; + } + }; + bool declaration = false; + Dwarf_Attribute attr_mem; + dwarf_formflag(dwarf_attr(die, DW_AT_declaration, &attr_mem), + &declaration); + if (!declaration) { + // let's be curious and look deeper in the tree, + // function are not necessarily at the first level, but + // might be nested inside a namespace, structure etc. + Dwarf_Die die_mem; + Dwarf_Die *indie = find_fundie_by_pc(die, pc, &die_mem); + if (indie) { + *result = die_mem; + return result; + } + } + } while (dwarf_siblingof(die, result) == 0); + return 0; + } + + template + static bool deep_first_search_by_pc(Dwarf_Die *parent_die, Dwarf_Addr pc, + CB cb) { + Dwarf_Die die_mem; + if (dwarf_child(parent_die, &die_mem) != 0) { + return false; + } + + bool branch_has_pc = false; + Dwarf_Die *die = &die_mem; + do { + bool declaration = false; + Dwarf_Attribute attr_mem; + dwarf_formflag(dwarf_attr(die, DW_AT_declaration, &attr_mem), + &declaration); + if (!declaration) { + // let's be curious and look deeper in the tree, function are + // not necessarily at the first level, but might be nested + // inside a namespace, structure, a function, an inlined + // function etc. + branch_has_pc = deep_first_search_by_pc(die, pc, cb); + } + if (!branch_has_pc) { + branch_has_pc = die_has_pc(die, pc); + } + if (branch_has_pc) { + cb(die); + } + } while (dwarf_siblingof(die, &die_mem) == 0); + return branch_has_pc; + } + + static const char *die_call_file(Dwarf_Die *die) { + Dwarf_Attribute attr_mem; + Dwarf_Word file_idx = 0; + + dwarf_formudata(dwarf_attr(die, DW_AT_call_file, &attr_mem), &file_idx); + + if (file_idx == 0) { + return 0; + } + + Dwarf_Die die_mem; + Dwarf_Die *cudie = dwarf_diecu(die, &die_mem, 0, 0); + if (!cudie) { + return 0; + } + + Dwarf_Files *files = 0; + size_t nfiles; + dwarf_getsrcfiles(cudie, &files, &nfiles); + if (!files) { + return 0; + } + + return dwarf_filesrc(files, file_idx, 0, 0); + } +}; +#endif // BACKWARD_HAS_DW == 1 + +#if BACKWARD_HAS_DWARF == 1 + +template <> +class TraceResolverLinuxImpl + : public TraceResolverLinuxBase { +public: + TraceResolverLinuxImpl() : _dwarf_loaded(false) {} + + template void load_stacktrace(ST &) {} + + ResolvedTrace resolve(ResolvedTrace trace) { + // trace.addr is a virtual address in memory pointing to some code. + // Let's try to find from which loaded object it comes from. + // The loaded object can be yourself btw. + + Dl_info symbol_info; + int dladdr_result = 0; +#if defined(__GLIBC__) + link_map *link_map; + // We request the link map so we can get information about offsets + dladdr_result = + dladdr1(trace.addr, &symbol_info, reinterpret_cast(&link_map), + RTLD_DL_LINKMAP); +#else + // Android doesn't have dladdr1. Don't use the linker map. + dladdr_result = dladdr(trace.addr, &symbol_info); +#endif + if (!dladdr_result) { + return trace; // dat broken trace... + } + + // Now we get in symbol_info: + // .dli_fname: + // pathname of the shared object that contains the address. + // .dli_fbase: + // where the object is loaded in memory. + // .dli_sname: + // the name of the nearest symbol to trace.addr, we expect a + // function name. + // .dli_saddr: + // the exact address corresponding to .dli_sname. + // + // And in link_map: + // .l_addr: + // difference between the address in the ELF file and the address + // in memory + // l_name: + // absolute pathname where the object was found + + if (symbol_info.dli_sname) { + trace.object_function = demangle(symbol_info.dli_sname); + } + + if (!symbol_info.dli_fname) { + return trace; + } + + trace.object_filename = resolve_exec_path(symbol_info); + dwarf_fileobject &fobj = load_object_with_dwarf(symbol_info.dli_fname); + if (!fobj.dwarf_handle) { + return trace; // sad, we couldn't load the object :( + } + +#if defined(__GLIBC__) + // Convert the address to a module relative one by looking at + // the module's loading address in the link map + Dwarf_Addr address = reinterpret_cast(trace.addr) - + reinterpret_cast(link_map->l_addr); +#else + Dwarf_Addr address = reinterpret_cast(trace.addr); +#endif + + if (trace.object_function.empty()) { + symbol_cache_t::iterator it = fobj.symbol_cache.lower_bound(address); + + if (it != fobj.symbol_cache.end()) { + if (it->first != address) { + if (it != fobj.symbol_cache.begin()) { + --it; + } + } + trace.object_function = demangle(it->second.c_str()); + } + } + + // Get the Compilation Unit DIE for the address + Dwarf_Die die = find_die(fobj, address); + + if (!die) { + return trace; // this time we lost the game :/ + } + + // libdwarf doesn't give us direct access to its objects, it always + // allocates a copy for the caller. We keep that copy alive in a cache + // and we deallocate it later when it's no longer required. + die_cache_entry &die_object = get_die_cache(fobj, die); + if (die_object.isEmpty()) + return trace; // We have no line section for this DIE + + die_linemap_t::iterator it = die_object.line_section.lower_bound(address); + + if (it != die_object.line_section.end()) { + if (it->first != address) { + if (it == die_object.line_section.begin()) { + // If we are on the first item of the line section + // but the address does not match it means that + // the address is below the range of the DIE. Give up. + return trace; + } else { + --it; + } + } + } else { + return trace; // We didn't find the address. + } + + // Get the Dwarf_Line that the address points to and call libdwarf + // to get source file, line and column info. + Dwarf_Line line = die_object.line_buffer[it->second]; + Dwarf_Error error = DW_DLE_NE; + + char *filename; + if (dwarf_linesrc(line, &filename, &error) == DW_DLV_OK) { + trace.source.filename = std::string(filename); + dwarf_dealloc(fobj.dwarf_handle.get(), filename, DW_DLA_STRING); + } + + Dwarf_Unsigned number = 0; + if (dwarf_lineno(line, &number, &error) == DW_DLV_OK) { + trace.source.line = number; + } else { + trace.source.line = 0; + } + + if (dwarf_lineoff_b(line, &number, &error) == DW_DLV_OK) { + trace.source.col = number; + } else { + trace.source.col = 0; + } + + std::vector namespace_stack; + deep_first_search_by_pc(fobj, die, address, namespace_stack, + inliners_search_cb(trace, fobj, die)); + + dwarf_dealloc(fobj.dwarf_handle.get(), die, DW_DLA_DIE); + + return trace; + } + +public: + static int close_dwarf(Dwarf_Debug dwarf) { + return dwarf_finish(dwarf, NULL); + } + +private: + bool _dwarf_loaded; + + typedef details::handle> + dwarf_file_t; + + typedef details::handle> + dwarf_elf_t; + + typedef details::handle> + dwarf_handle_t; + + typedef std::map die_linemap_t; + + typedef std::map die_specmap_t; + + struct die_cache_entry { + die_specmap_t spec_section; + die_linemap_t line_section; + Dwarf_Line *line_buffer; + Dwarf_Signed line_count; + Dwarf_Line_Context line_context; + + inline bool isEmpty() { + return line_buffer == NULL || line_count == 0 || line_context == NULL || + line_section.empty(); + } + + die_cache_entry() : line_buffer(0), line_count(0), line_context(0) {} + + ~die_cache_entry() { + if (line_context) { + dwarf_srclines_dealloc_b(line_context); + } + } + }; + + typedef std::map die_cache_t; + + typedef std::map symbol_cache_t; + + struct dwarf_fileobject { + dwarf_file_t file_handle; + dwarf_elf_t elf_handle; + dwarf_handle_t dwarf_handle; + symbol_cache_t symbol_cache; + + // Die cache + die_cache_t die_cache; + die_cache_entry *current_cu; + }; + + typedef details::hashtable::type + fobj_dwarf_map_t; + fobj_dwarf_map_t _fobj_dwarf_map; + + static bool cstrings_eq(const char *a, const char *b) { + if (!a || !b) { + return false; + } + return strcmp(a, b) == 0; + } + + dwarf_fileobject &load_object_with_dwarf(const std::string &filename_object) { + + if (!_dwarf_loaded) { + // Set the ELF library operating version + // If that fails there's nothing we can do + _dwarf_loaded = elf_version(EV_CURRENT) != EV_NONE; + } + + fobj_dwarf_map_t::iterator it = _fobj_dwarf_map.find(filename_object); + if (it != _fobj_dwarf_map.end()) { + return it->second; + } + + // this new object is empty for now + dwarf_fileobject &r = _fobj_dwarf_map[filename_object]; + + dwarf_file_t file_handle; + file_handle.reset(open(filename_object.c_str(), O_RDONLY)); + if (file_handle.get() < 0) { + return r; + } + + // Try to get an ELF handle. We need to read the ELF sections + // because we want to see if there is a .gnu_debuglink section + // that points to a split debug file + dwarf_elf_t elf_handle; + elf_handle.reset(elf_begin(file_handle.get(), ELF_C_READ, NULL)); + if (!elf_handle) { + return r; + } + + const char *e_ident = elf_getident(elf_handle.get(), 0); + if (!e_ident) { + return r; + } + + // Get the number of sections + // We use the new APIs as elf_getshnum is deprecated + size_t shdrnum = 0; + if (elf_getshdrnum(elf_handle.get(), &shdrnum) == -1) { + return r; + } + + // Get the index to the string section + size_t shdrstrndx = 0; + if (elf_getshdrstrndx(elf_handle.get(), &shdrstrndx) == -1) { + return r; + } + + std::string debuglink; + // Iterate through the ELF sections to try to get a gnu_debuglink + // note and also to cache the symbol table. + // We go the preprocessor way to avoid having to create templated + // classes or using gelf (which might throw a compiler error if 64 bit + // is not supported +#define ELF_GET_DATA(ARCH) \ + Elf_Scn *elf_section = 0; \ + Elf_Data *elf_data = 0; \ + Elf##ARCH##_Shdr *section_header = 0; \ + Elf_Scn *symbol_section = 0; \ + size_t symbol_count = 0; \ + size_t symbol_strings = 0; \ + Elf##ARCH##_Sym *symbol = 0; \ + const char *section_name = 0; \ + \ + while ((elf_section = elf_nextscn(elf_handle.get(), elf_section)) != NULL) { \ + section_header = elf##ARCH##_getshdr(elf_section); \ + if (section_header == NULL) { \ + return r; \ + } \ + \ + if ((section_name = elf_strptr(elf_handle.get(), shdrstrndx, \ + section_header->sh_name)) == NULL) { \ + return r; \ + } \ + \ + if (cstrings_eq(section_name, ".gnu_debuglink")) { \ + elf_data = elf_getdata(elf_section, NULL); \ + if (elf_data && elf_data->d_size > 0) { \ + debuglink = \ + std::string(reinterpret_cast(elf_data->d_buf)); \ + } \ + } \ + \ + switch (section_header->sh_type) { \ + case SHT_SYMTAB: \ + symbol_section = elf_section; \ + symbol_count = section_header->sh_size / section_header->sh_entsize; \ + symbol_strings = section_header->sh_link; \ + break; \ + \ + /* We use .dynsyms as a last resort, we prefer .symtab */ \ + case SHT_DYNSYM: \ + if (!symbol_section) { \ + symbol_section = elf_section; \ + symbol_count = section_header->sh_size / section_header->sh_entsize; \ + symbol_strings = section_header->sh_link; \ + } \ + break; \ + } \ + } \ + \ + if (symbol_section && symbol_count && symbol_strings) { \ + elf_data = elf_getdata(symbol_section, NULL); \ + symbol = reinterpret_cast(elf_data->d_buf); \ + for (size_t i = 0; i < symbol_count; ++i) { \ + int type = ELF##ARCH##_ST_TYPE(symbol->st_info); \ + if (type == STT_FUNC && symbol->st_value > 0) { \ + r.symbol_cache[symbol->st_value] = std::string( \ + elf_strptr(elf_handle.get(), symbol_strings, symbol->st_name)); \ + } \ + ++symbol; \ + } \ + } + + if (e_ident[EI_CLASS] == ELFCLASS32) { + ELF_GET_DATA(32) + } else if (e_ident[EI_CLASS] == ELFCLASS64) { + // libelf might have been built without 64 bit support +#if __LIBELF64 + ELF_GET_DATA(64) +#endif + } + + if (!debuglink.empty()) { + // We have a debuglink section! Open an elf instance on that + // file instead. If we can't open the file, then return + // the elf handle we had already opened. + dwarf_file_t debuglink_file; + debuglink_file.reset(open(debuglink.c_str(), O_RDONLY)); + if (debuglink_file.get() > 0) { + dwarf_elf_t debuglink_elf; + debuglink_elf.reset(elf_begin(debuglink_file.get(), ELF_C_READ, NULL)); + + // If we have a valid elf handle, return the new elf handle + // and file handle and discard the original ones + if (debuglink_elf) { + elf_handle = move(debuglink_elf); + file_handle = move(debuglink_file); + } + } + } + + // Ok, we have a valid ELF handle, let's try to get debug symbols + Dwarf_Debug dwarf_debug; + Dwarf_Error error = DW_DLE_NE; + dwarf_handle_t dwarf_handle; + + int dwarf_result = dwarf_elf_init(elf_handle.get(), DW_DLC_READ, NULL, NULL, + &dwarf_debug, &error); + + // We don't do any special handling for DW_DLV_NO_ENTRY specially. + // If we get an error, or the file doesn't have debug information + // we just return. + if (dwarf_result != DW_DLV_OK) { + return r; + } + + dwarf_handle.reset(dwarf_debug); + + r.file_handle = move(file_handle); + r.elf_handle = move(elf_handle); + r.dwarf_handle = move(dwarf_handle); + + return r; + } + + die_cache_entry &get_die_cache(dwarf_fileobject &fobj, Dwarf_Die die) { + Dwarf_Error error = DW_DLE_NE; + + // Get the die offset, we use it as the cache key + Dwarf_Off die_offset; + if (dwarf_dieoffset(die, &die_offset, &error) != DW_DLV_OK) { + die_offset = 0; + } + + die_cache_t::iterator it = fobj.die_cache.find(die_offset); + + if (it != fobj.die_cache.end()) { + fobj.current_cu = &it->second; + return it->second; + } + + die_cache_entry &de = fobj.die_cache[die_offset]; + fobj.current_cu = &de; + + Dwarf_Addr line_addr; + Dwarf_Small table_count; + + // The addresses in the line section are not fully sorted (they might + // be sorted by block of code belonging to the same file), which makes + // it necessary to do so before searching is possible. + // + // As libdwarf allocates a copy of everything, let's get the contents + // of the line section and keep it around. We also create a map of + // program counter to line table indices so we can search by address + // and get the line buffer index. + // + // To make things more difficult, the same address can span more than + // one line, so we need to keep the index pointing to the first line + // by using insert instead of the map's [ operator. + + // Get the line context for the DIE + if (dwarf_srclines_b(die, 0, &table_count, &de.line_context, &error) == + DW_DLV_OK) { + // Get the source lines for this line context, to be deallocated + // later + if (dwarf_srclines_from_linecontext(de.line_context, &de.line_buffer, + &de.line_count, + &error) == DW_DLV_OK) { + + // Add all the addresses to our map + for (int i = 0; i < de.line_count; i++) { + if (dwarf_lineaddr(de.line_buffer[i], &line_addr, &error) != + DW_DLV_OK) { + line_addr = 0; + } + de.line_section.insert(std::pair(line_addr, i)); + } + } + } + + // For each CU, cache the function DIEs that contain the + // DW_AT_specification attribute. When building with -g3 the function + // DIEs are separated in declaration and specification, with the + // declaration containing only the name and parameters and the + // specification the low/high pc and other compiler attributes. + // + // We cache those specifications so we don't skip over the declarations, + // because they have no pc, and we can do namespace resolution for + // DWARF function names. + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + Dwarf_Die current_die = 0; + if (dwarf_child(die, ¤t_die, &error) == DW_DLV_OK) { + for (;;) { + Dwarf_Die sibling_die = 0; + + Dwarf_Half tag_value; + dwarf_tag(current_die, &tag_value, &error); + + if (tag_value == DW_TAG_subprogram || + tag_value == DW_TAG_inlined_subroutine) { + + Dwarf_Bool has_attr = 0; + if (dwarf_hasattr(current_die, DW_AT_specification, &has_attr, + &error) == DW_DLV_OK) { + if (has_attr) { + Dwarf_Attribute attr_mem; + if (dwarf_attr(current_die, DW_AT_specification, &attr_mem, + &error) == DW_DLV_OK) { + Dwarf_Off spec_offset = 0; + if (dwarf_formref(attr_mem, &spec_offset, &error) == + DW_DLV_OK) { + Dwarf_Off spec_die_offset; + if (dwarf_dieoffset(current_die, &spec_die_offset, &error) == + DW_DLV_OK) { + de.spec_section[spec_offset] = spec_die_offset; + } + } + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + } + } + + int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error); + if (result == DW_DLV_ERROR) { + break; + } else if (result == DW_DLV_NO_ENTRY) { + break; + } + + if (current_die != die) { + dwarf_dealloc(dwarf, current_die, DW_DLA_DIE); + current_die = 0; + } + + current_die = sibling_die; + } + } + return de; + } + + static Dwarf_Die get_referenced_die(Dwarf_Debug dwarf, Dwarf_Die die, + Dwarf_Half attr, bool global) { + Dwarf_Error error = DW_DLE_NE; + Dwarf_Attribute attr_mem; + + Dwarf_Die found_die = NULL; + if (dwarf_attr(die, attr, &attr_mem, &error) == DW_DLV_OK) { + Dwarf_Off offset; + int result = 0; + if (global) { + result = dwarf_global_formref(attr_mem, &offset, &error); + } else { + result = dwarf_formref(attr_mem, &offset, &error); + } + + if (result == DW_DLV_OK) { + if (dwarf_offdie(dwarf, offset, &found_die, &error) != DW_DLV_OK) { + found_die = NULL; + } + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + return found_die; + } + + static std::string get_referenced_die_name(Dwarf_Debug dwarf, Dwarf_Die die, + Dwarf_Half attr, bool global) { + Dwarf_Error error = DW_DLE_NE; + std::string value; + + Dwarf_Die found_die = get_referenced_die(dwarf, die, attr, global); + + if (found_die) { + char *name; + if (dwarf_diename(found_die, &name, &error) == DW_DLV_OK) { + if (name) { + value = std::string(name); + } + dwarf_dealloc(dwarf, name, DW_DLA_STRING); + } + dwarf_dealloc(dwarf, found_die, DW_DLA_DIE); + } + + return value; + } + + // Returns a spec DIE linked to the passed one. The caller should + // deallocate the DIE + static Dwarf_Die get_spec_die(dwarf_fileobject &fobj, Dwarf_Die die) { + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + Dwarf_Error error = DW_DLE_NE; + Dwarf_Off die_offset; + if (fobj.current_cu && + dwarf_die_CU_offset(die, &die_offset, &error) == DW_DLV_OK) { + die_specmap_t::iterator it = + fobj.current_cu->spec_section.find(die_offset); + + // If we have a DIE that completes the current one, check if + // that one has the pc we are looking for + if (it != fobj.current_cu->spec_section.end()) { + Dwarf_Die spec_die = 0; + if (dwarf_offdie(dwarf, it->second, &spec_die, &error) == DW_DLV_OK) { + return spec_die; + } + } + } + + // Maybe we have an abstract origin DIE with the function information? + return get_referenced_die(fobj.dwarf_handle.get(), die, + DW_AT_abstract_origin, true); + } + + static bool die_has_pc(dwarf_fileobject &fobj, Dwarf_Die die, Dwarf_Addr pc) { + Dwarf_Addr low_pc = 0, high_pc = 0; + Dwarf_Half high_pc_form = 0; + Dwarf_Form_Class return_class; + Dwarf_Error error = DW_DLE_NE; + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + bool has_lowpc = false; + bool has_highpc = false; + bool has_ranges = false; + + if (dwarf_lowpc(die, &low_pc, &error) == DW_DLV_OK) { + // If we have a low_pc check if there is a high pc. + // If we don't have a high pc this might mean we have a base + // address for the ranges list or just an address. + has_lowpc = true; + + if (dwarf_highpc_b(die, &high_pc, &high_pc_form, &return_class, &error) == + DW_DLV_OK) { + // We do have a high pc. In DWARF 4+ this is an offset from the + // low pc, but in earlier versions it's an absolute address. + + has_highpc = true; + // In DWARF 2/3 this would be a DW_FORM_CLASS_ADDRESS + if (return_class == DW_FORM_CLASS_CONSTANT) { + high_pc = low_pc + high_pc; + } + + // We have low and high pc, check if our address + // is in that range + return pc >= low_pc && pc < high_pc; + } + } else { + // Reset the low_pc, in case dwarf_lowpc failing set it to some + // undefined value. + low_pc = 0; + } + + // Check if DW_AT_ranges is present and search for the PC in the + // returned ranges list. We always add the low_pc, as it not set it will + // be 0, in case we had a DW_AT_low_pc and DW_AT_ranges pair + bool result = false; + + Dwarf_Attribute attr; + if (dwarf_attr(die, DW_AT_ranges, &attr, &error) == DW_DLV_OK) { + + Dwarf_Off offset; + if (dwarf_global_formref(attr, &offset, &error) == DW_DLV_OK) { + Dwarf_Ranges *ranges; + Dwarf_Signed ranges_count = 0; + Dwarf_Unsigned byte_count = 0; + + if (dwarf_get_ranges_a(dwarf, offset, die, &ranges, &ranges_count, + &byte_count, &error) == DW_DLV_OK) { + has_ranges = ranges_count != 0; + for (int i = 0; i < ranges_count; i++) { + if (ranges[i].dwr_addr1 != 0 && + pc >= ranges[i].dwr_addr1 + low_pc && + pc < ranges[i].dwr_addr2 + low_pc) { + result = true; + break; + } + } + dwarf_ranges_dealloc(dwarf, ranges, ranges_count); + } + } + } + + // Last attempt. We might have a single address set as low_pc. + if (!result && low_pc != 0 && pc == low_pc) { + result = true; + } + + // If we don't have lowpc, highpc and ranges maybe this DIE is a + // declaration that relies on a DW_AT_specification DIE that happens + // later. Use the specification cache we filled when we loaded this CU. + if (!result && (!has_lowpc && !has_highpc && !has_ranges)) { + Dwarf_Die spec_die = get_spec_die(fobj, die); + if (spec_die) { + result = die_has_pc(fobj, spec_die, pc); + dwarf_dealloc(dwarf, spec_die, DW_DLA_DIE); + } + } + + return result; + } + + static void get_type(Dwarf_Debug dwarf, Dwarf_Die die, std::string &type) { + Dwarf_Error error = DW_DLE_NE; + + Dwarf_Die child = 0; + if (dwarf_child(die, &child, &error) == DW_DLV_OK) { + get_type(dwarf, child, type); + } + + if (child) { + type.insert(0, "::"); + dwarf_dealloc(dwarf, child, DW_DLA_DIE); + } + + char *name; + if (dwarf_diename(die, &name, &error) == DW_DLV_OK) { + type.insert(0, std::string(name)); + dwarf_dealloc(dwarf, name, DW_DLA_STRING); + } else { + type.insert(0, ""); + } + } + + static std::string get_type_by_signature(Dwarf_Debug dwarf, Dwarf_Die die) { + Dwarf_Error error = DW_DLE_NE; + + Dwarf_Sig8 signature; + Dwarf_Bool has_attr = 0; + if (dwarf_hasattr(die, DW_AT_signature, &has_attr, &error) == DW_DLV_OK) { + if (has_attr) { + Dwarf_Attribute attr_mem; + if (dwarf_attr(die, DW_AT_signature, &attr_mem, &error) == DW_DLV_OK) { + if (dwarf_formsig8(attr_mem, &signature, &error) != DW_DLV_OK) { + return std::string(""); + } + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + } + + Dwarf_Unsigned next_cu_header; + Dwarf_Sig8 tu_signature; + std::string result; + bool found = false; + + while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, &tu_signature, 0, + &next_cu_header, 0, &error) == DW_DLV_OK) { + + if (strncmp(signature.signature, tu_signature.signature, 8) == 0) { + Dwarf_Die type_cu_die = 0; + if (dwarf_siblingof_b(dwarf, 0, 0, &type_cu_die, &error) == DW_DLV_OK) { + Dwarf_Die child_die = 0; + if (dwarf_child(type_cu_die, &child_die, &error) == DW_DLV_OK) { + get_type(dwarf, child_die, result); + found = !result.empty(); + dwarf_dealloc(dwarf, child_die, DW_DLA_DIE); + } + dwarf_dealloc(dwarf, type_cu_die, DW_DLA_DIE); + } + } + } + + if (found) { + while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, 0, 0, + &next_cu_header, 0, &error) == DW_DLV_OK) { + // Reset the cu header state. Unfortunately, libdwarf's + // next_cu_header API keeps its own iterator per Dwarf_Debug + // that can't be reset. We need to keep fetching elements until + // the end. + } + } else { + // If we couldn't resolve the type just print out the signature + std::ostringstream string_stream; + string_stream << "<0x" << std::hex << std::setfill('0'); + for (int i = 0; i < 8; ++i) { + string_stream << std::setw(2) << std::hex + << (int)(unsigned char)(signature.signature[i]); + } + string_stream << ">"; + result = string_stream.str(); + } + return result; + } + + struct type_context_t { + bool is_const; + bool is_typedef; + bool has_type; + bool has_name; + std::string text; + + type_context_t() + : is_const(false), is_typedef(false), has_type(false), has_name(false) { + } + }; + + // Types are resolved from right to left: we get the variable name first + // and then all specifiers (like const or pointer) in a chain of DW_AT_type + // DIEs. Call this function recursively until we get a complete type + // string. + static void set_parameter_string(dwarf_fileobject &fobj, Dwarf_Die die, + type_context_t &context) { + char *name; + Dwarf_Error error = DW_DLE_NE; + + // typedefs contain also the base type, so we skip it and only + // print the typedef name + if (!context.is_typedef) { + if (dwarf_diename(die, &name, &error) == DW_DLV_OK) { + if (!context.text.empty()) { + context.text.insert(0, " "); + } + context.text.insert(0, std::string(name)); + dwarf_dealloc(fobj.dwarf_handle.get(), name, DW_DLA_STRING); + } + } else { + context.is_typedef = false; + context.has_type = true; + if (context.is_const) { + context.text.insert(0, "const "); + context.is_const = false; + } + } + + bool next_type_is_const = false; + bool is_keyword = true; + + Dwarf_Half tag = 0; + Dwarf_Bool has_attr = 0; + if (dwarf_tag(die, &tag, &error) == DW_DLV_OK) { + switch (tag) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + case DW_TAG_enumeration_type: + context.has_type = true; + if (dwarf_hasattr(die, DW_AT_signature, &has_attr, &error) == + DW_DLV_OK) { + // If we have a signature it means the type is defined + // in .debug_types, so we need to load the DIE pointed + // at by the signature and resolve it + if (has_attr) { + std::string type = + get_type_by_signature(fobj.dwarf_handle.get(), die); + if (context.is_const) + type.insert(0, "const "); + + if (!context.text.empty()) + context.text.insert(0, " "); + context.text.insert(0, type); + } + + // Treat enums like typedefs, and skip printing its + // base type + context.is_typedef = (tag == DW_TAG_enumeration_type); + } + break; + case DW_TAG_const_type: + next_type_is_const = true; + break; + case DW_TAG_pointer_type: + context.text.insert(0, "*"); + break; + case DW_TAG_reference_type: + context.text.insert(0, "&"); + break; + case DW_TAG_restrict_type: + context.text.insert(0, "restrict "); + break; + case DW_TAG_rvalue_reference_type: + context.text.insert(0, "&&"); + break; + case DW_TAG_volatile_type: + context.text.insert(0, "volatile "); + break; + case DW_TAG_typedef: + // Propagate the const-ness to the next type + // as typedefs are linked to its base type + next_type_is_const = context.is_const; + context.is_typedef = true; + context.has_type = true; + break; + case DW_TAG_base_type: + context.has_type = true; + break; + case DW_TAG_formal_parameter: + context.has_name = true; + break; + default: + is_keyword = false; + break; + } + } + + if (!is_keyword && context.is_const) { + context.text.insert(0, "const "); + } + + context.is_const = next_type_is_const; + + Dwarf_Die ref = + get_referenced_die(fobj.dwarf_handle.get(), die, DW_AT_type, true); + if (ref) { + set_parameter_string(fobj, ref, context); + dwarf_dealloc(fobj.dwarf_handle.get(), ref, DW_DLA_DIE); + } + + if (!context.has_type && context.has_name) { + context.text.insert(0, "void "); + context.has_type = true; + } + } + + // Resolve the function return type and parameters + static void set_function_parameters(std::string &function_name, + std::vector &ns, + dwarf_fileobject &fobj, Dwarf_Die die) { + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + Dwarf_Error error = DW_DLE_NE; + Dwarf_Die current_die = 0; + std::string parameters; + bool has_spec = true; + // Check if we have a spec DIE. If we do we use it as it contains + // more information, like parameter names. + Dwarf_Die spec_die = get_spec_die(fobj, die); + if (!spec_die) { + has_spec = false; + spec_die = die; + } + + std::vector::const_iterator it = ns.begin(); + std::string ns_name; + for (it = ns.begin(); it < ns.end(); ++it) { + ns_name.append(*it).append("::"); + } + + if (!ns_name.empty()) { + function_name.insert(0, ns_name); + } + + // See if we have a function return type. It can be either on the + // current die or in its spec one (usually true for inlined functions) + std::string return_type = + get_referenced_die_name(dwarf, die, DW_AT_type, true); + if (return_type.empty()) { + return_type = get_referenced_die_name(dwarf, spec_die, DW_AT_type, true); + } + if (!return_type.empty()) { + return_type.append(" "); + function_name.insert(0, return_type); + } + + if (dwarf_child(spec_die, ¤t_die, &error) == DW_DLV_OK) { + for (;;) { + Dwarf_Die sibling_die = 0; + + Dwarf_Half tag_value; + dwarf_tag(current_die, &tag_value, &error); + + if (tag_value == DW_TAG_formal_parameter) { + // Ignore artificial (ie, compiler generated) parameters + bool is_artificial = false; + Dwarf_Attribute attr_mem; + if (dwarf_attr(current_die, DW_AT_artificial, &attr_mem, &error) == + DW_DLV_OK) { + Dwarf_Bool flag = 0; + if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) { + is_artificial = flag != 0; + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + + if (!is_artificial) { + type_context_t context; + set_parameter_string(fobj, current_die, context); + + if (parameters.empty()) { + parameters.append("("); + } else { + parameters.append(", "); + } + parameters.append(context.text); + } + } + + int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error); + if (result == DW_DLV_ERROR) { + break; + } else if (result == DW_DLV_NO_ENTRY) { + break; + } + + if (current_die != die) { + dwarf_dealloc(dwarf, current_die, DW_DLA_DIE); + current_die = 0; + } + + current_die = sibling_die; + } + } + if (parameters.empty()) + parameters = "("; + parameters.append(")"); + + // If we got a spec DIE we need to deallocate it + if (has_spec) + dwarf_dealloc(dwarf, spec_die, DW_DLA_DIE); + + function_name.append(parameters); + } + + // defined here because in C++98, template function cannot take locally + // defined types... grrr. + struct inliners_search_cb { + void operator()(Dwarf_Die die, std::vector &ns) { + Dwarf_Error error = DW_DLE_NE; + Dwarf_Half tag_value; + Dwarf_Attribute attr_mem; + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + + dwarf_tag(die, &tag_value, &error); + + switch (tag_value) { + char *name; + case DW_TAG_subprogram: + if (!trace.source.function.empty()) + break; + if (dwarf_diename(die, &name, &error) == DW_DLV_OK) { + trace.source.function = std::string(name); + dwarf_dealloc(dwarf, name, DW_DLA_STRING); + } else { + // We don't have a function name in this DIE. + // Check if there is a referenced non-defining + // declaration. + trace.source.function = + get_referenced_die_name(dwarf, die, DW_AT_abstract_origin, true); + if (trace.source.function.empty()) { + trace.source.function = + get_referenced_die_name(dwarf, die, DW_AT_specification, true); + } + } + + // Append the function parameters, if available + set_function_parameters(trace.source.function, ns, fobj, die); + + // If the object function name is empty, it's possible that + // there is no dynamic symbol table (maybe the executable + // was stripped or not built with -rdynamic). See if we have + // a DWARF linkage name to use instead. We try both + // linkage_name and MIPS_linkage_name because the MIPS tag + // was the unofficial one until it was adopted in DWARF4. + // Old gcc versions generate MIPS_linkage_name + if (trace.object_function.empty()) { + details::demangler demangler; + + if (dwarf_attr(die, DW_AT_linkage_name, &attr_mem, &error) != + DW_DLV_OK) { + if (dwarf_attr(die, DW_AT_MIPS_linkage_name, &attr_mem, &error) != + DW_DLV_OK) { + break; + } + } + + char *linkage; + if (dwarf_formstring(attr_mem, &linkage, &error) == DW_DLV_OK) { + trace.object_function = demangler.demangle(linkage); + dwarf_dealloc(dwarf, linkage, DW_DLA_STRING); + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + break; + + case DW_TAG_inlined_subroutine: + ResolvedTrace::SourceLoc sloc; + + if (dwarf_diename(die, &name, &error) == DW_DLV_OK) { + sloc.function = std::string(name); + dwarf_dealloc(dwarf, name, DW_DLA_STRING); + } else { + // We don't have a name for this inlined DIE, it could + // be that there is an abstract origin instead. + // Get the DW_AT_abstract_origin value, which is a + // reference to the source DIE and try to get its name + sloc.function = + get_referenced_die_name(dwarf, die, DW_AT_abstract_origin, true); + } + + set_function_parameters(sloc.function, ns, fobj, die); + + std::string file = die_call_file(dwarf, die, cu_die); + if (!file.empty()) + sloc.filename = file; + + Dwarf_Unsigned number = 0; + if (dwarf_attr(die, DW_AT_call_line, &attr_mem, &error) == DW_DLV_OK) { + if (dwarf_formudata(attr_mem, &number, &error) == DW_DLV_OK) { + sloc.line = number; + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + + if (dwarf_attr(die, DW_AT_call_column, &attr_mem, &error) == + DW_DLV_OK) { + if (dwarf_formudata(attr_mem, &number, &error) == DW_DLV_OK) { + sloc.col = number; + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + + trace.inliners.push_back(sloc); + break; + }; + } + ResolvedTrace &trace; + dwarf_fileobject &fobj; + Dwarf_Die cu_die; + inliners_search_cb(ResolvedTrace &t, dwarf_fileobject &f, Dwarf_Die c) + : trace(t), fobj(f), cu_die(c) {} + }; + + static Dwarf_Die find_fundie_by_pc(dwarf_fileobject &fobj, + Dwarf_Die parent_die, Dwarf_Addr pc, + Dwarf_Die result) { + Dwarf_Die current_die = 0; + Dwarf_Error error = DW_DLE_NE; + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + + if (dwarf_child(parent_die, ¤t_die, &error) != DW_DLV_OK) { + return NULL; + } + + for (;;) { + Dwarf_Die sibling_die = 0; + Dwarf_Half tag_value; + dwarf_tag(current_die, &tag_value, &error); + + switch (tag_value) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + if (die_has_pc(fobj, current_die, pc)) { + return current_die; + } + }; + bool declaration = false; + Dwarf_Attribute attr_mem; + if (dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) == + DW_DLV_OK) { + Dwarf_Bool flag = 0; + if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) { + declaration = flag != 0; + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + + if (!declaration) { + // let's be curious and look deeper in the tree, functions are + // not necessarily at the first level, but might be nested + // inside a namespace, structure, a function, an inlined + // function etc. + Dwarf_Die die_mem = 0; + Dwarf_Die indie = find_fundie_by_pc(fobj, current_die, pc, die_mem); + if (indie) { + result = die_mem; + return result; + } + } + + int res = dwarf_siblingof(dwarf, current_die, &sibling_die, &error); + if (res == DW_DLV_ERROR) { + return NULL; + } else if (res == DW_DLV_NO_ENTRY) { + break; + } + + if (current_die != parent_die) { + dwarf_dealloc(dwarf, current_die, DW_DLA_DIE); + current_die = 0; + } + + current_die = sibling_die; + } + return NULL; + } + + template + static bool deep_first_search_by_pc(dwarf_fileobject &fobj, + Dwarf_Die parent_die, Dwarf_Addr pc, + std::vector &ns, CB cb) { + Dwarf_Die current_die = 0; + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + Dwarf_Error error = DW_DLE_NE; + + if (dwarf_child(parent_die, ¤t_die, &error) != DW_DLV_OK) { + return false; + } + + bool branch_has_pc = false; + bool has_namespace = false; + for (;;) { + Dwarf_Die sibling_die = 0; + + Dwarf_Half tag; + if (dwarf_tag(current_die, &tag, &error) == DW_DLV_OK) { + if (tag == DW_TAG_namespace || tag == DW_TAG_class_type) { + char *ns_name = NULL; + if (dwarf_diename(current_die, &ns_name, &error) == DW_DLV_OK) { + if (ns_name) { + ns.push_back(std::string(ns_name)); + } else { + ns.push_back(""); + } + dwarf_dealloc(dwarf, ns_name, DW_DLA_STRING); + } else { + ns.push_back(""); + } + has_namespace = true; + } + } + + bool declaration = false; + Dwarf_Attribute attr_mem; + if (tag != DW_TAG_class_type && + dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) == + DW_DLV_OK) { + Dwarf_Bool flag = 0; + if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) { + declaration = flag != 0; + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + } + + if (!declaration) { + // let's be curious and look deeper in the tree, function are + // not necessarily at the first level, but might be nested + // inside a namespace, structure, a function, an inlined + // function etc. + branch_has_pc = deep_first_search_by_pc(fobj, current_die, pc, ns, cb); + } + + if (!branch_has_pc) { + branch_has_pc = die_has_pc(fobj, current_die, pc); + } + + if (branch_has_pc) { + cb(current_die, ns); + } + + int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error); + if (result == DW_DLV_ERROR) { + return false; + } else if (result == DW_DLV_NO_ENTRY) { + break; + } + + if (current_die != parent_die) { + dwarf_dealloc(dwarf, current_die, DW_DLA_DIE); + current_die = 0; + } + + if (has_namespace) { + has_namespace = false; + ns.pop_back(); + } + current_die = sibling_die; + } + + if (has_namespace) { + ns.pop_back(); + } + return branch_has_pc; + } + + static std::string die_call_file(Dwarf_Debug dwarf, Dwarf_Die die, + Dwarf_Die cu_die) { + Dwarf_Attribute attr_mem; + Dwarf_Error error = DW_DLE_NE; + Dwarf_Unsigned file_index; + + std::string file; + + if (dwarf_attr(die, DW_AT_call_file, &attr_mem, &error) == DW_DLV_OK) { + if (dwarf_formudata(attr_mem, &file_index, &error) != DW_DLV_OK) { + file_index = 0; + } + dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR); + + if (file_index == 0) { + return file; + } + + char **srcfiles = 0; + Dwarf_Signed file_count = 0; + if (dwarf_srcfiles(cu_die, &srcfiles, &file_count, &error) == DW_DLV_OK) { + if (file_count > 0 && file_index <= static_cast(file_count)) { + file = std::string(srcfiles[file_index - 1]); + } + + // Deallocate all strings! + for (int i = 0; i < file_count; ++i) { + dwarf_dealloc(dwarf, srcfiles[i], DW_DLA_STRING); + } + dwarf_dealloc(dwarf, srcfiles, DW_DLA_LIST); + } + } + return file; + } + + Dwarf_Die find_die(dwarf_fileobject &fobj, Dwarf_Addr addr) { + // Let's get to work! First see if we have a debug_aranges section so + // we can speed up the search + + Dwarf_Debug dwarf = fobj.dwarf_handle.get(); + Dwarf_Error error = DW_DLE_NE; + Dwarf_Arange *aranges; + Dwarf_Signed arange_count; + + Dwarf_Die returnDie; + bool found = false; + if (dwarf_get_aranges(dwarf, &aranges, &arange_count, &error) != + DW_DLV_OK) { + aranges = NULL; + } + + if (aranges) { + // We have aranges. Get the one where our address is. + Dwarf_Arange arange; + if (dwarf_get_arange(aranges, arange_count, addr, &arange, &error) == + DW_DLV_OK) { + + // We found our address. Get the compilation-unit DIE offset + // represented by the given address range. + Dwarf_Off cu_die_offset; + if (dwarf_get_cu_die_offset(arange, &cu_die_offset, &error) == + DW_DLV_OK) { + // Get the DIE at the offset returned by the aranges search. + // We set is_info to 1 to specify that the offset is from + // the .debug_info section (and not .debug_types) + int dwarf_result = + dwarf_offdie_b(dwarf, cu_die_offset, 1, &returnDie, &error); + + found = dwarf_result == DW_DLV_OK; + } + dwarf_dealloc(dwarf, arange, DW_DLA_ARANGE); + } + } + + if (found) + return returnDie; // The caller is responsible for freeing the die + + // The search for aranges failed. Try to find our address by scanning + // all compilation units. + Dwarf_Unsigned next_cu_header; + Dwarf_Half tag = 0; + returnDie = 0; + + while (!found && + dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, + &next_cu_header, 0, &error) == DW_DLV_OK) { + + if (returnDie) + dwarf_dealloc(dwarf, returnDie, DW_DLA_DIE); + + if (dwarf_siblingof(dwarf, 0, &returnDie, &error) == DW_DLV_OK) { + if ((dwarf_tag(returnDie, &tag, &error) == DW_DLV_OK) && + tag == DW_TAG_compile_unit) { + if (die_has_pc(fobj, returnDie, addr)) { + found = true; + } + } + } + } + + if (found) { + while (dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, + &next_cu_header, 0, &error) == DW_DLV_OK) { + // Reset the cu header state. Libdwarf's next_cu_header API + // keeps its own iterator per Dwarf_Debug that can't be reset. + // We need to keep fetching elements until the end. + } + } + + if (found) + return returnDie; + + // We couldn't find any compilation units with ranges or a high/low pc. + // Try again by looking at all DIEs in all compilation units. + Dwarf_Die cudie; + while (dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, + &next_cu_header, 0, &error) == DW_DLV_OK) { + if (dwarf_siblingof(dwarf, 0, &cudie, &error) == DW_DLV_OK) { + Dwarf_Die die_mem = 0; + Dwarf_Die resultDie = find_fundie_by_pc(fobj, cudie, addr, die_mem); + + if (resultDie) { + found = true; + break; + } + } + } + + if (found) { + while (dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, + &next_cu_header, 0, &error) == DW_DLV_OK) { + // Reset the cu header state. Libdwarf's next_cu_header API + // keeps its own iterator per Dwarf_Debug that can't be reset. + // We need to keep fetching elements until the end. + } + } + + if (found) + return cudie; + + // We failed. + return NULL; + } +}; +#endif // BACKWARD_HAS_DWARF == 1 + +template <> +class TraceResolverImpl + : public TraceResolverLinuxImpl {}; + +#endif // BACKWARD_SYSTEM_LINUX + +#ifdef BACKWARD_SYSTEM_DARWIN + +template class TraceResolverDarwinImpl; + +template <> +class TraceResolverDarwinImpl + : public TraceResolverImplBase { +public: + template void load_stacktrace(ST &st) { + using namespace details; + if (st.size() == 0) { + return; + } + _symbols.reset(backtrace_symbols(st.begin(), st.size())); + } + + ResolvedTrace resolve(ResolvedTrace trace) { + // parse: + // + + char *filename = _symbols[trace.idx]; + + // skip " " + while (*filename && *filename != ' ') + filename++; + while (*filename == ' ') + filename++; + + // find start of from end ( may contain a space) + char *p = filename + strlen(filename) - 1; + // skip to start of " + " + while (p > filename && *p != ' ') + p--; + while (p > filename && *p == ' ') + p--; + while (p > filename && *p != ' ') + p--; + while (p > filename && *p == ' ') + p--; + char *funcname_end = p + 1; + + // skip to start of "" + while (p > filename && *p != ' ') + p--; + char *funcname = p + 1; + + // skip to start of " " + while (p > filename && *p == ' ') + p--; + while (p > filename && *p != ' ') + p--; + while (p > filename && *p == ' ') + p--; + + // skip "", handling the case where it contains a + char *filename_end = p + 1; + if (p == filename) { + // something went wrong, give up + filename_end = filename + strlen(filename); + funcname = filename_end; + } + trace.object_filename.assign( + filename, filename_end); // ok even if filename_end is the ending \0 + // (then we assign entire string) + + if (*funcname) { // if it's not end of string + *funcname_end = '\0'; + + trace.object_function = this->demangle(funcname); + trace.object_function += " "; + trace.object_function += (funcname_end + 1); + trace.source.function = trace.object_function; // we cannot do better. + } + return trace; + } + +private: + details::handle _symbols; +}; + +template <> +class TraceResolverImpl + : public TraceResolverDarwinImpl {}; + +#endif // BACKWARD_SYSTEM_DARWIN + +#ifdef BACKWARD_SYSTEM_WINDOWS + +// Load all symbol info +// Based on: +// https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app/28276227#28276227 + +struct module_data { + std::string image_name; + std::string module_name; + void *base_address; + DWORD load_size; +}; + +class get_mod_info { + HANDLE process; + static const int buffer_length = 4096; + +public: + get_mod_info(HANDLE h) : process(h) {} + + module_data operator()(HMODULE module) { + module_data ret; + char temp[buffer_length]; + MODULEINFO mi; + + GetModuleInformation(process, module, &mi, sizeof(mi)); + ret.base_address = mi.lpBaseOfDll; + ret.load_size = mi.SizeOfImage; + + GetModuleFileNameExA(process, module, temp, sizeof(temp)); + ret.image_name = temp; + GetModuleBaseNameA(process, module, temp, sizeof(temp)); + ret.module_name = temp; + std::vector img(ret.image_name.begin(), ret.image_name.end()); + std::vector mod(ret.module_name.begin(), ret.module_name.end()); + SymLoadModule64(process, 0, &img[0], &mod[0], (DWORD64)ret.base_address, + ret.load_size); + return ret; + } +}; + +template <> class TraceResolverImpl { +public: + TraceResolverImpl() { + + HANDLE process = GetCurrentProcess(); + + std::vector modules; + DWORD cbNeeded; + std::vector module_handles(1); + SymInitialize(process, NULL, false); + DWORD symOptions = SymGetOptions(); + symOptions |= SYMOPT_LOAD_LINES | SYMOPT_UNDNAME; + SymSetOptions(symOptions); + EnumProcessModules(process, &module_handles[0], + module_handles.size() * sizeof(HMODULE), &cbNeeded); + module_handles.resize(cbNeeded / sizeof(HMODULE)); + EnumProcessModules(process, &module_handles[0], + module_handles.size() * sizeof(HMODULE), &cbNeeded); + std::transform(module_handles.begin(), module_handles.end(), + std::back_inserter(modules), get_mod_info(process)); + void *base = modules[0].base_address; + IMAGE_NT_HEADERS *h = ImageNtHeader(base); + image_type = h->FileHeader.Machine; + } + + template void load_stacktrace(ST &) {} + + static const int max_sym_len = 255; + struct symbol_t { + SYMBOL_INFO sym; + char buffer[max_sym_len]; + } sym; + + DWORD64 displacement; + + ResolvedTrace resolve(ResolvedTrace t) { + HANDLE process = GetCurrentProcess(); + + char name[256]; + + memset(&sym, 0, sizeof(sym)); + sym.sym.SizeOfStruct = sizeof(SYMBOL_INFO); + sym.sym.MaxNameLen = max_sym_len; + + if (!SymFromAddr(process, (ULONG64)t.addr, &displacement, &sym.sym)) { + // TODO: error handling everywhere + char* lpMsgBuf; + DWORD dw = GetLastError(); + + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (char*)&lpMsgBuf, 0, NULL); + + printf(lpMsgBuf); + + // abort(); + } + UnDecorateSymbolName(sym.sym.Name, (PSTR)name, 256, UNDNAME_COMPLETE); + + DWORD offset = 0; + IMAGEHLP_LINE line; + if (SymGetLineFromAddr(process, (ULONG64)t.addr, &offset, &line)) { + t.object_filename = line.FileName; + t.source.filename = line.FileName; + t.source.line = line.LineNumber; + t.source.col = offset; + } + + t.source.function = name; + t.object_filename = ""; + t.object_function = name; + + return t; + } + + DWORD machine_type() const { return image_type; } + +private: + DWORD image_type; +}; + +#endif + +class TraceResolver : public TraceResolverImpl {}; + +/*************** CODE SNIPPET ***************/ + +class SourceFile { +public: + typedef std::vector> lines_t; + + SourceFile() {} + SourceFile(const std::string &path) { + // 1. If BACKWARD_CXX_SOURCE_PREFIXES is set then assume it contains + // a colon-separated list of path prefixes. Try prepending each + // to the given path until a valid file is found. + const std::vector &prefixes = get_paths_from_env_variable(); + for (size_t i = 0; i < prefixes.size(); ++i) { + // Double slashes (//) should not be a problem. + std::string new_path = prefixes[i] + '/' + path; + _file.reset(new std::ifstream(new_path.c_str())); + if (is_open()) + break; + } + // 2. If no valid file found then fallback to opening the path as-is. + if (!_file || !is_open()) { + _file.reset(new std::ifstream(path.c_str())); + } + } + bool is_open() const { return _file->is_open(); } + + lines_t &get_lines(unsigned line_start, unsigned line_count, lines_t &lines) { + using namespace std; + // This function make uses of the dumbest algo ever: + // 1) seek(0) + // 2) read lines one by one and discard until line_start + // 3) read line one by one until line_start + line_count + // + // If you are getting snippets many time from the same file, it is + // somewhat a waste of CPU, feel free to benchmark and propose a + // better solution ;) + + _file->clear(); + _file->seekg(0); + string line; + unsigned line_idx; + + for (line_idx = 1; line_idx < line_start; ++line_idx) { + std::getline(*_file, line); + if (!*_file) { + return lines; + } + } + + // think of it like a lambda in C++98 ;) + // but look, I will reuse it two times! + // What a good boy am I. + struct isspace { + bool operator()(char c) { return std::isspace(c); } + }; + + bool started = false; + for (; line_idx < line_start + line_count; ++line_idx) { + getline(*_file, line); + if (!*_file) { + return lines; + } + if (!started) { + if (std::find_if(line.begin(), line.end(), not_isspace()) == line.end()) + continue; + started = true; + } + lines.push_back(make_pair(line_idx, line)); + } + + lines.erase( + std::find_if(lines.rbegin(), lines.rend(), not_isempty()).base(), + lines.end()); + return lines; + } + + lines_t get_lines(unsigned line_start, unsigned line_count) { + lines_t lines; + return get_lines(line_start, line_count, lines); + } + + // there is no find_if_not in C++98, lets do something crappy to + // workaround. + struct not_isspace { + bool operator()(char c) { return !std::isspace(c); } + }; + // and define this one here because C++98 is not happy with local defined + // struct passed to template functions, fuuuu. + struct not_isempty { + bool operator()(const lines_t::value_type &p) { + return !(std::find_if(p.second.begin(), p.second.end(), not_isspace()) == + p.second.end()); + } + }; + + void swap(SourceFile &b) { _file.swap(b._file); } + +#ifdef BACKWARD_ATLEAST_CXX11 + SourceFile(SourceFile &&from) : _file(nullptr) { swap(from); } + SourceFile &operator=(SourceFile &&from) { + swap(from); + return *this; + } +#else + explicit SourceFile(const SourceFile &from) { + // some sort of poor man's move semantic. + swap(const_cast(from)); + } + SourceFile &operator=(const SourceFile &from) { + // some sort of poor man's move semantic. + swap(const_cast(from)); + return *this; + } +#endif + +private: + details::handle> + _file; + + std::vector get_paths_from_env_variable_impl() { + std::vector paths; + const char *prefixes_str = std::getenv("BACKWARD_CXX_SOURCE_PREFIXES"); + if (prefixes_str && prefixes_str[0]) { + paths = details::split_source_prefixes(prefixes_str); + } + return paths; + } + + const std::vector &get_paths_from_env_variable() { + static std::vector paths = get_paths_from_env_variable_impl(); + return paths; + } + +#ifdef BACKWARD_ATLEAST_CXX11 + SourceFile(const SourceFile &) = delete; + SourceFile &operator=(const SourceFile &) = delete; +#endif +}; + +class SnippetFactory { +public: + typedef SourceFile::lines_t lines_t; + + lines_t get_snippet(const std::string &filename, unsigned line_start, + unsigned context_size) { + + SourceFile &src_file = get_src_file(filename); + unsigned start = line_start - context_size / 2; + return src_file.get_lines(start, context_size); + } + + lines_t get_combined_snippet(const std::string &filename_a, unsigned line_a, + const std::string &filename_b, unsigned line_b, + unsigned context_size) { + SourceFile &src_file_a = get_src_file(filename_a); + SourceFile &src_file_b = get_src_file(filename_b); + + lines_t lines = + src_file_a.get_lines(line_a - context_size / 4, context_size / 2); + src_file_b.get_lines(line_b - context_size / 4, context_size / 2, lines); + return lines; + } + + lines_t get_coalesced_snippet(const std::string &filename, unsigned line_a, + unsigned line_b, unsigned context_size) { + SourceFile &src_file = get_src_file(filename); + + using std::max; + using std::min; + unsigned a = min(line_a, line_b); + unsigned b = max(line_a, line_b); + + if ((b - a) < (context_size / 3)) { + return src_file.get_lines((a + b - context_size + 1) / 2, context_size); + } + + lines_t lines = src_file.get_lines(a - context_size / 4, context_size / 2); + src_file.get_lines(b - context_size / 4, context_size / 2, lines); + return lines; + } + +private: + typedef details::hashtable::type src_files_t; + src_files_t _src_files; + + SourceFile &get_src_file(const std::string &filename) { + src_files_t::iterator it = _src_files.find(filename); + if (it != _src_files.end()) { + return it->second; + } + SourceFile &new_src_file = _src_files[filename]; + new_src_file = SourceFile(filename); + return new_src_file; + } +}; + +/*************** PRINTER ***************/ + +namespace ColorMode { +enum type { automatic, never, always }; +} + +class cfile_streambuf : public std::streambuf { +public: + cfile_streambuf(FILE *_sink) : sink(_sink) {} + int_type underflow() override { return traits_type::eof(); } + int_type overflow(int_type ch) override { + if (traits_type::not_eof(ch) && fwrite(&ch, sizeof ch, 1, sink) == 1) { + return ch; + } + return traits_type::eof(); + } + + std::streamsize xsputn(const char_type *s, std::streamsize count) override { + return static_cast( + fwrite(s, sizeof *s, static_cast(count), sink)); + } + +#ifdef BACKWARD_ATLEAST_CXX11 +public: + cfile_streambuf(const cfile_streambuf &) = delete; + cfile_streambuf &operator=(const cfile_streambuf &) = delete; +#else +private: + cfile_streambuf(const cfile_streambuf &); + cfile_streambuf &operator=(const cfile_streambuf &); +#endif + +private: + FILE *sink; + std::vector buffer; +}; + +#ifdef BACKWARD_SYSTEM_LINUX + +namespace Color { +enum type { yellow = 33, purple = 35, reset = 39 }; +} // namespace Color + +class Colorize { +public: + Colorize(std::ostream &os) : _os(os), _reset(false), _enabled(false) {} + + void activate(ColorMode::type mode) { _enabled = mode == ColorMode::always; } + + void activate(ColorMode::type mode, FILE *fp) { activate(mode, fileno(fp)); } + + void set_color(Color::type ccode) { + if (!_enabled) + return; + + // I assume that the terminal can handle basic colors. Seriously I + // don't want to deal with all the termcap shit. + _os << "\033[" << static_cast(ccode) << "m"; + _reset = (ccode != Color::reset); + } + + ~Colorize() { + if (_reset) { + set_color(Color::reset); + } + } + +private: + void activate(ColorMode::type mode, int fd) { + activate(mode == ColorMode::automatic && isatty(fd) ? ColorMode::always + : mode); + } + + std::ostream &_os; + bool _reset; + bool _enabled; +}; + +#else // ndef BACKWARD_SYSTEM_LINUX + +namespace Color { +enum type { yellow = 0, purple = 0, reset = 0 }; +} // namespace Color + +class Colorize { +public: + Colorize(std::ostream &) {} + void activate(ColorMode::type) {} + void activate(ColorMode::type, FILE *) {} + void set_color(Color::type) {} +}; + +#endif // BACKWARD_SYSTEM_LINUX + +class Printer { +public: + bool snippet; + ColorMode::type color_mode; + bool address; + bool object; + int inliner_context_size; + int trace_context_size; + + Printer() + : snippet(true), color_mode(ColorMode::automatic), address(false), + object(false), inliner_context_size(5), trace_context_size(7) {} + + template FILE *print(ST &st, FILE *fp = stderr) { + cfile_streambuf obuf(fp); + std::ostream os(&obuf); + Colorize colorize(os); + colorize.activate(color_mode, fp); + print_stacktrace(st, os, colorize); + return fp; + } + + template std::ostream &print(ST &st, std::ostream &os) { + Colorize colorize(os); + colorize.activate(color_mode); + print_stacktrace(st, os, colorize); + return os; + } + + template + FILE *print(IT begin, IT end, FILE *fp = stderr, size_t thread_id = 0) { + cfile_streambuf obuf(fp); + std::ostream os(&obuf); + Colorize colorize(os); + colorize.activate(color_mode, fp); + print_stacktrace(begin, end, os, thread_id, colorize); + return fp; + } + + template + std::ostream &print(IT begin, IT end, std::ostream &os, + size_t thread_id = 0) { + Colorize colorize(os); + colorize.activate(color_mode); + print_stacktrace(begin, end, os, thread_id, colorize); + return os; + } + + TraceResolver const &resolver() const { return _resolver; } + +private: + TraceResolver _resolver; + SnippetFactory _snippets; + + template + void print_stacktrace(ST &st, std::ostream &os, Colorize &colorize) { + print_header(os, st.thread_id()); + _resolver.load_stacktrace(st); + for (size_t trace_idx = st.size(); trace_idx > 0; --trace_idx) { + print_trace(os, _resolver.resolve(st[trace_idx - 1]), colorize); + } + } + + template + void print_stacktrace(IT begin, IT end, std::ostream &os, size_t thread_id, + Colorize &colorize) { + print_header(os, thread_id); + for (; begin != end; ++begin) { + print_trace(os, *begin, colorize); + } + } + + void print_header(std::ostream &os, size_t thread_id) { + os << "Stack trace (most recent call last)"; + if (thread_id) { + os << " in thread " << thread_id; + } + os << ":\n"; + } + + void print_trace(std::ostream &os, const ResolvedTrace &trace, + Colorize &colorize) { + os << "#" << std::left << std::setw(2) << trace.idx << std::right; + bool already_indented = true; + + if (!trace.source.filename.size() || object) { + os << " Object \"" << trace.object_filename << "\", at " << trace.addr + << ", in " << trace.object_function << "\n"; + already_indented = false; + } + + for (size_t inliner_idx = trace.inliners.size(); inliner_idx > 0; + --inliner_idx) { + if (!already_indented) { + os << " "; + } + const ResolvedTrace::SourceLoc &inliner_loc = + trace.inliners[inliner_idx - 1]; + print_source_loc(os, " | ", inliner_loc); + if (snippet) { + print_snippet(os, " | ", inliner_loc, colorize, Color::purple, + inliner_context_size); + } + already_indented = false; + } + + if (trace.source.filename.size()) { + if (!already_indented) { + os << " "; + } + print_source_loc(os, " ", trace.source, trace.addr); + if (snippet) { + print_snippet(os, " ", trace.source, colorize, Color::yellow, + trace_context_size); + } + } + } + + void print_snippet(std::ostream &os, const char *indent, + const ResolvedTrace::SourceLoc &source_loc, + Colorize &colorize, Color::type color_code, + int context_size) { + using namespace std; + typedef SnippetFactory::lines_t lines_t; + + lines_t lines = _snippets.get_snippet(source_loc.filename, source_loc.line, + static_cast(context_size)); + + for (lines_t::const_iterator it = lines.begin(); it != lines.end(); ++it) { + if (it->first == source_loc.line) { + colorize.set_color(color_code); + os << indent << ">"; + } else { + os << indent << " "; + } + os << std::setw(4) << it->first << ": " << it->second << "\n"; + if (it->first == source_loc.line) { + colorize.set_color(Color::reset); + } + } + } + + void print_source_loc(std::ostream &os, const char *indent, + const ResolvedTrace::SourceLoc &source_loc, + void *addr = nullptr) { + os << indent << "Source \"" << source_loc.filename << "\", line " + << source_loc.line << ", in " << source_loc.function; + + if (address && addr != nullptr) { + os << " [" << addr << "]"; + } + os << "\n"; + } +}; + +/*************** SIGNALS HANDLING ***************/ + +#if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_DARWIN) + +class SignalHandling { +public: + static std::vector make_default_signals() { + const int posix_signals[] = { + // Signals for which the default action is "Core". + SIGABRT, // Abort signal from abort(3) + SIGBUS, // Bus error (bad memory access) + SIGFPE, // Floating point exception + SIGILL, // Illegal Instruction + SIGIOT, // IOT trap. A synonym for SIGABRT + SIGQUIT, // Quit from keyboard + SIGSEGV, // Invalid memory reference + SIGSYS, // Bad argument to routine (SVr4) + SIGTRAP, // Trace/breakpoint trap + SIGXCPU, // CPU time limit exceeded (4.2BSD) + SIGXFSZ, // File size limit exceeded (4.2BSD) +#if defined(BACKWARD_SYSTEM_DARWIN) + SIGEMT, // emulation instruction executed +#endif + }; + return std::vector(posix_signals, + posix_signals + + sizeof posix_signals / sizeof posix_signals[0]); + } + + SignalHandling(const std::vector &posix_signals = make_default_signals()) + : _loaded(false) { + bool success = true; + + const size_t stack_size = 1024 * 1024 * 8; + _stack_content.reset(static_cast(malloc(stack_size))); + if (_stack_content) { + stack_t ss; + ss.ss_sp = _stack_content.get(); + ss.ss_size = stack_size; + ss.ss_flags = 0; + if (sigaltstack(&ss, nullptr) < 0) { + success = false; + } + } else { + success = false; + } + + for (size_t i = 0; i < posix_signals.size(); ++i) { + struct sigaction action; + memset(&action, 0, sizeof action); + action.sa_flags = + static_cast(SA_SIGINFO | SA_ONSTACK | SA_NODEFER | SA_RESETHAND); + sigfillset(&action.sa_mask); + sigdelset(&action.sa_mask, posix_signals[i]); +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" +#endif + action.sa_sigaction = &sig_handler; +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + + int r = sigaction(posix_signals[i], &action, nullptr); + if (r < 0) + success = false; + } + + _loaded = success; + } + + bool loaded() const { return _loaded; } + + static void handleSignal(int, siginfo_t *info, void *_ctx) { + ucontext_t *uctx = static_cast(_ctx); + + StackTrace st; + void *error_addr = nullptr; +#ifdef REG_RIP // x86_64 + error_addr = reinterpret_cast(uctx->uc_mcontext.gregs[REG_RIP]); +#elif defined(REG_EIP) // x86_32 + error_addr = reinterpret_cast(uctx->uc_mcontext.gregs[REG_EIP]); +#elif defined(__arm__) + error_addr = reinterpret_cast(uctx->uc_mcontext.arm_pc); +#elif defined(__aarch64__) + #if defined(__APPLE__) + error_addr = reinterpret_cast(uctx->uc_mcontext->__ss.__pc); + #elif + error_addr = reinterpret_cast(uctx->uc_mcontext.pc); + #endif +#elif defined(__mips__) + error_addr = reinterpret_cast( + reinterpret_cast(&uctx->uc_mcontext)->sc_pc); +#elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \ + defined(__POWERPC__) + error_addr = reinterpret_cast(uctx->uc_mcontext.regs->nip); +#elif defined(__s390x__) + error_addr = reinterpret_cast(uctx->uc_mcontext.psw.addr); +#elif defined(__APPLE__) && defined(__x86_64__) + error_addr = reinterpret_cast(uctx->uc_mcontext->__ss.__rip); +#elif defined(__APPLE__) + error_addr = reinterpret_cast(uctx->uc_mcontext->__ss.__eip); +#else +#warning ":/ sorry, ain't know no nothing none not of your architecture!" +#endif + if (error_addr) { + st.load_from(error_addr, 32, reinterpret_cast(uctx), + info->si_addr); + } else { + st.load_here(32, reinterpret_cast(uctx), info->si_addr); + } + + Printer printer; + printer.address = true; + printer.print(st, stderr); + +#if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L + psiginfo(info, nullptr); +#else + (void)info; +#endif + } + +private: + details::handle _stack_content; + bool _loaded; + +#ifdef __GNUC__ + __attribute__((noreturn)) +#endif + static void + sig_handler(int signo, siginfo_t *info, void *_ctx) { + handleSignal(signo, info, _ctx); + + // try to forward the signal. + raise(info->si_signo); + + // terminate the process immediately. + puts("watf? exit"); + _exit(EXIT_FAILURE); + } +}; + +#endif // BACKWARD_SYSTEM_LINUX || BACKWARD_SYSTEM_DARWIN + +#ifdef BACKWARD_SYSTEM_WINDOWS + +class SignalHandling { +public: + SignalHandling(const std::vector & = std::vector()) + : reporter_thread_([]() { + /* We handle crashes in a utility thread: + backward structures and some Windows functions called here + need stack space, which we do not have when we encounter a + stack overflow. + To support reporting stack traces during a stack overflow, + we create a utility thread at startup, which waits until a + crash happens or the program exits normally. */ + + { + std::unique_lock lk(mtx()); + cv().wait(lk, [] { return crashed() != crash_status::running; }); + } + if (crashed() == crash_status::crashed) { + handle_stacktrace(skip_recs()); + } + { + std::unique_lock lk(mtx()); + crashed() = crash_status::ending; + } + cv().notify_one(); + }) { + SetUnhandledExceptionFilter(crash_handler); + + signal(SIGABRT, signal_handler); + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + + std::set_terminate(&terminator); + std::set_unexpected(&terminator); + _set_purecall_handler(&terminator); + _set_invalid_parameter_handler(&invalid_parameter_handler); + } + bool loaded() const { return true; } + + ~SignalHandling() { + { + std::unique_lock lk(mtx()); + crashed() = crash_status::normal_exit; + } + + cv().notify_one(); + + reporter_thread_.join(); + } + +private: + static CONTEXT *ctx() { + static CONTEXT data; + return &data; + } + + enum class crash_status { running, crashed, normal_exit, ending }; + + static crash_status &crashed() { + static crash_status data; + return data; + } + + static std::mutex &mtx() { + static std::mutex data; + return data; + } + + static std::condition_variable &cv() { + static std::condition_variable data; + return data; + } + + static HANDLE &thread_handle() { + static HANDLE handle; + return handle; + } + + std::thread reporter_thread_; + + // TODO: how not to hardcode these? + static const constexpr int signal_skip_recs = +#ifdef __clang__ + // With clang, RtlCaptureContext also captures the stack frame of the + // current function Below that, there ar 3 internal Windows functions + 4 +#else + // With MSVC cl, RtlCaptureContext misses the stack frame of the current + // function The first entries during StackWalk are the 3 internal Windows + // functions + 3 +#endif + ; + + static int &skip_recs() { + static int data; + return data; + } + + static inline void terminator() { + crash_handler(signal_skip_recs); + abort(); + } + + static inline void signal_handler(int) { + crash_handler(signal_skip_recs); + abort(); + } + + static inline void __cdecl invalid_parameter_handler(const wchar_t *, + const wchar_t *, + const wchar_t *, + unsigned int, + uintptr_t) { + crash_handler(signal_skip_recs); + abort(); + } + + NOINLINE static LONG WINAPI crash_handler(EXCEPTION_POINTERS *info) { + // The exception info supplies a trace from exactly where the issue was, + // no need to skip records + crash_handler(0, info->ContextRecord); + return EXCEPTION_CONTINUE_SEARCH; + } + + NOINLINE static void crash_handler(int skip, CONTEXT *ct = nullptr) { + + if (ct == nullptr) { + RtlCaptureContext(ctx()); + } else { + memcpy(ctx(), ct, sizeof(CONTEXT)); + } + DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &thread_handle(), 0, FALSE, + DUPLICATE_SAME_ACCESS); + + skip_recs() = skip; + + { + std::unique_lock lk(mtx()); + crashed() = crash_status::crashed; + } + + cv().notify_one(); + + { + std::unique_lock lk(mtx()); + cv().wait(lk, [] { return crashed() != crash_status::crashed; }); + } + } + + static void handle_stacktrace(int skip_frames = 0) { + // printer creates the TraceResolver, which can supply us a machine type + // for stack walking. Without this, StackTrace can only guess using some + // macros. + // StackTrace also requires that the PDBs are already loaded, which is done + // in the constructor of TraceResolver + Printer printer; + + StackTrace st; + st.set_machine_type(printer.resolver().machine_type()); + st.set_context(ctx()); + st.set_thread_handle(thread_handle()); + st.load_here(32 + skip_frames); + st.skip_n_firsts(skip_frames); + + printer.address = true; + printer.print(st, std::cerr); + } +}; + +#endif // BACKWARD_SYSTEM_WINDOWS + +#ifdef BACKWARD_SYSTEM_UNKNOWN + +class SignalHandling { +public: + SignalHandling(const std::vector & = std::vector()) {} + bool init() { return false; } + bool loaded() { return false; } +}; + +#endif // BACKWARD_SYSTEM_UNKNOWN + +} // namespace backward + +#endif /* H_GUARD */ diff --git a/lib/include/srslte/common/band_helper.h b/lib/include/srslte/common/band_helper.h new file mode 100644 index 000000000..e2521277a --- /dev/null +++ b/lib/include/srslte/common/band_helper.h @@ -0,0 +1,106 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_BAND_HELPER_H +#define SRSLTE_BAND_HELPER_H + +#include +#include +#include + +namespace srslte { + +// Helper class to handle frequency bands and ARFCNs +// For NR: NR-ARFCN and channel raster as per TS 38.104 +class srslte_band_helper +{ +public: + srslte_band_helper() = default; + ~srslte_band_helper() = default; + + // Return frequency of given NR-ARFCN in Hz + double nr_arfcn_to_freq(uint32_t nr_arfcn); + + // Possible values of delta f_raster in Table 5.4.2.3-1 and Table 5.4.2.3-2 + enum delta_f_raster_t { + DEFAULT = 0, // for bands with 2 possible values for delta_f_raster (e.g. 15 and 30 kHz), the lower is chosen + KHZ_15, + KHZ_30, + KHZ_60, + KHZ_100, + KHZ_120 + }; + + // Return vector of bands that ARFCN is valid for + // For bands with 2 possible raster offsets, delta_f_raster needs to be specified + std::vector get_bands_nr(uint32_t nr_arfcn, delta_f_raster_t delta_f_raster = DEFAULT); + +private: + // Table 5.4.2.1-1 + struct nr_raster_params { + double delta_F_global_kHz; + double F_REF_Offs_MHz; + uint32_t N_REF_Offs; + uint32_t N_REF_min; + uint32_t N_REF_max; + }; + + // Helper to calculate F_REF according to Table 5.4.2.1-1 + nr_raster_params get_raster_params(uint32_t nr_arfcn); + + static const uint32_t max_nr_arfcn = 3279165; + static constexpr std::array nr_fr_params = {{ + // clang-format off + // Frequency range 0 - 3000 MHz + {5, 0.0, 0, 0, 599999}, + // Frequency range 3000 - 24250 MHz + {15, 3000.0, 600000, 600000, 2016666}, + // Frequency range 24250 - 100000 MHz + {60, 24250.08, 2016667, 2016667, max_nr_arfcn} + // clang-format on + }}; + + // Elements of Table 5.4.2.3-1 in TS 38.104 + struct nr_band { + uint8_t band; + delta_f_raster_t delta_f_raster; + uint32_t ul_nref_first; + uint32_t ul_nref_step; + uint32_t ul_nref_last; + uint32_t dl_nref_first; + uint32_t dl_nref_step; + uint32_t dl_nref_last; + }; + + // List of NR bands for FR1 (Table 5.4.2.3-1) + // bands with more than one raster offset have multiple entries + // TODO: add remaining bands + static const uint32_t nof_nr_bands_fr1 = 7; + static constexpr std::array nr_band_table_fr1 = {{ + // clang-format off + {74, KHZ_100, 285400, 20, 294000, 295000, 20, 303600}, + // n75+n76 missing + {77, KHZ_15, 620000, 1, 680000, 620000, 1, 680000}, + {77, KHZ_30, 620000, 2, 680000, 620000, 2, 680000}, + + {78, KHZ_15, 620000, 1, 653333, 620000, 1, 653333}, + {78, KHZ_30, 620000, 2, 653332, 620000, 2, 653332}, + + {79, KHZ_15, 693334, 2, 733333, 693334, 2, 733333}, + {79, KHZ_30, 693334, 2, 733332, 693334, 2, 733332} + // clang-format on + }}; +}; + +} // namespace srslte + +#endif // SRSLTE_BAND_HELPER_H \ No newline at end of file diff --git a/lib/include/srslte/common/basic_pnf.h b/lib/include/srslte/common/basic_pnf.h index 13ed91836..d5c90d756 100644 --- a/lib/include/srslte/common/basic_pnf.h +++ b/lib/include/srslte/common/basic_pnf.h @@ -27,7 +27,7 @@ #include "srslte/adt/choice_type.h" #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -83,7 +83,8 @@ public: rand_gen(RAND_SEED), rand_dist(MIN_TB_LEN, MAX_TB_LEN) { - log_h->set_level(srslte::LOG_LEVEL_WARNING); + logger.set_level(srslog::basic_levels::warning); + logger.set_hex_dump_max_size(-1); } ~srslte_basic_pnf() { stop(); }; @@ -323,7 +324,7 @@ private: { basic_vnf_api::msg_header_t* header = (basic_vnf_api::msg_header_t*)buffer; - log_h->debug("Received %s (%d B) in TTI\n", basic_vnf_api::msg_type_text[header->type], len); + logger.debug("Received %s (%d B) in TTI", basic_vnf_api::msg_type_text[header->type], len); switch (header->type) { case basic_vnf_api::SF_IND: @@ -370,7 +371,7 @@ private: if (rf_out_queue != nullptr) { uint32_t len = sizeof(*msg) - sizeof(msg->pdus->data) + msg->pdus->length; - srslte::unique_byte_buffer_t tx = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t tx = srslte::make_byte_buffer(); memcpy(tx->msg, msg, len); rf_out_queue->push(std::move(tx)); } @@ -461,8 +462,8 @@ private: dl_ind.pdus[i].type = tx_req->pdus[i].type; memcpy(dl_ind.pdus[i].data, tx_req->pdus[i].data, dl_ind.pdus[i].length); tot_bytes += dl_ind.pdus[i].length; - log_h->info_hex( - dl_ind.pdus[i].data, dl_ind.pdus[i].length, "Sending to UE a PDU (%d bytes)\n", dl_ind.pdus[i].length); + logger.info( + dl_ind.pdus[i].data, dl_ind.pdus[i].length, "Sending to UE a PDU (%d bytes)", dl_ind.pdus[i].length); } } } else { @@ -479,7 +480,7 @@ private: tot_bytes = N_bytes; } - log_h->info_hex(dl_ind.pdus[0].data, N_bytes, "Sending to UE a TB (%d bytes)\n", N_bytes); + logger.info(dl_ind.pdus[0].data, N_bytes, "Sending to UE a TB (%d bytes)", N_bytes); } if (tot_bytes > 0 and tot_bytes < tb_size) { @@ -518,8 +519,7 @@ private: std::unique_ptr tx_thread, rx_thread; std::string tx_thread_name = "TX_PNF", rx_thread_name = "RX_PNF"; bool running = false; - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - srslte::log_ref log_h{"PNF"}; + srslog::basic_logger& logger = srslog::fetch_basic_logger("PNF", false); std::mutex mutex; std::atomic tti; diff --git a/lib/include/srslte/common/basic_vnf.h b/lib/include/srslte/common/basic_vnf.h index 03aca8d05..ed2cb38f7 100644 --- a/lib/include/srslte/common/basic_vnf.h +++ b/lib/include/srslte/common/basic_vnf.h @@ -24,10 +24,10 @@ #include "basic_vnf_api.h" #include "common.h" -#include "srslte/common/logmap.h" #include "srslte/common/threads.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/interfaces/ue_nr_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -44,7 +44,7 @@ namespace srslte { class srslte_basic_vnf : public thread { public: - srslte_basic_vnf(const vnf_args_t& args_, srslte::logger* logger_, stack_interface_phy_nr* stack_); + srslte_basic_vnf(const vnf_args_t& args_, stack_interface_phy_nr* stack_); ~srslte_basic_vnf(); bool stop(); @@ -69,11 +69,9 @@ private: // helpers uint32_t calc_full_msg_len(const basic_vnf_api::tx_request_msg_t& msg); - srslte::logger* m_logger = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger = srslog::fetch_basic_logger("VNF", false); srsenb::stack_interface_phy_nr* m_gnb_stack = nullptr; srsue::stack_interface_phy_nr* m_ue_stack = nullptr; - srslte::byte_buffer_pool* m_pool = nullptr; std::unique_ptr m_tx_req_msg; diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index ba351cf60..a65bd861b 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_BUFFER_POOL_H #define SRSLTE_BUFFER_POOL_H +#include "byte_buffer.h" #include #include #include @@ -35,6 +36,7 @@ #include "srslte/common/common.h" #include "srslte/common/log.h" +#include "srslte/srslog/srslog.h" namespace srslte { @@ -61,7 +63,11 @@ public: pthread_mutex_init(&mutex, nullptr); pthread_cond_init(&cv_not_empty, nullptr); for (uint32_t i = 0; i < nof_buffers; i++) { - buffer_t* b = new buffer_t; + buffer_t* b = new (std::nothrow) buffer_t; + if (!b) { + perror("Error allocating memory. Exiting...\n"); + exit(-1); + } available.push(b); } capacity = nof_buffers; @@ -170,70 +176,74 @@ private: class byte_buffer_pool { + using mem_chunk = typename std::aligned_storage::type; + public: // Singleton static methods - static std::unique_ptr instance; - static byte_buffer_pool* get_instance(int capacity = -1); - static void cleanup(); - byte_buffer_pool(int capacity = -1) + static byte_buffer_pool* get_instance(int capacity = -1) { - log = nullptr; - pool = new buffer_pool(capacity); + static std::unique_ptr instance(new byte_buffer_pool(capacity)); + return instance.get(); } + byte_buffer_pool(int capacity = -1) : pool(capacity) {} byte_buffer_pool(const byte_buffer_pool& other) = delete; + byte_buffer_pool(byte_buffer_pool&& other) = delete; byte_buffer_pool& operator=(const byte_buffer_pool& other) = delete; - ~byte_buffer_pool() { delete pool; } - byte_buffer_t* allocate(const char* debug_name = nullptr, bool blocking = false) + byte_buffer_pool& operator=(byte_buffer_pool&& other) = delete; + void* allocate(const char* debug_name = nullptr, bool blocking = false) { - return pool->allocate(debug_name, blocking); + return pool.allocate(debug_name, blocking); } - void set_log(srslte::log* log) { this->log = log; } - void deallocate(byte_buffer_t* b) + void enable_logger(bool enabled) { print_to_log = enabled; } + void deallocate(void* b) { if (!b) { return; } - b->clear(); - if (!pool->deallocate(b)) { - if (log) { + if (!pool.deallocate(static_cast(b))) { #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - log->error("Deallocating PDU: Addr=0x%p, name=%s not found in pool\n", b, b->debug_name); + print_error("Error deallocating PDU: Addr=0x%p, name=%s not found in pool", (void*)b, b->debug_name); #else - log->error("Deallocating PDU: Addr=0x%p\n", b); + print_error("Error deallocating PDU: Addr=0x%p", (void*)b); #endif - } else { -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - printf("Error deallocating PDU: Addr=0x%p, name=%s not found in pool\n", b, b->debug_name); -#else - printf("Error deallocating PDU: Addr=0x%p\n", b); -#endif - } } - b = nullptr; } - void print_all_buffers() { pool->print_all_buffers(); } + void print_all_buffers() { pool.print_all_buffers(); } private: - srslte::log* log; - buffer_pool* pool; + /// Formats and prints the input string and arguments into the configured output stream. + template + void print_error(const char* str, Args&&... args) + { + if (print_to_log) { + srslog::fetch_basic_logger("POOL", false).error(str, std::forward(args)...); + } else { + fmt::printf(std::string(str) + "\n", std::forward(args)...); + } + } + +private: + bool print_to_log = false; + buffer_pool pool; }; -inline void byte_buffer_deleter::operator()(byte_buffer_t* buf) const +inline unique_byte_buffer_t make_byte_buffer() noexcept { - if (buf) { - pool->deallocate(buf); + return std::unique_ptr(new (std::nothrow) byte_buffer_t()); +} + +inline unique_byte_buffer_t make_byte_buffer(uint32_t size, uint8_t value) noexcept +{ + return std::unique_ptr(new (std::nothrow) byte_buffer_t(size, value)); +} + +inline unique_byte_buffer_t make_byte_buffer(const char* debug_ctxt) noexcept +{ + std::unique_ptr buffer(new (std::nothrow) byte_buffer_t()); + if (buffer == nullptr) { + srslog::fetch_basic_logger("POOL").error("Failed to allocate byte buffer in %s", debug_ctxt); } -} - -inline unique_byte_buffer_t allocate_unique_buffer(byte_buffer_pool& pool, bool blocking = false) -{ - return unique_byte_buffer_t(pool.allocate(nullptr, blocking), byte_buffer_deleter(&pool)); -} - -inline unique_byte_buffer_t -allocate_unique_buffer(byte_buffer_pool& pool, const char* debug_name, bool blocking = false) -{ - return unique_byte_buffer_t(pool.allocate(debug_name, blocking), byte_buffer_deleter(&pool)); + return buffer; } } // namespace srslte diff --git a/lib/include/srslte/common/byte_buffer.h b/lib/include/srslte/common/byte_buffer.h new file mode 100644 index 000000000..3719c4747 --- /dev/null +++ b/lib/include/srslte/common/byte_buffer.h @@ -0,0 +1,231 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_BYTE_BUFFER_H +#define SRSLTE_BYTE_BUFFER_H + +#include "common.h" +#include +#include + +//#define SRSLTE_BUFFER_POOL_LOG_ENABLED + +namespace srslte { + +#define ENABLE_TIMESTAMP + +struct buffer_latency_calc { + void clear() + { +#ifdef ENABLE_TIMESTAMP + timestamp_is_set = false; +#endif + } + + std::chrono::microseconds get_latency_us() const + { +#ifdef ENABLE_TIMESTAMP + if (!timestamp_is_set) { + return std::chrono::microseconds{0}; + } + return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - tp); +#else + return std::chrono::microseconds{0}; +#endif + } + + std::chrono::high_resolution_clock::time_point get_timestamp() const { return tp; } + + void set_timestamp() + { +#ifdef ENABLE_TIMESTAMP + tp = std::chrono::high_resolution_clock::now(); + timestamp_is_set = true; +#endif + } + + void set_timestamp(std::chrono::high_resolution_clock::time_point tp_) + { +#ifdef ENABLE_TIMESTAMP + tp = tp_; + timestamp_is_set = true; +#endif + } + +private: +#ifdef ENABLE_TIMESTAMP + std::chrono::high_resolution_clock::time_point tp; + bool timestamp_is_set = false; +#endif +}; + +/****************************************************************************** + * Byte buffer + * + * Generic byte buffer with headroom to accommodate packet headers and custom + * copy constructors & assignment operators for quick copying. Byte buffer + * holds a next pointer to support linked lists. + *****************************************************************************/ +class byte_buffer_t +{ +public: + using iterator = uint8_t*; + using const_iterator = const uint8_t*; + + uint32_t N_bytes = 0; + uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BYTES]; + uint8_t* msg = nullptr; +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN]; +#endif + + struct buffer_metadata_t { + uint32_t pdcp_sn = 0; + buffer_latency_calc tp; + } md; + + byte_buffer_t() : msg(&buffer[SRSLTE_BUFFER_HEADER_OFFSET]) + { +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + bzero(debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); +#endif + } + explicit byte_buffer_t(uint32_t size) : msg(&buffer[SRSLTE_BUFFER_HEADER_OFFSET]), N_bytes(size) + { +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + bzero(debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); +#endif + } + byte_buffer_t(uint32_t size, uint8_t val) : byte_buffer_t(size) { std::fill(msg, msg + N_bytes, val); } + byte_buffer_t(const byte_buffer_t& buf) : msg(&buffer[SRSLTE_BUFFER_HEADER_OFFSET]), md(buf.md), N_bytes(buf.N_bytes) + { + // copy actual contents + memcpy(msg, buf.msg, N_bytes); + } + + byte_buffer_t& operator=(const byte_buffer_t& buf) + { + // avoid self assignment + if (&buf == this) + return *this; + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bytes = buf.N_bytes; + md = buf.md; + memcpy(msg, buf.msg, N_bytes); + return *this; + } + + void clear() + { + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bytes = 0; + md = {}; + } + uint32_t get_headroom() { return msg - buffer; } + // Returns the remaining space from what is reported to be the length of msg + uint32_t get_tailroom() { return (sizeof(buffer) - (msg - buffer) - N_bytes); } + std::chrono::microseconds get_latency_us() const { return md.tp.get_latency_us(); } + + std::chrono::high_resolution_clock::time_point get_timestamp() const { return md.tp.get_timestamp(); } + + void set_timestamp() { md.tp.set_timestamp(); } + + void set_timestamp(std::chrono::high_resolution_clock::time_point tp_) { md.tp.set_timestamp(tp_); } + + void append_bytes(uint8_t* buf, uint32_t size) + { + memcpy(&msg[N_bytes], buf, size); + N_bytes += size; + } + + uint8_t* data() { return msg; } + const uint8_t* data() const { return msg; } + uint32_t size() const { return N_bytes; } + iterator begin() { return msg; } + const iterator begin() const { return msg; } + iterator end() { return msg + N_bytes; } + const_iterator end() const { return msg + N_bytes; } + + void* operator new(size_t sz); + void* operator new(size_t sz, const std::nothrow_t& nothrow_value) noexcept; + void* operator new[](size_t sz) = delete; + void operator delete(void* ptr); + void operator delete[](void* ptr) = delete; +}; + +struct bit_buffer_t { + uint32_t N_bits = 0; + uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BITS]; + uint8_t* msg = nullptr; +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + char debug_name[128]; +#endif + + bit_buffer_t() : msg(&buffer[SRSLTE_BUFFER_HEADER_OFFSET]) {} + bit_buffer_t(const bit_buffer_t& buf) : msg(&buffer[SRSLTE_BUFFER_HEADER_OFFSET]), N_bits(buf.N_bits) + { + memcpy(msg, buf.msg, N_bits); + } + bit_buffer_t& operator=(const bit_buffer_t& buf) + { + // avoid self assignment + if (&buf == this) { + return *this; + } + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bits = buf.N_bits; + memcpy(msg, buf.msg, N_bits); + return *this; + } + void clear() + { + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bits = 0; + } + uint32_t get_headroom() { return msg - buffer; } +}; + +// Create a Managed Life-Time Byte Buffer +class byte_buffer_pool; + +using unique_byte_buffer_t = std::unique_ptr; + +/// +/// Utilities to create a span out of a byte_buffer. +/// + +using byte_span = span; +using const_byte_span = span; + +inline byte_span make_span(byte_buffer_t& b) +{ + return byte_span{b.msg, b.N_bytes}; +} + +inline const_byte_span make_span(const byte_buffer_t& b) +{ + return const_byte_span{b.msg, b.N_bytes}; +} + +inline byte_span make_span(unique_byte_buffer_t& b) +{ + return byte_span{b->msg, b->N_bytes}; +} + +inline const_byte_span make_span(const unique_byte_buffer_t& b) +{ + return const_byte_span{b->msg, b->N_bytes}; +} + +} // namespace srslte + +#endif // SRSLTE_BYTE_BUFFER_H diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 428f3a7c3..a5426323b 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -74,17 +74,6 @@ #define SRSLTE_MAX_BUFFER_SIZE_BITS (SRSLTE_MAX_TBSIZE_BITS + SRSLTE_BUFFER_HEADER_OFFSET) #define SRSLTE_MAX_BUFFER_SIZE_BYTES (SRSLTE_MAX_TBSIZE_BITS / 8 + SRSLTE_BUFFER_HEADER_OFFSET) -//#define SRSLTE_BUFFER_POOL_LOG_ENABLED - -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED -#define pool_allocate (srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__)) -#define pool_allocate_blocking (srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__, true)) -#define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128 -#else -#define pool_allocate (srslte::allocate_unique_buffer(*pool)) -#define pool_allocate_blocking (srslte::allocate_unique_buffer(*pool, true)) -#endif - /******************************************************************************* TYPEDEFS *******************************************************************************/ @@ -93,212 +82,6 @@ namespace srslte { #define ENABLE_TIMESTAMP -/****************************************************************************** - * Byte and Bit buffers - * - * Generic buffers with headroom to accommodate packet headers and custom - * copy constructors & assignment operators for quick copying. Byte buffer - * holds a next pointer to support linked lists. - *****************************************************************************/ -class byte_buffer_t -{ -public: - uint32_t N_bytes; - uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BYTES]; - uint8_t* msg; -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN]; -#endif - - byte_buffer_t() : N_bytes(0) - { - bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - next = NULL; -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - bzero(debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); -#endif - } - byte_buffer_t(const byte_buffer_t& buf) - { - bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - next = NULL; - // copy actual contents - N_bytes = buf.N_bytes; - memcpy(msg, buf.msg, N_bytes); - } - byte_buffer_t& operator=(const byte_buffer_t& buf) - { - // avoid self assignment - if (&buf == this) - return *this; - bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - next = NULL; - N_bytes = buf.N_bytes; - memcpy(msg, buf.msg, N_bytes); - return *this; - } - void clear() - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bytes = 0; -#ifdef ENABLE_TIMESTAMP - timestamp_is_set = false; -#endif - } - uint32_t get_headroom() { return msg - buffer; } - // Returns the remaining space from what is reported to be the length of msg - uint32_t get_tailroom() { return (sizeof(buffer) - (msg - buffer) - N_bytes); } - std::chrono::microseconds get_latency_us() - { -#ifdef ENABLE_TIMESTAMP - if (!timestamp_is_set) { - return std::chrono::microseconds{0}; - } - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - tp); -#else - return std::chrono::microseconds{0}; -#endif - } - - std::chrono::high_resolution_clock::time_point get_timestamp() { return tp; } - - void set_timestamp() - { -#ifdef ENABLE_TIMESTAMP - tp = std::chrono::high_resolution_clock::now(); - timestamp_is_set = true; -#endif - } - - void set_timestamp(std::chrono::high_resolution_clock::time_point tp_) - { - tp = tp_; - timestamp_is_set = true; - } - - void append_bytes(uint8_t* buf, uint32_t size) - { - memcpy(&msg[N_bytes], buf, size); - N_bytes += size; - } - -private: -#ifdef ENABLE_TIMESTAMP - std::chrono::high_resolution_clock::time_point tp; - bool timestamp_is_set = false; -#endif - byte_buffer_t* next; -}; - -struct bit_buffer_t { - uint32_t N_bits; - uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BITS]; - uint8_t* msg; -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - char debug_name[128]; -#endif - - bit_buffer_t() : N_bits(0) - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; -#ifdef ENABLE_TIMESTAMP - timestamp_is_set = false; -#endif - } - bit_buffer_t(const bit_buffer_t& buf) - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bits = buf.N_bits; - memcpy(msg, buf.msg, N_bits); - } - bit_buffer_t& operator=(const bit_buffer_t& buf) - { - // avoid self assignment - if (&buf == this) { - return *this; - } - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bits = buf.N_bits; - memcpy(msg, buf.msg, N_bits); - return *this; - } - void clear() - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bits = 0; -#ifdef ENABLE_TIMESTAMP - timestamp_is_set = false; -#endif - } - uint32_t get_headroom() { return msg - buffer; } - long get_latency_us() - { -#ifdef ENABLE_TIMESTAMP - if (!timestamp_is_set) - return 0; - gettimeofday(×tamp[2], NULL); - return timestamp[0].tv_usec; -#else - return 0; -#endif - } - void set_timestamp() - { -#ifdef ENABLE_TIMESTAMP - gettimeofday(×tamp[1], NULL); - timestamp_is_set = true; -#endif - } - -private: -#ifdef ENABLE_TIMESTAMP - struct timeval timestamp[3]; - bool timestamp_is_set; -#endif -}; - -// Create a Managed Life-Time Byte Buffer -class byte_buffer_pool; -class byte_buffer_deleter -{ -public: - explicit byte_buffer_deleter(byte_buffer_pool* pool_ = nullptr) : pool(pool_) {} - void operator()(byte_buffer_t* buf) const; - byte_buffer_pool* pool; -}; - -typedef std::unique_ptr unique_byte_buffer_t; - -/// -/// Utilities to create a span out of a byte_buffer. -/// - -using byte_span = span; -using const_byte_span = span; - -inline byte_span make_span(byte_buffer_t& b) -{ - return byte_span{b.msg, b.N_bytes}; -} - -inline const_byte_span make_span(const byte_buffer_t& b) -{ - return const_byte_span{b.msg, b.N_bytes}; -} - -inline byte_span make_span(unique_byte_buffer_t& b) -{ - return byte_span{b->msg, b->N_bytes}; -} - -inline const_byte_span make_span(const unique_byte_buffer_t& b) -{ - return const_byte_span{b->msg, b->N_bytes}; -} - // helper functions inline const char* enum_to_text(const char* const array[], uint32_t nof_types, uint32_t enum_val) { diff --git a/lib/include/srslte/common/common_helper.h b/lib/include/srslte/common/common_helper.h index 360fccab3..f46e5492f 100644 --- a/lib/include/srslte/common/common_helper.h +++ b/lib/include/srslte/common/common_helper.h @@ -27,7 +27,7 @@ #ifndef SRSLTE_COMMON_HELPER_H #define SRSLTE_COMMON_HELPER_H -#include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -41,10 +41,9 @@ inline void log_args(int argc, char* argv[], const std::string& service) for (int32_t i = 1; i < argc; i++) { s1 << argv[i] << " "; } - s1 << std::endl; - srslte::logmap::get(service)->set_level(srslte::LOG_LEVEL_INFO); - srslte::logmap::get(service)->info("%s", s1.str().c_str()); + srslog::fetch_basic_logger(service, false).set_level(srslog::basic_levels::info); + srslog::fetch_basic_logger(service).info("%s", s1.str().c_str()); } inline void check_scaling_governor(const std::string& device_name) diff --git a/lib/include/srslte/common/enb_events.h b/lib/include/srslte/common/enb_events.h index 1519b4119..007b3ae10 100644 --- a/lib/include/srslte/common/enb_events.h +++ b/lib/include/srslte/common/enb_events.h @@ -39,22 +39,28 @@ public: virtual ~event_logger_interface() = default; /// Logs into the underlying log channel the RRC connected event. - virtual void log_rrc_connected(unsigned cause) = 0; + virtual void log_rrc_connected(uint32_t enb_cc_idx, const std::string& asn1, unsigned error_code, uint16_t rnti) = 0; /// Logs into the underlying log channel the RRC disconnected event. - virtual void log_rrc_disconnect(unsigned reason) = 0; + virtual void log_rrc_disconnect(uint32_t enb_cc_idx, unsigned reason, uint16_t rnti) = 0; /// Logs into the underlying log channel the S1 context create event. - virtual void log_s1_ctx_create(uint32_t mme_id, uint32_t enb_id, uint16_t rnti) = 0; + virtual void log_s1_ctx_create(uint32_t enb_cc_idx, uint32_t mme_id, uint32_t enb_id, uint16_t rnti) = 0; /// Logs into the underlying log channel the S1 context delete event. - virtual void log_s1_ctx_delete(uint32_t mme_id, uint32_t enb_id, uint16_t rnti) = 0; + virtual void log_s1_ctx_delete(uint32_t enb_cc_idx, uint32_t mme_id, uint32_t enb_id, uint16_t rnti) = 0; - /// Logs into the underlying log channel the when a sector has been started. + /// Logs into the underlying log channel when a sector has been started. virtual void log_sector_start(uint32_t cc_idx, uint32_t pci, uint32_t cell_id) = 0; - /// Logs into the underlying log channel the when a sector has been stopped. + /// Logs into the underlying log channel when a sector has been stopped. virtual void log_sector_stop(uint32_t cc_idx, uint32_t pci, uint32_t cell_id) = 0; + + /// Logs into the underlying log channel a measurement report event.. + virtual void log_measurement_report(uint32_t enb_cc_idx, const std::string& asn1, uint16_t rnti) = 0; + + /// Logs into the underlying log channel a RLF event. + virtual void log_rlf(uint32_t enb_cc_idx, const std::string& asn1, uint16_t rnti) = 0; }; /// Singleton class to provide global access to the event_logger_interface interface. diff --git a/lib/include/srslte/common/fsm.h b/lib/include/srslte/common/fsm.h index c97a7f2b0..1a6f80c0c 100644 --- a/lib/include/srslte/common/fsm.h +++ b/lib/include/srslte/common/fsm.h @@ -24,18 +24,19 @@ #include "srslte/adt/detail/type_utils.h" #include "srslte/adt/move_callback.h" -#include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include +#include #include #include #include #include -#define otherfsmDebug(f, fmt, ...) f->get_log()->debug("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) -#define otherfsmInfo(f, fmt, ...) f->get_log()->info("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) +#define otherfsmDebug(f, fmt, ...) f->get_logger().debug("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) +#define otherfsmInfo(f, fmt, ...) f->get_logger().info("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) #define otherfsmWarning(f, fmt, ...) \ - f->get_log()->warning("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) -#define otherfsmError(f, fmt, ...) f->get_log()->error("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) + f->get_logger().warning("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) +#define otherfsmError(f, fmt, ...) f->get_logger().error("FSM \"%s\" - " fmt, get_type_name(*f).c_str(), ##__VA_ARGS__) #define fsmDebug(fmt, ...) otherfsmDebug(this, fmt, ##__VA_ARGS__) #define fsmInfo(fmt, ...) otherfsmInfo(this, fmt, ##__VA_ARGS__) @@ -168,7 +169,7 @@ static auto get_state_recursive(FSM* f) -> disable_if_fsm_state struct state_traits { - static_assert(FSM::template can_hold_state(), "FSM type does not hold provided State\n"); + static_assert(FSM::template can_hold_state(), "FSM type does not hold provided State"); using state_t = State; using is_subfsm = std::integral_constant::value>; @@ -234,7 +235,7 @@ struct apply_first_guard_pass > { // Log Transition if (std::is_same::value) { otherfsmInfo(static_cast(f), - "Event \"%s\" triggered state \"%s\" update\n", + "Event \"%s\" triggered state \"%s\" update", get_type_name().c_str(), get_type_name().c_str()); } else { @@ -259,7 +260,7 @@ struct apply_first_guard_pass > { { if (should_log_unhandled_event(&ev)) { otherfsmDebug(static_cast(f), - "unhandled event caught in state \"%s\": \"%s\"\n", + "unhandled event caught in state \"%s\": \"%s\"", get_type_name().c_str(), get_type_name().c_str()); } @@ -394,7 +395,7 @@ public: struct state_list : public std::tuple { using tuple_base_t = std::tuple; using init_state_t = typename std::decay(std::declval()))>::type; - static_assert(not type_list_contains(), "An FSM cannot contain itself as state\n"); + static_assert(not type_list_contains(), "An FSM cannot contain itself as state"); template state_list(base_fsm_t* f, Args&&... args) : tuple_base_t(std::forward(args)...) @@ -516,7 +517,7 @@ protected: public: static const bool is_nested = false; - explicit fsm_t(srslte::log_ref log_) : log_h(log_) {} + explicit fsm_t(srslog::basic_logger& logger) : logger(logger) {} // Push Events to FSM template @@ -536,9 +537,9 @@ public: return ret; } - void set_fsm_event_log_level(srslte::LOG_LEVEL_ENUM e) { fsm_event_log_level = e; } + void set_fsm_event_log_level(srslog::basic_levels lvl) { log_level = lvl; } - srslte::log_ref get_log() const { return log_h; } + srslog::basic_logger& get_logger() const { return logger; } bool is_trigger_locked() const { return trigger_locked; } @@ -546,18 +547,18 @@ public: template void log_fsm_activity(const char* format, Args&&... args) { - switch (fsm_event_log_level) { - case LOG_LEVEL_DEBUG: - log_h->debug(format, std::forward(args)...); + switch (log_level) { + case srslog::basic_levels::debug: + logger.debug(format, std::forward(args)...); break; - case LOG_LEVEL_INFO: - log_h->info(format, std::forward(args)...); + case srslog::basic_levels::info: + logger.info(format, std::forward(args)...); break; - case LOG_LEVEL_WARNING: - log_h->warning(format, std::forward(args)...); + case srslog::basic_levels::warning: + logger.warning(format, std::forward(args)...); break; - case LOG_LEVEL_ERROR: - log_h->error(format, std::forward(args)...); + case srslog::basic_levels::error: + logger.error(format, std::forward(args)...); break; default: break; @@ -579,9 +580,9 @@ protected: pending_events.emplace_back(std::bind([this](Ev& e) { process_event(std::move(e)); }, std::move(e))); } - srslte::log_ref log_h; - srslte::LOG_LEVEL_ENUM fsm_event_log_level = LOG_LEVEL_INFO; - bool trigger_locked = false; + srslog::basic_logger& logger; + srslog::basic_levels log_level = srslog::basic_levels::info; + bool trigger_locked = false; std::deque > pending_events; }; @@ -602,7 +603,7 @@ public: parent_t* parent_fsm() { return fsm_ptr; } - srslte::log_ref get_log() const { return parent_fsm()->get_log(); } + srslog::basic_logger& get_logger() const { return parent_fsm()->get_logger(); } // Push Events to root FSM template @@ -643,7 +644,7 @@ class proc_fsm_t : public fsm_t using fsm_t::derived; protected: - using fsm_t::log_h; + using fsm_t::logger; public: using base_t = proc_fsm_t; @@ -659,14 +660,14 @@ public: void enter(Derived* f) { if (f->launch_counter > 0) { - f->log_h->warning( - "FSM \"%s\": No result was set for run no. %d\n", get_type_name().c_str(), f->launch_counter); + f->logger.warning( + "FSM \"%s\": No result was set for run no. %d", get_type_name().c_str(), f->launch_counter); } } void enter(Derived* f, const complete_ev& ev) { - f->log_h->info("FSM \"%s\": Finished run no. %d\n", get_type_name().c_str(), f->launch_counter); + f->logger.info("FSM \"%s\": Finished run no. %d", get_type_name().c_str(), f->launch_counter); f->last_result = ev.result; for (auto& func : f->listening_fsms) { func(ev); @@ -677,11 +678,11 @@ public: void exit(Derived* f) { f->launch_counter++; - f->log_h->info("FSM \"%s\": Starting run no. %d\n", get_type_name().c_str(), f->launch_counter); + f->logger.info("FSM \"%s\": Starting run no. %d", get_type_name().c_str(), f->launch_counter); } }; - explicit proc_fsm_t(srslte::log_ref log_) : fsm_t(log_) {} + explicit proc_fsm_t(srslog::basic_logger& logger) : fsm_t(logger) {} bool is_running() const { return not base_t::template is_in_state(); } @@ -720,7 +721,7 @@ public: void enter(FSM* f, const Ev& ev) { if (proc_ptr->is_running()) { - f->get_log()->error("Unable to launch proc1\n"); + f->get_logger().error("Unable to launch proc1"); f->trigger(typename ProcFSM::complete_ev{false}); } proc_ptr->trigger(srslte::proc_launch_ev{ev}); diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index d5299f10f..652b59aa4 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_INTERFACES_COMMON_H #define SRSLTE_INTERFACES_COMMON_H +#include "srslte/common/byte_buffer.h" #include "srslte/common/security.h" #include "srslte/phy/common/phy_common.h" #include diff --git a/lib/include/srslte/common/mac_nr_pcap.h b/lib/include/srslte/common/mac_nr_pcap.h deleted file mode 100644 index 8a5440ac4..000000000 --- a/lib/include/srslte/common/mac_nr_pcap.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#ifndef SRSLTE_MAC_NR_PCAP_H -#define SRSLTE_MAC_NR_PCAP_H - -#include - -namespace srslte { - -class mac_nr_pcap -{ -public: - mac_nr_pcap(); - ~mac_nr_pcap(); - void enable(const bool& enable_); - void open(const std::string& filename, const uint16_t& ue_id = 0); - void close(); - - void set_ue_id(const uint16_t& ue_id); - - void write_dl_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint8_t harqid, uint32_t tti); - void write_ul_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); - void write_dl_ra_rnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); - void write_dl_bch(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); - void write_dl_pch(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); - void write_dl_si_rnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); - -private: - bool enable_write = false; - std::string filename; - FILE* pcap_file = nullptr; - uint32_t ue_id = 0; - void pack_and_write(uint8_t* pdu, - uint32_t pdu_len_bytes, - uint32_t tti, - uint16_t crnti_, - uint8_t harqid, - uint8_t direction, - uint8_t rnti_type); -}; - -} // namespace srslte - -#endif // SRSLTE_MAC_NR_PCAP_H diff --git a/lib/include/srslte/common/mac_pcap.h b/lib/include/srslte/common/mac_pcap.h index 5a66a368c..2af747467 100644 --- a/lib/include/srslte/common/mac_pcap.h +++ b/lib/include/srslte/common/mac_pcap.h @@ -25,24 +25,26 @@ #include "srslte/common/block_queue.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" -#include "srslte/common/logmap.h" #include "srslte/common/pcap.h" #include "srslte/common/threads.h" +#include "srslte/srslog/srslog.h" #include #include #include + namespace srslte { class mac_pcap : srslte::thread { public: - mac_pcap(); + mac_pcap(srslte_rat_t rat); ~mac_pcap(); - void enable(bool en); - uint32_t open(const char* filename, uint32_t ue_id = 0); + void enable(bool enable); + uint32_t open(std::string filename, uint32_t ue_id = 0); uint32_t close(); void set_ue_id(uint16_t ue_id); + // EUTRA void write_ul_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint32_t reTX, uint32_t tti, uint8_t cc_idx); void write_dl_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, bool crc_ok, uint32_t tti, uint8_t cc_idx); @@ -59,25 +61,44 @@ public: // Sidelink void write_sl_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint32_t reTX, uint32_t tti, uint8_t cc_idx); + // NR + void write_dl_crnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint8_t harqid, uint32_t tti); + void write_ul_crnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); + void write_dl_ra_rnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); + void write_dl_bch_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); + void write_dl_pch_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); + void write_dl_si_rnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti); + private: - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref log; - bool running = false; - FILE* pcap_file = nullptr; - uint32_t ue_id = 0; - void pack_and_queue(uint8_t* pdu, - uint32_t pdu_len_bytes, - uint32_t reTX, - bool crc_ok, - uint8_t cc_idx, - uint32_t tti, - uint16_t crnti_, - uint8_t direction, - uint8_t rnti_type); + srslog::basic_logger& logger; + bool running = false; + srslte_rat_t rat = srslte_rat_t::nulltype; + uint32_t dlt = 0; // The DLT used for the PCAP file + std::string filename; + FILE* pcap_file = nullptr; + uint32_t ue_id = 0; + void pack_and_queue(uint8_t* payload, + uint32_t payload_len, + uint32_t reTX, + bool crc_ok, + uint8_t cc_idx, + uint32_t tti, + uint16_t crnti_, + uint8_t direction, + uint8_t rnti_type); + void pack_and_queue_nr(uint8_t* payload, + uint32_t payload_len, + uint32_t tti, + uint16_t crnti, + uint8_t harqid, + uint8_t direction, + uint8_t rnti_type); typedef struct { - MAC_Context_Info_t context; - unique_byte_buffer_t pdu; + // Different PCAP context for both RATs + MAC_Context_Info_t context; + mac_nr_context_info_t context_nr; + unique_byte_buffer_t pdu; } pcap_pdu_t; block_queue queue; std::mutex mutex; diff --git a/lib/include/srslte/common/network_utils.h b/lib/include/srslte/common/network_utils.h index 38a98cdeb..7ac6331bc 100644 --- a/lib/include/srslte/common/network_utils.h +++ b/lib/include/srslte/common/network_utils.h @@ -23,7 +23,6 @@ #define SRSLTE_RX_SOCKET_HANDLER_H #include "srslte/common/buffer_pool.h" -#include "srslte/common/logmap.h" #include "srslte/common/threads.h" #include @@ -134,7 +133,7 @@ public: using sctp_recv_callback_t = std::function; - rx_multisocket_handler(std::string name_, srslte::log_ref log_, int thread_prio = 65); + rx_multisocket_handler(std::string name_, srslog::basic_logger& logger, int thread_prio = 65); rx_multisocket_handler(rx_multisocket_handler&&) = delete; rx_multisocket_handler(const rx_multisocket_handler&) = delete; rx_multisocket_handler& operator=(const rx_multisocket_handler&) = delete; @@ -157,12 +156,12 @@ private: cmd_id_t cmd = cmd_id_t::EXIT; int new_fd = -1; }; - bool remove_socket_unprotected(int fd, fd_set* total_fd_set, int* max_fd); + std::map::iterator + remove_socket_unprotected(int fd, fd_set* total_fd_set, int* max_fd); // args - std::string name; - srslte::log_ref log_h; - srslte::byte_buffer_pool* pool = nullptr; + std::string name; + srslog::basic_logger& logger; // state std::mutex socket_mutex; diff --git a/lib/include/srslte/common/signal_handler.h b/lib/include/srslte/common/signal_handler.h index 155baaac4..d834b8386 100644 --- a/lib/include/srslte/common/signal_handler.h +++ b/lib/include/srslte/common/signal_handler.h @@ -28,6 +28,7 @@ #define SRSLTE_SIGNAL_HANDLER_H #include "srslte/srslog/sink.h" +#include "srslte/srslog/srslog.h" #include #include @@ -38,14 +39,15 @@ extern "C" { #define SRSLTE_TERM_TIMEOUT_S (5) // static vars required by signal handling -static srslog::sink* log_sink = nullptr; -static bool running = true; +static srslog::sink* log_sink = nullptr; +static bool running = true; static void srslte_signal_handler(int signal) { switch (signal) { case SIGALRM: fprintf(stderr, "Couldn't stop after %ds. Forcing exit.\n", SRSLTE_TERM_TIMEOUT_S); + srslog::flush(); //:TODO: refactor the sighandler, should not depend on log utilities if (log_sink) { log_sink->flush(); diff --git a/lib/include/srslte/common/test_common.h b/lib/include/srslte/common/test_common.h index 96d98244c..e2f5b8b44 100644 --- a/lib/include/srslte/common/test_common.h +++ b/lib/include/srslte/common/test_common.h @@ -29,6 +29,8 @@ #include "srslte/common/log.h" #include "srslte/common/log_filter.h" #include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" +#include #include namespace srslte { @@ -91,6 +93,65 @@ public: uint32_t error_counter = 0, warn_counter = 0; }; +/// This custom sink intercepts log messages to count error and warning log entries. +class log_sink_spy : public srslog::sink +{ +public: + explicit log_sink_spy(std::unique_ptr f) : + srslog::sink(std::move(f)), s(srslog::get_default_sink()) + { + error_counter.store(0); + warning_counter.store(0); + } + + /// Identifier of this custom sink. + static const char* name() { return "log_sink_spy"; } + + /// Returns the number of log entries tagged as errors. + unsigned get_error_counter() const + { + // Flush to make sure all entries have been processed by the backend. + srslog::flush(); + return error_counter.load(); + } + + /// Returns the number of log entries tagged as warnings. + unsigned get_warning_counter() const + { + // Flush to make sure all entries have been processed by the backend. + srslog::flush(); + return warning_counter.load(); + } + + /// Resets the counters back to 0. + void reset_counters() + { + // Flush to make sure all entries have been processed by the backend. + srslog::flush(); + error_counter.store(0); + warning_counter.store(0); + } + + srslog::detail::error_string write(srslog::detail::memory_buffer buffer) override + { + std::string entry(buffer.data(), buffer.size()); + if (entry.find("[E]") != std::string::npos) { + error_counter.fetch_add(1); + } else if (entry.find("[W]") != std::string::npos) { + warning_counter.fetch_add(1); + } + + return s.write(buffer); + } + + srslog::detail::error_string flush() override { return s.flush(); } + +private: + srslog::sink& s; + std::atomic error_counter; + std::atomic warning_counter; +}; + // specialization of test_log_filter to store last logged message class nullsink_log : public test_log_filter { @@ -200,7 +261,7 @@ private: } \ } while (0) -#define TESTASSERT(cond) CONDERROR((not(cond)), "[%s][Line %d] Fail at \"%s\"\n", __FUNCTION__, __LINE__, (#cond)) +#define TESTASSERT(cond) CONDERROR((not(cond)), "[%s][Line %d] Fail at \"%s\"", __FUNCTION__, __LINE__, (#cond)) #else // if C diff --git a/lib/include/srslte/common/time_prof.h b/lib/include/srslte/common/time_prof.h index b1287ce16..506ea5ca8 100644 --- a/lib/include/srslte/common/time_prof.h +++ b/lib/include/srslte/common/time_prof.h @@ -22,8 +22,9 @@ #ifndef SRSLTE_TIME_PROF_H #define SRSLTE_TIME_PROF_H -#include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include +#include #ifdef ENABLE_TIMEPROF #define TPROF_ENABLE_DEFAULT true @@ -57,8 +58,7 @@ class tprof public: template explicit tprof(Args&&... args) : prof(std::forward(args)...) - { - } + {} void start() { meas.start(); } @@ -80,8 +80,7 @@ class tprof public: template explicit tprof(Args&&... args) - { - } + {} void start() {} @@ -115,8 +114,7 @@ struct mutexed_tprof { template explicit mutexed_tprof(Args&&... args) : prof(std::forward(args)...) - { - } + {} measure start() { return measure{this}; } Prof prof; @@ -135,8 +133,7 @@ struct mutexed_tprof { template explicit mutexed_tprof(Args&&... args) - { - } + {} measure start() { return measure{}; } }; @@ -144,11 +141,11 @@ struct avg_time_stats { avg_time_stats(const char* name_, const char* logname, size_t print_period_); void operator()(std::chrono::nanoseconds duration); - srslte::log_ref log_ptr; - std::string name; - double avg_val = 1; - long count = 0, max_val = 0, min_val = std::numeric_limits::max(); - long print_period = 0; + srslog::basic_logger& logger; + std::string name; + double avg_val = 1; + long count = 0, max_val = 0, min_val = std::numeric_limits::max(); + long print_period = 0; }; template @@ -158,7 +155,7 @@ public: sliding_window_stats(const char* name_, const char* logname, size_t print_period_ = 10); void operator()(std::chrono::nanoseconds duration); - srslte::log_ref log_ptr; + srslog::basic_logger& logger; std::string name; std::vector sliding_window; size_t window_idx = 0; diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index 0e8d2f098..9dd7b67ea 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -73,11 +73,11 @@ class timer_handler bool set(uint32_t duration_) { if (duration_ > MAX_TIMER_DURATION) { - ERROR("Error: timer durations above %u are not supported\n", MAX_TIMER_DURATION); + ERROR("Error: timer durations above %u are not supported", MAX_TIMER_DURATION); return false; } if (not active) { - ERROR("Error: setting inactive timer id=%d\n", id()); + ERROR("Error: setting inactive timer id=%d", id()); return false; } duration = duration_; @@ -101,7 +101,7 @@ class timer_handler { std::unique_lock lock(parent->mutex); if (not active) { - ERROR("Error: calling run() for inactive timer id=%d\n", id()); + ERROR("Error: calling run() for inactive timer id=%d", id()); return; } timeout = parent->cur_time + duration; diff --git a/lib/include/srslte/common/tti_point.h b/lib/include/srslte/common/tti_point.h index 2b7f287d6..4f8b75289 100644 --- a/lib/include/srslte/common/tti_point.h +++ b/lib/include/srslte/common/tti_point.h @@ -22,8 +22,9 @@ #ifndef SRSLTE_TTI_POINT_H #define SRSLTE_TTI_POINT_H -#include "logmap.h" #include "srslte/adt/interval.h" +#include "srslte/common/common.h" +#include "srslte/srslog/srslog.h" #include #include @@ -39,7 +40,7 @@ struct tti_point { if (diff < 10240) { tti_val = 10240 - diff - 1; } else { - srslte::logmap::get("COMMON")->error("Invalid TTI point assigned\n"); + srslog::fetch_basic_logger("COMMON").error("Invalid TTI point assigned"); } } } diff --git a/lib/include/srslte/interfaces/enb_gtpu_interfaces.h b/lib/include/srslte/interfaces/enb_gtpu_interfaces.h new file mode 100644 index 000000000..9f90b9f4d --- /dev/null +++ b/lib/include/srslte/interfaces/enb_gtpu_interfaces.h @@ -0,0 +1,46 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_ENB_GTPU_INTERFACES_H +#define SRSLTE_ENB_GTPU_INTERFACES_H + +namespace srsenb { + +// GTPU interface for PDCP +class gtpu_interface_pdcp +{ +public: + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; +}; + +// GTPU interface for RRC +class gtpu_interface_rrc +{ +public: + struct bearer_props { + bool forward_from_teidin_present = false; + bool flush_before_teidin_present = false; + uint32_t forward_from_teidin = 0; + uint32_t flush_before_teidin = 0; + }; + + virtual uint32_t + add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props = nullptr) = 0; + virtual void set_tunnel_status(uint32_t teidin, bool dl_active) = 0; + virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) = 0; + virtual void rem_user(uint16_t rnti) = 0; +}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_GTPU_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 52518d98e..ca54baa30 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -19,567 +19,16 @@ * */ -#include "srslte/srslte.h" - -#include "pdcp_interface_types.h" -#include "rlc_interface_types.h" -#include "rrc_interface_types.h" -#include "srslte/asn1/rrc_utils.h" -#include "srslte/asn1/s1ap_utils.h" #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" -#include "srslte/common/security.h" -#include "srslte/interfaces/sched_interface.h" -#include +#include "srslte/srslte.h" #ifndef SRSLTE_ENB_INTERFACES_H #define SRSLTE_ENB_INTERFACES_H namespace srsenb { -/* Interface PHY -> MAC */ -class mac_interface_phy_lte -{ -public: - const static int MAX_GRANTS = 64; - - /** - * DL grant structure per UE - */ - struct dl_sched_grant_t { - srslte_dci_dl_t dci = {}; - uint8_t* data[SRSLTE_MAX_TB] = {}; - srslte_softbuffer_tx_t* softbuffer_tx[SRSLTE_MAX_TB] = {}; - }; - - /** - * DL Scheduling result per cell/carrier - */ - typedef struct { - dl_sched_grant_t pdsch[MAX_GRANTS]; //< DL Grants - uint32_t nof_grants; //< Number of DL grants - uint32_t cfi; //< Current CFI of the cell, it can vary across cells - } dl_sched_t; - - /** - * List of DL scheduling results, one entry per cell/carrier - */ - typedef std::vector dl_sched_list_t; - - typedef struct { - uint16_t rnti; - bool ack; - } ul_sched_ack_t; - - /** - * UL grant information per UE - */ - typedef struct { - srslte_dci_ul_t dci; - uint32_t current_tx_nb; - uint8_t* data; - bool needs_pdcch; - srslte_softbuffer_rx_t* softbuffer_rx; - } ul_sched_grant_t; - - /** - * UL Scheduling result per cell/carrier - */ - typedef struct { - ul_sched_grant_t pusch[MAX_GRANTS]; - ul_sched_ack_t phich[MAX_GRANTS]; - uint32_t nof_grants; - uint32_t nof_phich; - } ul_sched_t; - - /** - * List of UL scheduling results, one entry per cell/carrier - */ - typedef std::vector ul_sched_list_t; - - virtual int sr_detected(uint32_t tti, uint16_t rnti) = 0; - virtual void rach_detected(uint32_t tti, uint32_t primary_cc_idx, uint32_t preamble_idx, uint32_t time_adv) = 0; - - /** - * PHY callback for giving MAC the Rank Indicator information of a given RNTI for an eNb cell/carrier. - * - * @param tti the given TTI - * @param rnti the UE identifier in the eNb - * @param cc_idx The eNb Cell/Carrier where the measurement corresponds - * @param ri_value the actual Rank Indicator value, 0 for 1 layer, 1 for two layers and so on. - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int ri_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t ri_value) = 0; - - /** - * PHY callback for giving MAC the Pre-coding Matrix Indicator information of a given RNTI for an eNb cell/carrier. - * - * @param tti the given TTI - * @param rnti the UE identifier in the eNb - * @param cc_idx The eNb Cell/Carrier where the measurement corresponds - * @param pmi_value the actual PMI value - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) = 0; - - /** - * PHY callback for for giving MAC the Channel Quality information of a given RNTI, TTI and eNb cell/carrier - * @param tti the given TTI - * @param rnti the UE identifier in the eNb - * @param cc_idx The eNb Cell/Carrier where the measurement corresponds - * @param cqi_value the corresponding Channel Quality Information - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) = 0; - - typedef enum { PUSCH = 0, PUCCH, SRS } ul_channel_t; - - /** - * PHY callback for giving MAC the SNR in dB of an UL transmission for a given RNTI at a given carrier - * - * @param tti The measurement was made - * @param rnti The UE identifier in the eNb - * @param cc_idx The eNb Cell/Carrier where the UL transmission was received - * @param snr_db The actual SNR of the received signal - * @param ch Indicates uplink channel (PUSCH, PUCCH or SRS) - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr_db, ul_channel_t ch) = 0; - - /** - * PHY callback for giving MAC the Time Aligment information in microseconds of a given RNTI during a TTI processing - * - * @param tti The measurement was made - * @param rnti The UE identifier in the eNb - * @param ta_us The actual time alignment in microseconds - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int ta_info(uint32_t tti, uint16_t rnti, float ta_us) = 0; - - /** - * PHY callback for giving MAC the HARQ DL ACK/NACK feedback information for a given RNTI, TTI, eNb cell/carrier and - * Transport block. - * - * @param tti the given TTI - * @param rnti the UE identifier in the eNb - * @param cc_idx the eNb Cell/Carrier identifier - * @param tb_idx the transport block index - * @param ack true for ACK, false for NACK, do not call for DTX - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) = 0; - - /** - * Informs MAC about a received PUSCH transmission for given RNTI, TTI and eNb Cell/carrier. - * - * This function does not deallocate the uplink buffer. The function push_pdu() must be called after this - * to inform the MAC that the uplink buffer can be discarded or pushed to the stack - * - * @param tti the given TTI - * @param rnti the UE identifier in the eNb - * @param cc_idx the eNb Cell/Carrier identifier - * @param nof_bytes the number of grants carrierd by the PUSCH message - * @param crc_res the CRC check, set to true if the message was decoded succesfully - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) = 0; - - /** - * Pushes an uplink PDU through the stack if crc_res==true or discards it if crc_res==false - * - * @param tti the given TTI - * @param rnti the UE identifier in the eNb - * @param enb_cc_idx the eNb Cell/Carrier identifier - * @param nof_bytes the number of grants carrierd by the PUSCH message - * @param crc_res the CRC check, set to true if the message was decoded succesfully - * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs - */ - virtual int push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) = 0; - - virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0; - virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0; - virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0; - virtual void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0; -}; - -/* Interface MAC -> PHY */ -class phy_interface_mac_lte -{ -public: - /** - * Removes an RNTI context from all the physical layer components, including secondary cells - * @param rnti identifier of the user - */ - virtual void rem_rnti(uint16_t rnti) = 0; - - /** - * Pregenerates the scrambling sequences for a given RNTI. - * WARNING: This function make take several ms to complete. - * - * @param rnti identifier of the user - */ - virtual int pregen_sequences(uint16_t rnti) = 0; - - /** - * - * @param stop - */ - virtual void set_mch_period_stop(uint32_t stop) = 0; - - /** - * Activates and/or deactivates Secondary Cells in the PHY for a given RNTI. Requires the RNTI of the given UE and a - * vector with the activation/deactivation values. Use true for activation and false for deactivation. The index 0 is - * reserved for PCell and will not be used. - * - * @param rnti identifier of the user - * @param activation vector with the activate/deactivate. - */ - virtual void set_activation_deactivation_scell(uint16_t rnti, - const std::array& activation) = 0; -}; - -/* Interface RRC -> PHY */ -class phy_interface_rrc_lte -{ -public: - srslte::phy_cfg_mbsfn_t mbsfn_cfg; - - virtual void configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, const srslte::mcch_msg_t& mcch) = 0; - - struct phy_rrc_cfg_t { - bool configured = false; ///< Indicates whether PHY shall consider configuring this cell/carrier - uint32_t enb_cc_idx = 0; ///< eNb Cell index - srslte::phy_cfg_t phy_cfg = {}; ///< Dedicated physical layer configuration - }; - - typedef std::vector phy_rrc_cfg_list_t; - - /** - * Sets the physical layer dedicated configuration for a given RNTI. The dedicated configuration list shall provide - * all the required information configuration for the following cases: - * - Add an RNTI straight from RRC - * - Moving primary to another serving cell - * - Add/Remove secondary serving cells - * - * Remind this call will partially reconfigure the primary serving cell, `complete_config``shall be called - * in order to complete the configuration. - * - * @param rnti the given RNTI - * @param phy_cfg_list Physical layer configuration for the indicated eNb cell - */ - virtual void set_config(uint16_t rnti, const phy_rrc_cfg_list_t& phy_cfg_list) = 0; - - /** - * Instructs the physical layer the configuration has been complete from upper layers for a given RNTI - * - * @param rnti the given UE identifier (RNTI) - */ - virtual void complete_config(uint16_t rnti) = 0; -}; - -class mac_interface_rrc -{ -public: - /* Provides cell configuration including SIB periodicity, etc. */ - virtual int cell_cfg(const std::vector& cell_cfg) = 0; - virtual void reset() = 0; - - /* Manages UE configuration context */ - virtual int ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg) = 0; - virtual int ue_rem(uint16_t rnti) = 0; - - /** - * Called after Msg3 reception to set the UE C-RNTI, resolve contention, and alter the UE's configuration in the - * scheduler and phy. - * - * @param temp_crnti temporary C-RNTI of the UE - * @param crnti chosen C-RNTI for the UE - * @param cfg new UE scheduler configuration - */ - virtual int ue_set_crnti(uint16_t temp_crnti, uint16_t crnti, sched_interface::ue_cfg_t* cfg) = 0; - - /* Manages UE bearers and associated configuration */ - virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg) = 0; - virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0; - virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0; - virtual void write_mcch(const srslte::sib2_mbms_t* sib2_, - const srslte::sib13_t* sib13_, - const srslte::mcch_msg_t* mcch_, - const uint8_t* mcch_payload, - const uint8_t mcch_payload_length) = 0; - - /** - * Allocate a C-RNTI for a new user, without adding it to the phy layer and scheduler yet - * @return value of the allocated C-RNTI - */ - virtual uint16_t reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) = 0; -}; - -class mac_interface_rlc -{ -public: - virtual int rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0; -}; - -// RLC interface for MAC -class rlc_interface_mac -{ -public: - /* MAC calls RLC to get RLC segment of nof_bytes length. - * Segmentation happens in this function. RLC PDU is stored in payload. */ - virtual int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) = 0; - - virtual void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) = 0; - - /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. - * PDU gets placed into the buffer and higher layer thread gets notified. */ - virtual void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) = 0; -}; - -// RLC interface for PDCP -class rlc_interface_pdcp -{ -public: - /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls - * RLC PDUs according to TB size. */ - virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual void discard_sdu(uint16_t rnti, uint32_t lcid, uint32_t sn) = 0; - virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0; - virtual bool sdu_queue_is_full(uint16_t rnti, uint32_t lcid) = 0; -}; - -// RLC interface for RRC -class rlc_interface_rrc -{ -public: - virtual void clear_buffer(uint16_t rnti) = 0; - virtual void add_user(uint16_t rnti) = 0; - virtual void rem_user(uint16_t rnti) = 0; - virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg) = 0; - virtual void add_bearer_mrb(uint16_t rnti, uint32_t lcid) = 0; - virtual void del_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual bool resume_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual void reestablish(uint16_t rnti) = 0; -}; - -// PDCP interface for GTPU -class pdcp_interface_gtpu -{ -public: - virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; -}; - -// PDCP interface for RRC -class pdcp_interface_rrc -{ -public: - virtual void reset(uint16_t rnti) = 0; - virtual void add_user(uint16_t rnti) = 0; - virtual void rem_user(uint16_t rnti) = 0; - virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::pdcp_config_t cnfg) = 0; - virtual void del_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual void config_security(uint16_t rnti, uint32_t lcid, srslte::as_security_config_t sec_cfg) = 0; - virtual void enable_integrity(uint16_t rnti, uint32_t lcid) = 0; - virtual void enable_encryption(uint16_t rnti, uint32_t lcid) = 0; - virtual bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) = 0; - virtual bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) = 0; - virtual void reestablish(uint16_t rnti) = 0; -}; - -// PDCP interface for RLC -class pdcp_interface_rlc -{ -public: - /* RLC calls PDCP to push a PDCP PDU. */ - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; -}; - -// RRC interface for RLC -class rrc_interface_rlc -{ -public: - virtual void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) = 0; - virtual void max_retx_attempted(uint16_t rnti) = 0; - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; -}; - -// RRC interface for MAC -class rrc_interface_mac -{ -public: - /* Radio Link failure */ - virtual int add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) = 0; - virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0; - virtual void set_activity_user(uint16_t rnti) = 0; - virtual bool is_paging_opportunity(uint32_t tti, uint32_t* payload_len) = 0; - - ///< Provide packed SIB to MAC (buffer is managed by RRC) - virtual uint8_t* read_pdu_bcch_dlsch(const uint8_t enb_cc_idx, const uint32_t sib_index) = 0; -}; - -// RRC interface for PDCP -class rrc_interface_pdcp -{ -public: - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; -}; - -// RRC interface for S1AP -class rrc_interface_s1ap -{ -public: - virtual void write_dl_info(uint16_t rnti, srslte::unique_byte_buffer_t sdu) = 0; - virtual void release_complete(uint16_t rnti) = 0; - virtual bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) = 0; - virtual bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) = 0; - virtual bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) = 0; - virtual void modify_erabs(uint16_t rnti, - const asn1::s1ap::erab_modify_request_s& msg, - std::vector* erabs_modified, - std::vector* erabs_failed_to_modify) = 0; - virtual bool release_erabs(uint32_t rnti) = 0; - virtual void release_erabs(uint32_t rnti, - const asn1::s1ap::erab_release_cmd_s& msg, - std::vector* erabs_released, - std::vector* erabs_failed_to_release) = 0; - virtual void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) = 0; - - /** - * Reports the reception of S1 HandoverCommand / HandoverPreparationFailure or abnormal conditions during - * S1 Handover preparation back to RRC. - * - * @param rnti user - * @param is_success true if ho cmd was received - * @param container TargeteNB RRCConnectionReconfiguration message with MobilityControlInfo - */ - virtual void ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique_byte_buffer_t container) = 0; - virtual uint16_t - start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg, - const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container) = 0; - virtual void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) = 0; -}; - -// GTPU interface for PDCP -class gtpu_interface_pdcp -{ -public: - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; -}; - -// GTPU interface for RRC -class gtpu_interface_rrc -{ -public: - virtual uint32_t add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) = 0; - virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0; - virtual void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) = 0; - virtual void rem_user(uint16_t rnti) = 0; -}; - -// S1AP interface for RRC -class s1ap_interface_rrc -{ -public: - struct bearer_status_info { - uint8_t erab_id; - uint16_t pdcp_dl_sn, pdcp_ul_sn; - uint16_t dl_hfn, ul_hfn; - }; - - virtual void - initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) = 0; - virtual void initial_ue(uint16_t rnti, - asn1::s1ap::rrc_establishment_cause_e cause, - srslte::unique_byte_buffer_t pdu, - uint32_t m_tmsi, - uint8_t mmec) = 0; - - virtual void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) = 0; - virtual bool user_exists(uint16_t rnti) = 0; - virtual void user_mod(uint16_t old_rnti, uint16_t new_rnti) = 0; - virtual bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) = 0; - virtual void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) = 0; - virtual void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) = 0; - virtual bool is_mme_connected() = 0; - - /** - * Command the s1ap to transmit a HandoverRequired message to MME. - * This message initiates the S1 handover preparation procedure at the Source eNB - * - * @param rnti user to perform S1 handover - * @param target_eci eNB Id + Cell Id of the target eNB - * @param target_plmn PLMN of the target eNB - * @param rrc_container RRC container with SourceENBToTargetENBTransparentContainer message. - * @return true if successful - */ - virtual bool send_ho_required(uint16_t rnti, - uint32_t target_eci, - srslte::plmn_id_t target_plmn, - srslte::unique_byte_buffer_t rrc_container) = 0; - - /** - * Command the s1ap to transmit eNBStatusTransfer message to MME. This message passes the PDCP context of the UE - * performing S1 handover from source eNB to target eNB. - * - * @param rnti user to perform S1 handover - * @param bearer_status_list PDCP SN and HFN status of the bearers to be preserved at target eNB - * @return true if successful - */ - virtual bool send_enb_status_transfer_proc(uint16_t rnti, std::vector& bearer_status_list) = 0; - - /* Acknowledge Handover Request message back to MME. - * This message signals the completion of the HandoverPreparation from the TeNB point of view. */ - virtual bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, - uint16_t rnti, - srslte::unique_byte_buffer_t ho_cmd, - srslte::span > admitted_bearers) = 0; - - /** - * Notify MME that Handover is complete - */ - virtual void send_ho_notify(uint16_t rnti, uint64_t target_eci) = 0; - - /** - * Cancel on-going S1 Handover. MME should release UE context in target eNB - * SeNB --> MME - */ - virtual void send_ho_cancel(uint16_t rnti) = 0; -}; - -// Combined interface for PHY to access stack (MAC and RRC) -class stack_interface_phy_lte : public mac_interface_phy_lte -{ -public: - virtual void tti_clock() = 0; -}; - -// Combined interface for stack (MAC and RRC) to access PHY -class phy_interface_stack_lte : public phy_interface_mac_lte, public phy_interface_rrc_lte -{}; - -typedef struct { - uint32_t enb_id; // 20-bit id (lsb bits) - uint8_t cell_id; // 8-bit cell id - uint16_t tac; // 16-bit tac - uint16_t mcc; // BCD-coded with 0xF filler - uint16_t mnc; // BCD-coded with 0xF filler - std::string mme_addr; - std::string gtp_bind_addr; - std::string s1c_bind_addr; - std::string enb_name; -} s1ap_args_t; - -struct mac_args_t { - uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells - sched_interface::sched_args_t sched; - int nr_tb_size = -1; - uint32_t max_nof_ues; -}; - +class stack_interface_phy_lte; class stack_interface_s1ap_lte { public: diff --git a/lib/include/srslte/interfaces/enb_mac_interfaces.h b/lib/include/srslte/interfaces/enb_mac_interfaces.h new file mode 100644 index 000000000..0b4d6f3fd --- /dev/null +++ b/lib/include/srslte/interfaces/enb_mac_interfaces.h @@ -0,0 +1,247 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/interfaces/rrc_interface_types.h" +#include "srslte/interfaces/sched_interface.h" + +#ifndef SRSLTE_ENB_MAC_INTERFACES_H +#define SRSLTE_ENB_MAC_INTERFACES_H + +namespace srsenb { + +struct mac_args_t { + uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells + sched_interface::sched_args_t sched; + int nr_tb_size = -1; + uint32_t max_nof_ues; +}; + +/* Interface PHY -> MAC */ +class mac_interface_phy_lte +{ +public: + const static int MAX_GRANTS = 64; + + /** + * DL grant structure per UE + */ + struct dl_sched_grant_t { + srslte_dci_dl_t dci = {}; + uint8_t* data[SRSLTE_MAX_TB] = {}; + srslte_softbuffer_tx_t* softbuffer_tx[SRSLTE_MAX_TB] = {}; + }; + + /** + * DL Scheduling result per cell/carrier + */ + typedef struct { + dl_sched_grant_t pdsch[MAX_GRANTS]; //< DL Grants + uint32_t nof_grants; //< Number of DL grants + uint32_t cfi; //< Current CFI of the cell, it can vary across cells + } dl_sched_t; + + /** + * List of DL scheduling results, one entry per cell/carrier + */ + typedef std::vector dl_sched_list_t; + + typedef struct { + uint16_t rnti; + bool ack; + } ul_sched_ack_t; + + /** + * UL grant information per UE + */ + typedef struct { + srslte_dci_ul_t dci; + uint32_t pid; + uint32_t current_tx_nb; + uint8_t* data; + bool needs_pdcch; + srslte_softbuffer_rx_t* softbuffer_rx; + } ul_sched_grant_t; + + /** + * UL Scheduling result per cell/carrier + */ + typedef struct { + ul_sched_grant_t pusch[MAX_GRANTS]; + ul_sched_ack_t phich[MAX_GRANTS]; + uint32_t nof_grants; + uint32_t nof_phich; + } ul_sched_t; + + /** + * List of UL scheduling results, one entry per cell/carrier + */ + typedef std::vector ul_sched_list_t; + + virtual int sr_detected(uint32_t tti, uint16_t rnti) = 0; + virtual void rach_detected(uint32_t tti, uint32_t primary_cc_idx, uint32_t preamble_idx, uint32_t time_adv) = 0; + + /** + * PHY callback for giving MAC the Rank Indicator information of a given RNTI for an eNb cell/carrier. + * + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param cc_idx The eNb Cell/Carrier where the measurement corresponds + * @param ri_value the actual Rank Indicator value, 0 for 1 layer, 1 for two layers and so on. + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int ri_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t ri_value) = 0; + + /** + * PHY callback for giving MAC the Pre-coding Matrix Indicator information of a given RNTI for an eNb cell/carrier. + * + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param cc_idx The eNb Cell/Carrier where the measurement corresponds + * @param pmi_value the actual PMI value + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) = 0; + + /** + * PHY callback for for giving MAC the Channel Quality information of a given RNTI, TTI and eNb cell/carrier + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param cc_idx The eNb Cell/Carrier where the measurement corresponds + * @param cqi_value the corresponding Channel Quality Information + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) = 0; + + typedef enum { PUSCH = 0, PUCCH, SRS } ul_channel_t; + + /** + * PHY callback for giving MAC the SNR in dB of an UL transmission for a given RNTI at a given carrier + * + * @param tti The measurement was made + * @param rnti The UE identifier in the eNb + * @param cc_idx The eNb Cell/Carrier where the UL transmission was received + * @param snr_db The actual SNR of the received signal + * @param ch Indicates uplink channel (PUSCH, PUCCH or SRS) + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr_db, ul_channel_t ch) = 0; + + /** + * PHY callback for giving MAC the Time Aligment information in microseconds of a given RNTI during a TTI processing + * + * @param tti The measurement was made + * @param rnti The UE identifier in the eNb + * @param ta_us The actual time alignment in microseconds + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int ta_info(uint32_t tti, uint16_t rnti, float ta_us) = 0; + + /** + * PHY callback for giving MAC the HARQ DL ACK/NACK feedback information for a given RNTI, TTI, eNb cell/carrier and + * Transport block. + * + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param cc_idx the eNb Cell/Carrier identifier + * @param tb_idx the transport block index + * @param ack true for ACK, false for NACK, do not call for DTX + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) = 0; + + /** + * Informs MAC about a received PUSCH transmission for given RNTI, TTI and eNb Cell/carrier. + * + * This function does not deallocate the uplink buffer. The function push_pdu() must be called after this + * to inform the MAC that the uplink buffer can be discarded or pushed to the stack + * + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param cc_idx the eNb Cell/Carrier identifier + * @param nof_bytes the number of grants carrierd by the PUSCH message + * @param crc_res the CRC check, set to true if the message was decoded succesfully + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) = 0; + + /** + * Pushes an uplink PDU through the stack if crc_res==true or discards it if crc_res==false + * + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param enb_cc_idx the eNb Cell/Carrier identifier + * @param nof_bytes the number of grants carrierd by the PUSCH message + * @param crc_res the CRC check, set to true if the message was decoded succesfully + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) = 0; + + virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0; + virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0; + virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0; + virtual void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0; +}; + +class mac_interface_rlc +{ +public: + virtual int rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0; +}; + +class mac_interface_rrc +{ +public: + /* Provides cell configuration including SIB periodicity, etc. */ + virtual int cell_cfg(const std::vector& cell_cfg) = 0; + virtual void reset() = 0; + + /* Manages UE configuration context */ + virtual int ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg) = 0; + virtual int ue_rem(uint16_t rnti) = 0; + + /** + * Called after Msg3 reception to set the UE C-RNTI, resolve contention, and alter the UE's configuration in the + * scheduler and phy. + * + * @param temp_crnti temporary C-RNTI of the UE + * @param crnti chosen C-RNTI for the UE + * @param cfg new UE scheduler configuration + */ + virtual int ue_set_crnti(uint16_t temp_crnti, uint16_t crnti, sched_interface::ue_cfg_t* cfg) = 0; + + /* Manages UE bearers and associated configuration */ + virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg) = 0; + virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0; + virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0; + virtual void write_mcch(const srslte::sib2_mbms_t* sib2_, + const srslte::sib13_t* sib13_, + const srslte::mcch_msg_t* mcch_, + const uint8_t* mcch_payload, + const uint8_t mcch_payload_length) = 0; + + /** + * Allocate a C-RNTI for a new user, without adding it to the phy layer and scheduler yet + * @return value of the allocated C-RNTI + */ + virtual uint16_t reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) = 0; +}; + +// Combined interface for PHY to access stack (MAC and RRC) +class stack_interface_phy_lte : public mac_interface_phy_lte +{ +public: + virtual void tti_clock() = 0; +}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_MAC_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_metrics_interface.h b/lib/include/srslte/interfaces/enb_metrics_interface.h index b1f50f359..29e197954 100644 --- a/lib/include/srslte/interfaces/enb_metrics_interface.h +++ b/lib/include/srslte/interfaces/enb_metrics_interface.h @@ -31,6 +31,7 @@ #include "srsenb/hdr/stack/upper/s1ap_metrics.h" #include "srslte/common/metrics_hub.h" #include "srslte/radio/radio_metrics.h" +#include "srslte/upper/pdcp_metrics.h" #include "srslte/upper/rlc_metrics.h" #include "srsue/hdr/stack/upper/gw_metrics.h" @@ -40,10 +41,15 @@ struct rlc_metrics_t { std::vector ues; }; +struct pdcp_metrics_t { + std::vector ues; +}; + struct stack_metrics_t { mac_metrics_t mac; rrc_metrics_t rrc; rlc_metrics_t rlc; + pdcp_metrics_t pdcp; s1ap_metrics_t s1ap; }; diff --git a/lib/include/srslte/interfaces/enb_pdcp_interfaces.h b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h new file mode 100644 index 000000000..ba5ee32f3 --- /dev/null +++ b/lib/include/srslte/interfaces/enb_pdcp_interfaces.h @@ -0,0 +1,62 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/byte_buffer.h" +#include "srslte/interfaces/pdcp_interface_types.h" +#include + +#ifndef SRSLTE_ENB_PDCP_INTERFACES_H +#define SRSLTE_ENB_PDCP_INTERFACES_H + +namespace srsenb { + +// PDCP interface for GTPU +class pdcp_interface_gtpu +{ +public: + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn = -1) = 0; + virtual std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) = 0; +}; + +// PDCP interface for RRC +class pdcp_interface_rrc +{ +public: + virtual void reset(uint16_t rnti) = 0; + virtual void add_user(uint16_t rnti) = 0; + virtual void rem_user(uint16_t rnti) = 0; + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn = -1) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::pdcp_config_t cnfg) = 0; + virtual void del_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual void config_security(uint16_t rnti, uint32_t lcid, srslte::as_security_config_t sec_cfg) = 0; + virtual void enable_integrity(uint16_t rnti, uint32_t lcid) = 0; + virtual void enable_encryption(uint16_t rnti, uint32_t lcid) = 0; + virtual void send_status_report(uint16_t rnti) = 0; + virtual void send_status_report(uint16_t rnti, uint32_t lcid) = 0; + virtual bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) = 0; + virtual bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) = 0; + virtual void reestablish(uint16_t rnti) = 0; +}; + +// PDCP interface for RLC +class pdcp_interface_rlc +{ +public: + /* RLC calls PDCP to push a PDCP PDU. */ + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; + virtual void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) = 0; + virtual void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) = 0; +}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_PDCP_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_phy_interfaces.h b/lib/include/srslte/interfaces/enb_phy_interfaces.h new file mode 100644 index 000000000..65fdf9597 --- /dev/null +++ b/lib/include/srslte/interfaces/enb_phy_interfaces.h @@ -0,0 +1,102 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/interfaces/rrc_interface_types.h" +#include "srslte/phy/common/phy_common.h" + +#ifndef SRSLTE_ENB_PHY_INTERFACES_H +#define SRSLTE_ENB_PHY_INTERFACES_H + +namespace srsenb { + +/* Interface MAC -> PHY */ +class phy_interface_mac_lte +{ +public: + /** + * Removes an RNTI context from all the physical layer components, including secondary cells + * @param rnti identifier of the user + */ + virtual void rem_rnti(uint16_t rnti) = 0; + + /** + * Pregenerates the scrambling sequences for a given RNTI. + * WARNING: This function make take several ms to complete. + * + * @param rnti identifier of the user + */ + virtual int pregen_sequences(uint16_t rnti) = 0; + + /** + * + * @param stop + */ + virtual void set_mch_period_stop(uint32_t stop) = 0; + + /** + * Activates and/or deactivates Secondary Cells in the PHY for a given RNTI. Requires the RNTI of the given UE and a + * vector with the activation/deactivation values. Use true for activation and false for deactivation. The index 0 is + * reserved for PCell and will not be used. + * + * @param rnti identifier of the user + * @param activation vector with the activate/deactivate. + */ + virtual void set_activation_deactivation_scell(uint16_t rnti, + const std::array& activation) = 0; +}; + +/* Interface RRC -> PHY */ +class phy_interface_rrc_lte +{ +public: + srslte::phy_cfg_mbsfn_t mbsfn_cfg; + + virtual void configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, const srslte::mcch_msg_t& mcch) = 0; + + struct phy_rrc_cfg_t { + bool configured = false; ///< Indicates whether PHY shall consider configuring this cell/carrier + uint32_t enb_cc_idx = 0; ///< eNb Cell index + srslte::phy_cfg_t phy_cfg = {}; ///< Dedicated physical layer configuration + }; + + typedef std::vector phy_rrc_cfg_list_t; + + /** + * Sets the physical layer dedicated configuration for a given RNTI. The dedicated configuration list shall provide + * all the required information configuration for the following cases: + * - Add an RNTI straight from RRC + * - Moving primary to another serving cell + * - Add/Remove secondary serving cells + * + * Remind this call will partially reconfigure the primary serving cell, `complete_config``shall be called + * in order to complete the configuration. + * + * @param rnti the given RNTI + * @param phy_cfg_list Physical layer configuration for the indicated eNb cell + */ + virtual void set_config(uint16_t rnti, const phy_rrc_cfg_list_t& phy_cfg_list) = 0; + + /** + * Instructs the physical layer the configuration has been complete from upper layers for a given RNTI + * + * @param rnti the given UE identifier (RNTI) + */ + virtual void complete_config(uint16_t rnti) = 0; +}; + +// Combined interface for stack (MAC and RRC) to access PHY +class phy_interface_stack_lte : public phy_interface_mac_lte, public phy_interface_rrc_lte +{}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_PHY_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_rlc_interfaces.h b/lib/include/srslte/interfaces/enb_rlc_interfaces.h new file mode 100644 index 000000000..02b1057be --- /dev/null +++ b/lib/include/srslte/interfaces/enb_rlc_interfaces.h @@ -0,0 +1,67 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_ENB_RLC_INTERFACES_H +#define SRSLTE_ENB_RLC_INTERFACES_H + +#include "srslte/common/byte_buffer.h" +#include "srslte/interfaces/rlc_interface_types.h" + +namespace srsenb { + +// RLC interface for MAC +class rlc_interface_mac +{ +public: + /* MAC calls RLC to get RLC segment of nof_bytes length. + * Segmentation happens in this function. RLC PDU is stored in payload. */ + virtual int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) = 0; + + virtual void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) = 0; + + /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. + * PDU gets placed into the buffer and higher layer thread gets notified. */ + virtual void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) = 0; +}; + +// RLC interface for PDCP +class rlc_interface_pdcp +{ +public: + /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls + * RLC PDUs according to TB size. */ + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void discard_sdu(uint16_t rnti, uint32_t lcid, uint32_t sn) = 0; + virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0; + virtual bool sdu_queue_is_full(uint16_t rnti, uint32_t lcid) = 0; +}; + +// RLC interface for RRC +class rlc_interface_rrc +{ +public: + virtual void clear_buffer(uint16_t rnti) = 0; + virtual void add_user(uint16_t rnti) = 0; + virtual void rem_user(uint16_t rnti) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::rlc_config_t cnfg) = 0; + virtual void add_bearer_mrb(uint16_t rnti, uint32_t lcid) = 0; + virtual void del_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual bool resume_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual void reestablish(uint16_t rnti) = 0; +}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_RLC_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_rrc_interfaces.h b/lib/include/srslte/interfaces/enb_rrc_interfaces.h new file mode 100644 index 000000000..6028b4bc2 --- /dev/null +++ b/lib/include/srslte/interfaces/enb_rrc_interfaces.h @@ -0,0 +1,92 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/asn1/s1ap_utils.h" +#include "srslte/interfaces/enb_rrc_interface_types.h" +#include "srslte/interfaces/sched_interface.h" + +#ifndef SRSLTE_ENB_RRC_INTERFACES_H +#define SRSLTE_ENB_RRC_INTERFACES_H + +namespace srsenb { + +// RRC interface for S1AP +class rrc_interface_s1ap +{ +public: + virtual void write_dl_info(uint16_t rnti, srslte::unique_byte_buffer_t sdu) = 0; + virtual void release_complete(uint16_t rnti) = 0; + virtual bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) = 0; + virtual bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) = 0; + virtual bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) = 0; + virtual void modify_erabs(uint16_t rnti, + const asn1::s1ap::erab_modify_request_s& msg, + std::vector* erabs_modified, + std::vector* erabs_failed_to_modify) = 0; + virtual bool release_erabs(uint32_t rnti) = 0; + virtual void release_erabs(uint32_t rnti, + const asn1::s1ap::erab_release_cmd_s& msg, + std::vector* erabs_released, + std::vector* erabs_failed_to_release) = 0; + virtual void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) = 0; + + /** + * Reports the reception of S1 HandoverCommand / HandoverPreparationFailure or abnormal conditions during + * S1 Handover preparation back to RRC. + * + * @param rnti user + * @param is_success true if ho cmd was received + * @param container TargeteNB RRCConnectionReconfiguration message with MobilityControlInfo + */ + virtual void ho_preparation_complete(uint16_t rnti, + bool is_success, + const asn1::s1ap::ho_cmd_s& msg, + srslte::unique_byte_buffer_t container) = 0; + virtual uint16_t + start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg, + const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container) = 0; + virtual void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) = 0; +}; + +/// RRC interface for RLC +class rrc_interface_rlc +{ +public: + virtual void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) = 0; + virtual void max_retx_attempted(uint16_t rnti) = 0; + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; +}; + +/// RRC interface for MAC +class rrc_interface_mac +{ +public: + /* Radio Link failure */ + virtual int add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) = 0; + virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual void set_activity_user(uint16_t rnti) = 0; + virtual bool is_paging_opportunity(uint32_t tti, uint32_t* payload_len) = 0; + + ///< Provide packed SIB to MAC (buffer is managed by RRC) + virtual uint8_t* read_pdu_bcch_dlsch(const uint8_t enb_cc_idx, const uint32_t sib_index) = 0; +}; + +/// RRC interface for PDCP +class rrc_interface_pdcp +{ +public: + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; +}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_RRC_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_s1ap_interfaces.h b/lib/include/srslte/interfaces/enb_s1ap_interfaces.h new file mode 100644 index 000000000..90d7cdca4 --- /dev/null +++ b/lib/include/srslte/interfaces/enb_s1ap_interfaces.h @@ -0,0 +1,119 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/asn1/s1ap_utils.h" +#include "srslte/interfaces/rrc_interface_types.h" + +#ifndef SRSLTE_ENB_S1AP_INTERFACES_H +#define SRSLTE_ENB_S1AP_INTERFACES_H + +namespace srsenb { + +struct s1ap_args_t { + uint32_t enb_id; // 20-bit id (lsb bits) + uint8_t cell_id; // 8-bit cell id + uint16_t tac; // 16-bit tac + uint16_t mcc; // BCD-coded with 0xF filler + uint16_t mnc; // BCD-coded with 0xF filler + std::string mme_addr; + std::string gtp_bind_addr; + std::string s1c_bind_addr; + std::string enb_name; +}; + +// S1AP interface for RRC +class s1ap_interface_rrc +{ +public: + struct bearer_status_info { + uint8_t erab_id; + uint16_t pdcp_dl_sn, pdcp_ul_sn; + uint16_t dl_hfn, ul_hfn; + }; + + virtual void initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, + asn1::s1ap::rrc_establishment_cause_e cause, + srslte::unique_byte_buffer_t pdu) = 0; + virtual void initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, + asn1::s1ap::rrc_establishment_cause_e cause, + srslte::unique_byte_buffer_t pdu, + uint32_t m_tmsi, + uint8_t mmec) = 0; + + virtual void write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) = 0; + virtual bool user_exists(uint16_t rnti) = 0; + virtual void user_mod(uint16_t old_rnti, uint16_t new_rnti) = 0; + virtual bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) = 0; + virtual void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) = 0; + virtual void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) = 0; + virtual bool is_mme_connected() = 0; + + /** + * Command the s1ap to transmit a HandoverRequired message to MME. + * This message initiates the S1 handover preparation procedure at the Source eNB + * + * @param rnti user to perform S1 handover + * @param target_eci eNB Id + Cell Id of the target eNB + * @param target_plmn PLMN of the target eNB + * @param fwd_erabs E-RABs that are candidates to DL forwarding + * @param rrc_container RRC container with SourceENBToTargetENBTransparentContainer message. + * @return true if successful + */ + virtual bool send_ho_required(uint16_t rnti, + uint32_t target_eci, + srslte::plmn_id_t target_plmn, + srslte::span fwd_erabs, + srslte::unique_byte_buffer_t rrc_container) = 0; + + /** + * Command the s1ap to transmit eNBStatusTransfer message to MME. This message passes the PDCP context of the UE + * performing S1 handover from source eNB to target eNB. + * + * @param rnti user to perform S1 handover + * @param bearer_status_list PDCP SN and HFN status of the bearers to be preserved at target eNB + * @return true if successful + */ + virtual bool send_enb_status_transfer_proc(uint16_t rnti, std::vector& bearer_status_list) = 0; + + /* Acknowledge Handover Request message back to MME. + * This message signals the completion of the HandoverPreparation from the TeNB point of view. */ + virtual bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, + uint16_t rnti, + uint32_t enb_cc_idx, + srslte::unique_byte_buffer_t ho_cmd, + srslte::span admitted_bearers) = 0; + + /** + * Notify MME that Handover is complete + */ + virtual void send_ho_notify(uint16_t rnti, uint64_t target_eci) = 0; + + /** + * Cancel on-going S1 Handover. MME should release UE context in target eNB + * SeNB --> MME + */ + virtual void send_ho_cancel(uint16_t rnti) = 0; + + /** + * Called during release of a subset of eNB E-RABs. Send E-RAB RELEASE INDICATION to MME. + * SeNB --> MME + */ + virtual bool release_erabs(uint16_t rnti, const std::vector& erabs_successfully_released) = 0; + + virtual bool send_ue_cap_info_indication(uint16_t rnti, srslte::unique_byte_buffer_t ue_radio_cap) = 0; +}; + +} // namespace srsenb + +#endif // SRSLTE_ENB_S1AP_INTERFACES_H diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h index f3b9da8c6..f9d99e700 100644 --- a/lib/include/srslte/interfaces/epc_interfaces.h +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -116,15 +116,15 @@ public: virtual bool modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtpc_f_teid_ie dw_user_fteid, uint32_t up_ctrl_teid) = 0; virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4) = 0; virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4) = 0; - virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, - std::queue& pkt_queue) = 0; + virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, + std::queue& pkt_queue) = 0; }; class gtpc_interface_gtpu // GTP-U -> GTP-C { public: - virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::byte_buffer_t* msg) = 0; - virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) = 0; + virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::unique_byte_buffer_t msg) = 0; + virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) = 0; }; } // namespace srsepc diff --git a/lib/include/srslte/interfaces/gnb_interfaces.h b/lib/include/srslte/interfaces/gnb_interfaces.h index 76a94b41d..f682ccc09 100644 --- a/lib/include/srslte/interfaces/gnb_interfaces.h +++ b/lib/include/srslte/interfaces/gnb_interfaces.h @@ -91,8 +91,11 @@ class pdcp_interface_rlc_nr { public: /* RLC calls PDCP to push a PDCP PDU. */ - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& tx_count) = 0; + virtual void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& tx_count) = 0; }; + class pdcp_interface_rrc_nr { public: @@ -105,6 +108,7 @@ public: virtual void enable_integrity(uint16_t rnti, uint32_t lcid) = 0; virtual void enable_encryption(uint16_t rnti, uint32_t lcid) = 0; }; + class pdcp_interface_sdap_nr { public: diff --git a/lib/include/srslte/interfaces/mac_interface_types.h b/lib/include/srslte/interfaces/mac_interface_types.h index 409874a02..07af779db 100644 --- a/lib/include/srslte/interfaces/mac_interface_types.h +++ b/lib/include/srslte/interfaces/mac_interface_types.h @@ -125,6 +125,26 @@ struct rach_cfg_t { } }; +// 38.321 5.1.1 Not complete yet +struct rach_nr_cfg_t { + uint32_t prach_ConfigurationIndex; + int PreambleReceivedTargetPower; + uint32_t preambleTransMax; + uint32_t powerRampingStep; + uint32_t ra_responseWindow; + uint32_t ra_ContentionResolutionTimer; + + rach_nr_cfg_t() { reset(); } + void reset() + { + prach_ConfigurationIndex = 0; + PreambleReceivedTargetPower = 0; + powerRampingStep = 0; + preambleTransMax = 0; + ra_responseWindow = 0; + } +}; + struct mac_cfg_t { // Default constructor with default values as in 36.331 9.2.2 mac_cfg_t() { set_defaults(); } diff --git a/lib/include/srslte/interfaces/pdcp_interface_types.h b/lib/include/srslte/interfaces/pdcp_interface_types.h index b8e6909b0..31e034f11 100644 --- a/lib/include/srslte/interfaces/pdcp_interface_types.h +++ b/lib/include/srslte/interfaces/pdcp_interface_types.h @@ -39,6 +39,7 @@ namespace srslte { // LTE and NR common config const uint8_t PDCP_SN_LEN_5 = 5; const uint8_t PDCP_SN_LEN_7 = 7; +const uint8_t PDCP_SN_LEN_15 = 15; const uint8_t PDCP_SN_LEN_12 = 12; const uint8_t PDCP_SN_LEN_18 = 18; @@ -51,6 +52,18 @@ enum pdcp_dc_field_t { }; static const char* pdcp_dc_field_text[PDCP_DC_FIELD_N_ITEMS] = {"Control PDU", "Data PDU"}; +enum pdcp_pdu_type_t { + PDCP_PDU_TYPE_STATUS_REPORT = 0, + PDCP_PDU_TYPE_INTERSPERSED_ROHC_FEEDBACK_PACKET, + PDCP_PDU_TYPE_LWA_STATUS_REPORT, + PDCP_PDU_TYPE_LWA_END_MARKER_PACKET, + PDCP_PDU_TYPE_N_ITEMS, +}; +static const char* pdcp_pdu_type_text[PDCP_PDU_TYPE_N_ITEMS] = {"PDCP Report PDU", + "Interspersed ROCH Feedback Packet", + "LWA Status Report", + "LWA End-marker Packet"}; + // Taken from PDCP-Config (TS 38.331 version 15.2.1) enum class pdcp_t_reordering_t { ms0 = 0, @@ -120,14 +133,16 @@ public: security_direction_t rx_direction_, uint8_t sn_len_, pdcp_t_reordering_t t_reordering_, - pdcp_discard_timer_t discard_timer_) : + pdcp_discard_timer_t discard_timer_, + bool status_report_required_) : bearer_id(bearer_id_), rb_type(rb_type_), tx_direction(tx_direction_), rx_direction(rx_direction_), sn_len(sn_len_), t_reordering(t_reordering_), - discard_timer(discard_timer_) + discard_timer(discard_timer_), + status_report_required(status_report_required_) { hdr_len_bytes = ceilf((float)sn_len / 8); } @@ -142,6 +157,8 @@ public: pdcp_t_reordering_t t_reordering = pdcp_t_reordering_t::ms500; pdcp_discard_timer_t discard_timer = pdcp_discard_timer_t::infinity; + bool status_report_required = false; + // TODO: Support the following configurations // bool do_rohc; }; diff --git a/lib/include/srslte/interfaces/rrc_nr_interface_types.h b/lib/include/srslte/interfaces/rrc_nr_interface_types.h new file mode 100644 index 000000000..aeca76ead --- /dev/null +++ b/lib/include/srslte/interfaces/rrc_nr_interface_types.h @@ -0,0 +1,560 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_RRC_NR_INTERFACE_TYPES_H +#define SRSLTE_RRC_NR_INTERFACE_TYPES_H + +#include "srslte/config.h" +#include "srslte/srslte.h" +#include + +namespace srslte { + +/*************************** + * PHY Config + **************************/ + +struct phy_cfg_nr_t { + srslte_sch_hl_cfg_nr_t pdsch = {}; + srslte_sch_hl_cfg_nr_t pusch = {}; + srslte_pucch_nr_hl_cfg_t pucch = {}; + srslte_prach_cfg_t prach = {}; + srslte_ue_dl_nr_pdcch_cfg_t pdcch = {}; + srslte_ue_dl_nr_harq_ack_cfg_t harq_ack = {}; + + phy_cfg_nr_t() + { + // Default PDSCH configuration + pdsch.sch_cfg.mcs_table = srslte_mcs_table_256qam; + + // Default PRACH configuration + prach.is_nr = true; + prach.config_idx = 16; + prach.root_seq_idx = 1; + prach.freq_offset = 0; + prach.zero_corr_zone = 0; + prach.num_ra_preambles = 64; + prach.hs_flag = false; + + // physicalCellGroupConfig + // pdsch-HARQ-ACK-Codebook: dynamic (1) + harq_ack.pdsch_harq_ack_codebook = srslte_pdsch_harq_ack_codebook_dynamic; + + // commonControlResourceSet + // controlResourceSetId: 1 + // frequencyDomainResources: ff0000000000 + // duration: 1 + // cce-REG-MappingType: nonInterleaved (1) + // nonInterleaved: NULL + // precoderGranularity: sameAsREG-bundle (0) + pdcch.coreset[1].coreset_id = 1; + pdcch.coreset[1].precoder_granularity = srslte_coreset_precoder_granularity_reg_bundle; + pdcch.coreset[1].duration = 1; + pdcch.coreset[1].mapping_type = srslte_coreset_mapping_type_non_interleaved; + for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + pdcch.coreset[1].freq_resources[i] = (i < 8); + } + pdcch.coreset_present[1] = true; + + // SearchSpace + // searchSpaceId: 1 + // controlResourceSetId: 1 + // monitoringSlotPeriodicityAndOffset: sl1 (0) + // sl1: NULL + // monitoringSymbolsWithinSlot: 8000 [bit length 14, 2 LSB pad bits, 1000 0000 0000 00.. decimal value 8192] + // nrofCandidates + // aggregationLevel1: n0 (0) + // aggregationLevel2: n0 (0) + // aggregationLevel4: n1 (1) + // aggregationLevel8: n0 (0) + // aggregationLevel16: n0 (0) + // searchSpaceType: common (0) + // common + // dci-Format0-0-AndFormat1-0 + srslte_search_space_t search_space1 = {}; + search_space1.id = 1; + search_space1.coreset_id = 1; + search_space1.nof_candidates[0] = 0; + search_space1.nof_candidates[1] = 0; + search_space1.nof_candidates[2] = 1; + search_space1.nof_candidates[3] = 0; + search_space1.nof_candidates[4] = 0; + search_space1.type = srslte_search_space_type_common_3; + pdcch.search_space[1] = search_space1; + pdcch.search_space_present[1] = true; + + // ra-SearchSpace: 1 + pdcch.ra_rnti = 0x16; //< Supposed to be deduced from PRACH configuration + pdcch.ra_search_space = search_space1; + pdcch.ra_search_space.type = srslte_search_space_type_common_1; + pdcch.ra_search_space_present = true; + + // pdsch-ConfigCommon: setup (1) + // setup + // pdsch-TimeDomainAllocationList: 2 items + // Item 0 + // PDSCH-TimeDomainResourceAllocation + // mappingType: typeA (0) + // startSymbolAndLength: 40 + // Item 1 + // PDSCH-TimeDomainResourceAllocation + // mappingType: typeA (0) + // startSymbolAndLength: 57 + pdsch.common_time_ra[0].mapping_type = srslte_sch_mapping_type_A; + pdsch.common_time_ra[0].sliv = 40; + pdsch.common_time_ra[0].k = 0; + pdsch.common_time_ra[1].mapping_type = srslte_sch_mapping_type_A; + pdsch.common_time_ra[1].sliv = 57; + pdsch.common_time_ra[1].k = 0; + pdsch.nof_common_time_ra = 2; + + // pusch-ConfigCommon: setup (1) + // setup + // pusch-TimeDomainAllocationList: 2 items + // Item 0 + // PUSCH-TimeDomainResourceAllocation + // k2: 4 + // mappingType: typeA (0) + // startSymbolAndLength: 27 + // Item 1 + // PUSCH-TimeDomainResourceAllocation + // k2: 5 + // mappingType: typeA (0) + // startSymbolAndLength: 27 + // p0-NominalWithGrant: -90dBm + pusch.common_time_ra[0].mapping_type = srslte_sch_mapping_type_A; + pusch.common_time_ra[0].sliv = 27; + pusch.common_time_ra[0].k = 4; + pusch.common_time_ra[1].mapping_type = srslte_sch_mapping_type_A; + pusch.common_time_ra[1].sliv = 27; + pusch.common_time_ra[1].k = 5; + pusch.nof_common_time_ra = 2; + + // pusch-Config: setup (1) + // setup + // dmrs-UplinkForPUSCH-MappingTypeA: setup (1) + // setup + // dmrs-AdditionalPosition: pos1 (1) + // transformPrecodingDisabled + pusch.dmrs_typeA.additional_pos = srslte_dmrs_sch_add_pos_1; + pusch.dmrs_typeA.present = true; + // pusch-PowerControl + // msg3-Alpha: alpha1 (7) + // p0-NominalWithoutGrant: -90dBm + // p0-AlphaSets: 1 item + // Item 0 + // P0-PUSCH-AlphaSet + // p0-PUSCH-AlphaSetId: 0 + // p0: 0dB + // alpha: alpha1 (7) + // pathlossReferenceRSToAddModList: 1 item + // Item 0 + // PUSCH-PathlossReferenceRS + // pusch-PathlossReferenceRS-Id: 0 + // referenceSignal: ssb-Index (0) + // ssb-Index: 0 + // sri-PUSCH-MappingToAddModList: 1 item + // Item 0 + // SRI-PUSCH-PowerControl + // sri-PUSCH-PowerControlId: 0 + // sri-PUSCH-PathlossReferenceRS-Id: 0 + // sri-P0-PUSCH-AlphaSetId: 0 + // sri-PUSCH-ClosedLoopIndex: i0 (0) + // resourceAllocation: resourceAllocationType1 (1) + // uci-OnPUSCH: setup (1) + // setup + // betaOffsets: semiStatic (1) + // semiStatic + // betaOffsetACK-Index1: 9 + // betaOffsetACK-Index2: 9 + // betaOffsetACK-Index3: 9 + // betaOffsetCSI-Part1-Index1: 6 + // betaOffsetCSI-Part1-Index2: 6 + // betaOffsetCSI-Part2-Index1: 6 + // betaOffsetCSI-Part2-Index2: 6 + // scaling: f1 (3) + + // pucch-Config: setup (1) + // setup + // resourceSetToAddModList: 2 items + pucch.enabled = true; + // Item 0 + // PUCCH-ResourceSet + // pucch-ResourceSetId: 0 + // resourceList: 8 items + // Item 0 + // PUCCH-ResourceId: 0 + // Item 1 + // PUCCH-ResourceId: 1 + // Item 2 + // PUCCH-ResourceId: 2 + // Item 3 + // PUCCH-ResourceId: 3 + // Item 4 + // PUCCH-ResourceId: 4 + // Item 5 + // PUCCH-ResourceId: 5 + // Item 6 + // PUCCH-ResourceId: 6 + // Item 7 + // PUCCH-ResourceId: 7 + pucch.sets[0].nof_resources = 8; + + // Item 1 + // PUCCH-ResourceSet + // pucch-ResourceSetId: 1 + // resourceList: 8 items + // Item 0 + // PUCCH-ResourceId: 8 + // Item 1 + // PUCCH-ResourceId: 9 + // Item 2 + // PUCCH-ResourceId: 10 + // Item 3 + // PUCCH-ResourceId: 11 + // Item 4 + // PUCCH-ResourceId: 12 + // Item 5 + // PUCCH-ResourceId: 13 + // Item 6 + // PUCCH-ResourceId: 14 + // Item 7 + // PUCCH-ResourceId: 15 + pucch.sets[1].nof_resources = 8; + + // resourceToAddModList: 18 items + // Item 0 + // PUCCH-Resource + // pucch-ResourceId: 0 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 0 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 0 + pucch.sets[0].resources[0].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[0].starting_prb = 0; + pucch.sets[0].resources[0].initial_cyclic_shift = 0; + pucch.sets[0].resources[0].nof_symbols = 14; + pucch.sets[0].resources[0].start_symbol_idx = 0; + pucch.sets[0].resources[0].time_domain_occ = 0; + + // Item 1 + // PUCCH-Resource + // pucch-ResourceId: 1 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 4 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 0 + pucch.sets[0].resources[1].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[1].starting_prb = 0; + pucch.sets[0].resources[1].initial_cyclic_shift = 4; + pucch.sets[0].resources[1].nof_symbols = 14; + pucch.sets[0].resources[1].start_symbol_idx = 0; + pucch.sets[0].resources[1].time_domain_occ = 0; + + // Item 2 + // PUCCH-Resource + // pucch-ResourceId: 2 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 8 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 0 + pucch.sets[0].resources[2].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[2].starting_prb = 0; + pucch.sets[0].resources[2].initial_cyclic_shift = 8; + pucch.sets[0].resources[2].nof_symbols = 14; + pucch.sets[0].resources[2].start_symbol_idx = 0; + pucch.sets[0].resources[2].time_domain_occ = 0; + + // Item 3 + // PUCCH-Resource + // pucch-ResourceId: 3 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 0 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 1 + pucch.sets[0].resources[3].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[3].starting_prb = 0; + pucch.sets[0].resources[3].initial_cyclic_shift = 0; + pucch.sets[0].resources[3].nof_symbols = 14; + pucch.sets[0].resources[3].start_symbol_idx = 0; + pucch.sets[0].resources[3].time_domain_occ = 1; + + // Item 4 + // PUCCH-Resource + // pucch-ResourceId: 4 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 4 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 1 + pucch.sets[0].resources[4].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[4].starting_prb = 0; + pucch.sets[0].resources[4].initial_cyclic_shift = 4; + pucch.sets[0].resources[4].nof_symbols = 14; + pucch.sets[0].resources[4].start_symbol_idx = 0; + pucch.sets[0].resources[4].time_domain_occ = 1; + + // Item 5 + // PUCCH-Resource + // pucch-ResourceId: 5 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 8 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 1 + pucch.sets[0].resources[5].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[5].starting_prb = 0; + pucch.sets[0].resources[5].initial_cyclic_shift = 8; + pucch.sets[0].resources[5].nof_symbols = 14; + pucch.sets[0].resources[5].start_symbol_idx = 0; + pucch.sets[0].resources[5].time_domain_occ = 1; + + // Item 6 + // PUCCH-Resource + // pucch-ResourceId: 6 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 0 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 2 + pucch.sets[0].resources[6].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[6].starting_prb = 0; + pucch.sets[0].resources[6].initial_cyclic_shift = 0; + pucch.sets[0].resources[6].nof_symbols = 14; + pucch.sets[0].resources[6].start_symbol_idx = 0; + pucch.sets[0].resources[6].time_domain_occ = 2; + + // Item 7 + // PUCCH-Resource + // pucch-ResourceId: 7 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 4 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 2 + pucch.sets[0].resources[7].format = SRSLTE_PUCCH_NR_FORMAT_1; + pucch.sets[0].resources[7].starting_prb = 0; + pucch.sets[0].resources[7].initial_cyclic_shift = 0; + pucch.sets[0].resources[7].nof_symbols = 14; + pucch.sets[0].resources[7].start_symbol_idx = 0; + pucch.sets[0].resources[7].time_domain_occ = 2; + + // Item 8 + // PUCCH-Resource + // pucch-ResourceId: 8 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 0 + pucch.sets[1].resources[0].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[0].starting_prb = 51; + pucch.sets[1].resources[0].nof_prb = 1; + pucch.sets[1].resources[0].nof_symbols = 2; + pucch.sets[1].resources[0].start_symbol_idx = 0; + + // Item 9 + // PUCCH-Resource + // pucch-ResourceId: 9 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 2 + pucch.sets[1].resources[1].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[1].starting_prb = 51; + pucch.sets[1].resources[1].nof_prb = 1; + pucch.sets[1].resources[1].nof_symbols = 2; + pucch.sets[1].resources[1].start_symbol_idx = 2; + + // Item 10 + // PUCCH-Resource + // pucch-ResourceId: 10 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 4 + pucch.sets[1].resources[2].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[2].starting_prb = 51; + pucch.sets[1].resources[2].nof_prb = 1; + pucch.sets[1].resources[2].nof_symbols = 2; + pucch.sets[1].resources[2].start_symbol_idx = 4; + + // Item 11 + // PUCCH-Resource + // pucch-ResourceId: 11 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 6 + pucch.sets[1].resources[3].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[3].starting_prb = 51; + pucch.sets[1].resources[3].nof_prb = 1; + pucch.sets[1].resources[3].nof_symbols = 2; + pucch.sets[1].resources[3].start_symbol_idx = 6; + + // Item 12 + // PUCCH-Resource + // pucch-ResourceId: 12 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 8 + pucch.sets[1].resources[4].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[4].starting_prb = 51; + pucch.sets[1].resources[4].nof_prb = 1; + pucch.sets[1].resources[4].nof_symbols = 2; + pucch.sets[1].resources[4].start_symbol_idx = 8; + + // Item 13 + // PUCCH-Resource + // pucch-ResourceId: 13 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 10 + pucch.sets[1].resources[5].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[5].starting_prb = 51; + pucch.sets[1].resources[5].nof_prb = 1; + pucch.sets[1].resources[5].nof_symbols = 2; + pucch.sets[1].resources[5].start_symbol_idx = 10; + + // Item 14 + // PUCCH-Resource + // pucch-ResourceId: 14 + // startingPRB: 51 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 12 + pucch.sets[1].resources[6].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[6].starting_prb = 51; + pucch.sets[1].resources[6].nof_prb = 1; + pucch.sets[1].resources[6].nof_symbols = 2; + pucch.sets[1].resources[6].start_symbol_idx = 12; + + // Item 15 + // PUCCH-Resource + // pucch-ResourceId: 15 + // startingPRB: 1 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 0 + pucch.sets[1].resources[7].format = SRSLTE_PUCCH_NR_FORMAT_2; + pucch.sets[1].resources[7].starting_prb = 51; + pucch.sets[1].resources[7].nof_prb = 1; + pucch.sets[1].resources[7].nof_symbols = 2; + pucch.sets[1].resources[7].start_symbol_idx = 2; + + // Item 16 + // PUCCH-Resource + // pucch-ResourceId: 16 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 8 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 2 + // Item 17 + // PUCCH-Resource + // pucch-ResourceId: 17 + // startingPRB: 1 + // format: format2 (2) + // format2 + // nrofPRBs: 1 + // nrofSymbols: 2 + // startingSymbolIndex: 2 + // format1: setup (1) + // setup + // format2: setup (1) + // setup + // maxCodeRate: zeroDot25 (2) + for (uint32_t i = 0; i < SRSLTE_PUCCH_NR_MAX_NOF_SETS; i++) { + srslte_pucch_nr_resource_set_t* set = &pucch.sets[i]; + for (uint32_t j = 0; j < set->nof_resources; j++) { + if (set->resources[j].format == SRSLTE_PUCCH_NR_FORMAT_2) { + set->resources[j].max_code_rate = 2; // 0.25 + } + } + } + + // schedulingRequestResourceToAddModList: 1 item + // Item 0 + // SchedulingRequestResourceConfig + // schedulingRequestResourceId: 1 + // schedulingRequestID: 0 + // periodicityAndOffset: sl40 (10) + // sl40: 8 + // resource: 16 + + // dl-DataToUL-ACK: 7 items + // Item 0 + // dl-DataToUL-ACK item: 8 + // Item 1 + // dl-DataToUL-ACK item: 7 + // Item 2 + // dl-DataToUL-ACK item: 6 + // Item 3 + // dl-DataToUL-ACK item: 5 + // Item 4 + // dl-DataToUL-ACK item: 4 + // Item 5 + // dl-DataToUL-ACK item: 12 + // Item 6 + // dl-DataToUL-ACK item: 11 + harq_ack.dl_data_to_ul_ack[0] = 8; + harq_ack.dl_data_to_ul_ack[1] = 7; + harq_ack.dl_data_to_ul_ack[2] = 6; + harq_ack.dl_data_to_ul_ack[3] = 5; + harq_ack.dl_data_to_ul_ack[4] = 4; + harq_ack.dl_data_to_ul_ack[5] = 12; + harq_ack.dl_data_to_ul_ack[6] = 11; + harq_ack.nof_dl_data_to_ul_ack = 7; + } +}; +} // namespace srslte + +#endif // SRSLTE_RRC_NR_INTERFACE_TYPES_H diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 87253831c..5b2858172 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -87,10 +87,15 @@ public: class gw_interface_nas { public: - virtual int setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str) = 0; + virtual int setup_if_addr(uint32_t eps_bearer_id, + uint32_t lcid, + uint8_t pdn_type, + uint32_t ip_addr, + uint8_t* ipv6_if_id, + char* err_str) = 0; virtual int apply_traffic_flow_template(const uint8_t& eps_bearer_id, const uint8_t& lcid, - const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) = 0; + const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) = 0; typedef enum { TEST_LOOP_INACTIVE = 0, @@ -111,7 +116,8 @@ public: class gw_interface_rrc { public: - virtual void add_mch_port(uint32_t lcid, uint32_t port) = 0; + virtual void add_mch_port(uint32_t lcid, uint32_t port) = 0; + virtual int update_lcid(uint32_t eps_bearer_id, uint32_t new_lcid) = 0; }; // GW interface for PDCP @@ -212,7 +218,7 @@ public: virtual void paging_completed(bool outcome) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0; virtual uint32_t get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id) = 0; - virtual bool has_nr_dc() = 0; + virtual bool has_nr_dc() = 0; }; // RRC interface for PDCP @@ -250,8 +256,8 @@ public: virtual uint32_t get_ipv4_addr() = 0; virtual bool get_ipv6_addr(uint8_t* ipv6_addr) = 0; virtual void - plmn_search_completed(const rrc_interface_nas::found_plmn_t found_plmns[rrc_interface_nas::MAX_FOUND_PLMNS], - int nof_plmns) = 0; + plmn_search_completed(const rrc_interface_nas::found_plmn_t found_plmns[rrc_interface_nas::MAX_FOUND_PLMNS], + int nof_plmns) = 0; virtual bool connection_request_completed(bool outcome) = 0; }; @@ -262,7 +268,7 @@ public: virtual void reestablish() = 0; virtual void reestablish(uint32_t lcid) = 0; virtual void reset() = 0; - virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, int sn = -1) = 0; virtual void add_bearer(uint32_t lcid, srslte::pdcp_config_t cnfg) = 0; virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0; virtual void config_security(uint32_t lcid, srslte::as_security_config_t sec_cfg) = 0; @@ -270,6 +276,8 @@ public: virtual void enable_integrity(uint32_t lcid, srslte::srslte_direction_t direction) = 0; virtual void enable_encryption(uint32_t lcid, srslte::srslte_direction_t direction = srslte::srslte_direction_t::DIRECTION_TXRX) = 0; + virtual void send_status_report() = 0; + virtual void send_status_report(uint32_t lcid) = 0; }; // RRC NR interface for RRC (LTE) class rrc_nr_interface_rrc @@ -301,11 +309,13 @@ class pdcp_interface_rlc { public: /* RLC calls PDCP to push a PDCP PDU. */ - virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_pcch(srslte::unique_byte_buffer_t sdu) = 0; - virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_pcch(srslte::unique_byte_buffer_t sdu) = 0; + virtual void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) = 0; + virtual void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn) = 0; + virtual void notify_failure(uint32_t lcid, const std::vector& pdcp_sn) = 0; }; class pdcp_interface_gw @@ -526,6 +536,10 @@ typedef struct { std::vector dl_earfcn_list = {3400}; // vectorized version of dl_earfcn that gets populated during init std::map ul_earfcn_map; // Map linking DL EARFCN and UL EARFCN + std::string dl_nr_arfcn = "632628"; // comma-separated list of DL NR ARFCNs + std::vector dl_nr_arfcn_list = { + 632628}; // vectorized version of dl_nr_arfcn that gets populated during init + float dl_freq = -1.0f; float ul_freq = -1.0f; @@ -621,8 +635,8 @@ public: } prach_info_t; virtual void - prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm, float ta_base_sec = 0.0f) = 0; - virtual prach_info_t prach_get_info() = 0; + prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm, float ta_base_sec = 0.0f) = 0; + virtual prach_info_t prach_get_info() = 0; /* Indicates the transmission of a SR signal in the next opportunity */ virtual void sr_send() = 0; diff --git a/lib/include/srslte/interfaces/ue_nr_interfaces.h b/lib/include/srslte/interfaces/ue_nr_interfaces.h index 1bc43bbb4..1c02179a9 100644 --- a/lib/include/srslte/interfaces/ue_nr_interfaces.h +++ b/lib/include/srslte/interfaces/ue_nr_interfaces.h @@ -24,6 +24,8 @@ #include "srslte/common/interfaces_common.h" #include "srslte/interfaces/mac_interface_types.h" +#include "srslte/interfaces/rrc_nr_interface_types.h" +#include #include namespace srsue { @@ -55,12 +57,31 @@ public: virtual int sf_indication(const uint32_t tti) = 0; ///< FIXME: rename to slot indication + // Query the MAC for the current RNTI to look for + struct sched_rnti_t { + uint16_t id; + srslte_rnti_type_t type; + }; + virtual sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) = 0; + virtual sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) = 0; + /// Indicate succussfully received TB to MAC. The TB buffer is allocated in the PHY and handed as unique_ptr to MAC virtual void tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) = 0; /// Indicate reception of UL grant (only TBS is provided). Buffer for resulting MAC PDU is provided by MAC and is /// passed as pointer to PHY during tx_reuqest - virtual void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant) = 0; + virtual void + new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* phy_tx_pdu) = 0; + + /** + * @brief Indicate the successful transmission of a PRACH. + * @param tti The TTI from the PHY viewpoint at which the PRACH was sent over-the-air (not to the radio). + * @param s_id The index of the first OFDM symbol of the specified PRACH (0 <= s_id < 14). + * @param t_id The index of the first slot of the specified PRACH (0 <= t_id < 80). + * @param f_id The index of the specified PRACH in the frequency domain (0 <= f_id < 8). + * @param ul_carrier_id The UL carrier used for Msg1 transmission (0 for NUL carrier, and 1 for SUL carrier). + */ + virtual void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) = 0; }; class mac_interface_rrc_nr @@ -69,6 +90,38 @@ public: virtual void setup_lcid(const srslte::logical_channel_config_t& config) = 0; virtual void set_config(const srslte::bsr_cfg_t& bsr_cfg) = 0; virtual void set_config(const srslte::sr_cfg_t& sr_cfg) = 0; + virtual void set_config(const srslte::rach_nr_cfg_t& rach_cfg) = 0; + + // RRC triggers MAC ra procedure + virtual void start_ra_procedure() = 0; + + // RRC informs MAC about the (randomly) selected ID used for contention-based RA + virtual void set_contention_id(const uint64_t ue_identity) = 0; + + // RRC informs MAC about new UE identity for contention-free RA + virtual bool set_crnti(const uint16_t crnti) = 0; +}; + +struct phy_args_nr_t { + uint32_t nof_carriers; + uint32_t nof_prb; + uint32_t nof_phy_threads; + uint32_t worker_cpu_mask; + srslte::phy_log_args_t log; + srslte_ue_dl_nr_args_t dl; + srslte_ue_ul_nr_args_t ul; + + phy_args_nr_t() + { + dl.nof_rx_antennas = 1; + dl.nof_max_prb = 100; + dl.pdsch.measure_evm = true; + dl.pdsch.measure_time = true; + dl.pdsch.sch.disable_simd = false; + ul.nof_max_prb = 100; + ul.pusch.measure_time = true; + ul.pusch.sch.disable_simd = false; + } }; class phy_interface_mac_nr @@ -80,11 +133,26 @@ public: uint8_t* data; // always a pointer in our case } tx_request_t; + // MAC informs PHY about UL grant included in RAR PDU + virtual int set_ul_grant(std::array packed_ul_grant, + uint16_t rnti, + srslte_rnti_type_t rnti_type) = 0; + + // MAC instructs PHY to transmit MAC TB at the given TTI virtual int tx_request(const tx_request_t& request) = 0; + + /// Instruct PHY to send PRACH in the next occasion. + virtual void send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec = 0.0f) = 0; }; class phy_interface_rrc_nr -{}; +{ +public: + virtual bool set_config(const srslte::phy_cfg_nr_t& cfg) = 0; +}; // Combined interface for PHY to access stack (MAC and RRC) class stack_interface_phy_nr : public mac_interface_phy_nr, diff --git a/lib/include/srslte/mac/mac_rar_pdu_nr.h b/lib/include/srslte/mac/mac_rar_pdu_nr.h new file mode 100644 index 000000000..6ef9857d9 --- /dev/null +++ b/lib/include/srslte/mac/mac_rar_pdu_nr.h @@ -0,0 +1,107 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_MAC_RAR_PDU_NR_H +#define SRSLTE_MAC_RAR_PDU_NR_H + +#include "srslte/common/common.h" +#include "srslte/config.h" +#include "srslte/phy/common/phy_common_nr.h" +#include "srslte/srslog/srslog.h" +#include +#include +#include + +namespace srslte { + +class mac_rar_pdu_nr; + +// 3GPP 38.321 v15.3.0 Sec 6.1.5 +class mac_rar_subpdu_nr +{ +public: + // Possible types of RAR subpdus (same like EUTRA) + typedef enum { BACKOFF = 0, RAPID } rar_subh_type_t; + + mac_rar_subpdu_nr(mac_rar_pdu_nr* parent_); + + // RAR content length in bits (38.321 Sec 6.2.3) + static const uint32_t UL_GRANT_NBITS = SRSLTE_RAR_UL_GRANT_NBITS; + static const uint32_t TA_COMMAND_NBITS = 12; + + // getter + bool read_subpdu(const uint8_t* ptr); + bool has_more_subpdus(); + uint32_t get_total_length(); + bool has_rapid() const; + uint8_t get_rapid() const; + uint16_t get_temp_crnti() const; + uint32_t get_ta() const; + std::array get_ul_grant() const; + bool has_backoff() const; + uint8_t get_backoff() const; + + // setter + uint32_t write_subpdu(const uint8_t* start_); + void set_backoff(const uint8_t backoff_indicator_); + + std::string to_string(); + +private: + int header_length = 1; // RAR PDU subheader is always 1 B + int payload_length = 0; // only used if MAC RAR is included + + std::array ul_grant = {}; + uint16_t ta = 0; // 12bit TA + uint16_t temp_crnti = 0; + uint16_t rapid = 0; + uint8_t backoff_indicator = 0; + rar_subh_type_t type = BACKOFF; + bool E_bit = 0; + + srslog::basic_logger& logger; + + mac_rar_pdu_nr* parent = nullptr; +}; + +class mac_rar_pdu_nr +{ +public: + mac_rar_pdu_nr(); + ~mac_rar_pdu_nr() = default; + + bool pack(); + bool unpack(const uint8_t* payload, const uint32_t& len); + uint32_t get_num_subpdus(); + // Returns reference to a single subPDU + const mac_rar_subpdu_nr& get_subpdu(const uint32_t& index); + // Returns reference to all subPDUs + const std::vector& get_subpdus(); + + uint32_t get_remaining_len(); + + void set_si_rapid(uint16_t si_rapid_); // configured through SIB1 for on-demand SI request (See 38.331 Sec 5.2.1) + bool has_si_rapid(); + + std::string to_string(); + +private: + std::vector subpdus; + uint32_t remaining_len = 0; + uint16_t si_rapid = 0; + bool si_rapid_set = false; + srslog::basic_logger& logger; +}; + +} // namespace srslte + +#endif // SRSLTE_MAC_RAR_PDU_NR_H diff --git a/lib/include/srslte/mac/mac_nr_pdu.h b/lib/include/srslte/mac/mac_sch_pdu_nr.h similarity index 62% rename from lib/include/srslte/mac/mac_nr_pdu.h rename to lib/include/srslte/mac/mac_sch_pdu_nr.h index b90d0ee81..bddaf9102 100644 --- a/lib/include/srslte/mac/mac_nr_pdu.h +++ b/lib/include/srslte/mac/mac_sch_pdu_nr.h @@ -19,21 +19,22 @@ * */ -#ifndef SRSLTE_MAC_NR_PDU_H -#define SRSLTE_MAC_NR_PDU_H +#ifndef SRSLTE_MAC_SCH_PDU_NR_H +#define SRSLTE_MAC_SCH_PDU_NR_H #include "srslte/common/common.h" #include "srslte/common/logmap.h" #include "srslte/config.h" +#include "srslte/srslog/srslog.h" #include #include #include namespace srslte { -class mac_nr_sch_pdu; +class mac_sch_pdu_nr; -class mac_nr_sch_subpdu +class mac_sch_subpdu_nr { public: // 3GPP 38.321 v15.3.0 Combined Tables 6.2.1-1, 6.2.1-2 @@ -50,6 +51,7 @@ public: LONG_TRUNC_BSR = 0b111100, CCCH_SIZE_48 = 0b110100, CCCH_SIZE_64 = 0b000000, + SE_PHR = 0b111001, // Single Entry PHR SHORT_BSR = 0b111101, LONG_BSR = 0b111110, @@ -58,7 +60,7 @@ public: PADDING = 0b111111, } nr_lcid_sch_t; - mac_nr_sch_subpdu(mac_nr_sch_pdu* parent_); + mac_sch_subpdu_nr(mac_sch_pdu_nr* parent_); nr_lcid_sch_t get_type(); bool is_sdu(); @@ -71,10 +73,27 @@ public: uint32_t get_sdu_length(); uint32_t get_lcid(); uint8_t* get_sdu(); + uint16_t get_c_rnti(); + // both return the reported values as per TS 38.321, mapping to dB according to TS 38.133 Sec 10.1.17 not done here + uint8_t get_phr(); + uint8_t get_pcmax(); + + // BSR + struct lcg_bsr_t { + uint8_t lcg_id; + uint8_t buffer_size; + }; + lcg_bsr_t get_sbsr(); + static const uint8_t max_num_lcg_lbsr = 8; + std::array get_lbsr(); + + // setters void set_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_); - void set_padding(const uint32_t len_); + void set_c_rnti(const uint16_t crnti_); + void set_se_phr(const uint8_t phr_, const uint8_t pcmax_); + void set_sbsr(const lcg_bsr_t bsr_); uint32_t write_subpdu(const uint8_t* start_); @@ -88,39 +107,49 @@ private: bool F_bit = false; uint8_t* sdu = nullptr; - mac_nr_sch_pdu* parent = nullptr; - srslte::log_ref log_h; + static const uint8_t mac_ce_payload_len = 8 + 1; // Long BSR has max. 9 octets (see sizeof_ce() too) + std::array ce_write_buffer; // Buffer for CE payload + + mac_sch_pdu_nr* parent = nullptr; }; -class mac_nr_sch_pdu +class mac_sch_pdu_nr { public: - mac_nr_sch_pdu(bool ulsch_ = false) : ulsch(ulsch_) {} + mac_sch_pdu_nr(bool ulsch_ = false) : ulsch(ulsch_), logger(srslog::fetch_basic_logger("MAC")) {} void pack(); void unpack(const uint8_t* payload, const uint32_t& len); uint32_t get_num_subpdus(); - const mac_nr_sch_subpdu& get_subpdu(const uint32_t& index); + const mac_sch_subpdu_nr& get_subpdu(const uint32_t& index); bool is_ulsch(); void init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool is_ulsch_ = false); void init_rx(bool ulsch_ = false); + // Add SDU or CEs to PDU + // All functions will return SRSLTE_SUCCESS on success, and SRSLE_ERROR otherwise uint32_t add_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_); + uint32_t add_crnti_ce(const uint16_t crnti_); + uint32_t add_se_phr_ce(const uint8_t phr_, const uint8_t pcmax_); + uint32_t add_sbsr_ce(const mac_sch_subpdu_nr::lcg_bsr_t bsr_); uint32_t get_remaing_len(); private: uint32_t size_header_sdu(const uint32_t lcid_, const uint32_t nbytes); + /// Private helper that adds a subPDU to the MAC PDU + uint32_t add_sudpdu(mac_sch_subpdu_nr& subpdu); bool ulsch = false; - std::vector subpdus; + std::vector subpdus; byte_buffer_t* buffer = nullptr; uint32_t pdu_len = 0; uint32_t remaining_len = 0; + srslog::basic_logger& logger; }; } // namespace srslte -#endif // SRSLTE_MAC_NR_PDU_H +#endif // SRSLTE_MAC_SCH_PDU_NR_H diff --git a/lib/include/srslte/mac/pdu.h b/lib/include/srslte/mac/pdu.h index d7394891f..dd6700db6 100644 --- a/lib/include/srslte/mac/pdu.h +++ b/lib/include/srslte/mac/pdu.h @@ -24,6 +24,7 @@ #include "srslte/common/interfaces_common.h" #include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -127,10 +128,10 @@ template class pdu { public: - pdu(uint32_t max_subheaders_, log_ref log_h_) : + pdu(uint32_t max_subheaders_, srslog::basic_logger& logger) : max_subheaders(max_subheaders_), subheaders(max_subheaders_), - log_h(log_h_), + logger(logger), nof_subheaders(0), cur_idx(-1), pdu_len(0), @@ -242,12 +243,7 @@ public: if (ret && ((ptr - init_ptr) >= (int32_t)pdu_len)) { // stop processing last subheader indicates another one but all bytes are consumed nof_subheaders = 0; - if (log_h) { - log_h->warning_hex( - init_ptr, pdu_len, "Corrupted MAC PDU - all bytes have been consumed (pdu_len=%d)\n", pdu_len); - } else { - srslte::console("Corrupted MAC PDU - all bytes have been consumed (pdu_len=%d)\n", pdu_len); - } + logger.warning(init_ptr, pdu_len, "Corrupted MAC PDU - all bytes have been consumed (pdu_len=%d)", pdu_len); return SRSLTE_ERROR; } } while (ret && (nof_subheaders + 1) < (int)max_subheaders && ((int32_t)pdu_len > (ptr - init_ptr))); @@ -258,13 +254,7 @@ public: // stop processing if we read payload beyond the PDU length if ((ptr - init_ptr) > (int32_t)pdu_len) { nof_subheaders = 0; - - if (log_h) { - log_h->warning_hex( - init_ptr, pdu_len, "Corrupted MAC PDU - all bytes have been consumed (pdu_len=%d)\n", pdu_len); - } else { - srslte::console("Corrupted MAC PDU - all bytes have been consumed (pdu_len=%d)\n", pdu_len); - } + logger.warning(init_ptr, pdu_len, "Corrupted MAC PDU - all bytes have been consumed (pdu_len=%d)", pdu_len); return SRSLTE_ERROR; } } @@ -272,16 +262,16 @@ public: } protected: - std::vector subheaders; - uint32_t pdu_len; - uint32_t rem_len; - int cur_idx; - int nof_subheaders; - uint32_t max_subheaders; - bool pdu_is_ul; - byte_buffer_t* buffer_tx = nullptr; - int last_sdu_idx; - srslte::log_ref log_h; + std::vector subheaders; + uint32_t pdu_len; + uint32_t rem_len; + int cur_idx; + int nof_subheaders; + uint32_t max_subheaders; + bool pdu_is_ul; + byte_buffer_t* buffer_tx = nullptr; + int last_sdu_idx; + srslog::basic_logger& logger; /* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */ virtual void init_(byte_buffer_t* buffer_tx_, uint32_t pdu_len_bytes, bool is_ulsch) @@ -401,11 +391,11 @@ private: class sch_pdu : public pdu { public: - sch_pdu(uint32_t max_subh, const log_ref& log_h_) : pdu(max_subh, log_h_) {} + sch_pdu(uint32_t max_subh, srslog::basic_logger& logger) : pdu(max_subh, logger) {} void parse_packet(uint8_t* ptr); uint8_t* write_packet(); - uint8_t* write_packet(srslte::log_ref log); + uint8_t* write_packet(srslog::basic_logger& log); bool has_space_ce(uint32_t nbytes, bool var_len = false); bool has_space_sdu(uint32_t nbytes); int get_pdu_len(); @@ -466,7 +456,7 @@ private: class rar_pdu : public pdu { public: - rar_pdu(uint32_t max_rars = 16, srslte::log_ref log_ = srslte::logmap::get("MAC")); + rar_pdu(uint32_t max_rars = 16, srslog::basic_logger& logger = srslog::fetch_basic_logger("MAC")); void set_backoff(uint8_t bi); bool has_backoff(); @@ -483,7 +473,7 @@ private: class mch_pdu : public sch_pdu { public: - mch_pdu(uint32_t max_subh, const log_ref& log_h_) : sch_pdu(max_subh, log_h_) {} + mch_pdu(uint32_t max_subh, srslog::basic_logger& logger) : sch_pdu(max_subh, logger) {} private: /* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */ diff --git a/lib/include/srslte/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index 9495d1ce8..e290138db 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -42,8 +42,10 @@ public: virtual void process_pdu(uint8_t* buff, uint32_t len, channel_t channel) = 0; }; - pdu_queue(uint32_t pool_size = DEFAULT_POOL_SIZE) : pool(pool_size), callback(NULL) {} - void init(process_callback* callback, log_ref log_h_); + pdu_queue(srslog::basic_logger& logger, uint32_t pool_size = DEFAULT_POOL_SIZE) : + pool(pool_size), callback(NULL), logger(logger) + {} + void init(process_callback* callback); uint8_t* request(uint32_t len); void deallocate(const uint8_t* pdu); @@ -70,8 +72,8 @@ private: block_queue pdu_q; buffer_pool pool; - process_callback* callback; - log_ref log_h; + process_callback* callback; + srslog::basic_logger& logger; }; } // namespace srslte diff --git a/lib/include/srslte/phy/ch_estimation/csi_rs.h b/lib/include/srslte/phy/ch_estimation/csi_rs.h index fbd3efaba..78470c58c 100644 --- a/lib/include/srslte/phy/ch_estimation/csi_rs.h +++ b/lib/include/srslte/phy/ch_estimation/csi_rs.h @@ -107,15 +107,15 @@ typedef struct SRSLTE_API { } srslte_csi_rs_nzp_resource_t; SRSLTE_API int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_csi_rs_nzp_resource_t* resource, cf_t* grid); typedef struct SRSLTE_API { - float rsrp; - float rsrp_dB; - float epre; - float epre_dB; + float rsrp; + float rsrp_dB; + float epre; + float epre_dB; float n0; float n0_dB; float snr_dB; @@ -123,7 +123,7 @@ typedef struct SRSLTE_API { } srslte_csi_rs_measure_t; SRSLTE_API int srslte_csi_rs_nzp_measure(const srslte_carrier_nr_t* carrier, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_csi_rs_nzp_resource_t* resource, const cf_t* grid, srslte_csi_rs_measure_t* measure); diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_pdcch.h b/lib/include/srslte/phy/ch_estimation/dmrs_pdcch.h index 0169399cf..2b385f43d 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_pdcch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_pdcch.h @@ -43,7 +43,7 @@ */ SRSLTE_API int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_dci_location_t* dci_location, cf_t* sf_symbols); @@ -119,9 +119,8 @@ SRSLTE_API void srslte_dmrs_pdcch_estimator_free(srslte_dmrs_pdcch_estimator_t* * @param[in] sf_symbols Received resource grid. * @return SRSLTE_SUCCESS if the configurations are valid, otherwise it returns an SRSLTE_ERROR code */ -SRSLTE_API int srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const cf_t* sf_symbols); +SRSLTE_API int +srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, const srslte_slot_cfg_t* slot_cfg, const cf_t* sf_symbols); /** * @brief PDSCH DMRS measurement results diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_pucch.h b/lib/include/srslte/phy/ch_estimation/dmrs_pucch.h index c489d8fce..f355a293b 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_pucch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_pucch.h @@ -51,7 +51,7 @@ SRSLTE_API int srslte_dmrs_pucch_format_3_4_get_symbol_idx(const srslte_pucch_nr SRSLTE_API int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, cf_t* slot_symbols); @@ -69,7 +69,7 @@ SRSLTE_API int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* SRSLTE_API int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const cf_t* slot_symbols, srslte_chest_ul_res_t* res); @@ -87,7 +87,7 @@ SRSLTE_API int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, cf_t* slot_symbols); @@ -105,7 +105,7 @@ int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const cf_t* slot_symbols, srslte_chest_ul_res_t* res); diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_sch.h b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h index 56aff46bc..b3e92673c 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_sch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h @@ -41,7 +41,7 @@ * @see srslte_dmrs_sch_estimate */ typedef struct { - bool is_ue; + bool is_rx; srslte_carrier_nr_t carrier; @@ -56,12 +56,12 @@ typedef struct { /** * @brief Computes the symbol indexes carrying DMRS and stores them in symbols_idx - * @param pdsch_cfg PDSCH configuration provided by upper layers + * @param dmrs_cfg DMRS configuration * @param grant PDSCH information provided by a DCI * @param symbols_idx is the destination pointer where the symbols indexes are stored * @return It returns the number of symbols if inputs are valid, otherwise, it returns SRSLTE_ERROR code. */ -SRSLTE_API int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* pdsch_cfg, +SRSLTE_API int srslte_dmrs_sch_get_symbols_idx(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslte_sch_grant_nr_t* grant, uint32_t symbols_idx[SRSLTE_DMRS_SCH_MAX_SYMBOLS]); @@ -78,11 +78,11 @@ SRSLTE_API int srslte_dmrs_sch_get_sc_idx(const srslte_dmrs_sch_cfg_t* cfg, uint /** * @brief Calculates the number of resource elements taken by a PDSCH-DMRS for a given PDSCH transmission - * @param pdsch_cfg PDSCH configuration provided by upper layers + * @param dmrs_cfg PDSCH-DMRS configuration * @param grant PDSCH information provided by a DCI * @return it returns the number of resource elements if the configuration is valid, otherwise it returns SRSLTE_ERROR */ -SRSLTE_API int srslte_dmrs_sch_get_N_prb(const srslte_sch_cfg_nr_t* cfg, const srslte_sch_grant_nr_t* grant); +SRSLTE_API int srslte_dmrs_sch_get_N_prb(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslte_sch_grant_nr_t* grant); /** * @brief Stringifies the PDSCH DMRS configuration @@ -100,10 +100,10 @@ SRSLTE_API int srslte_dmrs_sch_cfg_to_str(const srslte_dmrs_sch_cfg_t* cfg, char * @brief Initialises DMRS PDSCH object * * @param q DMRS PDSCH object - * @param is_ue indicates whethe the object is for a UE (in this case, it shall initialise as an estimator) + * @param is_rx indicates whether the object is used as receiver (in this case, it shall initialise as an estimator) * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ -SRSLTE_API int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_ue); +SRSLTE_API int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_rx); /** * @brief Frees DMRS PDSCH object @@ -135,7 +135,7 @@ SRSLTE_API int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_ca * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ SRSLTE_API int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant, cf_t* sf_symbols); @@ -155,7 +155,7 @@ SRSLTE_API int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ SRSLTE_API int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant, const cf_t* sf_symbols, diff --git a/lib/include/srslte/phy/channel/channel.h b/lib/include/srslte/phy/channel/channel.h index 752ab6254..8fde01860 100644 --- a/lib/include/srslte/phy/channel/channel.h +++ b/lib/include/srslte/phy/channel/channel.h @@ -69,14 +69,14 @@ public: uint32_t rlf_t_off_ms = 2000; } args_t; - channel(const args_t& channel_args, uint32_t _nof_channels); + channel(const args_t& channel_args, uint32_t _nof_channels, srslog::basic_logger& logger); ~channel(); - void set_logger(log_filter* _log_h); void set_srate(uint32_t srate); void set_signal_power_dBfs(float power_dBfs); void run(cf_t* in[SRSLTE_MAX_CHANNELS], cf_t* out[SRSLTE_MAX_CHANNELS], uint32_t len, const srslte_timestamp_t& t); private: + srslog::basic_logger& logger; float hst_init_phase = 0.0f; srslte_channel_fading_t* fading[SRSLTE_MAX_CHANNELS] = {}; srslte_channel_delay_t* delay[SRSLTE_MAX_CHANNELS] = {}; @@ -85,7 +85,6 @@ private: srslte_channel_rlf_t* rlf = nullptr; cf_t* buffer_in = nullptr; cf_t* buffer_out = nullptr; - log_filter* log_h = nullptr; uint32_t nof_channels = 0; uint32_t current_srate = 0; args_t args = {}; diff --git a/lib/include/srslte/phy/common/phy_common_nr.h b/lib/include/srslte/phy/common/phy_common_nr.h index 6b86b8965..35f28912c 100644 --- a/lib/include/srslte/phy/common/phy_common_nr.h +++ b/lib/include/srslte/phy/common/phy_common_nr.h @@ -117,6 +117,11 @@ extern "C" { */ #define SRSLTE_MAX_NOF_DL_ALLOCATION 16 +/** + * @brief Maximum dl-DataToUL-ACK value. This is defined by TS 38.331 v15.10.1 in PUCCH-Config + */ +#define SRSLTE_MAX_NOF_DL_DATA_TO_UL 8 + typedef enum SRSLTE_API { srslte_coreset_mapping_type_non_interleaved = 0, srslte_coreset_mapping_type_interleaved, @@ -139,15 +144,33 @@ typedef enum SRSLTE_API { */ typedef enum SRSLTE_API { srslte_sch_mapping_type_A = 0, srslte_sch_mapping_type_B } srslte_sch_mapping_type_t; +/** + * @brief Search spaces + * @remark Described in TS 38.213 V15.10.0 Section 10.1 UE procedure for determining physical downlink control channel + * assignment + */ typedef enum SRSLTE_API { - srslte_search_space_type_common = 0, - srslte_search_space_type_common_0, - srslte_search_space_type_common_0A, - srslte_search_space_type_common_1, - srslte_search_space_type_common_2, - srslte_search_space_type_ue, + srslte_search_space_type_common_0 = 0, ///< configured by pdcch-ConfigSIB1 in MIB or by searchSpaceSIB1 in + ///< PDCCH-ConfigCommon or by searchSpaceZero in PDCCH-ConfigCommon + srslte_search_space_type_common_0A, ///< configured by searchSpaceOtherSystemInformation in PDCCH-ConfigCommon + srslte_search_space_type_common_1, ///< configured by ra-SearchSpace in PDCCH-ConfigCommon + srslte_search_space_type_common_2, ///< configured by pagingSearchSpace in PDCCH-ConfigCommon + srslte_search_space_type_common_3, ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = common + srslte_search_space_type_ue, ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = ue-Specific + srslte_search_space_type_rar, ///< Indicates that a grant was given by MAC RAR as described in TS 38.213 clause 8.2 + srslte_search_space_type_cg ///< Indicates that a grant was given by Configured Grant from the upper layers } srslte_search_space_type_t; +/** + * @brief Helper macro to get if a search space type is common or not + */ +#define SRSLTE_SEARCH_SPACE_IS_COMMON(SS_TYPE) ((SS_TYPE) < srslte_search_space_type_ue) + +/** + * @brief RAR content length in bits (see TS 38.321 Sec 6.2.3) + */ +#define SRSLTE_RAR_UL_GRANT_NBITS (27) + /** * @brief Indicates the MCS table the UE shall use for PDSCH and/or PUSCH without transform precoding */ @@ -160,16 +183,17 @@ typedef enum SRSLTE_API { /** * @brief RNTI types + * @remark Usage described in TS 38.321 Table 7.1-2: RNTI usage. */ typedef enum SRSLTE_API { srslte_rnti_type_c = 0, - srslte_rnti_type_p, - srslte_rnti_type_si, - srslte_rnti_type_ra, - srslte_rnti_type_tc, - srslte_rnti_type_cs, - srslte_rnti_type_sp_csi, - srslte_rnti_type_mcs_crnti, + srslte_rnti_type_p, ///< @brief Paging and System Information change notification (PCH) + srslte_rnti_type_si, ///< @brief Broadcast of System Information (DL-SCH) + srslte_rnti_type_ra, ///< @brief Random Access Response (DL-SCH) + srslte_rnti_type_tc, ///< @brief Contention Resolution (when no valid C-RNTI is available) (DL-SCH) + srslte_rnti_type_cs, ///< @brief Configured scheduled unicast transmission (DL-SCH, UL-SCH) + srslte_rnti_type_sp_csi, ///< @brief Activation of Semi-persistent CSI reporting on PUSCH + srslte_rnti_type_mcs_c, ///< @brief Dynamically scheduled unicast transmission (DL-SCH) } srslte_rnti_type_t; /** @@ -202,6 +226,15 @@ typedef enum SRSLTE_API { srslte_xoverhead_18 } srslte_xoverhead_t; +/** + * @brief PDSCH HARQ ACK codebook configuration + * @remark Described in TS 38.331 V15.10.0 PhysicalCellGroupConfig + */ +typedef enum SRSLTE_API { + srslte_pdsch_harq_ack_codebook_none = 0, + srslte_pdsch_harq_ack_codebook_semi_static, + srslte_pdsch_harq_ack_codebook_dynamic, +} srslte_pdsch_harq_ack_codebook_t; /** * @brief NR carrier parameters. It is a combination of fixed cell and bandwidth-part (BWP) */ @@ -225,7 +258,7 @@ typedef struct SRSLTE_API { /// Left for future parameters /// ... -} srslte_dl_slot_cfg_t; +} srslte_slot_cfg_t; /** * @brief Min number of OFDM symbols in a control resource set. @@ -251,8 +284,9 @@ typedef struct SRSLTE_API { * @brief CORESET parameters as defined in TS 38.331 V15.10.0 - ControlResourceSet */ typedef struct SRSLTE_API { - srslte_coreset_mapping_type_t mapping_type; uint32_t id; + uint32_t coreset_id; + srslte_coreset_mapping_type_t mapping_type; uint32_t duration; bool freq_resources[SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE]; srslte_coreset_bundle_size_t interleaver_size; @@ -270,11 +304,19 @@ typedef struct SRSLTE_API { */ typedef struct SRSLTE_API { uint32_t id; + uint32_t coreset_id; uint32_t duration; // in slots srslte_search_space_type_t type; uint32_t nof_candidates[SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR]; } srslte_search_space_t; +/** + * @brief Get the RNTI type name for NR + * @param rnti_type RNTI type name + * @return Constant string with the RNTI type name + */ +SRSLTE_API const char* srslte_rnti_type_str(srslte_rnti_type_t rnti_type); + /** * @brief Calculates the bandwidth of a given CORESET in physical resource blocks (PRB) . This function uses the * frequency domain resources bit-map for counting the number of PRB. @@ -320,6 +362,25 @@ SRSLTE_API const char* srslte_mcs_table_to_str(srslte_mcs_table_t mcs_table); */ SRSLTE_API srslte_mcs_table_t srslte_mcs_table_from_str(const char* str); +/** + * @brief Computes the minimum valid symbol size for a given amount of PRB + * @attention The valid FFT sizes are radix 2 and radix 3 between 128 to 4096 points. + * @param nof_prb Number of PRB + * @return The minimum valid FFT size if the number of PRB is in range, 0 otherwise + */ +SRSLTE_API uint32_t srslte_min_symbol_sz_rb(uint32_t nof_prb); + +/** + * @brief Computes the time in seconds between two symbols in a slot + * @note l0 is expected to be smaller than l1 + * @remark All symbol size reference and values are taken from TS 38.211 section 5.3 OFDM baseband signal generation + * @param l0 First symbol index within the slot + * @param l1 Second symbol index within the slot + * @param numerology NR Carrier numerology + * @return Returns the time in seconds between the two symbols if the condition above is satisfied, 0 seconds otherwise + */ +SRSLTE_API float srslte_symbol_distance_s(uint32_t l0, uint32_t l1, uint32_t numerology); + #ifdef __cplusplus } #endif diff --git a/lib/include/srslte/phy/common/sequence.h b/lib/include/srslte/phy/common/sequence.h index 8f3119094..eada05c3c 100644 --- a/lib/include/srslte/phy/common/sequence.h +++ b/lib/include/srslte/phy/common/sequence.h @@ -34,7 +34,7 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common.h" -#define SRSLTE_SEQUENCE_MOD(X) ((X) & (uint32_t)INT32_MAX) +#define SRSLTE_SEQUENCE_MOD(X) ((uint32_t)((X) & (uint64_t)INT32_MAX)) typedef struct SRSLTE_API { uint32_t x1; diff --git a/lib/include/srslte/phy/dft/ofdm.h b/lib/include/srslte/phy/dft/ofdm.h index 34bf052d0..38e890e1f 100644 --- a/lib/include/srslte/phy/dft/ofdm.h +++ b/lib/include/srslte/phy/dft/ofdm.h @@ -85,8 +85,28 @@ typedef struct SRSLTE_API { cf_t* window_offset_buffer; } srslte_ofdm_t; +/** + * @brief Initialises or reconfigures OFDM receiver + * + * @note The reconfiguration of the OFDM object considers only CP, number of PRB and optionally the FFT size + * @attention The OFDM object must be zeroed externally prior calling the initialization for first time + * + * @param q OFDM object + * @param cfg OFDM configuration + * @return SRSLTE_SUCCESS if the initialization/reconfiguration is successful, SRSLTE_ERROR code otherwise + */ SRSLTE_API int srslte_ofdm_rx_init_cfg(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg); +/** + * @brief Initialises or reconfigures OFDM transmitter + * + * @note The reconfiguration of the OFDM object considers only CP, number of PRB and optionally the FFT size + * @attention The OFDM object must be zeroed externally prior calling the initialization for first time + * + * @param q OFDM object + * @param cfg OFDM configuration + * @return SRSLTE_SUCCESS if the initialization/reconfiguration is successful, SRSLTE_ERROR code otherwise + */ SRSLTE_API int srslte_ofdm_tx_init_cfg(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg); SRSLTE_API int diff --git a/lib/include/srslte/phy/enb/enb_dl_nr.h b/lib/include/srslte/phy/enb/enb_dl_nr.h index d221b92e0..8059739f6 100644 --- a/lib/include/srslte/phy/enb/enb_dl_nr.h +++ b/lib/include/srslte/phy/enb/enb_dl_nr.h @@ -62,17 +62,15 @@ SRSLTE_API int srslte_enb_dl_nr_base_zero(srslte_enb_dl_nr_t* q); SRSLTE_API void srslte_enb_dl_nr_gen_signal(srslte_enb_dl_nr_t* q); -SRSLTE_API int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const srslte_dci_dl_nr_t* dci_dl); +SRSLTE_API int +srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, const srslte_slot_cfg_t* slot_cfg, const srslte_dci_dl_nr_t* dci_dl); -SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_sch_cfg_nr_t* cfg, - uint8_t* data[SRSLTE_MAX_TB]); +SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, + const srslte_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + uint8_t* data[SRSLTE_MAX_TB]); SRSLTE_API int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len); - #endif // SRSLTE_ENB_DL_NR_H diff --git a/lib/include/srslte/phy/fec/ldpc/ldpc_decoder.h b/lib/include/srslte/phy/fec/ldpc/ldpc_decoder.h index 46a57df54..e00ff32cc 100644 --- a/lib/include/srslte/phy/fec/ldpc/ldpc_decoder.h +++ b/lib/include/srslte/phy/fec/ldpc/ldpc_decoder.h @@ -45,6 +45,9 @@ typedef enum { SRSLTE_LDPC_DECODER_C_AVX2, /*!< \brief %Decoder working with 8-bit integer-valued LLRs (AVX2 version). */ SRSLTE_LDPC_DECODER_C_AVX2_FLOOD, /*!< \brief %Decoder working with 8-bit integer-valued LLRs, flooded scheduling (AVX2 version). */ + SRSLTE_LDPC_DECODER_C_AVX512, /*!< \brief %Decoder working with 8-bit integer-valued LLRs (AVX512 version). */ + SRSLTE_LDPC_DECODER_C_AVX512_FLOOD, /*!< \brief %Decoder working with 8-bit integer-valued LLRs, flooded scheduling + (AVX512 version). */ } srslte_ldpc_decoder_type_t; /*! diff --git a/lib/include/srslte/phy/fec/ldpc/ldpc_encoder.h b/lib/include/srslte/phy/fec/ldpc/ldpc_encoder.h index 0742fbe32..cca6ac27a 100644 --- a/lib/include/srslte/phy/fec/ldpc/ldpc_encoder.h +++ b/lib/include/srslte/phy/fec/ldpc/ldpc_encoder.h @@ -22,7 +22,7 @@ /*! * \file ldpc_encoder.h * \brief Declaration of the LDPC encoder. - * \author David Gregoratti + * \author David Gregoratti and Jesus Gomez * \date 2020 * * \copyright Software Radio Systems Limited @@ -42,6 +42,9 @@ typedef enum SRSLTE_API { #if LV_HAVE_AVX2 SRSLTE_LDPC_ENCODER_AVX2, /*!< \brief SIMD-optimized encoder. */ #endif // LV_HAVE_AVX2 +#if LV_HAVE_AVX512 + SRSLTE_LDPC_ENCODER_AVX512, /*!< \brief SIMD-optimized encoder. */ +#endif // LV_HAVE_AVX512 } srslte_ldpc_encoder_type_t; /*! @@ -65,6 +68,8 @@ typedef struct SRSLTE_API { void (*encode_high_rate)(void*, uint8_t*); /*! \brief Pointer to the encoder for the high-rate region (SIMD-optimized version). */ void (*encode_high_rate_avx2)(void*); + /*! \brief Pointer to the encoder for the high-rate region (SIMD-AVX512-optimized version). */ + void (*encode_high_rate_avx512)(void*); } srslte_ldpc_encoder_t; diff --git a/lib/include/srslte/phy/fec/polar/polar_code.h b/lib/include/srslte/phy/fec/polar/polar_code.h index 9634220c9..9b8ce7251 100644 --- a/lib/include/srslte/phy/fec/polar/polar_code.h +++ b/lib/include/srslte/phy/fec/polar/polar_code.h @@ -360,7 +360,7 @@ static inline const uint16_t* get_mother_code(uint8_t n) return mother_code_10; break; default: - ERROR("Wrong code_size_log\n"); + ERROR("Wrong code_size_log"); return NULL; } } @@ -390,7 +390,7 @@ static inline const uint16_t* get_blk_interleaver(uint8_t n) return blk_interleaver_10; break; default: - ERROR("Wrong code_size_log (%d)\n", n); + ERROR("Wrong code_size_log (%d)", n); return NULL; } } diff --git a/lib/include/srslte/phy/fec/turbo/turbodecoder_iter.h b/lib/include/srslte/phy/fec/turbo/turbodecoder_iter.h index bdf99295e..1cbf06767 100644 --- a/lib/include/srslte/phy/fec/turbo/turbodecoder_iter.h +++ b/lib/include/srslte/phy/fec/turbo/turbodecoder_iter.h @@ -139,7 +139,7 @@ void MAKE_CALL(run_tdec_iteration)(srslte_tdec_t* h, llr_t* input) h->n_iter++; } else { - ERROR("Error CB index not set (call srslte_tdec_new_cb() first\n"); + ERROR("Error CB index not set (call srslte_tdec_new_cb() first"); } } diff --git a/lib/include/srslte/phy/modem/evm.h b/lib/include/srslte/phy/modem/evm.h index 18eefb741..2028caaf2 100644 --- a/lib/include/srslte/phy/modem/evm.h +++ b/lib/include/srslte/phy/modem/evm.h @@ -183,7 +183,7 @@ static inline void srslte_evm_buffer_resize(srslte_evm_buffer_t* q, uint32_t new \ /* Return NAN if EVM buffers, modem table, LLR, symbols or bits missing*/ \ if (!q || !modem_table || !modem_table->nbits_x_symbol || !llr || !symbols || !nof_bits) { \ - ERROR("Invalid inputs %p %p %p %p %d\n", q, modem_table, llr, symbols, nof_bits); \ + ERROR("Invalid inputs %p %p %p %p %d", q, modem_table, llr, symbols, nof_bits); \ return evm_rms; \ } \ \ diff --git a/lib/include/srslte/phy/phch/dci_nr.h b/lib/include/srslte/phy/phch/dci_nr.h index 005843412..3523fd143 100644 --- a/lib/include/srslte/phy/phch/dci_nr.h +++ b/lib/include/srslte/phy/phch/dci_nr.h @@ -29,6 +29,7 @@ typedef struct SRSLTE_API { srslte_dci_location_t location; srslte_search_space_type_t search_space; + uint32_t coreset_id; uint8_t payload[50]; srslte_rnti_type_t rnti_type; uint32_t nof_bits; @@ -37,11 +38,12 @@ typedef struct SRSLTE_API { } srslte_dci_msg_nr_t; typedef struct SRSLTE_API { - uint16_t rnti; - srslte_rnti_type_t rnti_type; - srslte_dci_format_nr_t format; - srslte_dci_location_t location; - srslte_search_space_t search_space; + uint16_t rnti; + srslte_rnti_type_t rnti_type; + srslte_dci_format_nr_t format; + srslte_dci_location_t location; + srslte_search_space_type_t search_space; + uint32_t coreset_id; // Common fields uint32_t freq_domain_assigment; ///< Frequency domain resource assignment @@ -69,14 +71,76 @@ typedef struct SRSLTE_API { } srslte_dci_dl_nr_t; +typedef struct SRSLTE_API { + // Context information + uint16_t rnti; + srslte_rnti_type_t rnti_type; + srslte_dci_format_nr_t format; + srslte_dci_location_t location; + srslte_search_space_type_t search_space; + uint32_t coreset_id; + + // Common fields + uint32_t freq_domain_assigment; ///< Frequency domain resource assignment + uint32_t time_domain_assigment; ///< Time domain resource assignment + uint32_t freq_hopping_flag; ///< Frequency hopping flag + uint32_t mcs; ///< Modulation and coding scheme + uint32_t rv; ///< Redundancy version + uint32_t reserved; ///< Reserved bits + + // C-RNTI or CS-RNTI or MCS-C-RNTI + uint32_t ndi; ///< New data indicator + uint32_t pid; ///< HARQ process number + uint32_t tpc; ///< TPC command for scheduled PUCCH + uint32_t pucch_resource; ///< PUCCH resource indicator + uint32_t harq_feedback; ///< PDSCH-to-HARQ_feedback timing indicator + + // Frequency hopping + uint32_t frequency_offset; ///< frequency offset + + // Random Access Response Grant + uint32_t csi_request; +} srslte_dci_ul_nr_t; + +/** + * @brief Indicates whether the provided DCI message format bit indicator belongs to DCI format 1_0 according according + * to the RNTI type. If invalid, the DCI message is likely to be format 0_0 + * @param dci_msg Provides DCI format 1_0 message + * @return true if the DCI message is format 1_0, false otherwise + */ +SRSLTE_API bool srslte_dci_nr_format_1_0_valid(const srslte_dci_msg_nr_t* dci_msg); + SRSLTE_API int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, const srslte_dci_dl_nr_t* dci, srslte_dci_msg_nr_t* msg); -SRSLTE_API SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier, - const srslte_coreset_t* coreset, - srslte_rnti_type_t rnti_type); +SRSLTE_API int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset, + srslte_rnti_type_t rnti_type); + +SRSLTE_API int srslte_dci_nr_format_0_0_pack(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset0, + const srslte_dci_ul_nr_t* dci, + srslte_dci_msg_nr_t* msg); + +SRSLTE_API int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset, + srslte_dci_msg_nr_t* msg, + srslte_dci_ul_nr_t* dci); + +/** + * @brief Unpacks DCI from Random Access Response Grant + * @remark Described in TS 38.213 Table 8.2-1: Random Access Response Grant Content field size + * @param msg + * @param dci + * @return SRSLTE_SUCCESS if unpacked correctly, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_dci_nr_rar_unpack(srslte_dci_msg_nr_t* msg, srslte_dci_ul_nr_t* dci); + +SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset, + srslte_rnti_type_t rnti_type); SRSLTE_API int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, @@ -88,4 +152,8 @@ SRSLTE_API int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrie srslte_dci_msg_nr_t* msg, srslte_dci_dl_nr_t* dci); +SRSLTE_API int srslte_dci_ul_nr_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len); + +SRSLTE_API int srslte_dci_dl_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len); + #endif // SRSLTE_DCI_NR_H diff --git a/lib/include/srslte/phy/phch/pdcch_nr.h b/lib/include/srslte/phy/phch/pdcch_nr.h index 586149953..af151441f 100644 --- a/lib/include/srslte/phy/phch/pdcch_nr.h +++ b/lib/include/srslte/phy/phch/pdcch_nr.h @@ -113,6 +113,14 @@ SRSLTE_API int srslte_pdcch_nr_init_rx(srslte_pdcch_nr_t* q, const srslte_pdcch_ SRSLTE_API void srslte_pdcch_nr_free(srslte_pdcch_nr_t* q); +/** + * @brief Sets carrier and CORESET configuration for a given PDCCH object + * @note This function shall not allocate, free memory or perform any heavy computations + * @param[in,out] q PDCCH encoder/decoder object + * @param[in] carrier New carrier configuration + * @param[in] coreset New CORESET configuration + * @return SRSLTE_SUCCESS if the configurations are valid, otherwise it returns an SRSLTE_ERROR code + */ SRSLTE_API int srslte_pdcch_nr_set_carrier(srslte_pdcch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset); diff --git a/lib/include/srslte/phy/phch/phch_cfg_nr.h b/lib/include/srslte/phy/phch/phch_cfg_nr.h index 826920d98..efa9f182a 100644 --- a/lib/include/srslte/phy/phch/phch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/phch_cfg_nr.h @@ -68,7 +68,7 @@ typedef enum { } srslte_dmrs_sch_add_pos_t; /** - * @brief Provides PDSCH DMRS configuration from higher layers + * @brief Provides PDSCH DMRS configuration * @remark Parameters described in TS 38.331 V15.10.0 */ typedef struct { @@ -91,21 +91,23 @@ typedef struct { } srslte_dmrs_sch_cfg_t; /** - * @brief flatten PDSCH time domain allocation parameters + * @brief Common flatten PDSCH and PUSCH time domain allocation parameters * @remark Described in TS 38.331 V15.10.0 Section PDSCH-TimeDomainResourceAllocationList + * @remark Described in TS 38.331 V15.10.0 Section PUSCH-TimeDomainResourceAllocationList */ typedef struct SRSLTE_API { - /// Slot offset between DCI and its scheduled PDSCH - uint32_t k0; + /// For PDSCH Slot offset between DCI and its scheduled PDSCH + /// For PUSCH parameter K2 + uint32_t k; - /// PDSCH mapping type + /// SCH mapping type srslte_sch_mapping_type_t mapping_type; /// An index giving valid combinations of start symbol and length (jointly encoded) as start and length indicator /// (SLIV). The network configures the field so that the allocation does not cross the slot boundary uint32_t sliv; -} srslte_pdsch_time_ra_t; +} srslte_sch_time_ra_t; /** * @brief PDSCH grant information provided by the Downlink Control Information (DCI) @@ -116,20 +118,23 @@ typedef struct SRSLTE_API { srslte_rnti_type_t rnti_type; /// Time domain resources - uint32_t k0; // PDSCH only - uint32_t k2; // PUSCH only + uint32_t k; // k0 for PDSCH, k2 for PUSCH uint32_t S; uint32_t L; srslte_sch_mapping_type_t mapping; /// Frequency domain resources - bool prb_idx[SRSLTE_MAX_PRB_NR]; + bool prb_idx[SRSLTE_MAX_PRB_NR]; uint32_t nof_prb; /// Number of DMRS groups without data /// Described in TS 38.214 Section 5.1.6.2 uint32_t nof_dmrs_cdm_groups_without_data; + /// Linear DMRS power offset. Zero means unset and it is equivalent to one. + /// For PUSCH, see TS 38.214 Table 6.2.2-1 for more information + float beta_dmrs; + /// Spatial resources uint32_t nof_layers; @@ -153,21 +158,57 @@ typedef struct SRSLTE_API { * @remark Described in TS 38.331 V15.10.0 Section PUSCH-Config */ typedef struct SRSLTE_API { + // Serving cell parameters + uint32_t scs_cfg; // Subcarrier spacing configuration + srslte_dmrs_sch_typeA_pos_t typeA_pos; bool scrambling_id_present; uint32_t scambling_id; // Identifier used to initialize data scrambling (0-1023) - srslte_dmrs_sch_cfg_t dmrs_typeA; - srslte_dmrs_sch_cfg_t dmrs_typeB; - srslte_sch_grant_nr_t grant; + struct { + srslte_dmrs_sch_type_t type; + srslte_dmrs_sch_add_pos_t additional_pos; + srslte_dmrs_sch_len_t length; + bool scrambling_id0_present; + uint32_t scrambling_id0; + bool scrambling_id1_present; + uint32_t scrambling_id1; + bool present; + } dmrs_typeA; - bool pdsch_time_is_default; ///< Set to true if pdsch_time_ra contains the configuration from pdsch-ConfigCommon or - ///< pdsch-Config - srslte_pdsch_time_ra_t pdsch_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION]; + struct { + srslte_dmrs_sch_type_t type; + srslte_dmrs_sch_add_pos_t additional_pos; + srslte_dmrs_sch_len_t length; + bool scrambling_id0_present; + uint32_t scrambling_id0; + bool scrambling_id1_present; + uint32_t scrambling_id1; + bool present; + } dmrs_typeB; + + srslte_sch_time_ra_t common_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION]; + uint32_t nof_common_time_ra; + + srslte_sch_time_ra_t dedicated_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION]; + uint32_t nof_dedicated_time_ra; bool rbg_size_cfg_1; ///< RBG size configuration (1 or 2) srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters +} srslte_sch_hl_cfg_nr_t; + +/** + * @brief Common NR-SCH (PDSCH and PUSCH for NR) configuration + */ +typedef struct SRSLTE_API { + bool scrambling_id_present; + uint32_t scambling_id; // Identifier used to initialize data scrambling (0-1023) + + srslte_dmrs_sch_cfg_t dmrs; + srslte_sch_grant_nr_t grant; + + srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters /// Uplink params bool enable_transform_precoder; diff --git a/lib/include/srslte/phy/phch/prach.h b/lib/include/srslte/phy/phch/prach.h index c83f1b533..8548f96d1 100644 --- a/lib/include/srslte/phy/phch/prach.h +++ b/lib/include/srslte/phy/phch/prach.h @@ -40,6 +40,12 @@ #define SRSLTE_PRACH_MAX_LEN (2 * 24576 + 21024) // Maximum Tcp + Tseq +// Long PRACH ZC sequence sequence length +#define SRSLTE_PRACH_N_ZC_LONG 839 + +// Short PRACH ZC sequence sequence length +#define SRSLTE_PRACH_N_ZC_SHORT 139 + /** Generation and detection of RACH signals for uplink. * Currently only supports preamble formats 0-3. * Does not currently support high speed flag. @@ -49,7 +55,7 @@ typedef struct { int idx; float factor; - cf_t phase_array[2 * 839]; + cf_t phase_array[2 * SRSLTE_PRACH_N_ZC_LONG]; } srslte_prach_cancellation_t; typedef struct SRSLTE_API { @@ -74,8 +80,8 @@ typedef struct SRSLTE_API { uint32_t N_cp; // Cyclic prefix length // Generated tables - cf_t seqs[64][839]; // Our set of 64 preamble sequences - cf_t dft_seqs[64][839]; // DFT-precoded seqs + cf_t seqs[64][SRSLTE_PRACH_N_ZC_LONG]; // Our set of 64 preamble sequences + cf_t dft_seqs[64][SRSLTE_PRACH_N_ZC_LONG]; // DFT-precoded seqs uint64_t dft_gen_bitmap; // Bitmap where each bit Indicates if the dft has been generated for sequence i. uint32_t root_seqs_idx[64]; // Indices of root seqs in seqs table uint32_t N_roots; // Number of root sequences used in this configuration diff --git a/lib/include/srslte/phy/phch/pucch_cfg_nr.h b/lib/include/srslte/phy/phch/pucch_cfg_nr.h index b322a91f1..21c2ae206 100644 --- a/lib/include/srslte/phy/phch/pucch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/pucch_cfg_nr.h @@ -76,6 +76,16 @@ */ #define SRSLTE_PUCCH_NR_MAX_CODE_RATE 7 +/** + * Maximum number of NR-PUCCH resources per set (TS 38.331 maxNrofPUCCH-ResourcesPerSet) + */ +#define SRSLTE_PUCCH_NR_MAX_NOF_RESOURCES_PER_SET 32 + +/** + * Maximum number NR-PUCCH resource sets (TS 38.331 maxNrofPUCCH-ResourceSets) + */ +#define SRSLTE_PUCCH_NR_MAX_NOF_SETS 4 + typedef enum SRSLTE_API { SRSLTE_PUCCH_NR_FORMAT_0 = 0, SRSLTE_PUCCH_NR_FORMAT_1, @@ -135,6 +145,18 @@ typedef struct SRSLTE_API { bool additional_dmrs; ///< UE enables 2 DMRS symbols per hop of a PUCCH Format 3 or 4 } srslte_pucch_nr_resource_t; +typedef struct SRSLTE_API { + srslte_pucch_nr_resource_t resources[SRSLTE_PUCCH_NR_MAX_NOF_RESOURCES_PER_SET]; + uint32_t nof_resources; ///< Set to 0 if it is NOT provided by higher layers + uint32_t max_payload_size; ///< Maximum payload size, set to 0 if not present +} srslte_pucch_nr_resource_set_t; + +typedef struct SRSLTE_API { + srslte_pucch_nr_common_cfg_t common; ///< NR-PUCCH configuration common for all formats and resources + srslte_pucch_nr_resource_set_t sets[SRSLTE_PUCCH_NR_MAX_NOF_SETS]; ///< Resource sets, indexed by pucch-ResourceSetId + bool enabled; ///< Set to true if any set is enabled +} srslte_pucch_nr_hl_cfg_t; + /** * @brief Validates an NR-PUCCH resource configuration provided by upper layers * @param resource Resource configuration to validate diff --git a/lib/include/srslte/phy/phch/pucch_nr.h b/lib/include/srslte/phy/phch/pucch_nr.h index e809195fc..d02e6ef2f 100644 --- a/lib/include/srslte/phy/phch/pucch_nr.h +++ b/lib/include/srslte/phy/phch/pucch_nr.h @@ -102,7 +102,7 @@ SRSLTE_API int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t* */ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, uint32_t l, uint32_t l_prime, uint32_t m0, @@ -124,7 +124,7 @@ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* car SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, uint32_t m_cs, cf_t* slot_symbols); @@ -144,7 +144,7 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, uint32_t m_cs, const cf_t* slot_symbols, @@ -177,7 +177,7 @@ SRSLTE_API cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, uint8_t* b, uint32_t nof_bits, @@ -199,7 +199,7 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, srslte_chest_ul_res_t* chest_res, cf_t* slot_symbols, @@ -221,7 +221,7 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const srslte_uci_cfg_nr_t* uci_cfg, const srslte_uci_value_nr_t* uci_value, @@ -243,11 +243,16 @@ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* SRSLTE_API int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const srslte_uci_cfg_nr_t* uci_cfg, srslte_chest_ul_res_t* chest_res, cf_t* slot_symbols, srslte_uci_value_nr_t* uci_value); +SRSLTE_API uint32_t srslte_pucch_nr_tx_info(const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data, + char* str, + uint32_t str_len); + #endif // SRSLTE_PUCCH_NR_H diff --git a/lib/include/srslte/phy/phch/pusch_nr.h b/lib/include/srslte/phy/phch/pusch_nr.h index 2853295e9..d3103cdb6 100644 --- a/lib/include/srslte/phy/phch/pusch_nr.h +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -67,7 +67,7 @@ typedef struct { float evm; } srslte_pusch_res_nr_t; -SRSLTE_API int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); +SRSLTE_API int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); SRSLTE_API int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); diff --git a/lib/include/srslte/phy/phch/ra_dl_nr.h b/lib/include/srslte/phy/phch/ra_dl_nr.h index 3c7163232..3449513d5 100644 --- a/lib/include/srslte/phy/phch/ra_dl_nr.h +++ b/lib/include/srslte/phy/phch/ra_dl_nr.h @@ -42,16 +42,18 @@ * @remark Defined by TS 38.214 V15.10.0 section 5.1.2.1.1 Determination of the resource allocation table to be used for * PDSCH * - * @param pdsch_cfg Flattened PDSCH configuration provided from higher layers + * @param cfg Flattened PDSCH configuration provided from higher layers * @param rnti_type Type of the RNTI of the corresponding DCI * @param ss_type Type of the SS for PDCCH + * @param coreset_id CORESET identifier associated with the PDCCH transmission * @param m Time domain resource assignment field value m provided in DCI * @param[out] Provides grant pointer to fill * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code */ -SRSLTE_API int srslte_ra_dl_nr_time(const srslte_sch_cfg_nr_t* pdsch_cfg, +SRSLTE_API int srslte_ra_dl_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, const srslte_rnti_type_t rnti_type, const srslte_search_space_type_t ss_type, + const uint32_t coreset_id, const uint8_t m, srslte_sch_grant_nr_t* grant); @@ -74,12 +76,12 @@ srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_type * * @remark Defined by TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility * - * @param pdsch_cfg PDSCH NR configuration by upper layers + * @param cfg PDSCH-DMRS NR configuration by upper layers * @param[out] grant Provides grant pointer to fill * @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code */ -SRSLTE_API int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_sch_cfg_nr_t* pdsch_cfg, - srslte_sch_grant_nr_t* grant); +SRSLTE_API int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_dmrs_sch_cfg_t* cfg, + srslte_sch_grant_nr_t* grant); /** * @brief Calculates the PDSCH frequency resource allocation and stores it in the provided PDSCH NR grant. @@ -89,12 +91,11 @@ SRSLTE_API int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const * @param cfg PDSCH NR configuration by upper layers * @param dci_dl Unpacked DCI used to schedule the PDSCH grant * @param[out] grant Provides grant pointer to fill - * @return + * @return SRSLTE_SUCCESS if the provided data is valid, SRSLTE_ERROR code otherwise */ -SRSLTE_API int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier, - const srslte_sch_cfg_nr_t* cfg, - const srslte_dci_dl_nr_t* dci_dl, - srslte_sch_grant_nr_t* grant); - +SRSLTE_API int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_sch_grant_nr_t* grant); #endif // SRSLTE_RA_DL_NR_H diff --git a/lib/include/srslte/phy/phch/ra_nr.h b/lib/include/srslte/phy/phch/ra_nr.h index c6fc61c29..b06d1d3c0 100644 --- a/lib/include/srslte/phy/phch/ra_nr.h +++ b/lib/include/srslte/phy/phch/ra_nr.h @@ -104,9 +104,30 @@ SRSLTE_API int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg, * @param pdsch_grant Generated PDSCH grant * @return 0 on success, -1 on error */ -SRSLTE_API int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, - const srslte_sch_cfg_nr_t* pdsch_cfg, - const srslte_dci_dl_nr_t* dci_dl, - srslte_sch_grant_nr_t* pdsch_grant); +SRSLTE_API int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* pdsch_cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_sch_cfg_nr_t* cfg, + srslte_sch_grant_nr_t* pdsch_grant); + +/** + * @brief Converts an unpacked UL DCI message to a PUSCH grant structure. + * Implements the procedures defined in Section 6 of 38.214 to compute the resource allocation (6.1.2) + * and modulation order, target rate, redundancy version and TBS (6.1.4) + * + * Note: Only TypeA PUSCH mapping type is supported + * + * @param carrier Carrier information struct + * @param pusch_hl_cfg PUSCH configuration provided by higher layers + * @param dci_ul DCI uplink (format 0_0 or 0_1) + * @param pusch_cfg PUSCH configuration after applying the procedure + * @param pusch_grant Generated PUSCH grant + * @return 0 on success, -1 on error + */ +SRSLTE_API int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg, + const srslte_dci_ul_nr_t* dci_ul, + srslte_sch_cfg_nr_t* pusch_cfg, + srslte_sch_grant_nr_t* pusch_grant); #endif // SRSLTE_RA_NR_H diff --git a/lib/include/srslte/phy/phch/ra_ul_nr.h b/lib/include/srslte/phy/phch/ra_ul_nr.h index 2b1629c1f..52ceb7779 100644 --- a/lib/include/srslte/phy/phch/ra_ul_nr.h +++ b/lib/include/srslte/phy/phch/ra_ul_nr.h @@ -22,10 +22,69 @@ #ifndef SRSLTE_RA_UL_NR_H #define SRSLTE_RA_UL_NR_H +#include "dci_nr.h" #include "srslte/config.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #include "srslte/phy/phch/pucch_cfg_nr.h" #include "uci_cfg_nr.h" +/** + * @brief Calculates the PUSCH time resource allocation and stores it in the provided PUSCH NR grant. + * + * @remark Defined by TS 38.214 V15.10.0 section 6.1.2.1.1 Determination of the resource allocation table to be used for + * PUSCH + * + * @param cfg Flattened PUSCH configuration provided from higher layers + * @param rnti_type Type of the RNTI of the corresponding DCI + * @param ss_type Type of the SS for PDCCH + * @param coreset_id CORESET identifier associated with the PDCCH transmission + * @param m Time domain resource assignment field value m provided in DCI + * @param[out] Provides grant pointer to fill + * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_rnti_type_t rnti_type, + const srslte_search_space_type_t ss_type, + const uint32_t coreset_id, + const uint8_t m, + srslte_sch_grant_nr_t* grant); + +/** + * @brief Calculates the PUSCH time resource default A and stores it in the provided PUSCH NR grant. + * + * @remark Defined by TS 38.214 V15.10.0 Table 6.1.2.1.1-2: Default PUSCH time domain resource allocation A for normal + * CP + * + * @param scs_cfg Sub-carrier spacing configuration for PUSCH (μ) + * @param m Time domain resource assignment field value m of the DCI + * @param[out] grant PUSCH grant + * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int +srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant); + +/** + * @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0 + * + * @remark Defined by TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure + * + * @param cfg PUSCH NR configuration by upper layers + * @param[out] grant Provides grant pointer to fill + * @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg, + srslte_sch_grant_nr_t* grant); + +/** + * @brief Calculates the ratio of PUSCH EPRE to DM-RS EPRE + * + * @remark Defined by TS 38.214 V15.10.0 Table 6.2.2-1: The ratio of PUSCH EPRE to DM-RS EPRE + * + * @param[out] grant Provides grant pointer to fill + * @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int srslte_ra_ul_nr_dmrs_power_offset(srslte_sch_grant_nr_t* grant); + /** * @brief Calculates the minimum number of PRB required for transmitting NR-PUCCH Format 2, 3 or 4 * @remark Based in TS 38.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR in a PUCCH @@ -34,4 +93,30 @@ SRSLTE_API int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* resource, const srslte_uci_cfg_nr_t* uci_cfg); +/** + * @brief Calculates the PUSCH frequency resource allocation and stores it in the provided PUSCH NR grant. + * + * @remark Defined by TS 38.214 V15.10.0 section 5.1.2.2 + * @param carrier Carrier information + * @param cfg PDSCH NR configuration by upper layers + * @param dci_dl Unpacked DCI used to schedule the PDSCH grant + * @param[out] grant Provides grant pointer to fill + * @return SRSLTE_SUCCESS if the provided data is valid, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_ra_ul_nr_freq(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_dci_ul_nr_t* dci_ul, + srslte_sch_grant_nr_t* grant); + +/** + * @brief Selects a valid PUCCH resource for transmission + * @param pucch_cfg PUCCH configuration from upper layers + * @param uci_cfg Uplink Control information configuration (and PDCCH context) + * @param[out] resource Selected resource for transmitting PUCCH + * @return SRSLTE_SUCCESS if provided configuration is valid, SRSLTE_ERROR code otherwise + */ +SRSLTE_API int srslte_ra_ul_nr_pucch_resource(const srslte_pucch_nr_hl_cfg_t* pucch_cfg, + const srslte_uci_cfg_nr_t* uci_cfg, + srslte_pucch_nr_resource_t* resource); + #endif // SRSLTE_RA_UL_NR_H diff --git a/lib/include/srslte/phy/phch/uci_cfg_nr.h b/lib/include/srslte/phy/phch/uci_cfg_nr.h index bc137daaf..41d6b57ee 100644 --- a/lib/include/srslte/phy/phch/uci_cfg_nr.h +++ b/lib/include/srslte/phy/phch/uci_cfg_nr.h @@ -26,6 +26,12 @@ #include #include +/** + * @brief Maximum number of Uplink Control Bits + * @remark TS 38.212 section 5.2.1 Polar coding: The value of A is no larger than 1706. + */ +#define SRSLTE_UCI_NR_MAX_NOF_BITS 1706U + /** * @brief Maximum number of HARQ ACK feedback bits that can be carried in Uplink Control Information (UCI) message */ @@ -52,12 +58,20 @@ * @brief Uplink Control Information (UCI) message configuration */ typedef struct SRSLTE_API { - uint32_t o_ack; ///< Number of HARQ-ACK bits - uint32_t o_sr; ///< Number of SR bits - uint32_t o_csi1; ///< Number of CSI1 report number of bits - uint32_t o_csi2; ///< Number of CSI2 report number of bits - srslte_mod_t modulation; ///< Modulation (PUSCH only) - uint16_t rnti; ///< RNTI + /// Common Parameters + uint32_t o_ack; ///< Number of HARQ-ACK bits + uint32_t o_sr; ///< Number of SR bits + uint32_t o_csi1; ///< Number of CSI1 report number of bits + uint32_t o_csi2; ///< Number of CSI2 report number of bits + + /// PUSCH only parameters + srslte_mod_t modulation; ///< Modulation + + /// PUCCH only parameters + uint16_t rnti; ///< RNTI + uint32_t pucch_resource_id; ///< PUCCH resource indicator field in the DCI format 1_0 or DCI format 1_1 + uint32_t n_cce_0; ///< index of a first CCE for the PDCCH reception + uint32_t N_cce; ///< number of CCEs in a CORESET of a PDCCH reception with DCI format 1_0 or DCI format 1_1 } srslte_uci_cfg_nr_t; /** @@ -71,4 +85,12 @@ typedef struct SRSLTE_API { bool valid; ///< Indicates whether the message has been decoded successfully, ignored in the transmitter } srslte_uci_value_nr_t; +/** + * @brief Uplink Control Information (UCI) data (configuration + values) + */ +typedef struct SRSLTE_API { + srslte_uci_cfg_nr_t cfg; + srslte_uci_value_nr_t value; +} srslte_uci_data_nr_t; + #endif // SRSLTE_UCI_CFG_NR_H diff --git a/lib/include/srslte/phy/phch/uci_nr.h b/lib/include/srslte/phy/phch/uci_nr.h index b3ccdbe7f..399391ebd 100644 --- a/lib/include/srslte/phy/phch/uci_nr.h +++ b/lib/include/srslte/phy/phch/uci_nr.h @@ -123,4 +123,20 @@ SRSLTE_API int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, int8_t* llr, srslte_uci_value_nr_t* value); +/** + * @brief Calculates the total number of UCI bits + * @param uci_cfg UCI configuration + * @return The number of total bits carrying HARQ ACK, CSI reports and SR bits + */ +SRSLTE_API uint32_t srslte_uci_nr_total_bits(const srslte_uci_cfg_nr_t* uci_cfg); + +/** + * @brief Converts to string an UCI data structure + * @param uci_data UCO data structure + * @param str Destination string + * @param str_len String length + * @return Resultant string length + */ +SRSLTE_API uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uint32_t str_len); + #endif // SRSLTE_UCI_NR_H diff --git a/lib/include/srslte/phy/ue/ue_dl_nr.h b/lib/include/srslte/phy/ue/ue_dl_nr.h index 16d2bd090..6fc90e479 100644 --- a/lib/include/srslte/phy/ue/ue_dl_nr.h +++ b/lib/include/srslte/phy/ue/ue_dl_nr.h @@ -28,6 +28,24 @@ #include "srslte/phy/phch/dci_nr.h" #include "srslte/phy/phch/pdcch_nr.h" #include "srslte/phy/phch/pdsch_nr.h" +#include "srslte/phy/phch/uci_cfg_nr.h" + +/** + * Maximum number of CORESET + * @remark Defined in TS 38.331 by maxNrofControlResourceSets-1 + */ +#define SRSLTE_UE_DL_NR_MAX_NOF_CORESET 12 + +/** + * Maximum number of Search spaces + * @remark Defined in TS 38.331 by maxNrofSearchSpaces-1 + */ +#define SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE 40 + +/** + * Maximum number of DCI messages to receive + */ +#define SRSLTE_MAX_DCI_MSG_NR 4 typedef struct SRSLTE_API { srslte_pdsch_nr_args_t pdsch; @@ -35,16 +53,72 @@ typedef struct SRSLTE_API { uint32_t nof_rx_antennas; uint32_t nof_max_prb; float pdcch_dmrs_corr_thr; + float pdcch_dmrs_epre_thr; } srslte_ue_dl_nr_args_t; +typedef struct SRSLTE_API { + srslte_coreset_t coreset[SRSLTE_UE_DL_NR_MAX_NOF_CORESET]; ///< PDCCH Control resource sets (CORESET) collection + bool coreset_present[SRSLTE_UE_DL_NR_MAX_NOF_CORESET]; ///< CORESET present flags + + srslte_search_space_t search_space[SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE]; + bool search_space_present[SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE]; + + uint16_t ra_rnti; ///< Needs to be deduced from the PRACH configuration + srslte_search_space_t ra_search_space; + bool ra_search_space_present; +} srslte_ue_dl_nr_pdcch_cfg_t; + +typedef struct { + uint32_t scell_idx; ///< Serving cell index + uint32_t v_dai_dl; ///< Downlink Assigment Index + bool dci_format_1_1; ///< Set to true if the PDSCH transmission is triggered by a PDCCH DCI format 1_1 transmission + uint32_t k1; ///< HARQ feedback timing + uint16_t rnti; + uint32_t pucch_resource_id; +} srslte_pdsch_ack_resource_nr_t; + +typedef struct { + srslte_pdsch_ack_resource_nr_t resource; + uint8_t value[SRSLTE_MAX_CODEWORDS]; // 0/1 or 2 for DTX + bool present; // set to true if there is a PDSCH on serving cell c associated with PDCCH in PDCCH monitoring occasion + // m, or there is a PDCCH indicating SPS PDSCH release on serving cell c + bool dl_bwp_changed; // set to true if PDCCH monitoring occasion m is before an active DL BWP change on serving cell c + bool ul_bwp_changed; // set to true if an active UL BWP change on the PCell and an active DL BWP change is not + // triggered by a DCI format 1_1 in PDCCH monitoring occasion m + bool second_tb_present; // set to true if two TB were detected in the PDCCH monitoring occasion m +} srslte_pdsch_ack_m_nr_t; + +#define SRSLTE_UCI_NR_MAX_M 10 + +typedef struct { + uint32_t M; + srslte_pdsch_ack_m_nr_t m[SRSLTE_UCI_NR_MAX_M]; +} srslte_pdsch_ack_cc_nr_t; + +typedef struct { + srslte_pdsch_ack_cc_nr_t cc[SRSLTE_MAX_CARRIERS]; + uint32_t nof_cc; + bool use_pusch; // Set to true, if UCI bits are carried by PUSCH +} srslte_pdsch_ack_nr_t; + +typedef struct SRSLTE_API { + bool harq_ack_spatial_bundling_pucch; ///< Param harq-ACK-SpatialBundlingPUCCH, set to true if provided + bool harq_ack_spatial_bundling_pusch; ///< Param harq-ACK-SpatialBundlingPUSCH, set to true if provided + srslte_pdsch_harq_ack_codebook_t pdsch_harq_ack_codebook; ///< pdsch-HARQ-ACK-Codebook configuration + bool max_cw_sched_dci_is_2; ///< Param maxNrofCodeWordsScheduledByDCI, set to true if present and equal to 2 + + uint32_t dl_data_to_ul_ack[SRSLTE_MAX_NOF_DL_DATA_TO_UL]; + uint32_t nof_dl_data_to_ul_ack; +} srslte_ue_dl_nr_harq_ack_cfg_t; + typedef struct SRSLTE_API { uint32_t max_prb; uint32_t nof_rx_antennas; float pdcch_dmrs_corr_thr; float pdcch_dmrs_epre_thr; - srslte_carrier_nr_t carrier; - srslte_coreset_t coreset; + srslte_carrier_nr_t carrier; + srslte_ue_dl_nr_pdcch_cfg_t cfg; srslte_ofdm_t fft[SRSLTE_MAX_PORTS]; @@ -53,9 +127,12 @@ typedef struct SRSLTE_API { srslte_pdsch_nr_t pdsch; srslte_dmrs_sch_t dmrs_pdsch; - srslte_dmrs_pdcch_estimator_t dmrs_pdcch; + srslte_dmrs_pdcch_estimator_t dmrs_pdcch[SRSLTE_UE_DL_NR_MAX_NOF_CORESET]; srslte_pdcch_nr_t pdcch; srslte_dmrs_pdcch_ce_t* pdcch_ce; + + srslte_dci_msg_nr_t pending_ul_dci_msg[SRSLTE_MAX_DCI_MSG_NR]; + uint32_t pending_ul_dci_count; } srslte_ue_dl_nr_t; SRSLTE_API int @@ -63,29 +140,43 @@ srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], const SRSLTE_API int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* carrier); -SRSLTE_API int srslte_ue_dl_nr_set_coreset(srslte_ue_dl_nr_t* q, const srslte_coreset_t* coreset); +SRSLTE_API int srslte_ue_dl_nr_set_pdcch_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_pdcch_cfg_t* cfg); SRSLTE_API void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q); -SRSLTE_API void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg_t* slot_cfg); +SRSLTE_API void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_slot_cfg_t* slot_cfg); -SRSLTE_API int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, - const srslte_search_space_t* search_space, - const srslte_dl_slot_cfg_t* slot_cfg, - uint16_t rnti, - srslte_dci_dl_nr_t* dci_dl_list, - uint32_t nof_dci_msg); +SRSLTE_API int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + uint16_t rnti, + srslte_rnti_type_t rnti_type, + srslte_dci_dl_nr_t* dci_dl_list, + uint32_t nof_dci_msg); -SRSLTE_API int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_sch_cfg_nr_t* cfg, - srslte_pdsch_res_nr_t* res); +SRSLTE_API int srslte_ue_dl_nr_find_ul_dci(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + uint16_t rnti, + srslte_rnti_type_t rnti_type, + srslte_dci_ul_nr_t* dci_ul_list, + uint32_t nof_dci_msg); -SRSLTE_API int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, - const srslte_sch_cfg_nr_t* cfg, - const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], - char* str, - uint32_t str_len); +SRSLTE_API int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + srslte_pdsch_res_nr_t* res); +SRSLTE_API int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], + char* str, + uint32_t str_len); + +SRSLTE_API int srslte_ue_dl_nr_pdsch_ack_resource(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_pdsch_ack_resource_nr_t* pdsch_ack_resource); + +SRSLTE_API int srslte_ue_dl_nr_gen_ack(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, + const srslte_pdsch_ack_nr_t* ack_info, + srslte_uci_data_nr_t* uci_data); #endif // SRSLTE_UE_DL_NR_H diff --git a/lib/include/srslte/phy/ue/ue_ul_nr.h b/lib/include/srslte/phy/ue/ue_ul_nr.h new file mode 100644 index 000000000..d5f592ed5 --- /dev/null +++ b/lib/include/srslte/phy/ue/ue_ul_nr.h @@ -0,0 +1,78 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ue_dl_nr.h + * + * Description: NR UE uplink physical layer procedures for data + * + * This module is a frontend to all the uplink data channel processing modules. + * + * Reference: + *****************************************************************************/ + +#ifndef SRSLTE_UE_UL_DATA_H +#define SRSLTE_UE_UL_DATA_H + +#include "srslte/phy/ch_estimation/dmrs_sch.h" +#include "srslte/phy/common/phy_common_nr.h" +#include "srslte/phy/dft/ofdm.h" +#include "srslte/phy/phch/phch_cfg_nr.h" +#include "srslte/phy/phch/pucch_cfg_nr.h" +#include "srslte/phy/phch/pucch_nr.h" +#include "srslte/phy/phch/pusch_nr.h" + +typedef struct SRSLTE_API { + srslte_pusch_nr_args_t pusch; + srslte_pucch_nr_args_t pucch; + uint32_t nof_max_prb; +} srslte_ue_ul_nr_args_t; + +typedef struct SRSLTE_API { + uint32_t max_prb; + + srslte_carrier_nr_t carrier; + + srslte_ofdm_t ifft; + + cf_t* sf_symbols[SRSLTE_MAX_PORTS]; + srslte_pusch_nr_t pusch; + srslte_pucch_nr_t pucch; + srslte_dmrs_sch_t dmrs; +} srslte_ue_ul_nr_t; + +SRSLTE_API int srslte_ue_ul_nr_init(srslte_ue_ul_nr_t* q, cf_t* output, const srslte_ue_ul_nr_args_t* args); + +SRSLTE_API int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* carrier); + +SRSLTE_API int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pusch_cfg, + uint8_t* data_); + +SRSLTE_API int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_pucch_nr_common_cfg_t* cfg, + const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data); + +SRSLTE_API void srslte_ue_ul_nr_free(srslte_ue_ul_nr_t* q); + +SRSLTE_API int +srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len); + +SRSLTE_API int srslte_ue_ul_nr_pucch_info(const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data, + char* str, + uint32_t str_len); + +#endif // SRSLTE_UE_UL_DATA_H diff --git a/lib/include/srslte/phy/ue/ue_ul_nr_data.h b/lib/include/srslte/phy/ue/ue_ul_nr_data.h deleted file mode 100644 index 774854492..000000000 --- a/lib/include/srslte/phy/ue/ue_ul_nr_data.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * @file ue_dl_nr.h - * - * Description: NR UE uplink physical layer procedures for data - * - * This module is a frontend to all the uplink data channel processing modules. - * - * Reference: - *****************************************************************************/ - -#ifndef SRSLTE_UE_UL_DATA_H -#define SRSLTE_UE_UL_DATA_H - -#include "srslte/phy/common/phy_common_nr.h" -#include "srslte/phy/phch/phch_cfg_nr.h" - -/** - * @brief Calculates the PUSCH time resource default A and stores it in the provided PUSCH NR grant. - * - * @remark Defined by TS 38.214 V15.10.0 Table 6.1.2.1.1-2: Default PUSCH time domain resource allocation A for normal - * CP - * - * @param m Time domain resource assignment field value m of the DCI - * @param[out] grant PUSCH grant - * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code - */ -SRSLTE_API int srslte_ue_ul_nr_pdsch_time_resource_default_A(uint32_t m, srslte_sch_grant_nr_t* grant); - -/** - * @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0 - * - * @remark Defined by TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure - * - * @param cfg PUSCH NR configuration by upper layers - * @param[out] grant Provides grant pointer to fill - * @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code - */ -SRSLTE_API int srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg, - srslte_sch_grant_nr_t* grant); - - -#endif // SRSLTE_UE_UL_DATA_H diff --git a/lib/include/srslte/phy/utils/debug.h b/lib/include/srslte/phy/utils/debug.h index 7a7f26600..6ae76fbdc 100644 --- a/lib/include/srslte/phy/utils/debug.h +++ b/lib/include/srslte/phy/utils/debug.h @@ -57,7 +57,7 @@ SRSLTE_API extern int handler_registered; #define DEBUG(_fmt, ...) \ do { \ if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { \ - fprintf(stdout, "[DEBUG]: " _fmt, ##__VA_ARGS__); \ + fprintf(stdout, "[DEBUG]: " _fmt "\n", ##__VA_ARGS__); \ } else { \ srslte_phy_log_print(LOG_LEVEL_DEBUG_S, _fmt, ##__VA_ARGS__); \ } \ @@ -66,7 +66,7 @@ SRSLTE_API extern int handler_registered; #define INFO(_fmt, ...) \ do { \ if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { \ - fprintf(stdout, "[INFO]: " _fmt, ##__VA_ARGS__); \ + fprintf(stdout, "[INFO]: " _fmt "\n", ##__VA_ARGS__); \ } else { \ srslte_phy_log_print(LOG_LEVEL_INFO_S, _fmt, ##__VA_ARGS__); \ } \ diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index 874e72486..97a308e4b 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -130,6 +130,7 @@ SRSLTE_API void srslte_vec_fprint_i(FILE* stream, const int* x, const uint32_t l SRSLTE_API void srslte_vec_fprint_s(FILE* stream, const int16_t* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_hex(FILE* stream, uint8_t* x, const uint32_t len); SRSLTE_API void srslte_vec_sprint_hex(char* str, const uint32_t max_str_len, uint8_t* x, const uint32_t len); +SRSLTE_API void srslte_vec_sprint_bin(char* str, const uint32_t max_str_len, const uint8_t* x, const uint32_t len); /* Saves/loads a vector to a file */ SRSLTE_API void srslte_vec_save_file(char* filename, const void* buffer, const uint32_t len); diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 54aed5e95..9888ba6e1 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -52,8 +52,7 @@ namespace srslte { class radio : public radio_interface_phy, public srslte::radio_base { public: - radio(srslte::log_filter* log_h); - radio(srslte::logger* logger_h); + radio(); ~radio(); int init(const rf_args_t& args_, phy_interface_radio* phy_) final; @@ -99,9 +98,7 @@ private: std::vector rf_info = {}; std::vector rx_offset_n = {}; rf_metrics_t rf_metrics = {}; - log_filter log_local = {}; - log_filter* log_h = nullptr; - srslte::logger* logger = nullptr; + srslog::basic_logger& logger = srslog::fetch_basic_logger("RF", false); phy_interface_radio* phy = nullptr; cf_t* zeros = nullptr; std::array dummy_buffers; @@ -133,6 +130,8 @@ private: std::vector cur_tx_freqs = {}; std::vector cur_rx_freqs = {}; + constexpr static const uint32_t max_resamp_buf_sz_ms = 5; ///< Maximum buffer size in ms for intermediate resampling + ///< buffers constexpr static double tx_max_gap_zeros = 4e-3; ///< Maximum transmission gap to fill with zeros, otherwise the burst ///< shall be stopped diff --git a/lib/include/srslte/radio/radio_base.h b/lib/include/srslte/radio/radio_base.h index f5f3621b2..216367855 100644 --- a/lib/include/srslte/radio/radio_base.h +++ b/lib/include/srslte/radio/radio_base.h @@ -38,7 +38,6 @@ class phy_interface_radio; class radio_base { public: - radio_base(srslte::logger* logger_ = nullptr) {} virtual ~radio_base() = default; virtual std::string get_type() = 0; diff --git a/lib/include/srslte/radio/radio_null.h b/lib/include/srslte/radio/radio_null.h index 45bae50f7..d651c1fb4 100644 --- a/lib/include/srslte/radio/radio_null.h +++ b/lib/include/srslte/radio/radio_null.h @@ -40,14 +40,13 @@ namespace srslte { class radio_null final : public radio_base, public radio_interface_phy { public: - explicit radio_null(srslte::logger* logger_); ~radio_null() final = default; std::string get_type() override { return "null"; } int init(const rf_args_t& args_, phy_interface_radio* phy_) override { - log->set_level(args.log_level); + logger.set_level(srslog::str_to_basic_level(args.log_level)); running = true; return SRSLTE_SUCCESS; @@ -67,61 +66,61 @@ public: bool is_continuous_tx() override { return false; } bool tx(rf_buffer_interface& buffer, const rf_timestamp_interface& tx_time) override { - log->info("%s\n", __PRETTY_FUNCTION__); + logger.info("%s", __PRETTY_FUNCTION__); return true; } - void tx_end() override { log->info("%s\n", __PRETTY_FUNCTION__); } + void tx_end() override { logger.info("%s", __PRETTY_FUNCTION__); } bool rx_now(rf_buffer_interface& buffer, rf_timestamp_interface& rxd_time) override { - log->info("%s\n", __PRETTY_FUNCTION__); + logger.info("%s", __PRETTY_FUNCTION__); return true; } - void set_rx_gain(const float& gain) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_rx_gain(const float& gain) override { logger.info("%s", __PRETTY_FUNCTION__); } - void set_rx_gain_th(const float& gain) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_rx_gain_th(const float& gain) override { logger.info("%s", __PRETTY_FUNCTION__); } float get_rx_gain() override { - log->info("%s\n", __PRETTY_FUNCTION__); + logger.info("%s", __PRETTY_FUNCTION__); return 0.0; } - void set_tx_gain(const float& gain) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_tx_gain(const float& gain) override { logger.info("%s", __PRETTY_FUNCTION__); } - void set_tx_freq(const uint32_t& channel_idx, const double& freq) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_tx_freq(const uint32_t& channel_idx, const double& freq) override { logger.info("%s", __PRETTY_FUNCTION__); } - void set_rx_freq(const uint32_t& channel_idx, const double& freq) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_rx_freq(const uint32_t& channel_idx, const double& freq) override { logger.info("%s", __PRETTY_FUNCTION__); } double get_freq_offset() override { - log->info("%s\n", __PRETTY_FUNCTION__); + logger.info("%s", __PRETTY_FUNCTION__); return 0.0; } - void set_tx_srate(const double& srate) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_tx_srate(const double& srate) override { logger.info("%s", __PRETTY_FUNCTION__); } - void set_rx_srate(const double& srate) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_rx_srate(const double& srate) override { logger.info("%s", __PRETTY_FUNCTION__); } - void set_channel_rx_offset(uint32_t ch, int32_t offset_samples) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void set_channel_rx_offset(uint32_t ch, int32_t offset_samples) override { logger.info("%s", __PRETTY_FUNCTION__); } srslte_rf_info_t* get_info() override { - log->info("%s\n", __PRETTY_FUNCTION__); + logger.info("%s", __PRETTY_FUNCTION__); return nullptr; } bool get_is_start_of_burst() override { return true; } - void release_freq(const uint32_t& carrier_idx) override { log->info("%s\n", __PRETTY_FUNCTION__); } + void release_freq(const uint32_t& carrier_idx) override { logger.info("%s", __PRETTY_FUNCTION__); } protected: rf_args_t args = {}; - srslte::log_ref log; - bool running = false; + srslog::basic_logger& logger = srslog::fetch_basic_logger("RF", false); + bool running = false; srslte::rf_metrics_t rf_metrics = {}; phy_interface_radio* phy = nullptr; diff --git a/lib/include/srslte/srslog/detail/log_backend.h b/lib/include/srslte/srslog/detail/log_backend.h index bf41f546a..37ac718ea 100644 --- a/lib/include/srslte/srslog/detail/log_backend.h +++ b/lib/include/srslte/srslog/detail/log_backend.h @@ -40,8 +40,9 @@ public: /// NOTE: Calling this function more than once has no side effects. virtual void start() = 0; - /// Pushes a log entry into the backend. - virtual void push(log_entry&& entry) = 0; + /// Pushes a log entry into the backend. Returns true on success, otherwise + /// false. + virtual bool push(log_entry&& entry) = 0; /// Returns true when the backend has been started, otherwise false. virtual bool is_running() const = 0; diff --git a/lib/include/srslte/srslog/detail/support/work_queue.h b/lib/include/srslte/srslog/detail/support/work_queue.h index 6451d4ee2..62fc8a100 100644 --- a/lib/include/srslte/srslog/detail/support/work_queue.h +++ b/lib/include/srslte/srslog/detail/support/work_queue.h @@ -49,32 +49,38 @@ public: work_queue(const work_queue&) = delete; work_queue& operator=(const work_queue&) = delete; - /// Inserts a new element into the back of the queue. - void push(const T& value) + /// Inserts a new element into the back of the queue. Returns false when the + /// queue is full, otherwise true. + bool push(const T& value) { cond_var.lock(); // Discard the new element if we reach the maximum capacity. if (queue.size() > capacity) { cond_var.unlock(); - return; + return false; } queue.push(value); cond_var.signal(); cond_var.unlock(); + + return true; } - /// Inserts a new element into the back of the queue. - void push(T&& value) + /// Inserts a new element into the back of the queue. Returns false when the + /// queue is full, otherwise true. + bool push(T&& value) { cond_var.lock(); // Discard the new element if we reach the maximum capacity. if (queue.size() > capacity) { cond_var.unlock(); - return; + return false; } queue.push(std::move(value)); cond_var.signal(); cond_var.unlock(); + + return true; } /// Extracts the top most element from the queue. diff --git a/lib/include/srslte/srslog/logger.h b/lib/include/srslte/srslog/logger.h index 0081c3fec..52985eb29 100644 --- a/lib/include/srslte/srslog/logger.h +++ b/lib/include/srslte/srslog/logger.h @@ -38,14 +38,12 @@ class logger_impl : public T static_assert(std::is_enum::value, "Expected enum type"); using enum_base_type = typename std::underlying_type::type; - static constexpr unsigned size = static_cast(Enum::LAST); + static constexpr unsigned size = static_cast(Enum::LAST) - 1; public: template explicit logger_impl(std::string id, Args&&... args) : - T{std::forward(args)...}, - logger_id(std::move(id)), - channels{&args...} + T{std::forward(args)...}, logger_id(std::move(id)), channels{&args...} { static_assert( sizeof...(args) == size, @@ -62,8 +60,18 @@ public: void set_level(Enum lvl) { detail::scoped_lock lock(m); + + // Disable all channels ... + if (lvl == Enum::none) { + for (unsigned i = 0, e = channels.size(); i != e; ++i) { + channels[i]->set_enabled(false); + } + return; + } + + // ... otherwise do it selectively. for (unsigned i = 0, e = channels.size(); i != e; ++i) { - channels[i]->set_enabled(static_cast(i) <= lvl); + channels[i]->set_enabled(static_cast(i + 1) <= lvl); } } @@ -112,8 +120,9 @@ struct is_logger> : std::true_type {}; /// /// To create a new logger type simply follow these steps: /// 1) Define an enum class where each element will represent a logging level. -/// Order the elements from highest to lowest logging level. The last -/// element should be called LAST as it is a sentinel value. +/// Order the elements from highest to lowest logging level. First element +/// should be "none", which represents a disabled logger. +/// The last element should be called LAST as it is a sentinel value. /// 2) Define a struct composed by only log_channel references. Declare the /// members in the same order as done in the enum. /// 3) Define the new logger type by using the build_logger_type alias. Pass @@ -122,7 +131,8 @@ struct is_logger> : std::true_type {}; /// Example to declare a logger with three logging levels: error, warning and /// info, being error the highest logging level and info the lowest: /// 1) Define the logging level enum: -/// enum class three_level_logger_levels { error, warning, info, LAST }; +/// enum class three_level_logger_levels { none, error, warning, info, LAST +/// }; /// 2) Define the struct of three channels (same order as in the enum): /// struct three_level_logger { /// log_channel &error; @@ -140,7 +150,7 @@ using build_logger_type = detail::logger_impl; /// /// Basic logger with four levels. -enum class basic_levels { error, warning, info, debug, LAST }; +enum class basic_levels { none, error, warning, info, debug, LAST }; struct basic_logger_channels { log_channel& error; log_channel& warning; @@ -149,6 +159,29 @@ struct basic_logger_channels { }; using basic_logger = build_logger_type; +/// Translates a string to the corresponding logger basic level. +inline basic_levels str_to_basic_level(std::string s) +{ + std::transform(s.begin(), s.end(), s.begin(), ::toupper); + + if ("NONE" == s) { + return basic_levels::none; + } + if ("ERROR" == s) { + return basic_levels::error; + } + if ("WARNING" == s) { + return basic_levels::warning; + } + if ("INFO" == s) { + return basic_levels::info; + } + if ("DEBUG" == s) { + return basic_levels::debug; + } + return basic_levels::none; +} + } // namespace srslog #endif // SRSLOG_LOGGER_H diff --git a/lib/include/srslte/srslog/srslog_c.h b/lib/include/srslte/srslog/srslog_c.h index 14b98716f..211f46ae7 100644 --- a/lib/include/srslte/srslog/srslog_c.h +++ b/lib/include/srslte/srslog/srslog_c.h @@ -125,6 +125,7 @@ void srslog_error(srslog_logger* log, const char* fmt, ...); const char* srslog_get_logger_id(srslog_logger* log); typedef enum { + srslog_lvl_none, /**< disable logger */ srslog_lvl_error, /**< error logging level */ srslog_lvl_warning, /**< warning logging level */ srslog_lvl_info, /**< info logging level */ diff --git a/lib/include/srslte/srslte.h b/lib/include/srslte/srslte.h index db3781b1c..f7374d492 100644 --- a/lib/include/srslte/srslte.h +++ b/lib/include/srslte/srslte.h @@ -107,9 +107,11 @@ extern "C" { #include "srslte/phy/phch/ra_dl_nr.h" #include "srslte/phy/phch/ra_nr.h" #include "srslte/phy/phch/ra_ul.h" +#include "srslte/phy/phch/ra_ul_nr.h" #include "srslte/phy/phch/regs.h" #include "srslte/phy/phch/sch.h" #include "srslte/phy/phch/uci.h" +#include "srslte/phy/phch/uci_nr.h" #include "srslte/phy/ue/ue_cell_search.h" #include "srslte/phy/ue/ue_dl.h" @@ -117,6 +119,7 @@ extern "C" { #include "srslte/phy/ue/ue_mib.h" #include "srslte/phy/ue/ue_sync.h" #include "srslte/phy/ue/ue_ul.h" +#include "srslte/phy/ue/ue_ul_nr.h" #include "srslte/phy/enb/enb_dl.h" #include "srslte/phy/enb/enb_dl_nr.h" diff --git a/lib/include/srslte/upper/gtpu.h b/lib/include/srslte/upper/gtpu.h index 8f7846d35..4ce56703c 100644 --- a/lib/include/srslte/upper/gtpu.h +++ b/lib/include/srslte/upper/gtpu.h @@ -66,49 +66,48 @@ namespace srslte { #define GTPU_MSG_END_MARKER 254 #define GTPU_MSG_DATA_PDU 255 -typedef struct { - uint8_t flags; - uint8_t message_type; - uint16_t length; - uint32_t teid; - uint16_t seq_number; - uint8_t n_pdu; - uint8_t next_ext_hdr_type; -} gtpu_header_t; +#define GTPU_EXT_HEADER_PDCP_PDU_NUMBER 0b11000000 -bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslte::log_ref gtpu_log); -bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslte::log_ref gtpu_log); +struct gtpu_header_t { + uint8_t flags = 0; + uint8_t message_type = 0; + uint16_t length = 0; + uint32_t teid = 0; + uint16_t seq_number = 0; + uint8_t n_pdu = 0; + uint8_t next_ext_hdr_type = 0; + std::vector ext_buffer; +}; + +bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslog::basic_logger& logger); +bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslog::basic_logger& logger); std::string gtpu_ntoa(uint32_t addr); -inline bool gtpu_supported_flags_check(gtpu_header_t* header, srslte::log_ref gtpu_log) +inline bool gtpu_supported_flags_check(gtpu_header_t* header, srslog::basic_logger& logger) { // flags if ((header->flags & GTPU_FLAGS_VERSION_MASK) != GTPU_FLAGS_VERSION_V1) { - gtpu_log->error("gtpu_header - Unhandled GTP-U Version. Flags: 0x%x\n", header->flags); + logger.error("gtpu_header - Unhandled GTP-U Version. Flags: 0x%x", header->flags); return false; } if (!(header->flags & GTPU_FLAGS_GTP_PROTOCOL)) { - gtpu_log->error("gtpu_header - Unhandled Protocol Type. Flags: 0x%x\n\n", header->flags); - return false; - } - if (header->flags & GTPU_FLAGS_EXTENDED_HDR) { - gtpu_log->error("gtpu_header - Unhandled Header Extensions. Flags: 0x%x\n\n", header->flags); + logger.error("gtpu_header - Unhandled Protocol Type. Flags: 0x%x", header->flags); return false; } if (header->flags & GTPU_FLAGS_PACKET_NUM) { - gtpu_log->error("gtpu_header - Unhandled Packet Number. Flags: 0x%x\n\n", header->flags); + logger.error("gtpu_header - Unhandled Packet Number. Flags: 0x%x", header->flags); return false; } return true; } -inline bool gtpu_supported_msg_type_check(gtpu_header_t* header, srslte::log_ref gtpu_log) +inline bool gtpu_supported_msg_type_check(gtpu_header_t* header, srslog::basic_logger& logger) { // msg_tpye if (header->message_type != GTPU_MSG_DATA_PDU && header->message_type != GTPU_MSG_ECHO_REQUEST && header->message_type != GTPU_MSG_ECHO_RESPONSE && header->message_type != GTPU_MSG_ERROR_INDICATION && header->message_type != GTPU_MSG_END_MARKER) { - gtpu_log->error("gtpu_header - Unhandled message type: 0x%x\n", header->message_type); + logger.error("gtpu_header - Unhandled message type: 0x%x", header->message_type); return false; } return true; diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 72fe4aaa2..2b834b1b9 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -45,7 +45,7 @@ public: void reestablish() override; void reestablish(uint32_t lcid) override; void reset() override; - void write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) override; + void write_sdu(uint32_t lcid, unique_byte_buffer_t sdu, int sn = -1) override; void write_sdu_mch(uint32_t lcid, unique_byte_buffer_t sdu); void add_bearer(uint32_t lcid, pdcp_config_t cnfg) override; void add_bearer_mrb(uint32_t lcid, pdcp_config_t cnfg); @@ -58,6 +58,8 @@ public: void enable_security_timed(uint32_t lcid, srslte_direction_t direction, uint32_t sn); bool get_bearer_state(uint32_t lcid, srslte::pdcp_lte_state_t* state); bool set_bearer_state(uint32_t lcid, const srslte::pdcp_lte_state_t& state); + void send_status_report() override; + void send_status_report(uint32_t lcid) override; // RLC interface void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) override; @@ -65,15 +67,25 @@ public: void write_pdu_bcch_bch(unique_byte_buffer_t sdu) override; void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) override; void write_pdu_pcch(unique_byte_buffer_t sdu) override; + void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn) override; + void notify_failure(uint32_t lcid, const std::vector& pdcp_sn) override; + + // eNB-only methods + std::map get_buffered_pdus(uint32_t lcid); + + // Metrics + void get_metrics(pdcp_metrics_t& m, const uint32_t nof_tti); + void reset_metrics(); private: srsue::rlc_interface_pdcp* rlc = nullptr; srsue::rrc_interface_pdcp* rrc = nullptr; srsue::gw_interface_pdcp* gw = nullptr; srslte::task_sched_handle task_sched; - srslte::log_ref pdcp_log; + srslog::basic_logger& logger; - std::map > pdcp_array, pdcp_array_mrb; + using pdcp_map_t = std::map >; + pdcp_map_t pdcp_array, pdcp_array_mrb; // cache valid lcids to be checked from separate thread std::mutex cache_mutex; @@ -81,6 +93,9 @@ private: bool valid_lcid(uint32_t lcid); bool valid_mch_lcid(uint32_t lcid); + + // Timer needed for metrics calculation + std::chrono::high_resolution_clock::time_point metrics_tp; }; } // namespace srslte diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index 07cba880a..b60b01252 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_PDCP_ENTITY_BASE_H #define SRSLTE_PDCP_ENTITY_BASE_H +#include "srslte/adt/accumulators.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/interfaces_common.h" @@ -32,6 +33,7 @@ #include "srslte/common/timers.h" #include "srslte/interfaces/pdcp_interface_types.h" #include "srslte/upper/byte_buffer_queue.h" +#include "srslte/upper/pdcp_metrics.h" namespace srslte { @@ -61,7 +63,7 @@ static const char pdcp_d_c_text[PDCP_D_C_N_ITEMS][20] = {"Control PDU", "Data PD class pdcp_entity_base { public: - pdcp_entity_base(task_sched_handle task_sched_, srslte::log_ref log_); + pdcp_entity_base(task_sched_handle task_sched_, srslog::basic_logger& logger); pdcp_entity_base(pdcp_entity_base&&) = default; virtual ~pdcp_entity_base(); virtual void reset() = 0; @@ -82,7 +84,7 @@ public: } else { integrity_direction = direction; } - log->debug("LCID=%d, integrity=%s\n", lcid, srslte_direction_text[integrity_direction]); + logger.debug("LCID=%d, integrity=%s", lcid, srslte_direction_text[integrity_direction]); } void enable_encryption(srslte_direction_t direction = DIRECTION_TXRX) @@ -95,7 +97,7 @@ public: } else { encryption_direction = direction; } - log->debug("LCID=%d encryption=%s\n", lcid, srslte_direction_text[integrity_direction]); + logger.debug("LCID=%d encryption=%s", lcid, srslte_direction_text[integrity_direction]); } void enable_security_timed(srslte_direction_t direction, uint32_t sn) @@ -108,7 +110,7 @@ public: enable_security_rx_sn = sn; break; default: - log->error("Timed security activation for direction %s not supported.\n", srslte_direction_text[direction]); + logger.error("Timed security activation for direction %s not supported.", srslte_direction_text[direction]); break; } } @@ -116,21 +118,31 @@ public: void config_security(as_security_config_t sec_cfg_); // GW/SDAP/RRC interface - virtual void write_sdu(unique_byte_buffer_t sdu) = 0; + virtual void write_sdu(unique_byte_buffer_t sdu, int sn = -1) = 0; // RLC interface - virtual void write_pdu(unique_byte_buffer_t pdu) = 0; + virtual void write_pdu(unique_byte_buffer_t pdu) = 0; + virtual void notify_delivery(const std::vector& pdcp_sns) = 0; + virtual void notify_failure(const std::vector& pdcp_sns) = 0; virtual void get_bearer_state(pdcp_lte_state_t* state) = 0; virtual void set_bearer_state(const pdcp_lte_state_t& state) = 0; + virtual std::map get_buffered_pdus() = 0; + + virtual void send_status_report() = 0; + // COUNT, HFN and SN helpers uint32_t HFN(uint32_t count); uint32_t SN(uint32_t count); uint32_t COUNT(uint32_t hfn, uint32_t sn); + // Metrics helpers + virtual pdcp_bearer_metrics_t get_metrics() = 0; + virtual void reset_metrics() = 0; + protected: - srslte::log_ref log; + srslog::basic_logger& logger; srslte::task_sched_handle task_sched; bool active = false; @@ -147,7 +159,8 @@ protected: SECURITY_DIRECTION_UPLINK, PDCP_SN_LEN_12, pdcp_t_reordering_t::ms500, - pdcp_discard_timer_t::infinity}; + pdcp_discard_timer_t::infinity, + false}; srslte::as_security_config_t sec_cfg = {}; @@ -158,12 +171,17 @@ protected: void cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint8_t* msg); // Common packing functions - bool is_control_pdu(const unique_byte_buffer_t& pdu); - uint32_t read_data_header(const unique_byte_buffer_t& pdu); - void discard_data_header(const unique_byte_buffer_t& pdu); - void write_data_header(const srslte::unique_byte_buffer_t& sdu, uint32_t count); - void extract_mac(const unique_byte_buffer_t& pdu, uint8_t* mac); - void append_mac(const unique_byte_buffer_t& sdu, uint8_t* mac); + bool is_control_pdu(const unique_byte_buffer_t& pdu); + pdcp_pdu_type_t get_control_pdu_type(const unique_byte_buffer_t& pdu); + uint32_t read_data_header(const unique_byte_buffer_t& pdu); + void discard_data_header(const unique_byte_buffer_t& pdu); + void write_data_header(const srslte::unique_byte_buffer_t& sdu, uint32_t count); + void extract_mac(const unique_byte_buffer_t& pdu, uint8_t* mac); + void append_mac(const unique_byte_buffer_t& sdu, uint8_t* mac); + + // Metrics helpers + pdcp_bearer_metrics_t metrics = {}; + srslte::rolling_average tx_pdu_ack_latency_ms; }; inline uint32_t pdcp_entity_base::HFN(uint32_t count) diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index c83410cf9..abd854802 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -50,7 +50,7 @@ public: srsue::rrc_interface_pdcp* rrc_, srsue::gw_interface_pdcp* gw_, srslte::task_sched_handle task_sched_, - srslte::log_ref log_, + srslog::basic_logger& logger, uint32_t lcid_, pdcp_config_t cfg_); ~pdcp_entity_lte() override; @@ -58,17 +58,37 @@ public: void reestablish() override; // GW/RRC interface - void write_sdu(unique_byte_buffer_t sdu) override; + void write_sdu(unique_byte_buffer_t sdu, int sn = -1) override; // RLC interface void write_pdu(unique_byte_buffer_t pdu) override; + void notify_failure(const std::vector& pdcp_sns) override; + void notify_delivery(const std::vector& pdcp_sns) override; // Config helpers bool check_valid_config(); + // TX SDU queue helper + bool store_sdu(uint32_t tx_count, const unique_byte_buffer_t& pdu); + + // Getter for unacknowledged PDUs. Used for handover + std::map get_buffered_pdus() override; + + // Status report helper(s) + void send_status_report() override; + void handle_status_report_pdu(srslte::unique_byte_buffer_t pdu); + + // Internal state getters/setters void get_bearer_state(pdcp_lte_state_t* state) override; void set_bearer_state(const pdcp_lte_state_t& state) override; + // Getter for the number of discard timers. Used for debugging. + uint32_t nof_discard_timers() const; + + // Metrics helpers + pdcp_bearer_metrics_t get_metrics() override; + void reset_metrics() override; + private: srsue::rlc_interface_pdcp* rlc = nullptr; srsue::rrc_interface_pdcp* rrc = nullptr; @@ -80,10 +100,37 @@ private: uint32_t reordering_window = 0; uint32_t maximum_pdcp_sn = 0; + // Discard callback (discardTimer) + class discard_callback; + std::vector discard_timers; + unique_timer* get_discard_timer(uint32_t sn); + void stop_discard_timer(uint32_t sn); + + // TX Queue + uint32_t maximum_allocated_sns_window = 2048; + std::map undelivered_sdus_queue; + + void handle_control_pdu(srslte::unique_byte_buffer_t pdu); void handle_srb_pdu(srslte::unique_byte_buffer_t pdu); void handle_um_drb_pdu(srslte::unique_byte_buffer_t pdu); void handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu); }; +// Discard callback (discardTimer) +class pdcp_entity_lte::discard_callback +{ +public: + discard_callback(pdcp_entity_lte* parent_, uint32_t sn_) + { + parent = parent_; + discard_sn = sn_; + }; + void operator()(uint32_t timer_id); + +private: + pdcp_entity_lte* parent; + uint32_t discard_sn; +}; + } // namespace srslte #endif // SRSLTE_PDCP_ENTITY_LTE_H diff --git a/lib/include/srslte/upper/pdcp_entity_nr.h b/lib/include/srslte/upper/pdcp_entity_nr.h index 27414d448..391e457be 100644 --- a/lib/include/srslte/upper/pdcp_entity_nr.h +++ b/lib/include/srslte/upper/pdcp_entity_nr.h @@ -46,7 +46,7 @@ public: srsue::rrc_interface_pdcp* rrc_, srsue::gw_interface_pdcp* gw_, srslte::task_sched_handle task_sched_, - srslte::log_ref log_, + srslog::basic_logger& logger, uint32_t lcid, pdcp_config_t cfg_); ~pdcp_entity_nr() final; @@ -54,10 +54,12 @@ public: void reestablish() final; // RRC interface - void write_sdu(unique_byte_buffer_t sdu) final; + void write_sdu(unique_byte_buffer_t sdu, int sn = -1) final; // RLC interface void write_pdu(unique_byte_buffer_t pdu) final; + void notify_delivery(const std::vector& tx_count) final; + void notify_failure(const std::vector& tx_count) final; // State variable setters (should be used only for testing) void set_tx_next(uint32_t tx_next_) { tx_next = tx_next_; } @@ -68,6 +70,12 @@ public: void get_bearer_state(pdcp_lte_state_t* state) override; void set_bearer_state(const pdcp_lte_state_t& state) override; + void send_status_report() override {} + pdcp_bearer_metrics_t get_metrics() override; + void reset_metrics() override; + + std::map get_buffered_pdus() override { return {}; } + // State variable getters (useful for testing) uint32_t nof_discard_timers() { return discard_timers_map.size(); } diff --git a/lib/include/srslte/upper/pdcp_metrics.h b/lib/include/srslte/upper/pdcp_metrics.h new file mode 100644 index 000000000..4af834283 --- /dev/null +++ b/lib/include/srslte/upper/pdcp_metrics.h @@ -0,0 +1,41 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_PDCP_METRICS_H +#define SRSLTE_PDCP_METRICS_H + +#include "srslte/common/common.h" +#include + +namespace srslte { + +typedef struct { + // PDU metrics + uint32_t num_tx_pdus; + uint32_t num_rx_pdus; + uint64_t num_tx_pdu_bytes; + uint64_t num_rx_pdu_bytes; + + // ACK specific metrics (requires RLC AM) + uint64_t num_tx_acked_bytes; //< Cumulative number of bytes that the PDCP knows to be acknowledged + uint64_t tx_notification_latency_ms; //< Average time in ms from PDU delivery to RLC to ACK notification from RLC + uint32_t num_tx_buffered_pdus; //< Number of PDUs waiting for ACK + uint32_t num_tx_buffered_pdus_bytes; //< Number of bytes of PDUs waiting for ACK +} pdcp_bearer_metrics_t; + +typedef struct { + pdcp_bearer_metrics_t bearer[SRSLTE_N_RADIO_BEARERS]; +} pdcp_metrics_t; + +} // namespace srslte + +#endif // SRSLTE_RLC_METRICS_H diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 3cad0651b..92c0818e0 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -95,7 +95,7 @@ private: void reset_metrics(); byte_buffer_pool* pool = nullptr; - srslte::log_ref rlc_log; + srslog::basic_logger& logger; srsue::pdcp_interface_rlc* pdcp = nullptr; srsue::rrc_interface_rlc* rrc = nullptr; srslte::timer_handler* timers = nullptr; diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index ff5d4547a..e29c3442e 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -23,6 +23,7 @@ #define SRSLTE_RLC_AM_LTE_H #include "srslte/adt/accumulators.h" +#include "srslte/adt/circular_array.h" #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/log.h" @@ -49,10 +50,12 @@ struct rlc_amd_rx_pdu_segments_t { }; struct rlc_amd_tx_pdu_t { - rlc_amd_pdu_header_t header; - unique_byte_buffer_t buf; - uint32_t retx_count; - bool is_acked; + rlc_amd_pdu_header_t header; + unique_byte_buffer_t buf; + std::vector pdcp_sns; + uint32_t retx_count; + uint32_t rlc_sn; + bool is_acked; }; struct rlc_amd_retx_t { @@ -62,10 +65,124 @@ struct rlc_amd_retx_t { uint32_t so_end; }; +struct rlc_sn_info_t { + uint32_t sn; + bool is_acked; +}; + +struct pdcp_sdu_info_t { + uint32_t sn; + bool fully_txed; // Boolean indicating if the SDU is fully transmitted. + bool fully_acked; // Boolean indicating if the SDU is fully acked. This is only necessary temporarely to avoid + // duplicate removal from the queue while processing the status report + std::vector rlc_sn_info_list; // List of RLC PDUs in transit and whether they have been acked or not. +}; + +struct tx_window_t { + tx_window_t() { clear(); } + void add_pdu(size_t sn) + { + assert(not active_flag[sn]); + window[sn].rlc_sn = sn; + active_flag[sn] = true; + count++; + } + void remove_pdu(size_t sn) + { + assert(active_flag[sn]); + window[sn] = {}; + active_flag[sn] = false; + count--; + } + rlc_amd_tx_pdu_t& operator[](size_t sn) + { + assert(has_sn(sn)); + return window[sn]; + } + size_t size() const { return count; } + bool empty() const { return count == 0; } + void clear() + { + std::fill(active_flag.begin(), active_flag.end(), false); + for (size_t i = 0; i < window.size(); ++i) { + window[i].pdcp_sns.clear(); + } + count = 0; + } + bool has_sn(uint32_t sn) const { return active_flag[sn] and window[sn].rlc_sn == sn; } + rlc_amd_tx_pdu_t& front() + { + assert(not empty()); + uint32_t min_rlc_sn = std::numeric_limits::max(), min_idx = std::numeric_limits::max(); + for (uint32_t i = 0; i < window.size(); ++i) { + if (active_flag[i] and window[i].rlc_sn < min_rlc_sn) { + min_idx = i; + min_rlc_sn = window[i].rlc_sn; + } + } + assert(has_sn(min_rlc_sn)); + return window[min_idx]; + } + +private: + size_t count = 0; + srslte::circular_array active_flag = {}; + srslte::circular_array window; +}; + +struct buffered_pdcp_pdu_list { +public: + explicit buffered_pdcp_pdu_list(); + void clear(); + + void add_pdcp_sdu(uint32_t sn) + { + assert(not has_pdcp_sn(sn)); + buffered_pdus[get_idx(sn)].sn = sn; + count++; + } + void clear_pdcp_sdu(uint32_t sn) + { + uint32_t sn_idx = get_idx(sn); + buffered_pdus[sn_idx].sn = invalid_sn; + buffered_pdus[sn_idx].fully_acked = false; + buffered_pdus[sn_idx].fully_txed = false; + buffered_pdus[sn_idx].rlc_sn_info_list.clear(); + count--; + } + + pdcp_sdu_info_t& operator[](uint32_t sn) + { + assert(has_pdcp_sn(sn)); + return buffered_pdus[get_idx(sn)]; + } + bool has_pdcp_sn(uint32_t pdcp_sn) const + { + assert(pdcp_sn <= max_pdcp_sn or pdcp_sn == status_report_sn); + return buffered_pdus[get_idx(pdcp_sn)].sn == pdcp_sn; + } + uint32_t nof_sdus() const { return count; } + +private: + const static size_t max_pdcp_sn = 262143u; + const static size_t max_buffer_idx = 4096u; + const static uint32_t status_report_sn = std::numeric_limits::max(); + const static uint32_t invalid_sn = std::numeric_limits::max() - 1; + + size_t get_idx(uint32_t sn) const + { + return (sn != status_report_sn) ? static_cast(sn % max_buffer_idx) : max_buffer_idx; + } + + // size equal to buffer_size + 1 (last element for Status Report) + std::vector buffered_pdus; + uint32_t count = 0; +}; + class rlc_am_lte : public rlc_common { public: - rlc_am_lte(srslte::log_ref log_, + rlc_am_lte(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, @@ -126,10 +243,11 @@ private: void set_bsr_callback(bsr_callback_t callback); private: - int build_status_pdu(uint8_t* payload, uint32_t nof_bytes); - int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes); - int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx); - int build_data_pdu(uint8_t* payload, uint32_t nof_bytes); + int build_status_pdu(uint8_t* payload, uint32_t nof_bytes); + int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes); + int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx); + int build_data_pdu(uint8_t* payload, uint32_t nof_bytes); + void update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu, std::vector& notify_info_vec); void debug_state(); @@ -141,9 +259,9 @@ private: bool poll_required(); bool do_status(); - rlc_am_lte* parent = nullptr; - byte_buffer_pool* pool = nullptr; - srslte::log_ref log; + rlc_am_lte* parent = nullptr; + byte_buffer_pool* pool = nullptr; + srslog::basic_logger& logger; /**************************************************************************** * Configurable parameters @@ -183,12 +301,15 @@ private: srslte::timer_handler::unique_timer poll_retx_timer; srslte::timer_handler::unique_timer status_prohibit_timer; + // SDU info for PDCP notifications + buffered_pdcp_pdu_list undelivered_sdu_info_queue; + // Callback function for buffer status report bsr_callback_t bsr_callback; // Tx windows - std::map tx_window; - std::deque retx_queue; + tx_window_t tx_window; + std::deque retx_queue; // Mutexes pthread_mutex_t mutex; @@ -228,9 +349,9 @@ private: void print_rx_segments(); bool add_segment_and_check(rlc_amd_rx_pdu_segments_t* pdu, rlc_amd_rx_pdu_t* segment); - rlc_am_lte* parent = nullptr; - byte_buffer_pool* pool = nullptr; - srslte::log_ref log; + rlc_am_lte* parent = nullptr; + byte_buffer_pool* pool = nullptr; + srslog::basic_logger& logger; /**************************************************************************** * Configurable parameters @@ -275,7 +396,7 @@ private: // Common variables needed/provided by parent class srsue::rrc_interface_rlc* rrc = nullptr; - srslte::log_ref log; + srslog::basic_logger& logger; srsue::pdcp_interface_rlc* pdcp = nullptr; srslte::timer_handler* timers = nullptr; uint32_t lcid = 0; @@ -309,6 +430,7 @@ uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); uint32_t rlc_am_packed_length(rlc_amd_retx_t retx); bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status); bool rlc_am_is_pdu_segment(uint8_t* payload); +std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue); std::string rlc_am_status_pdu_to_string(rlc_status_pdu_t* status); std::string rlc_amd_pdu_header_to_string(const rlc_amd_pdu_header_t& header); bool rlc_am_start_aligned(const uint8_t fi); diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index 4be7cfed8..e43cdc409 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -265,9 +265,9 @@ public: virtual void reset_metrics() = 0; // PDCP interface - virtual void write_sdu(unique_byte_buffer_t sdu) = 0; - virtual void discard_sdu(uint32_t discard_sn) = 0; - virtual bool sdu_queue_is_full() = 0; + virtual void write_sdu(unique_byte_buffer_t sdu) = 0; + virtual void discard_sdu(uint32_t discard_sn) = 0; + virtual bool sdu_queue_is_full() = 0; // MAC interface virtual bool has_data() = 0; @@ -291,7 +291,7 @@ private: // Do not block ever if (!rx_pdu_resume_queue.try_push(p)) { - srslte::logmap::get("RLC ")->warning("Dropping SDUs while bearer suspended.\n"); + srslog::fetch_basic_logger("RLC").warning("Dropping SDUs while bearer suspended."); return; } } @@ -301,7 +301,7 @@ private: { // Do not block ever if (not tx_sdu_resume_queue.try_push(std::move(sdu))) { - srslte::logmap::get("RLC ")->warning("Dropping SDUs while bearer suspended.\n"); + srslog::fetch_basic_logger("RLC").warning("Dropping SDUs while bearer suspended."); return; } } diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index 4180a270e..af8a6bbf4 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -34,7 +34,10 @@ namespace srslte { class rlc_tm final : public rlc_common { public: - rlc_tm(srslte::log_ref log_, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_); + rlc_tm(srslog::basic_logger& logger, + uint32_t lcid_, + srsue::pdcp_interface_rlc* pdcp_, + srsue::rrc_interface_rlc* rrc_); ~rlc_tm() override; bool configure(const rlc_config_t& cnfg) override; void stop() override; @@ -62,7 +65,7 @@ public: private: byte_buffer_pool* pool = nullptr; - srslte::log_ref log; + srslog::basic_logger& logger; uint32_t lcid = 0; srsue::pdcp_interface_rlc* pdcp = nullptr; srsue::rrc_interface_rlc* rrc = nullptr; diff --git a/lib/include/srslte/upper/rlc_um_base.h b/lib/include/srslte/upper/rlc_um_base.h index 75662c39b..159b29d29 100644 --- a/lib/include/srslte/upper/rlc_um_base.h +++ b/lib/include/srslte/upper/rlc_um_base.h @@ -39,7 +39,7 @@ namespace srslte { class rlc_um_base : public rlc_common { public: - rlc_um_base(srslte::log_ref log_, + rlc_um_base(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, @@ -91,10 +91,10 @@ protected: virtual uint32_t get_buffer_state() = 0; protected: - byte_buffer_pool* pool = nullptr; - srslte::log_ref log; - std::string rb_name; - rlc_um_base* parent = nullptr; + byte_buffer_pool* pool = nullptr; + srslog::basic_logger& logger; + std::string rb_name; + rlc_um_base* parent = nullptr; rlc_config_t cfg = {}; @@ -120,7 +120,6 @@ protected: // Receiver sub-class base class rlc_um_base_rx : public timer_callback { - public: rlc_um_base_rx(rlc_um_base* parent_); virtual ~rlc_um_base_rx(); @@ -133,7 +132,7 @@ protected: protected: byte_buffer_pool* pool = nullptr; - srslte::log_ref log; + srslog::basic_logger& logger; srslte::timer_handler* timers = nullptr; srsue::pdcp_interface_rlc* pdcp = nullptr; srsue::rrc_interface_rlc* rrc = nullptr; @@ -154,7 +153,7 @@ protected: // Common variables needed by parent class srsue::rrc_interface_rlc* rrc = nullptr; srsue::pdcp_interface_rlc* pdcp = nullptr; - srslte::log_ref log; + srslog::basic_logger& logger; srslte::timer_handler* timers = nullptr; uint32_t lcid = 0; rlc_config_t cfg = {}; diff --git a/lib/include/srslte/upper/rlc_um_lte.h b/lib/include/srslte/upper/rlc_um_lte.h index ec1508208..69befff76 100644 --- a/lib/include/srslte/upper/rlc_um_lte.h +++ b/lib/include/srslte/upper/rlc_um_lte.h @@ -43,7 +43,7 @@ typedef struct { class rlc_um_lte : public rlc_um_base { public: - rlc_um_lte(srslte::log_ref log_, + rlc_um_lte(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, diff --git a/lib/include/srslte/upper/rlc_um_nr.h b/lib/include/srslte/upper/rlc_um_nr.h index a989295bd..9bf4d806e 100644 --- a/lib/include/srslte/upper/rlc_um_nr.h +++ b/lib/include/srslte/upper/rlc_um_nr.h @@ -43,7 +43,7 @@ typedef struct { class rlc_um_nr : public rlc_um_base { public: - rlc_um_nr(srslte::log_ref log_, + rlc_um_nr(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index 29b52cd9b..a28121cb4 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -63,18 +63,15 @@ target_compile_options(s1ap_asn1 PRIVATE "-Os") target_link_libraries(s1ap_asn1 asn1_utils srslte_common) INSTALL(TARGETS s1ap_asn1 DESTINATION ${LIBRARY_DIR}) -if (ENABLE_5GNR) - # RRC NR ASN1 - add_library(rrc_nr_asn1 STATIC rrc_nr.cc rrc_nr_utils.cc) - target_compile_options(rrc_nr_asn1 PRIVATE "-Os") - target_link_libraries(rrc_nr_asn1 asn1_utils srslte_common) - INSTALL(TARGETS rrc_nr_asn1 DESTINATION ${LIBRARY_DIR}) - - # NGAP ASN1 - add_library(ngap_nr_asn1 STATIC ngap.cc) - target_compile_options(ngap_nr_asn1 PRIVATE "-Os") - target_link_libraries(ngap_nr_asn1 asn1_utils srslte_common) - INSTALL(TARGETS ngap_nr_asn1 DESTINATION ${LIBRARY_DIR}) -endif(ENABLE_5GNR) +# RRC NR ASN1 +add_library(rrc_nr_asn1 STATIC rrc_nr.cc rrc_nr_utils.cc) +target_compile_options(rrc_nr_asn1 PRIVATE "-Os") +target_link_libraries(rrc_nr_asn1 asn1_utils srslte_common) +INSTALL(TARGETS rrc_nr_asn1 DESTINATION ${LIBRARY_DIR}) +# NGAP ASN1 +add_library(ngap_nr_asn1 STATIC ngap.cc) +target_compile_options(ngap_nr_asn1 PRIVATE "-Os") +target_link_libraries(ngap_nr_asn1 asn1_utils srslte_common) +INSTALL(TARGETS ngap_nr_asn1 DESTINATION ${LIBRARY_DIR}) diff --git a/lib/src/asn1/asn1_utils.cc b/lib/src/asn1/asn1_utils.cc index 70c2b2a52..69062233a 100644 --- a/lib/src/asn1/asn1_utils.cc +++ b/lib/src/asn1/asn1_utils.cc @@ -20,11 +20,6 @@ */ #include "srslte/asn1/asn1_utils.h" -#include "srslte/common/logmap.h" -#include "srslte/srslog/bundled/fmt/core.h" -#include -#include /* va_list, va_start, va_arg, va_end */ -#include namespace asn1 { @@ -32,70 +27,16 @@ namespace asn1 { logging ************************/ -void vlog_print(srslte::LOG_LEVEL_ENUM log_level, const char* format, va_list args) -{ - char* args_msg = nullptr; - if (vasprintf(&args_msg, format, args) > 0) { - switch (log_level) { - case srslte::LOG_LEVEL_ERROR: - srslte::logmap::get("ASN1")->error("%s", args_msg); - break; - case srslte::LOG_LEVEL_WARNING: - srslte::logmap::get("ASN1")->warning("%s", args_msg); - break; - case srslte::LOG_LEVEL_INFO: - srslte::logmap::get("ASN1")->info("%s", args_msg); - break; - case srslte::LOG_LEVEL_DEBUG: - srslte::logmap::get("ASN1")->debug("%s", args_msg); - default: - break; - } - } - if (args_msg) { - free(args_msg); - } -} - -void log_error(const char* format, ...) -{ - va_list args; - va_start(args, format); - vlog_print(srslte::LOG_LEVEL_ERROR, format, args); - va_end(args); -} -void log_warning(const char* format, ...) -{ - va_list args; - va_start(args, format); - vlog_print(srslte::LOG_LEVEL_WARNING, format, args); - va_end(args); -} -void log_info(const char* format, ...) -{ - va_list args; - va_start(args, format); - vlog_print(srslte::LOG_LEVEL_INFO, format, args); - va_end(args); -} -void log_debug(const char* format, ...) -{ - va_list args; - va_start(args, format); - vlog_print(srslte::LOG_LEVEL_DEBUG, format, args); - va_end(args); -} - void warn_assert(bool cond, const char* filename, int lineno) { if (cond) { - log_warning("Assertion in [%s][%d] failed.\n", filename, lineno); + log_warning("Assertion in [%s][%d] failed.", filename, lineno); } } void invalid_enum_number(int value, const char* name) { - log_error("The provided enum value=%d of type %s cannot be translated into a number\n", value, name); + log_error("The provided enum value=%d of type %s cannot be translated into a number", value, name); } void assert_choice_type(uint32_t val, uint32_t choice_id) @@ -108,7 +49,7 @@ void assert_choice_type(uint32_t val, uint32_t choice_id) void assert_choice_type(const std::string& access_type, const std::string& current_type, const std::string& choice_type) { if (access_type != current_type) { - log_error("Invalid field access for choice type \"%s\" (\"%s\"!=\"%s\")\n", + log_error("Invalid field access for choice type \"%s\" (\"%s\"!=\"%s\")", choice_type.c_str(), access_type.c_str(), current_type.c_str()); @@ -123,13 +64,13 @@ void log_error_code(SRSASN_CODE code, const char* filename, int line) { switch (code) { case SRSASN_ERROR_ENCODE_FAIL: - log_error("[%s][%d] Encoding failure.\n", filename, line); + log_error("[%s][%d] Encoding failure.", filename, line); break; case SRSASN_ERROR_DECODE_FAIL: - log_error("[%s][%d] Decoding failure.\n", filename, line); + log_error("[%s][%d] Decoding failure.", filename, line); break; default: - log_warning("[%s][%d] SRSASN_CODE=%d not recognized.\n", filename, line, (int)code); + log_warning("[%s][%d] SRSASN_CODE=%d not recognized.", filename, line, (int)code); } } @@ -137,9 +78,9 @@ const char* convert_enum_idx(const char* array[], uint32_t nof_types, uint32_t e { if (enum_val >= nof_types) { if (enum_val == nof_types) { - log_error("The enum of type %s was not initialized.\n", enum_type); + log_error("The enum of type %s was not initialized.", enum_type); } else { - log_error("The enum value=%d of type %s is not valid.\n", enum_val, enum_type); + log_error("The enum value=%d of type %s is not valid.", enum_val, enum_type); } return ""; } @@ -151,9 +92,9 @@ ItemType map_enum_number(ItemType* array, uint32_t nof_types, uint32_t enum_val, { if (enum_val >= nof_types) { if (enum_val == nof_types) { - log_error("The enum of type %s is not initialized.\n", enum_type); + log_error("The enum of type %s is not initialized.", enum_type); } else { - log_error("The enum value=%d of type %s cannot be converted to a number.\n", enum_val, enum_type); + log_error("The enum value=%d of type %s cannot be converted to a number.", enum_val, enum_type); } return 0; } @@ -211,13 +152,13 @@ int bit_ref_impl::distance_bytes() const SRSASN_CODE bit_ref::pack(uint64_t val, uint32_t n_bits) { if (n_bits >= 64) { - log_error("This method only supports packing up to 64 bits\n"); + log_error("This method only supports packing up to 64 bits"); return SRSASN_ERROR_ENCODE_FAIL; } uint64_t mask; while (n_bits > 0) { if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_ENCODE_FAIL; } mask = ((1ul << n_bits) - 1ul); @@ -243,13 +184,13 @@ template SRSASN_CODE unpack_bits(T& val, Ptr& ptr, uint8_t& offset, const uint8_t* max_ptr, uint32_t n_bits) { if (n_bits > sizeof(T) * 8) { - log_error("This method only supports unpacking up to %d bits\n", (int)sizeof(T) * 8); + log_error("This method only supports unpacking up to %d bits", (int)sizeof(T) * 8); return SRSASN_ERROR_DECODE_FAIL; } val = 0; while (n_bits > 0) { if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } if ((uint32_t)(8 - offset) > n_bits) { @@ -311,7 +252,7 @@ SRSASN_CODE bit_ref_impl::unpack_bytes(uint8_t* buf, uint32_t n_bytes) return SRSASN_SUCCESS; } if (ptr + n_bytes >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } if (offset == 0) { @@ -332,7 +273,7 @@ SRSASN_CODE bit_ref_impl::align_bytes() if (offset == 0) return SRSASN_SUCCESS; if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } offset = 0; @@ -348,7 +289,7 @@ SRSASN_CODE bit_ref_impl::advance_bits(uint32_t n_bits) uint32_t bytes_offset = floorf((offset + n_bits) / 8.0f); if (ptr + bytes_required >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } ptr += bytes_offset; @@ -374,7 +315,7 @@ SRSASN_CODE bit_ref::pack_bytes(const uint8_t* buf, uint32_t n_bytes) return SRSASN_SUCCESS; } if (ptr + n_bytes >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_ENCODE_FAIL; } if (offset == 0) { @@ -394,7 +335,7 @@ SRSASN_CODE bit_ref::align_bytes_zero() if (offset == 0) return SRSASN_SUCCESS; if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved\n"); + log_error("Buffer size limit was achieved"); return SRSASN_ERROR_ENCODE_FAIL; } auto mask = static_cast(256u - (1u << (8u - offset))); @@ -412,7 +353,7 @@ SRSASN_CODE pack_unsupported_ext_flag(bit_ref& bref, bool ext) { HANDLE_CODE(bref.pack(ext, 1)); if (ext) { - log_error("ASN extensions not currently supported\n"); + log_error("ASN extensions not currently supported"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; @@ -422,7 +363,7 @@ SRSASN_CODE unpack_unsupported_ext_flag(bool& ext, bit_ref& bref) { SRSASN_CODE ret = bref.unpack(ext, 1); if (ext) { - log_error("ASN extensions not currently supported\n"); + log_error("ASN extensions not currently supported"); return SRSASN_ERROR_DECODE_FAIL; } return ret; @@ -456,7 +397,7 @@ SRSASN_CODE pack_enum(bit_ref& bref, uint32_t e, uint32_t nof_types, uint32_t no { if (e >= nof_types) { log_error( - "The provided enum is not within the range of possible values (%u>=%u)\n", (unsigned)e, (unsigned)nof_types); + "The provided enum is not within the range of possible values (%u>=%u)", (unsigned)e, (unsigned)nof_types); return SRSASN_ERROR_ENCODE_FAIL; } SRSASN_CODE ret; @@ -491,7 +432,7 @@ ValOrError unpack_enum(uint32_t nof_types, uint32_t nof_exts, bool has_ext, cbit ret.code = bref.unpack(ret.val, nof_bits); } if (ret.val >= nof_types) { - log_error("The provided enum is not within the range of possible values (%u>=%u)\n", + log_error("The provided enum is not within the range of possible values (%u>=%u)", (unsigned)ret.val, (unsigned)nof_types); ret.code = SRSASN_ERROR_DECODE_FAIL; @@ -517,7 +458,7 @@ template SRSASN_CODE pack_constrained_whole_number(bit_ref& bref, IntType n, IntType lb, IntType ub, bool aligned) { if (ub < lb or n < lb or n > ub) { - log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met\n", (long)lb, (long)n, (long)ub); + log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met", (long)lb, (long)n, (long)ub); return SRSASN_ERROR_ENCODE_FAIL; } uint64_t ra = (uint64_t)(ub - lb) + 1; // NOTE: Can overflow if IntType is kept @@ -583,7 +524,7 @@ template SRSASN_CODE unpack_constrained_whole_number(IntType& n, cbit_ref& bref, IntType lb, IntType ub, bool aligned) { if (ub < lb) { - log_error("The condition lb <= ub (%ld <= %ld) was not met\n", (long)lb, (long)ub); + log_error("The condition lb <= ub (%ld <= %ld) was not met", (long)lb, (long)ub); return SRSASN_ERROR_DECODE_FAIL; } uint64_t ra = (uint64_t)(ub - lb) + 1; // NOTE: Can overflow if IntType is kept. @@ -597,7 +538,7 @@ SRSASN_CODE unpack_constrained_whole_number(IntType& n, cbit_ref& bref, IntType HANDLE_CODE(bref.unpack(n, n_bits)); n += lb; if (n > ub) { - log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met\n", (long)lb, (long)n, (long)ub); + log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met", (long)lb, (long)n, (long)ub); return SRSASN_ERROR_DECODE_FAIL; } } else { @@ -653,7 +594,7 @@ SRSASN_CODE pack_norm_small_non_neg_whole_number(bit_ref& bref, UintType n) HANDLE_CODE(bref.pack(n, 7)); // [1 bit: 0 | 6 bit: n] } else { HANDLE_CODE(bref.pack(1, 1)); - log_error("Long small integers not supported\n"); + log_error("Long small integers not supported"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; @@ -667,7 +608,7 @@ SRSASN_CODE unpack_norm_small_non_neg_whole_number(UintType& n, cbit_ref& bref) if (not ext) { ret = bref.unpack(n, 6); } else { - log_error("Long small integers not supported\n"); + log_error("Long small integers not supported"); return SRSASN_ERROR_DECODE_FAIL; } return ret; @@ -794,7 +735,7 @@ SRSASN_CODE pack_length(bit_ref& bref, uint32_t val, bool aligned) HANDLE_CODE(bref.pack(0b10, 2)); HANDLE_CODE(bref.pack(val, 14)); } else { - log_error("Not handling sizes longer than 16383 octets\n"); + log_error("Not handling sizes longer than 16383 octets"); return SRSASN_ERROR_ENCODE_FAIL; } } else { @@ -833,7 +774,7 @@ SRSASN_CODE unpack_length(uint32_t& val, cbit_ref& bref, bool aligned) if (not ext) { ret = bref.unpack(val, 14); } else { - log_error("Not handling octet strings longer than 16383 octets\n"); + log_error("Not handling octet strings longer than 16383 octets"); val = 0; return SRSASN_ERROR_DECODE_FAIL; } @@ -856,8 +797,8 @@ SRSASN_CODE unpack_length(uint32_t& val, cbit_ref& bref, bool aligned) val = (val << 8u) + val_octet_2; return SRSASN_SUCCESS; } - // TODO: Error message - return SRSASN_ERROR_ENCODE_FAIL; + log_error("Not handling octet strings longer than 16383 octets"); + return SRSASN_ERROR_DECODE_FAIL; } } @@ -873,7 +814,7 @@ SRSASN_CODE pack_integer(bit_ref& bref, IntType n, IntType lb, IntType ub, bool if (has_ext) { HANDLE_CODE(bref.pack(not within_bounds, 1)); } else if (not within_bounds) { - log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met\n", (long)lb, (long)n, (long)ub); + log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met", (long)lb, (long)n, (long)ub); return SRSASN_ERROR_ENCODE_FAIL; } bool lower_bounded = lb != std::numeric_limits::min() or std::is_unsigned::value; @@ -1021,7 +962,7 @@ template struct integer_packer; uint64_t octstring_to_number(const uint8_t* ptr, uint32_t nbytes) { if (nbytes > 8) { - log_error("octstring of size=%d does not fit in an uint64_t\n", nbytes); + log_error("octstring of size=%d does not fit in an uint64_t", nbytes); return 0; } uint64_t val = 0; @@ -1034,7 +975,7 @@ uint64_t octstring_to_number(const uint8_t* ptr, uint32_t nbytes) void number_to_octstring(uint8_t* ptr, uint64_t number, uint32_t nbytes) { if (nbytes > 8) { - log_error("octstring of size=%d does not fit in an uint64_t\n", nbytes); + log_error("octstring of size=%d does not fit in an uint64_t", nbytes); return; } for (uint32_t i = 0; i < nbytes; ++i) { @@ -1063,7 +1004,7 @@ std::string octstring_to_string(const uint8_t* ptr, uint32_t N) void string_to_octstring(uint8_t* ptr, const std::string& str) { if (str.size() % 2 != 0) { - log_warning("The provided hex string size=%zd is not a multiple of 2\n.", str.size()); + log_warning("The provided hex string size=%zd is not a multiple of 2.", str.size()); } char cstr[] = "\0\0\0"; for (uint32_t i = 0; i < str.size(); i += 2) { @@ -1132,12 +1073,12 @@ SRSASN_CODE pack_length_prefix(bit_ref& bref, bool is_aligned = false) { if (has_ext and ub == std::numeric_limits::max()) { - log_error("has extension marker but it is an unbounded prefix size\n"); + log_error("has extension marker but it is an unbounded prefix size"); return SRSASN_ERROR_ENCODE_FAIL; } bool within_bounds = len >= lb and len <= ub; if (not within_bounds and not has_ext) { - log_error("bitstring length=%d is not within bounds [%d, %d]\n", len, lb, ub); + log_error("bitstring length=%d is not within bounds [%d, %d]", len, lb, ub); return SRSASN_ERROR_ENCODE_FAIL; } @@ -1168,7 +1109,7 @@ SRSASN_CODE pack_length_prefix(bit_ref& bref, SRSASN_CODE pack_bitfield(bit_ref& bref, const uint8_t* buf, uint32_t nbits, uint32_t lb, uint32_t ub, bool is_aligned) { if (nbits == 0) { - log_error("Invalid bitstring size=%d\n", nbits); + log_error("Invalid bitstring size=%d", nbits); return SRSASN_ERROR_ENCODE_FAIL; } if (is_aligned and (lb != ub or ub > 16)) { @@ -1231,7 +1172,7 @@ SRSASN_CODE unpack_length_prefix(uint32_t& len, cbit_ref& bref, uint32_t lb, uin SRSASN_CODE unpack_bitfield(uint8_t* buf, cbit_ref& bref, uint32_t n, uint32_t lb, uint32_t ub, bool is_aligned) { if (n > ASN_64K) { - log_error("bitstrings longer than 64K not supported\n"); + log_error("bitstrings longer than 64K not supported"); return SRSASN_ERROR_DECODE_FAIL; } if (n == 0) { @@ -1254,7 +1195,7 @@ SRSASN_CODE unpack_bitfield(uint8_t* buf, cbit_ref& bref, uint32_t n, uint32_t l void from_number(uint8_t* ptr, uint64_t number, uint32_t nbits) { if (nbits > 64u) { - log_error("bitstring of size=%d does not fit in an uint64_t\n", nbits); + log_error("bitstring of size=%d does not fit in an uint64_t", nbits); return; } uint32_t nof_bytes = ceil_frac(nbits, 8u); @@ -1279,7 +1220,7 @@ std::string to_string(const uint8_t* ptr, uint32_t nbits) uint64_t to_number(const uint8_t* ptr, uint32_t nbits) { if (nbits > 64u) { - log_error("bitstring of size=%d does not fit in an uint64_t\n", nbits); + log_error("bitstring of size=%d does not fit in an uint64_t", nbits); return 0; } uint64_t val = 0; @@ -1297,11 +1238,11 @@ uint64_t to_number(const uint8_t* ptr, uint32_t nbits) *********************/ void log_invalid_access_choice_id(uint32_t val, uint32_t choice_id) { - log_error("The access choide id is invalid (%zd!=%zd)\n", (size_t)val, (size_t)choice_id); + log_error("The access choide id is invalid (%zd!=%zd)", (size_t)val, (size_t)choice_id); } void log_invalid_choice_id(uint32_t val, const char* choice_type) { - log_error("Invalid choice id=%zd for choice type %s\n", (size_t)val, choice_type); + log_error("Invalid choice id=%zd for choice type %s", (size_t)val, choice_type); } /********************* @@ -1338,7 +1279,7 @@ pack(bit_ref& bref, const std::string& s, size_t lb, size_t ub, size_t alb, size if (not within_limits) { // TODO: print error // NOTE: This should be valid for exts - log_error("The PrintableString size=%zd is not within the limits [%zd, %zd]\n", s.size(), alb, aub); + log_error("The PrintableString size=%zd is not within the limits [%zd, %zd]", s.size(), alb, aub); return SRSASN_ERROR_ENCODE_FAIL; } size_t b = asn_string_utils::get_nof_bits_per_char(lb, ub, aligned); @@ -1375,7 +1316,7 @@ SRSASN_CODE unpack(std::string& s, cbit_ref& bref, size_t lb, size_t ub, size_t bool is_ext; HANDLE_CODE(bref.unpack(is_ext, 1)); if (is_ext) { - log_error("Extension of PrintableString not supported\n"); + log_error("Extension of PrintableString not supported"); return SRSASN_ERROR_DECODE_FAIL; } } @@ -1498,7 +1439,7 @@ varlength_field_pack_guard::~varlength_field_pack_guard() // check how many bytes were written in total uint32_t nof_bytes = bref_tracker->distance(bref0) / (uint32_t)8; if (nof_bytes > sizeof(buffer)) { - log_error("The packed variable sized field is too long for the reserved buffer (%zd > %zd)\n", + log_error("The packed variable sized field is too long for the reserved buffer (%zd > %zd)", (size_t)nof_bytes, sizeof(buffer)); } diff --git a/lib/src/asn1/gtpc.cc b/lib/src/asn1/gtpc.cc index 39ab07aca..3017be1c9 100644 --- a/lib/src/asn1/gtpc.cc +++ b/lib/src/asn1/gtpc.cc @@ -19,7 +19,7 @@ * */ #include "srslte/asn1/gtpc.h" -#include "srslte/common/common.h" +#include "srslte/common/byte_buffer.h" #include namespace srslte { diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index 9d4ab4c8a..32debefae 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -298,7 +298,6 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_mobile_id_ie(LIBLTE_MME_MOBILE_ID_STRUCT* mobi err = LIBLTE_SUCCESS; } else { - **ie_ptr = (0xFF << 4) | (0 << 3) | mobile_id->type_of_id; *ie_ptr += 1; // 4-Byte based ids @@ -4364,7 +4363,6 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_transaction_identifier_ie(uint8** LIBLTE_ERROR_ENUM liblte_mme_parse_msg_sec_header(LIBLTE_BYTE_MSG_STRUCT* msg, uint8* pd, uint8* sec_hdr_type) { - LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; if (msg != NULL && pd != NULL && sec_hdr_type != NULL) { @@ -4426,6 +4424,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_security_protected_nas_msg(LIBLTE_BYTE_MSG_STR uint32 count, LIBLTE_BYTE_MSG_STRUCT* sec_msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = sec_msg->msg; uint32 i; @@ -4472,6 +4471,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_attach_accept_msg(LIBLTE_MME_ATTACH_ACCEPT_MSG uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -4746,6 +4746,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_attach_complete_msg(LIBLTE_MME_ATTACH_COMPLETE uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -4821,6 +4822,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_attach_complete_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_attach_reject_msg(LIBLTE_MME_ATTACH_REJECT_MSG_STRUCT* attach_rej, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -4915,6 +4917,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_attach_reject_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_attach_request_msg(LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT* attach_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); return liblte_mme_pack_attach_request_msg(attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, 0, msg); } @@ -4923,6 +4926,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_attach_request_msg(LIBLTE_MME_ATTACH_REQUEST_M uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5284,6 +5288,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_attach_request_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_failure_msg(LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT* auth_fail, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5363,6 +5368,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_authentication_failure_msg(LIBLTE_BYTE_MSG_S LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_reject_msg(LIBLTE_MME_AUTHENTICATION_REJECT_MSG_STRUCT* auth_reject, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5419,6 +5425,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_authentication_reject_msg(LIBLTE_BYTE_MSG_ST LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_request_msg(LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT* auth_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5498,11 +5505,11 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_msg(LIBLTE_MME_AUTHENT uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; if (auth_resp != NULL && msg != NULL) { - if (LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type) { // Protocol Discriminator and Security Header Type *msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); @@ -5589,6 +5596,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_detach_accept_msg(LIBLTE_MME_DETACH_ACCEPT_MSG uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5660,6 +5668,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_detach_request_msg(LIBLTE_MME_DETACH_REQUEST_M uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5749,6 +5758,7 @@ liblte_mme_pack_downlink_nas_transport_msg(LIBLTE_MME_DOWNLINK_NAS_TRANSPORT_MSG uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5827,6 +5837,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_emm_information_msg(LIBLTE_MME_EMM_INFORMATION uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -5978,6 +5989,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_emm_status_msg(LIBLTE_MME_EMM_STATUS_MSG_STRUC uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6062,6 +6074,7 @@ liblte_mme_pack_extended_service_request_msg(LIBLTE_MME_EXTENDED_SERVICE_REQUEST uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6200,6 +6213,7 @@ liblte_mme_pack_guti_reallocation_command_msg(LIBLTE_MME_GUTI_REALLOCATION_COMMA uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6295,6 +6309,7 @@ liblte_mme_pack_guti_reallocation_complete_msg(LIBLTE_MME_GUTI_REALLOCATION_COMP uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6365,6 +6380,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_guti_reallocation_complete_msg( LIBLTE_ERROR_ENUM liblte_mme_pack_identity_request_msg(LIBLTE_MME_ID_REQUEST_MSG_STRUCT* id_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6432,6 +6448,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_identity_response_msg(LIBLTE_MME_ID_RESPONSE_M uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6510,6 +6527,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_security_mode_command_msg(LIBLTE_MME_SECURITY_ uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6651,6 +6669,7 @@ liblte_mme_pack_security_mode_complete_msg(LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6738,6 +6757,7 @@ liblte_mme_unpack_security_mode_complete_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_security_mode_reject_msg(LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT* sec_mode_rej, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6802,6 +6822,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_service_reject_msg(LIBLTE_MME_SERVICE_REJECT_M uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6910,6 +6931,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_service_reject_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_service_request_msg(LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT* service_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -6969,6 +6991,7 @@ liblte_mme_pack_tracking_area_update_accept_msg(LIBLTE_MME_TRACKING_AREA_UPDATE_ uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -7349,6 +7372,7 @@ liblte_mme_pack_tracking_area_update_reject_msg(LIBLTE_MME_TRACKING_AREA_UPDATE_ uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -7453,6 +7477,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_uplink_nas_transport_msg(LIBLTE_MME_UPLINK_NAS uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -8341,7 +8366,6 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_activate_default_eps_bearer_context_request_ uint8* msg_ptr = msg->msg; if (msg != NULL && act_def_eps_bearer_context_req != NULL) { - // EPS Bearer ID act_def_eps_bearer_context_req->eps_bearer_id = (*msg_ptr >> 4); msg_ptr++; @@ -9096,11 +9120,11 @@ srslte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INFORMATION_REQUEST_M uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; if (esm_info_req != NULL && msg != NULL) { - if (LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type) { // Protocol Discriminator and Security Header Type *msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); @@ -9147,11 +9171,11 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_esm_information_request_msg(LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT* esm_info_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; if (esm_info_req != NULL && msg != NULL) { - // Protocol Discriminator and EPS Bearer ID *msg_ptr = (esm_info_req->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT); msg_ptr++; @@ -9222,6 +9246,7 @@ liblte_mme_pack_esm_information_response_msg(LIBLTE_MME_ESM_INFORMATION_RESPONSE uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -9283,7 +9308,6 @@ srslte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT* uint8 sec_hdr_type; if (msg != NULL && esm_info_resp != NULL) { - // Security Header Type sec_hdr_type = (msg->msg[0] & 0xF0) >> 4; if (LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS == sec_hdr_type) { @@ -9381,6 +9405,7 @@ liblte_mme_unpack_esm_information_response_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_esm_status_msg(LIBLTE_MME_ESM_STATUS_MSG_STRUCT* esm_status, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -9821,6 +9846,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_modify_eps_bearer_context_request_msg( LIBLTE_ERROR_ENUM liblte_mme_pack_notification_msg(LIBLTE_MME_NOTIFICATION_MSG_STRUCT* notification, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -9887,6 +9913,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_pdn_connectivity_reject_msg(LIBLTE_MME_PDN_CONNECTIVITY_REJECT_MSG_STRUCT* pdn_con_rej, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -9986,6 +10013,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_pdn_connectivity_request_msg(LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT* pdn_con_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -10121,6 +10149,7 @@ liblte_mme_unpack_pdn_connectivity_request_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_pdn_disconnect_reject_msg(LIBLTE_MME_PDN_DISCONNECT_REJECT_MSG_STRUCT* pdn_discon_rej, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -10204,6 +10233,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_pdn_disconnect_request_msg(LIBLTE_MME_PDN_DISCONNECT_REQUEST_MSG_STRUCT* pdn_discon_req, LIBLTE_BYTE_MSG_STRUCT* msg) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -10281,6 +10311,7 @@ liblte_mme_unpack_pdn_disconnect_request_msg(LIBLTE_BYTE_MSG_STRUCT* LIBLTE_ERROR_ENUM liblte_mme_pack_activate_test_mode_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uint8 sec_hdr_type, uint32 count) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; @@ -10319,6 +10350,7 @@ liblte_mme_pack_activate_test_mode_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uin LIBLTE_ERROR_ENUM liblte_mme_pack_close_ue_test_loop_complete_msg(LIBLTE_BYTE_MSG_STRUCT* msg, uint8 sec_hdr_type, uint32 count) { + bzero(msg, sizeof(LIBLTE_BYTE_MSG_STRUCT)); LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; diff --git a/lib/src/asn1/rrc_nr.cc b/lib/src/asn1/rrc_nr.cc index 81c897b90..cb77658a8 100644 --- a/lib/src/asn1/rrc_nr.cc +++ b/lib/src/asn1/rrc_nr.cc @@ -4292,13 +4292,6 @@ SRSASN_CODE setup_release_c::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -template -std::string setup_release_c::types_opts::to_string() const -{ - static const char* options[] = {"release", "setup"}; - return convert_enum_idx(options, 2, value, "setup_release_c::types"); -} - // UAC-BarringPerCat ::= SEQUENCE SRSASN_CODE uac_barr_per_cat_s::pack(bit_ref& bref) const { diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 16005f5d0..0b4c3edb1 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -75,10 +75,22 @@ logical_channel_config_t make_mac_logical_channel_cfg_t(uint8_t lcid, const lc_c return logical_channel_config; } +rach_nr_cfg_t make_mac_rach_cfg(const rach_cfg_common_s& asn1_type) +{ + rach_nr_cfg_t rach_nr_cfg = {}; + rach_nr_cfg.powerRampingStep = asn1_type.rach_cfg_generic.pwr_ramp_step.to_number(); + rach_nr_cfg.ra_responseWindow = asn1_type.rach_cfg_generic.ra_resp_win.to_number(); + rach_nr_cfg.prach_ConfigurationIndex = asn1_type.rach_cfg_generic.prach_cfg_idx; + rach_nr_cfg.PreambleReceivedTargetPower = asn1_type.rach_cfg_generic.preamb_rx_target_pwr; + rach_nr_cfg.preambleTransMax = asn1_type.rach_cfg_generic.preamb_trans_max.to_number(); + rach_nr_cfg.ra_ContentionResolutionTimer = asn1_type.ra_contention_resolution_timer.to_number(); + return rach_nr_cfg; +}; + rlc_config_t make_rlc_config_t(const rlc_cfg_c& asn1_type) { rlc_config_t rlc_cfg = rlc_config_t::default_rlc_um_nr_config(); - rlc_cfg.rat = srslte_rat_t::nr; + rlc_cfg.rat = srslte_rat_t::nr; switch (asn1_type.type().value) { case rlc_cfg_c::types_opts::am: break; @@ -147,7 +159,8 @@ srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue is_ue ? SECURITY_DIRECTION_DOWNLINK : SECURITY_DIRECTION_UPLINK, sn_len, t_reordering, - discard_timer); + discard_timer, + false); return cfg; } @@ -180,4 +193,4 @@ int set_sched_cell_cfg_sib1(srsenb::sched_interface::cell_cfg_t* sched_cfg, cons return SRSLTE_SUCCESS; } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/lib/src/asn1/rrc_utils.cc b/lib/src/asn1/rrc_utils.cc index e003bc4c2..3820ef4af 100644 --- a/lib/src/asn1/rrc_utils.cc +++ b/lib/src/asn1/rrc_utils.cc @@ -215,7 +215,8 @@ srslte::pdcp_config_t make_srb_pdcp_config_t(const uint8_t bearer_id, bool is_ue is_ue ? SECURITY_DIRECTION_DOWNLINK : SECURITY_DIRECTION_UPLINK, PDCP_SN_LEN_5, pdcp_t_reordering_t::ms500, - pdcp_discard_timer_t::infinity); + pdcp_discard_timer_t::infinity, + false); return cfg; } @@ -227,10 +228,30 @@ srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue is_ue ? SECURITY_DIRECTION_DOWNLINK : SECURITY_DIRECTION_UPLINK, PDCP_SN_LEN_12, pdcp_t_reordering_t::ms500, - pdcp_discard_timer_t::infinity); + pdcp_discard_timer_t::infinity, + false); return cfg; } +uint8_t get_pdcp_drb_sn_len(const pdcp_cfg_s& pdcp_cfg) +{ + uint8_t sn_len = srslte::PDCP_SN_LEN_12; + if (pdcp_cfg.rlc_um_present) { + if (pdcp_cfg.rlc_um.pdcp_sn_size.value == pdcp_cfg_s::rlc_um_s_::pdcp_sn_size_e_::len7bits) { + sn_len = srslte::PDCP_SN_LEN_7; + } + } + if (pdcp_cfg.ext) { + if (pdcp_cfg.pdcp_sn_size_v1130_present) { + sn_len = srslte::PDCP_SN_LEN_15; + } + if (pdcp_cfg.pdcp_sn_size_v1310_present) { + sn_len = srslte::PDCP_SN_LEN_18; + } + } + return sn_len; +} + srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const asn1::rrc::pdcp_cfg_s& pdcp_cfg) { // TODO: complete config processing @@ -240,6 +261,48 @@ srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue case 10: discard_timer = pdcp_discard_timer_t::ms10; break; + case 20: + discard_timer = pdcp_discard_timer_t::ms20; + break; + case 30: + discard_timer = pdcp_discard_timer_t::ms30; + break; + case 40: + discard_timer = pdcp_discard_timer_t::ms40; + break; + case 50: + discard_timer = pdcp_discard_timer_t::ms50; + break; + case 60: + discard_timer = pdcp_discard_timer_t::ms60; + break; + case 75: + discard_timer = pdcp_discard_timer_t::ms75; + break; + case 100: + discard_timer = pdcp_discard_timer_t::ms100; + break; + case 150: + discard_timer = pdcp_discard_timer_t::ms150; + break; + case 200: + discard_timer = pdcp_discard_timer_t::ms200; + break; + case 250: + discard_timer = pdcp_discard_timer_t::ms250; + break; + case 300: + discard_timer = pdcp_discard_timer_t::ms300; + break; + case 500: + discard_timer = pdcp_discard_timer_t::ms500; + break; + case 750: + discard_timer = pdcp_discard_timer_t::ms750; + break; + case 1500: + discard_timer = pdcp_discard_timer_t::ms1500; + break; default: discard_timer = pdcp_discard_timer_t::infinity; break; @@ -257,15 +320,11 @@ srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue } } - uint8_t sn_len = srslte::PDCP_SN_LEN_12; - if (pdcp_cfg.rlc_um_present) { - if (pdcp_cfg.rlc_um.pdcp_sn_size.value == pdcp_cfg_s::rlc_um_s_::pdcp_sn_size_e_::len7bits) { - sn_len = srslte::PDCP_SN_LEN_7; - } - } + uint8_t sn_len = get_pdcp_drb_sn_len(pdcp_cfg); + bool status_report_required = false; if (pdcp_cfg.rlc_am_present) { - // TODO: handle RLC AM config for PDCP + status_report_required = pdcp_cfg.rlc_am.status_report_required; } pdcp_config_t cfg(bearer_id, @@ -274,7 +333,8 @@ srslte::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue is_ue ? SECURITY_DIRECTION_DOWNLINK : SECURITY_DIRECTION_UPLINK, sn_len, t_reordering, - discard_timer); + discard_timer, + status_report_required); return cfg; } @@ -319,7 +379,6 @@ void set_mac_cfg_t_main_cfg(mac_cfg_t* cfg, const asn1::rrc::mac_main_cfg_s& asn // RACH-Common section is always present void set_mac_cfg_t_rach_cfg_common(mac_cfg_t* cfg, const asn1::rrc::rach_cfg_common_s& asn1_type) { - // Preamble info cfg->rach_cfg.nof_preambles = asn1_type.preamb_info.nof_ra_preambs.to_number(); if (asn1_type.preamb_info.preambs_group_a_cfg_present) { @@ -401,7 +460,6 @@ srsenb::sched_interface::ant_info_ded_t make_ant_info_ded(const asn1::rrc::ant_i void set_phy_cfg_t_dedicated_cfg(phy_cfg_t* cfg, const asn1::rrc::phys_cfg_ded_s& asn1_type) { if (asn1_type.pucch_cfg_ded_present) { - if (asn1_type.pucch_cfg_ded.tdd_ack_nack_feedback_mode_present) { cfg->ul_cfg.pucch.tdd_ack_multiplex = asn1_type.pucch_cfg_ded.tdd_ack_nack_feedback_mode == asn1::rrc::pucch_cfg_ded_s::tdd_ack_nack_feedback_mode_e_::mux; @@ -414,7 +472,6 @@ void set_phy_cfg_t_dedicated_cfg(phy_cfg_t* cfg, const asn1::rrc::phys_cfg_ded_s auto* pucch_cfg_ded = asn1_type.pucch_cfg_ded_v1020.get(); if (pucch_cfg_ded->pucch_format_r10_present) { - typedef asn1::rrc::pucch_cfg_ded_v1020_s::pucch_format_r10_c_ pucch_format_r10_t; auto* pucch_format_r10 = &pucch_cfg_ded->pucch_format_r10; @@ -434,7 +491,6 @@ void set_phy_cfg_t_dedicated_cfg(phy_cfg_t* cfg, const asn1::rrc::phys_cfg_ded_s } } } else if (pucch_format_r10->type() == asn1::rrc::pucch_cfg_ded_v1020_s::pucch_format_r10_c_::types::ch_sel_r10) { - typedef pucch_format_r10_t::ch_sel_r10_s_ ch_sel_r10_t; auto* ch_sel_r10 = &pucch_format_r10->ch_sel_r10(); @@ -493,9 +549,7 @@ void set_phy_cfg_t_dedicated_cfg(phy_cfg_t* cfg, const asn1::rrc::phys_cfg_ded_s } if (asn1_type.cqi_report_cfg_present) { - if (asn1_type.cqi_report_cfg.cqi_report_periodic_present) { - cfg->dl_cfg.cqi_report.periodic_configured = asn1_type.cqi_report_cfg.cqi_report_periodic.type() == asn1::rrc::setup_e::setup; if (cfg->dl_cfg.cqi_report.periodic_configured) { @@ -523,7 +577,6 @@ void set_phy_cfg_t_dedicated_cfg(phy_cfg_t* cfg, const asn1::rrc::phys_cfg_ded_s } if (asn1_type.cqi_report_cfg.cqi_report_mode_aperiodic_present) { - cfg->dl_cfg.cqi_report.aperiodic_configured = true; cfg->dl_cfg.cqi_report.aperiodic_mode = make_aperiodic_mode(asn1_type.cqi_report_cfg.cqi_report_mode_aperiodic); } @@ -677,7 +730,6 @@ void set_phy_cfg_t_common_pwr_ctrl(phy_cfg_t* cfg, const asn1::rrc::ul_pwr_ctrl_ void set_phy_cfg_t_scell_config(phy_cfg_t* cfg, const asn1::rrc::scell_to_add_mod_r10_s& asn1_type) { if (asn1_type.rr_cfg_common_scell_r10_present) { - // Enable always CSI request extra bit cfg->dl_cfg.dci.multiple_csi_request_enabled = true; @@ -722,7 +774,6 @@ void set_phy_cfg_t_scell_config(phy_cfg_t* cfg, const asn1::rrc::scell_to_add_mo // Parse nonUL Configuration if (phys_cfg_ded_scell_r10->non_ul_cfg_r10_present) { - auto* non_ul_cfg = &phys_cfg_ded_scell_r10->non_ul_cfg_r10; // Parse Transmission mode diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index 1abc8b4de..efa2671aa 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -22,8 +22,10 @@ set(SOURCES arch_select.cc enb_events.cc backtrace.c + byte_buffer.cc + band_helper.cc buffer_pool.cc - crash_handler.c + crash_handler.cc gen_mch_tables.c liblte_security.cc log_filter.cc @@ -43,11 +45,8 @@ set(SOURCES arch_select.cc time_prof.cc version.c zuc.cc - s3g.cc) - -if (ENABLE_5GNR) - set(SOURCES ${SOURCES} mac_nr_pcap.cc basic_vnf.cc) -endif(ENABLE_5GNR) + s3g.cc + basic_vnf.cc) # Avoid warnings caused by libmbedtls about deprecated functions set_source_files_properties(security.cc PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations) @@ -58,8 +57,9 @@ add_dependencies(srslte_common gen_build_info) add_executable(arch_select arch_select.cc) -target_include_directories(srslte_common PUBLIC ${SEC_INCLUDE_DIRS}) -target_link_libraries(srslte_common srslte_phy srslog ${SEC_LIBRARIES}) +target_include_directories(srslte_common PUBLIC ${SEC_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR} ${BACKWARD_INCLUDE_DIRS}) +target_link_libraries(srslte_common srslte_phy srslog ${SEC_LIBRARIES} ${BACKWARD_LIBRARIES}) +target_compile_definitions(srslte_common PRIVATE ${BACKWARD_DEFINITIONS}) INSTALL(TARGETS srslte_common DESTINATION ${LIBRARY_DIR}) diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc new file mode 100644 index 000000000..3e04fbb0b --- /dev/null +++ b/lib/src/common/band_helper.cc @@ -0,0 +1,64 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/band_helper.h" +#include + +namespace srslte { + +// definition of static members +constexpr std::array + srslte_band_helper::nr_band_table_fr1; +constexpr std::array srslte_band_helper::nr_fr_params; + +// Formula in 5.4.2.1 +double srslte_band_helper::nr_arfcn_to_freq(uint32_t nr_arfcn) +{ + nr_raster_params params = get_raster_params(nr_arfcn); + return (params.F_REF_Offs_MHz * 1e6 + params.delta_F_global_kHz * (nr_arfcn - params.N_REF_Offs) * 1e3); +} + +// Implements 5.4.2.1 in TS 38.401 +std::vector srslte_band_helper::get_bands_nr(uint32_t nr_arfcn, + srslte_band_helper::delta_f_raster_t delta_f_raster) +{ + std::vector bands; + for (const auto& nr_band : nr_band_table_fr1) { + if (nr_arfcn >= nr_band.dl_nref_first && nr_arfcn <= nr_band.dl_nref_last && nr_arfcn % nr_band.dl_nref_step == 0) { + // band must not already be present + if (std::find(bands.begin(), bands.end(), nr_band.band) == bands.end()) { + if (delta_f_raster == DEFAULT) { + // add band if delta_f_raster has default value + bands.push_back(nr_band.band); + } else { + // if delta_f_raster is set explicitly, only add if band matches + if (nr_band.delta_f_raster == delta_f_raster) { + bands.push_back(nr_band.band); + } + } + } + } + } + return bands; +} + +srslte_band_helper::nr_raster_params srslte_band_helper::get_raster_params(uint32_t nr_arfcn) +{ + for (auto& fr : nr_fr_params) { + if (nr_arfcn >= fr.N_REF_min && nr_arfcn <= fr.N_REF_max) { + return fr; + } + } + return {}; // return empty params +} + +} // namespace srslte \ No newline at end of file diff --git a/lib/src/common/basic_vnf.cc b/lib/src/common/basic_vnf.cc index 59e651ad0..1e0a7f194 100644 --- a/lib/src/common/basic_vnf.cc +++ b/lib/src/common/basic_vnf.cc @@ -20,6 +20,7 @@ */ #include "srslte/common/basic_vnf.h" +#include "srslte/common/buffer_pool.h" #include "srslte/interfaces/ue_nr_interfaces.h" #include #include @@ -36,16 +37,11 @@ struct srslte_pnf_info_t { struct srslte_vnf_info_t {}; -srslte_basic_vnf::srslte_basic_vnf(const vnf_args_t& args_, srslte::logger* logger_, stack_interface_phy_nr* stack_) : - m_args(args_), - m_logger(logger_), - thread("BASIC_VNF_P7"), - m_tx_req_msg(new basic_vnf_api::tx_request_msg_t), - log_h("VNF"), - m_pool(srslte::byte_buffer_pool::get_instance()) +srslte_basic_vnf::srslte_basic_vnf(const vnf_args_t& args_, stack_interface_phy_nr* stack_) : + m_args(args_), thread("BASIC_VNF_P7"), m_tx_req_msg(new basic_vnf_api::tx_request_msg_t) { - log_h->set_level(m_args.log_level); - log_h->set_hex_limit(m_args.log_hex_limit); + logger.set_level(srslog::str_to_basic_level(m_args.log_level)); + logger.set_hex_dump_max_size(m_args.log_hex_limit); if (m_args.type == "gnb" || m_args.type == "ue") { if (m_args.type == "gnb") { @@ -54,10 +50,10 @@ srslte_basic_vnf::srslte_basic_vnf(const vnf_args_t& args_, srslte::logger* logg m_ue_stack = (srsue::stack_interface_phy_nr*)stack_; } - log_h->info("Initializing VNF for gNB\n"); + logger.info("Initializing VNF for gNB"); start(); } else { - log_h->error("Unknown VNF type. Exiting\n."); + logger.error("Unknown VNF type. Exiting."); } } @@ -107,7 +103,7 @@ void srslte_basic_vnf::run_thread() running = true; - log_h->info("Started VNF handler listening on %s:%d\n", m_args.bind_addr.c_str(), m_args.bind_port); + logger.info("Started VNF handler listening on %s:%d", m_args.bind_addr.c_str(), m_args.bind_port); while (running) { int ret = poll(&fd, 1, RX_TIMEOUT_MS); @@ -127,14 +123,14 @@ void srslte_basic_vnf::run_thread() break; } } - log_h->info("VNF thread stopped\n"); + logger.info("VNF thread stopped"); } int srslte_basic_vnf::handle_msg(const uint8_t* buffer, const uint32_t len) { basic_vnf_api::msg_header_t* header = (basic_vnf_api::msg_header_t*)buffer; - log_h->info("Received %s (%d B)\n", basic_vnf_api::msg_type_text[header->type], len); + logger.info("Received %s (%d B)", basic_vnf_api::msg_type_text[header->type], len); switch (header->type) { case basic_vnf_api::SF_IND: @@ -162,7 +158,7 @@ int srslte_basic_vnf::handle_msg(const uint8_t* buffer, const uint32_t len) int srslte_basic_vnf::handle_sf_ind(basic_vnf_api::sf_ind_msg_t* msg) { int ret = SRSLTE_SUCCESS; - log_h->info("Received %s for TTI=%d\n", basic_vnf_api::msg_type_text[msg->header.type], msg->tti); + logger.info("Received %s for TTI=%d", basic_vnf_api::msg_type_text[msg->header.type], msg->tti); // store Rx timestamp last_sf_indication_time = msg->t1; @@ -181,7 +177,7 @@ int srslte_basic_vnf::handle_sf_ind(basic_vnf_api::sf_ind_msg_t* msg) int srslte_basic_vnf::handle_dl_ind(basic_vnf_api::dl_ind_msg_t* msg) { int ret = SRSLTE_ERROR; - log_h->info("Received %s for TTI=%d\n", basic_vnf_api::msg_type_text[msg->header.type], msg->tti); + logger.info("Received %s for TTI=%d", basic_vnf_api::msg_type_text[msg->header.type], msg->tti); uint32_t cc_idx = 0; @@ -190,12 +186,12 @@ int srslte_basic_vnf::handle_dl_ind(basic_vnf_api::dl_ind_msg_t* msg) dl_grant.tti = msg->tti; if (msg->nof_pdus > SRSLTE_MAX_TB) { - log_h->error("Too many TBs (%d > %d)\n", msg->nof_pdus, SRSLTE_MAX_TB); + logger.error("Too many TBs (%d > %d)", msg->nof_pdus, SRSLTE_MAX_TB); goto exit; } for (uint32_t i = 0; i < msg->nof_pdus; ++i) { - dl_grant.tb[i] = srslte::allocate_unique_buffer(*m_pool); + dl_grant.tb[i] = srslte::make_byte_buffer(); if (dl_grant.tb[i]->get_tailroom() >= msg->pdus[i].length) { memcpy(dl_grant.tb[i]->msg, msg->pdus[i].data, msg->pdus[i].length); dl_grant.tb[i]->N_bytes = msg->pdus[i].length; @@ -203,7 +199,7 @@ int srslte_basic_vnf::handle_dl_ind(basic_vnf_api::dl_ind_msg_t* msg) m_ue_stack->tb_decoded(cc_idx, dl_grant); } } else { - log_h->error("TB too big to fit into buffer (%d > %d)\n", msg->pdus[i].length, dl_grant.tb[i]->get_tailroom()); + logger.error("TB too big to fit into buffer (%d > %d)", msg->pdus[i].length, dl_grant.tb[i]->get_tailroom()); } } @@ -216,10 +212,10 @@ exit: int srslte_basic_vnf::handle_ul_ind(basic_vnf_api::ul_ind_msg_t* msg) { - log_h->info("Received %s for TTI=%d\n", basic_vnf_api::msg_type_text[msg->header.type], msg->tti); + logger.info("Received %s for TTI=%d", basic_vnf_api::msg_type_text[msg->header.type], msg->tti); if (msg->pdus.type != basic_vnf_api::PUSCH) { - log_h->error("Received UL indication for wrong PDU type\n"); + logger.error("Received UL indication for wrong PDU type"); return SRSLTE_ERROR; } @@ -230,24 +226,25 @@ int srslte_basic_vnf::handle_ul_ind(basic_vnf_api::ul_ind_msg_t* msg) ul_grant.tti = msg->tti; ul_grant.tbs = msg->pdus.length; ul_grant.rnti = msg->rnti; - m_ue_stack->new_grant_ul(cc_idx, ul_grant); + srslte::unique_byte_buffer_t tx_pdu = srslte::make_byte_buffer(); + m_ue_stack->new_grant_ul(cc_idx, ul_grant, tx_pdu.get()); return SRSLTE_SUCCESS; } int srslte_basic_vnf::handle_rx_data_ind(basic_vnf_api::rx_data_ind_msg_t* msg) { - log_h->info("Received %s for TTI=%d\n", basic_vnf_api::msg_type_text[msg->header.type], msg->sfn); + logger.info("Received %s for TTI=%d", basic_vnf_api::msg_type_text[msg->header.type], msg->sfn); if (msg->nof_pdus != 1 || msg->pdus[0].type != basic_vnf_api::PUSCH) { - log_h->error("Received UL indication for wrong PDU type\n"); + logger.error("Received UL indication for wrong PDU type"); return SRSLTE_ERROR; } // fill struct srsenb::stack_interface_phy_nr::rx_data_ind_t rx_data = {}; rx_data.tti = msg->sfn; - rx_data.tb = srslte::allocate_unique_buffer(*m_pool); + rx_data.tb = srslte::make_byte_buffer(); if (rx_data.tb->get_tailroom() >= msg->pdus[0].length) { // copy actual data memcpy(rx_data.tb->msg, msg->pdus[0].data, msg->pdus[0].length); @@ -276,10 +273,10 @@ int srslte_basic_vnf::dl_config_request(const srsenb::phy_interface_stack_nr::dl uint32_t len = sizeof(dl_conf); // Send it to PNF - log_h->info("Sending %s (%d B)\n", basic_vnf_api::msg_type_text[dl_conf.header.type], len); + logger.info("Sending %s (%d B)", basic_vnf_api::msg_type_text[dl_conf.header.type], len); int n = 0; if ((n = sendto(sockfd, &dl_conf, len, MSG_CONFIRM, (struct sockaddr*)&client_addr, sizeof(client_addr))) < 0) { - log_h->error("sendto failed, ret=%d\n", n); + logger.error("sendto failed, ret=%d", n); } return 0; @@ -303,7 +300,7 @@ int srslte_basic_vnf::tx_request(const srsue::phy_interface_stack_nr::tx_request // copy data from TB0 memcpy(m_tx_req_msg->pdus[0].data, request.data, request.tb_len); } else { - log_h->error("Trying to send %d B PDU. Maximum size is %d B\n", request.tb_len, MAX_PDU_SIZE); + logger.error("Trying to send %d B PDU. Maximum size is %d B", request.tb_len, MAX_PDU_SIZE); } // calculate actual length of @@ -313,11 +310,11 @@ int srslte_basic_vnf::tx_request(const srsue::phy_interface_stack_nr::tx_request m_tx_req_msg->header.msg_len = len - sizeof(basic_vnf_api::msg_header_t); // Send it to PNF - log_h->info("Sending %s (%d B)\n", basic_vnf_api::msg_type_text[m_tx_req_msg->header.type], len); + logger.info("Sending %s (%d B)", basic_vnf_api::msg_type_text[m_tx_req_msg->header.type], len); int n = 0; if ((n = sendto(sockfd, m_tx_req_msg.get(), len, MSG_CONFIRM, (struct sockaddr*)&client_addr, sizeof(client_addr))) < 0) { - log_h->error("sendto failed, ret=%d\n", n); + logger.error("sendto failed, ret=%d", n); } return 0; @@ -326,7 +323,7 @@ int srslte_basic_vnf::tx_request(const srsue::phy_interface_stack_nr::tx_request int srslte_basic_vnf::tx_request(const srsenb::phy_interface_stack_nr::tx_request_t& request) { if (request.nof_pdus > MAX_NUM_PDUS) { - log_h->error("Trying to send %d PDUs but only %d supported\n", request.nof_pdus, MAX_NUM_PDUS); + logger.error("Trying to send %d PDUs but only %d supported", request.nof_pdus, MAX_NUM_PDUS); return SRSLTE_ERROR; } if (request.nof_pdus == 0) { @@ -348,7 +345,7 @@ int srslte_basic_vnf::tx_request(const srsenb::phy_interface_stack_nr::tx_reques // copy data from TB0 memcpy(m_tx_req_msg->pdus[i].data, request.pdus[i].data[0], m_tx_req_msg->pdus[i].length); } else { - log_h->error("Trying to send %d B PDU. Maximum size is %d B\n", request.pdus[i].length, MAX_PDU_SIZE); + logger.error("Trying to send %d B PDU. Maximum size is %d B", request.pdus[i].length, MAX_PDU_SIZE); } } @@ -359,21 +356,21 @@ int srslte_basic_vnf::tx_request(const srsenb::phy_interface_stack_nr::tx_reques m_tx_req_msg->header.msg_len = len - sizeof(basic_vnf_api::msg_header_t); // Send it to PNF - log_h->info("Sending %s (%d B)\n", basic_vnf_api::msg_type_text[m_tx_req_msg->header.type], len); - if (log_h->get_level() == LOG_LEVEL_DEBUG) { + logger.info("Sending %s (%d B)", basic_vnf_api::msg_type_text[m_tx_req_msg->header.type], len); + if (logger.debug.enabled()) { for (uint32_t i = 0; i < m_tx_req_msg->nof_pdus; ++i) { - log_h->debug_hex(m_tx_req_msg->pdus[i].data, - m_tx_req_msg->pdus[i].length, - "Sending PDU %s:%d (%d bytes)\n", - basic_vnf_api::msg_type_text[m_tx_req_msg->header.type], - m_tx_req_msg->pdus[i].index, - m_tx_req_msg->pdus[i].length); + logger.debug(m_tx_req_msg->pdus[i].data, + m_tx_req_msg->pdus[i].length, + "Sending PDU %s:%d (%d bytes)", + basic_vnf_api::msg_type_text[m_tx_req_msg->header.type], + m_tx_req_msg->pdus[i].index, + m_tx_req_msg->pdus[i].length); } } int n = 0; if ((n = sendto(sockfd, m_tx_req_msg.get(), len, MSG_CONFIRM, (struct sockaddr*)&client_addr, sizeof(client_addr))) < 0) { - log_h->error("sendto failed, ret=%d\n", n); + logger.error("sendto failed, ret=%d", n); } return 0; diff --git a/lib/src/common/buffer_pool.cc b/lib/src/common/buffer_pool.cc index 0fa7a99d4..16bae6bd0 100644 --- a/lib/src/common/buffer_pool.cc +++ b/lib/src/common/buffer_pool.cc @@ -24,28 +24,4 @@ #include #include -namespace srslte { - -std::unique_ptr byte_buffer_pool::instance; -static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; - -byte_buffer_pool* byte_buffer_pool::get_instance(int capacity) -{ - pthread_mutex_lock(&instance_mutex); - if (!instance) { - instance = std::unique_ptr(new byte_buffer_pool(capacity)); - } - pthread_mutex_unlock(&instance_mutex); - return instance.get(); -} - -void byte_buffer_pool::cleanup() -{ - pthread_mutex_lock(&instance_mutex); - if (instance) { - instance.reset(); - } - pthread_mutex_unlock(&instance_mutex); -} - -} // namespace srslte +namespace srslte {} // namespace srslte diff --git a/lib/src/common/byte_buffer.cc b/lib/src/common/byte_buffer.cc new file mode 100644 index 000000000..7a46c0008 --- /dev/null +++ b/lib/src/common/byte_buffer.cc @@ -0,0 +1,39 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/byte_buffer.h" +#include "srslte/common/buffer_pool.h" + +namespace srslte { + +void* byte_buffer_t::operator new(size_t sz, const std::nothrow_t& nothrow_value) noexcept +{ + assert(sz == sizeof(byte_buffer_t)); + return byte_buffer_pool::get_instance()->allocate(nullptr, false); +} + +void* byte_buffer_t::operator new(size_t sz) +{ + assert(sz == sizeof(byte_buffer_t)); + void* ptr = byte_buffer_pool::get_instance()->allocate(nullptr, false); + if (ptr == nullptr) { + throw std::bad_alloc(); + } + return ptr; +} + +void byte_buffer_t::operator delete(void* ptr) +{ + byte_buffer_pool::get_instance()->deallocate(ptr); +} + +} // namespace srslte diff --git a/lib/src/common/crash_handler.c b/lib/src/common/crash_handler.cc similarity index 90% rename from lib/src/common/crash_handler.c rename to lib/src/common/crash_handler.cc index 1234e92fc..051e079ad 100644 --- a/lib/src/common/crash_handler.c +++ b/lib/src/common/crash_handler.cc @@ -24,8 +24,17 @@ #include #include -#include "srslte/common/backtrace.h" #include "srslte/common/crash_handler.h" + +#if HAVE_BACKWARD +#include "srslte/common/backward.hpp" +using namespace backward; +void srslte_debug_handle_crash(int argc, char** argv) +{ + backward::SignalHandling sh; +} +#else // HAVE_BACKWARD +#include "srslte/common/backtrace.h" #include "srslte/version.h" const static char crash_file_name[] = "./srsLTE.backtrace.crash"; @@ -74,3 +83,5 @@ void srslte_debug_handle_crash(int argc, char** argv) signal(SIGFPE, crash_handler); signal(SIGPIPE, crash_handler); } + +#endif // HAVE_BACKWARD \ No newline at end of file diff --git a/lib/src/common/enb_events.cc b/lib/src/common/enb_events.cc index 1bac71f37..1dbf356ef 100644 --- a/lib/src/common/enb_events.cc +++ b/lib/src/common/enb_events.cc @@ -31,40 +31,89 @@ namespace { class null_event_logger : public event_logger_interface { public: - void log_rrc_connected(unsigned cause) override {} - void log_rrc_disconnect(unsigned reason) override {} - void log_s1_ctx_create(uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override {} - void log_s1_ctx_delete(uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override {} + void log_rrc_connected(uint32_t enb_cc_idx, const std::string& asn1, unsigned error_code, uint16_t rnti) override {} + void log_rrc_disconnect(uint32_t enb_cc_idx, unsigned reason, uint16_t rnti) override {} + void log_s1_ctx_create(uint32_t enb_cc_idx, uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override {} + void log_s1_ctx_delete(uint32_t enb_cc_idx, uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override {} void log_sector_start(uint32_t cc_idx, uint32_t pci, uint32_t cell_id) override {} void log_sector_stop(uint32_t cc_idx, uint32_t pci, uint32_t cell_id) override {} + void log_measurement_report(uint32_t enb_cc_idx, const std::string& asn1, uint16_t rnti) override {} + void log_rlf(uint32_t enb_cc_idx, const std::string& asn1, uint16_t rnti) override {} }; } // namespace +/// Returns the current time in seconds with ms precision since UNIX epoch. +static double get_time_stamp() +{ + auto tp = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(tp).count() * 1e-3; +} + namespace { /// Common metrics to all events. DECLARE_METRIC("type", metric_type_tag, std::string, ""); +DECLARE_METRIC("timestamp", metric_timestamp_tag, double, ""); +DECLARE_METRIC("sector_id", metric_sector_id, uint32_t, ""); DECLARE_METRIC("event_name", metric_event_name, std::string, ""); +DECLARE_METRIC("rnti", metric_rnti, uint16_t, ""); + +/// ASN1 message metrics. +DECLARE_METRIC("asn1_length", metric_asn1_length, uint32_t, ""); +DECLARE_METRIC("asn1_message", metric_asn1_message, std::string, ""); + /// Context for sector start/stop. DECLARE_METRIC("pci", metric_pci, uint32_t, ""); -DECLARE_METRIC("cell_identity", metric_cell_identity, uint32_t, ""); -DECLARE_METRIC("sector_id", metric_sector_id, uint32_t, ""); -DECLARE_METRIC_SET("event_data", mset_sector_event, metric_pci, metric_cell_identity, metric_sector_id); -using sector_event_t = srslog::build_context_type; +DECLARE_METRIC("cell_identity", metric_cell_identity, std::string, ""); +DECLARE_METRIC("sib9_home_enb_name", metric_sib9_home_enb_name, std::string, ""); +DECLARE_METRIC_SET("event_data", mset_sector_event, metric_pci, metric_cell_identity, metric_sib9_home_enb_name); +using sector_event_t = srslog:: + build_context_type; -/// Context for RRC connect/disconnect. -DECLARE_METRIC("cause", metric_cause, uint32_t, ""); -DECLARE_METRIC_SET("event_data", mset_rrc_event, metric_cause); -using rrc_event_t = srslog::build_context_type; +/// Context for RRC connect. +DECLARE_METRIC("error_code", metric_error_code, uint32_t, ""); +DECLARE_METRIC_SET("event_data", + mset_rrc_connect_event, + metric_rnti, + metric_asn1_length, + metric_asn1_message, + metric_error_code); +using rrc_connect_event_t = srslog::build_context_type; + +/// Context for RRC disconnect. +DECLARE_METRIC("reason", metric_reason, uint32_t, ""); +DECLARE_METRIC_SET("event_data", mset_rrc_disconnect_event, metric_reason, metric_rnti); +using rrc_disconnect_event_t = srslog::build_context_type; /// Context for S1 context create/delete. DECLARE_METRIC("mme_ue_s1ap_id", metric_ue_mme_id, uint32_t, ""); DECLARE_METRIC("enb_ue_s1ap_id", metric_ue_enb_id, uint32_t, ""); -DECLARE_METRIC("rnti", metric_rnti, uint16_t, ""); DECLARE_METRIC_SET("event_data", mset_s1apctx_event, metric_ue_mme_id, metric_ue_enb_id, metric_rnti); -using s1apctx_event_t = srslog::build_context_type; +using s1apctx_event_t = srslog:: + build_context_type; + +/// Context for the RLF event. +DECLARE_METRIC_SET("event_data", mset_rlfctx_event, metric_asn1_length, metric_asn1_message, metric_rnti); +using rlfctx_event_t = srslog:: + build_context_type; + +/// Context for measurement report. +DECLARE_METRIC_SET("event_data", mset_meas_report_event, metric_asn1_length, metric_asn1_message, metric_rnti); +using meas_report_event_t = srslog::build_context_type; /// Logs events into the configured log channel. class logging_event_logger : public event_logger_interface @@ -72,31 +121,41 @@ class logging_event_logger : public event_logger_interface public: explicit logging_event_logger(srslog::log_channel& c) : event_channel(c) {} - void log_rrc_connected(unsigned cause) override + void log_rrc_connected(uint32_t enb_cc_idx, const std::string& asn1, unsigned error_code, uint16_t rnti) override { - rrc_event_t ctx(""); + rrc_connect_event_t ctx(""); ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(enb_cc_idx); ctx.write("rrc_connect"); - ctx.get().write(cause); + ctx.get().write(rnti); + ctx.get().write(asn1.size()); + ctx.get().write(asn1); + ctx.get().write(error_code); event_channel(ctx); } - void log_rrc_disconnect(unsigned reason) override + void log_rrc_disconnect(uint32_t enb_cc_idx, unsigned reason, uint16_t rnti) override { - rrc_event_t ctx(""); + rrc_disconnect_event_t ctx(""); ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(enb_cc_idx); ctx.write("rrc_disconnect"); - ctx.get().write(reason); + ctx.get().write(reason); + ctx.get().write(rnti); event_channel(ctx); } - void log_s1_ctx_create(uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override + void log_s1_ctx_create(uint32_t enb_cc_idx, uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override { s1apctx_event_t ctx(""); ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(enb_cc_idx); ctx.write("s1_context_create"); ctx.get().write(mme_id); ctx.get().write(enb_id); @@ -104,11 +163,13 @@ public: event_channel(ctx); } - void log_s1_ctx_delete(uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override + void log_s1_ctx_delete(uint32_t enb_cc_idx, uint32_t mme_id, uint32_t enb_id, uint16_t rnti) override { s1apctx_event_t ctx(""); ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(enb_cc_idx); ctx.write("s1_context_delete"); ctx.get().write(mme_id); ctx.get().write(enb_id); @@ -121,10 +182,12 @@ public: sector_event_t ctx(""); ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(cc_idx); ctx.write("sector_start"); ctx.get().write(pci); - ctx.get().write(cell_id); - ctx.get().write(cc_idx); + ctx.get().write(fmt::to_string(cell_id)); + ctx.get().write("TODO"); event_channel(ctx); } @@ -133,10 +196,40 @@ public: sector_event_t ctx(""); ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(cc_idx); ctx.write("sector_stop"); ctx.get().write(pci); - ctx.get().write(cell_id); - ctx.get().write(cc_idx); + ctx.get().write(fmt::to_string(cell_id)); + ctx.get().write("TODO"); + event_channel(ctx); + } + + void log_measurement_report(uint32_t enb_cc_idx, const std::string& asn1, uint16_t rnti) override + { + meas_report_event_t ctx(""); + + ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(enb_cc_idx); + ctx.write("measurement_report"); + ctx.get().write(asn1.size()); + ctx.get().write(asn1); + ctx.get().write(rnti); + event_channel(ctx); + } + + void log_rlf(uint32_t enb_cc_idx, const std::string& asn1, uint16_t rnti) override + { + rlfctx_event_t ctx(""); + + ctx.write("event"); + ctx.write(get_time_stamp()); + ctx.write(enb_cc_idx); + ctx.write("radio_link_failure"); + ctx.get().write(asn1.size()); + ctx.get().write(asn1); + ctx.get().write(rnti); event_channel(ctx); } diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index 5802a1b3f..5c84c75b2 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -291,7 +291,7 @@ std::string log_filter::hex_string(const uint8_t* hex, int size) size = (size > hex_limit) ? hex_limit : size; } while (c < size) { - ss << " " << std::setw(4) << static_cast(c) << ": "; + ss << " " << std::setw(4) << static_cast(c) << ": "; int tmp = (size - c < 16) ? size - c : 16; for (int i = 0; i < tmp; i++) { ss << std::setw(2) << static_cast(hex[c++]) << " "; diff --git a/lib/src/common/mac_nr_pcap.cc b/lib/src/common/mac_nr_pcap.cc deleted file mode 100644 index 8b4f4a680..000000000 --- a/lib/src/common/mac_nr_pcap.cc +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srslte/common/mac_nr_pcap.h" -#include "srslte/common/pcap.h" -#include - -namespace srslte { - -mac_nr_pcap::mac_nr_pcap() {} - -mac_nr_pcap::~mac_nr_pcap() -{ - if (pcap_file) { - close(); - } -} - -void mac_nr_pcap::enable(const bool& enable_) -{ - enable_write = enable_; -} -void mac_nr_pcap::open(const std::string& filename_, const uint16_t& ue_id_) -{ - fprintf(stdout, "Opening MAC-NR PCAP with DLT=%d\n", UDP_DLT); - filename = filename_; - pcap_file = LTE_PCAP_Open(UDP_DLT, filename.c_str()); - ue_id = ue_id_; - enable_write = true; -} -void mac_nr_pcap::close() -{ - enable_write = false; - fprintf(stdout, "Saving MAC-NR PCAP to %s\n", filename.c_str()); - LTE_PCAP_Close(pcap_file); - pcap_file = nullptr; -} - -void mac_nr_pcap::set_ue_id(const uint16_t& ue_id_) -{ - ue_id = ue_id_; -} - -void mac_nr_pcap::pack_and_write(uint8_t* pdu, - uint32_t pdu_len_bytes, - uint32_t tti, - uint16_t crnti, - uint8_t harqid, - uint8_t direction, - uint8_t rnti_type) -{ - if (enable_write) { - mac_nr_context_info_t context = {}; - context.radioType = FDD_RADIO; - context.direction = direction; - context.rntiType = rnti_type; - context.rnti = crnti; - context.ueid = ue_id; - context.harqid = harqid; - context.system_frame_number = tti / 10; - context.sub_frame_number = tti % 10; - - if (pdu) { - NR_PCAP_MAC_WritePDU(pcap_file, &context, pdu, pdu_len_bytes); - } - } -} - -void mac_nr_pcap::write_dl_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) -{ - pack_and_write(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, C_RNTI); -} - -void mac_nr_pcap::write_ul_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) -{ - pack_and_write(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_UPLINK, C_RNTI); -} - -void mac_nr_pcap::write_dl_ra_rnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) -{ - pack_and_write(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, RA_RNTI); -} - -void mac_nr_pcap::write_dl_bch(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) -{ - pack_and_write(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, NO_RNTI); -} - -void mac_nr_pcap::write_dl_pch(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) -{ - pack_and_write(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, P_RNTI); -} - -void mac_nr_pcap::write_dl_si_rnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) -{ - pack_and_write(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, SI_RNTI); -} - -} // namespace srslte diff --git a/lib/src/common/mac_pcap.cc b/lib/src/common/mac_pcap.cc index 7f588d4d2..b7653d753 100644 --- a/lib/src/common/mac_pcap.cc +++ b/lib/src/common/mac_pcap.cc @@ -26,8 +26,8 @@ namespace srslte { -mac_pcap::mac_pcap() : - pool(srslte::byte_buffer_pool::get_instance()), log(srslte::logmap::get("MAC")), thread("PCAP_WRITER") +mac_pcap::mac_pcap(srslte_rat_t rat_) : + logger(srslog::fetch_basic_logger("MAC")), thread("PCAP_WRITER_" + to_string(rat_)), rat(rat_) {} mac_pcap::~mac_pcap() @@ -41,22 +41,36 @@ void mac_pcap::enable(bool enable_) running = enable_; } -uint32_t mac_pcap::open(const char* filename, uint32_t ue_id_) +uint32_t mac_pcap::open(std::string filename_, uint32_t ue_id_) { std::lock_guard lock(mutex); if (pcap_file != nullptr) { - log->error("PCAP writer already running. Close first.\n"); + logger.error("PCAP writer for %s already running. Close first.", filename_.c_str()); return SRSLTE_ERROR; } - pcap_file = LTE_PCAP_Open(MAC_LTE_DLT, filename); + // set DLT for selected RAT + switch (rat) { + case srslte_rat_t::lte: + dlt = MAC_LTE_DLT; + break; + case srslte_rat_t::nr: + dlt = UDP_DLT; + break; + default: + logger.error("Error opening PCAP. Unsupported RAT selected."); + return SRSLTE_ERROR; + } + + pcap_file = LTE_PCAP_Open(dlt, filename_.c_str()); if (pcap_file == nullptr) { - log->error("Couldn't open file to write PCAP\n"); + logger.error("Couldn't open %s to write PCAP", filename_.c_str()); return SRSLTE_ERROR; } - ue_id = ue_id_; - running = true; + filename = filename_; + ue_id = ue_id_; + running = true; // start writer thread start(); @@ -83,7 +97,7 @@ uint32_t mac_pcap::close() // close file handle { std::lock_guard lock(mutex); - srslte::console("Saving MAC PCAP file\n"); + srslte::console("Saving %s MAC PCAP (DLT=%d) to %s\n", to_string(rat).c_str(), dlt, filename.c_str()); LTE_PCAP_Close(pcap_file); pcap_file = nullptr; } @@ -94,7 +108,16 @@ uint32_t mac_pcap::close() void mac_pcap::write_pdu(pcap_pdu_t& pdu) { if (pdu.pdu != nullptr) { - LTE_PCAP_MAC_WritePDU(pcap_file, &pdu.context, pdu.pdu->msg, pdu.pdu->N_bytes); + switch (rat) { + case srslte_rat_t::lte: + LTE_PCAP_MAC_WritePDU(pcap_file, &pdu.context, pdu.pdu->msg, pdu.pdu->N_bytes); + break; + case srslte_rat_t::nr: + NR_PCAP_MAC_WritePDU(pcap_file, &pdu.context_nr, pdu.pdu->msg, pdu.pdu->N_bytes); + break; + default: + logger.error("Error writing PDU to PCAP. Unsupported RAT selected."); + } } } @@ -148,14 +171,47 @@ void mac_pcap::pack_and_queue(uint8_t* payload, pdu.context.subFrameNumber = (uint16_t)(tti % 10); // try to allocate PDU buffer - pdu.pdu = srslte::allocate_unique_buffer(*pool); + pdu.pdu = srslte::make_byte_buffer(); if (pdu.pdu != nullptr && pdu.pdu->get_tailroom() >= payload_len) { // copy payload into PDU buffer memcpy(pdu.pdu->msg, payload, payload_len); pdu.pdu->N_bytes = payload_len; queue.push(std::move(pdu)); } else { - log->info("Dropping PDU in PCAP. No buffer available or not enough space (pdu_len=%d).\n", payload_len); + logger.info("Dropping PDU in PCAP. No buffer available or not enough space (pdu_len=%d).", payload_len); + } + } +} + +// Function called from PHY worker context, locking not needed as PDU queue is thread-safe +void mac_pcap::pack_and_queue_nr(uint8_t* payload, + uint32_t payload_len, + uint32_t tti, + uint16_t crnti, + uint8_t harqid, + uint8_t direction, + uint8_t rnti_type) +{ + if (running && payload != nullptr) { + pcap_pdu_t pdu = {}; + pdu.context_nr.radioType = FDD_RADIO; + pdu.context_nr.direction = direction; + pdu.context_nr.rntiType = rnti_type; + pdu.context_nr.rnti = crnti; + pdu.context_nr.ueid = ue_id; + pdu.context_nr.harqid = harqid; + pdu.context_nr.system_frame_number = tti / 10; + pdu.context_nr.sub_frame_number = tti % 10; + + // try to allocate PDU buffer + pdu.pdu = srslte::make_byte_buffer(); + if (pdu.pdu != nullptr && pdu.pdu->get_tailroom() >= payload_len) { + // copy payload into PDU buffer + memcpy(pdu.pdu->msg, payload, payload_len); + pdu.pdu->N_bytes = payload_len; + queue.push(std::move(pdu)); + } else { + logger.info("Dropping PDU in NR PCAP. No buffer available or not enough space (pdu_len=%d).", payload_len); } } } @@ -215,6 +271,36 @@ void mac_pcap::write_dl_sirnti(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok pack_and_queue(pdu, pdu_len_bytes, 0, crc_ok, cc_idx, tti, SRSLTE_SIRNTI, DIRECTION_DOWNLINK, SI_RNTI); } +void mac_pcap::write_dl_crnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) +{ + pack_and_queue_nr(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, C_RNTI); +} + +void mac_pcap::write_ul_crnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) +{ + pack_and_queue_nr(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_UPLINK, C_RNTI); +} + +void mac_pcap::write_dl_ra_rnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) +{ + pack_and_queue_nr(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, RA_RNTI); +} + +void mac_pcap::write_dl_bch_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) +{ + pack_and_queue_nr(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, NO_RNTI); +} + +void mac_pcap::write_dl_pch_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) +{ + pack_and_queue_nr(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, P_RNTI); +} + +void mac_pcap::write_dl_si_rnti_nr(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint8_t harqid, uint32_t tti) +{ + pack_and_queue_nr(pdu, pdu_len_bytes, tti, rnti, harqid, DIRECTION_DOWNLINK, SI_RNTI); +} + void mac_pcap::write_ul_rrc_pdu(const uint8_t* input, const int32_t input_len) { uint8_t pdu[1024]; @@ -222,7 +308,7 @@ void mac_pcap::write_ul_rrc_pdu(const uint8_t* input, const int32_t input_len) // Size is limited by PDU buffer and MAC subheader (format 1 < 128 B) if (input_len > 128 - 7) { - log->error("PDU too large.\n"); + logger.error("PDU too large."); return; } diff --git a/lib/src/common/network_utils.cc b/lib/src/common/network_utils.cc index 647908ece..431c23e80 100644 --- a/lib/src/common/network_utils.cc +++ b/lib/src/common/network_utils.cc @@ -25,10 +25,10 @@ #include #include -#define rxSockError(fmt, ...) log_h->error("%s: " fmt, name.c_str(), ##__VA_ARGS__) -#define rxSockWarn(fmt, ...) log_h->warning("%s: " fmt, name.c_str(), ##__VA_ARGS__) -#define rxSockInfo(fmt, ...) log_h->info("%s: " fmt, name.c_str(), ##__VA_ARGS__) -#define rxSockDebug(fmt, ...) log_h->debug("%s: " fmt, name.c_str(), ##__VA_ARGS__) +#define rxSockError(fmt, ...) logger.error("%s: " fmt, name.c_str(), ##__VA_ARGS__) +#define rxSockWarn(fmt, ...) logger.warning("%s: " fmt, name.c_str(), ##__VA_ARGS__) +#define rxSockInfo(fmt, ...) logger.info("%s: " fmt, name.c_str(), ##__VA_ARGS__) +#define rxSockDebug(fmt, ...) logger.debug("%s: " fmt, name.c_str(), ##__VA_ARGS__) namespace srslte { @@ -113,7 +113,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty { int fd = socket((int)ip_type, (int)socket_type, (int)protocol); if (fd == -1) { - srslte::logmap::get(LOGSERVICE)->error("Failed to open %s socket.\n", net_utils::protocol_to_string(protocol)); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to open %s socket.", net_utils::protocol_to_string(protocol)); perror("Could not create socket\n"); return -1; } @@ -127,7 +127,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty evnts.sctp_shutdown_event = 1; evnts.sctp_address_event = 1; if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { - srslte::logmap::get(LOGSERVICE)->error("Failed to subscribe to SCTP_SHUTDOWN event: %s\n", strerror(errno)); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno)); perror("Could not regiester socket to SCTP events\n"); } @@ -147,9 +147,9 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty rto_opts.srto_max = 6000; // 6 seconds - srslte::logmap::get(LOGSERVICE) - ->debug( - "Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d\n", + srslog::fetch_basic_logger(LOGSERVICE) + .debug( + "Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d", rto_opts.srto_assoc_id, rto_opts.srto_initial, rto_opts.srto_min, @@ -170,10 +170,10 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty init_opts.sinit_max_attempts = 3; init_opts.sinit_max_init_timeo = 5000; // 5 seconds - srslte::logmap::get(LOGSERVICE) - ->debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d\n", - init_opts.sinit_max_attempts, - init_opts.sinit_max_init_timeo); + srslog::fetch_basic_logger(LOGSERVICE) + .debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d", + init_opts.sinit_max_attempts, + init_opts.sinit_max_init_timeo); if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, init_sz) < 0) { perror("Error setting SCTP_INITMSG sockopts\n"); return -1; @@ -186,13 +186,13 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty bool bind_addr(int fd, const sockaddr_in& addr_in) { if (fd < 0) { - srslte::logmap::get(LOGSERVICE)->error("Trying to bind to a closed socket\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("Trying to bind to a closed socket"); return false; } if (bind(fd, (struct sockaddr*)&addr_in, sizeof(addr_in)) != 0) { - srslte::logmap::get(LOGSERVICE) - ->error("Failed to bind on address %s: %s errno %d\n", get_ip(addr_in).c_str(), strerror(errno), errno); + srslog::fetch_basic_logger(LOGSERVICE) + .error("Failed to bind on address %s: %s errno %d", get_ip(addr_in).c_str(), strerror(errno), errno); perror("bind()"); return false; } @@ -203,7 +203,8 @@ bool bind_addr(int fd, const char* bind_addr_str, int port, sockaddr_in* addr_re { sockaddr_in addr_tmp{}; if (not net_utils::set_sockaddr(&addr_tmp, bind_addr_str, port)) { - srslte::logmap::get(LOGSERVICE)->error("Failed to convert IP address (%s) to sockaddr_in struct\n", bind_addr_str); + srslog::fetch_basic_logger(LOGSERVICE) + .error("Failed to convert IP address (%s) to sockaddr_in struct", bind_addr_str); return false; } bind_addr(fd, addr_tmp); @@ -216,20 +217,20 @@ bool bind_addr(int fd, const char* bind_addr_str, int port, sockaddr_in* addr_re bool connect_to(int fd, const char* dest_addr_str, int dest_port, sockaddr_in* dest_sockaddr) { if (fd < 0) { - srslte::logmap::get(LOGSERVICE)->error("tried to connect to remote address with an invalid socket.\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("tried to connect to remote address with an invalid socket."); return false; } sockaddr_in sockaddr_tmp{}; if (not net_utils::set_sockaddr(&sockaddr_tmp, dest_addr_str, dest_port)) { - srslte::logmap::get(LOGSERVICE) - ->error("Error converting IP address (%s) to sockaddr_in structure\n", dest_addr_str); + srslog::fetch_basic_logger(LOGSERVICE) + .error("Error converting IP address (%s) to sockaddr_in structure", dest_addr_str); return false; } if (dest_sockaddr != nullptr) { *dest_sockaddr = sockaddr_tmp; } if (connect(fd, (const struct sockaddr*)&sockaddr_tmp, sizeof(sockaddr_tmp)) == -1) { - srslte::logmap::get(LOGSERVICE)->info("Failed to establish socket connection to %s\n", dest_addr_str); + srslog::fetch_basic_logger(LOGSERVICE).info("Failed to establish socket connection to %s", dest_addr_str); perror("connect()"); return false; } @@ -294,7 +295,7 @@ bool socket_handler_t::open_socket(net_utils::addr_family ip_type, net_utils::protocol_type protocol) { if (sockfd >= 0) { - srslte::logmap::get(LOGSERVICE)->error("Socket is already open.\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("Socket is already open."); return false; } sockfd = net_utils::open_socket(ip_type, socket_type, protocol); @@ -331,7 +332,7 @@ bool sctp_init_server(socket_handler_t* socket, net_utils::socket_type socktype, } // Listen for connections if (listen(socket->fd(), SOMAXCONN) != 0) { - srslte::logmap::get(LOGSERVICE)->error("Failed to listen to incoming SCTP connections\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to listen to incoming SCTP connections"); return false; } return true; @@ -352,7 +353,7 @@ bool tcp_make_server(socket_handler_t* socket, const char* bind_addr_str, int po } // Listen for connections if (listen(socket->fd(), nof_connections) != 0) { - srslte::logmap::get(LOGSERVICE)->error("Failed to listen to incoming TCP connections\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to listen to incoming TCP connections"); return false; } return true; @@ -363,7 +364,7 @@ int tcp_accept(socket_handler_t* socket, sockaddr_in* destaddr) socklen_t clilen = sizeof(destaddr); int connfd = accept(socket->fd(), (struct sockaddr*)&destaddr, &clilen); if (connfd < 0) { - srslte::logmap::get(LOGSERVICE)->error("Failed to accept connection\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to accept connection"); perror("accept"); return -1; } @@ -374,12 +375,12 @@ int tcp_read(int remotefd, void* buf, size_t nbytes) { int n = ::read(remotefd, buf, nbytes); if (n == 0) { - srslte::logmap::get(LOGSERVICE)->info("TCP connection closed\n"); + srslog::fetch_basic_logger(LOGSERVICE).info("TCP connection closed"); close(remotefd); return 0; } if (n == -1) { - srslte::logmap::get(LOGSERVICE)->error("Failed to read from TCP socket."); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to read from TCP socket."); perror("TCP read"); } return n; @@ -393,7 +394,7 @@ int tcp_send(int remotefd, const void* buf, size_t nbytes) while (nbytes_remaining > 0) { ssize_t i = ::send(remotefd, ptr, nbytes_remaining, 0); if (i < 1) { - srslte::logmap::get(LOGSERVICE)->error("Failed to send data to TCP socket\n"); + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to send data to TCP socket"); perror("Error calling send()\n"); return i; } @@ -417,23 +418,21 @@ class recvfrom_pdu_task final : public rx_multisocket_handler::recv_task { public: using callback_t = std::function; - explicit recvfrom_pdu_task(srslte::byte_buffer_pool* pool_, srslte::log_ref log_, callback_t func_) : - pool(pool_), log_h(log_), func(std::move(func_)) - {} + explicit recvfrom_pdu_task(srslog::basic_logger& logger, callback_t func_) : logger(logger), func(std::move(func_)) {} bool operator()(int fd) override { - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, "Rxsocket", true); + srslte::unique_byte_buffer_t pdu(new byte_buffer_t()); sockaddr_in from = {}; socklen_t fromlen = sizeof(from); ssize_t n_recv = recvfrom(fd, pdu->msg, pdu->get_tailroom(), 0, (struct sockaddr*)&from, &fromlen); if (n_recv == -1 and errno != EAGAIN) { - log_h->error("Error reading from socket: %s\n", strerror(errno)); + logger.error("Error reading from socket: %s", strerror(errno)); return true; } if (n_recv == -1 and errno == EAGAIN) { - log_h->debug("Socket timeout reached\n"); + logger.debug("Socket timeout reached"); return true; } @@ -443,9 +442,8 @@ public: } private: - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref log_h; - callback_t func; + srslog::basic_logger& logger; + callback_t func; }; class sctp_recvmsg_pdu_task final : public rx_multisocket_handler::recv_task @@ -453,25 +451,25 @@ class sctp_recvmsg_pdu_task final : public rx_multisocket_handler::recv_task public: using callback_t = std::function< void(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags)>; - explicit sctp_recvmsg_pdu_task(srslte::byte_buffer_pool* pool_, srslte::log_ref log_, callback_t func_) : - pool(pool_), log_h(log_), func(std::move(func_)) + explicit sctp_recvmsg_pdu_task(srslog::basic_logger& logger, callback_t func_) : + logger(logger), func(std::move(func_)) {} bool operator()(int fd) override { // inside rx_sockets thread. Read socket - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, "Rxsocket", true); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); sockaddr_in from = {}; socklen_t fromlen = sizeof(from); sctp_sndrcvinfo sri = {}; int flags = 0; ssize_t n_recv = sctp_recvmsg(fd, pdu->msg, pdu->get_tailroom(), (struct sockaddr*)&from, &fromlen, &sri, &flags); if (n_recv == -1 and errno != EAGAIN) { - log_h->error("Error reading from SCTP socket: %s\n", strerror(errno)); + logger.error("Error reading from SCTP socket: %s", strerror(errno)); return true; } if (n_recv == -1 and errno == EAGAIN) { - log_h->debug("Socket timeout reached\n"); + logger.debug("Socket timeout reached"); return true; } @@ -490,22 +488,20 @@ public: } private: - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref log_h; - callback_t func; + srslog::basic_logger& logger; + callback_t func; }; /*************************************************************** * Rx Multisocket Handler **************************************************************/ -rx_multisocket_handler::rx_multisocket_handler(std::string name_, srslte::log_ref log_, int thread_prio) : - thread(name_), name(std::move(name_)), log_h(log_) +rx_multisocket_handler::rx_multisocket_handler(std::string name_, srslog::basic_logger& logger, int thread_prio) : + thread(name_), name(std::move(name_)), logger(logger) { - pool = srslte::byte_buffer_pool::get_instance(); // register control pipe fd if (pipe(pipefd) == -1) { - rxSockInfo("Failed to open control pipe\n"); + rxSockInfo("Failed to open control pipe"); return; } start(thread_prio); @@ -525,10 +521,10 @@ void rx_multisocket_handler::stop() ctrl_cmd_t msg{}; msg.cmd = ctrl_cmd_t::cmd_id_t::EXIT; if (write(pipefd[1], &msg, sizeof(msg)) != sizeof(msg)) { - rxSockError("while writing to control pipe\n"); + rxSockError("while writing to control pipe"); } } - rxSockDebug("Closing rx socket handler thread\n"); + rxSockDebug("Closing rx socket handler thread"); wait_thread_finish(); } @@ -537,7 +533,7 @@ void rx_multisocket_handler::stop() close(pipefd[1]); pipefd[0] = -1; pipefd[1] = -1; - rxSockDebug("closed.\n"); + rxSockDebug("closed."); } } @@ -547,7 +543,7 @@ void rx_multisocket_handler::stop() bool rx_multisocket_handler::add_socket_pdu_handler(int fd, recvfrom_callback_t pdu_task) { std::unique_ptr task; - task.reset(new srslte::recvfrom_pdu_task(pool, log_h, std::move(pdu_task))); + task.reset(new srslte::recvfrom_pdu_task(logger, std::move(pdu_task))); return add_socket_handler(fd, std::move(task)); } @@ -557,7 +553,7 @@ bool rx_multisocket_handler::add_socket_pdu_handler(int fd, recvfrom_callback_t bool rx_multisocket_handler::add_socket_sctp_pdu_handler(int fd, sctp_recv_callback_t pdu_task) { srslte::rx_multisocket_handler::task_callback_t task; - task.reset(new srslte::sctp_recvmsg_pdu_task(pool, log_h, std::move(pdu_task))); + task.reset(new srslte::sctp_recvmsg_pdu_task(logger, std::move(pdu_task))); return add_socket_handler(fd, std::move(task)); } @@ -565,11 +561,11 @@ bool rx_multisocket_handler::add_socket_handler(int fd, task_callback_t handler) { std::lock_guard lock(socket_mutex); if (fd < 0) { - rxSockError("Provided SCTP socket must be already open\n"); + rxSockError("Provided SCTP socket must be already open"); return false; } if (active_sockets.count(fd) > 0) { - rxSockError("Tried to register fd=%d, but this fd already exists\n", fd); + rxSockError("Tried to register fd=%d, but this fd already exists", fd); return false; } @@ -580,11 +576,11 @@ bool rx_multisocket_handler::add_socket_handler(int fd, task_callback_t handler) msg.cmd = ctrl_cmd_t::cmd_id_t::NEW_FD; msg.new_fd = fd; if (write(pipefd[1], &msg, sizeof(msg)) != sizeof(msg)) { - rxSockError("while writing to control pipe\n"); + rxSockError("while writing to control pipe"); return false; } - rxSockDebug("socket fd=%d has been registered.\n", fd); + rxSockDebug("socket fd=%d has been registered.", fd); return true; } @@ -593,7 +589,7 @@ bool rx_multisocket_handler::remove_socket(int fd) std::lock_guard lock(socket_mutex); auto it = active_sockets.find(fd); if (it == active_sockets.end()) { - rxSockError("The socket fd=%d to be removed does not exist\n", fd); + rxSockError("The socket fd=%d to be removed does not exist", fd); return false; } @@ -601,24 +597,26 @@ bool rx_multisocket_handler::remove_socket(int fd) msg.cmd = ctrl_cmd_t::cmd_id_t::RM_FD; msg.new_fd = fd; if (write(pipefd[1], &msg, sizeof(msg)) != sizeof(msg)) { - rxSockError("while writing to control pipe\n"); + rxSockError("while writing to control pipe"); return false; } return true; } -bool rx_multisocket_handler::remove_socket_unprotected(int fd, fd_set* total_fd_set, int* max_fd) +std::map::iterator +rx_multisocket_handler::remove_socket_unprotected(int fd, fd_set* total_fd_set, int* max_fd) { if (fd < 0) { - rxSockError("fd to be removed is not valid\n"); - return false; + rxSockError("fd to be removed is not valid"); + return active_sockets.end(); } - active_sockets.erase(fd); + auto it = active_sockets.find(fd); + it = active_sockets.erase(it); FD_CLR(fd, total_fd_set); // assumes ordering *max_fd = (active_sockets.empty()) ? pipefd[0] : std::max(pipefd[0], active_sockets.rbegin()->first); - rxSockDebug("Socket fd=%d has been successfully removed\n", fd); - return true; + rxSockDebug("Socket fd=%d has been successfully removed", fd); + return it; } void rx_multisocket_handler::run_thread() @@ -641,7 +639,7 @@ void rx_multisocket_handler::run_thread() continue; } if (n == 0) { - rxSockDebug("No data from select.\n"); + rxSockDebug("No data from select."); continue; } @@ -649,16 +647,19 @@ void rx_multisocket_handler::run_thread() std::lock_guard lock(socket_mutex); // call read callback for all SCTP/TCP/UDP connections - for (auto& handler_pair : active_sockets) { - int fd = handler_pair.first; - recv_task* callback = handler_pair.second.get(); + for (auto handler_it = active_sockets.begin(); handler_it != active_sockets.end();) { + int fd = handler_it->first; + recv_task* callback = handler_it->second.get(); if (not FD_ISSET(fd, &read_fd_set)) { + ++handler_it; continue; } bool socket_valid = callback->operator()(fd); if (not socket_valid) { - rxSockInfo("The socket fd=%d has been closed by peer\n", fd); - remove_socket_unprotected(fd, &total_fd_set, &max_fd); + rxSockInfo("The socket fd=%d has been closed by peer", fd); + handler_it = remove_socket_unprotected(fd, &total_fd_set, &max_fd); + } else { + ++handler_it; } } @@ -667,7 +668,7 @@ void rx_multisocket_handler::run_thread() ctrl_cmd_t msg; ssize_t nrd = read(pipefd[0], &msg, sizeof(msg)); if (nrd <= 0) { - rxSockError("Unable to read control message.\n"); + rxSockError("Unable to read control message."); continue; } switch (msg.cmd) { @@ -679,15 +680,15 @@ void rx_multisocket_handler::run_thread() FD_SET(msg.new_fd, &total_fd_set); max_fd = std::max(max_fd, msg.new_fd); } else { - rxSockError("added fd is not valid\n"); + rxSockError("added fd is not valid"); } break; case ctrl_cmd_t::cmd_id_t::RM_FD: remove_socket_unprotected(msg.new_fd, &total_fd_set, &max_fd); - rxSockDebug("Socket fd=%d has been successfully removed\n", msg.new_fd); + rxSockDebug("Socket fd=%d has been successfully removed", msg.new_fd); break; default: - rxSockError("ctrl message command %d is not valid\n", (int)msg.cmd); + rxSockError("ctrl message command %d is not valid", (int)msg.cmd); } } } diff --git a/lib/src/common/pcap.c b/lib/src/common/pcap.c index fac94cac5..ec2916e33 100644 --- a/lib/src/common/pcap.c +++ b/lib/src/common/pcap.c @@ -303,8 +303,8 @@ int NR_PCAP_MAC_WritePDU(FILE* fd, mac_nr_context_info_t* context, const unsigne memcpy(context_header + offset, &tmp16, 2); offset += 2; // dummy CRC - context_header[offset++] = 0xde; - context_header[offset++] = 0xad; + context_header[offset++] = 0x00; + context_header[offset++] = 0x00; // Start magic string memcpy(&context_header[offset], MAC_NR_START_STRING, strlen(MAC_NR_START_STRING)); diff --git a/lib/src/common/test/CMakeLists.txt b/lib/src/common/test/CMakeLists.txt index 0df3d51da..d25c83023 100644 --- a/lib/src/common/test/CMakeLists.txt +++ b/lib/src/common/test/CMakeLists.txt @@ -28,3 +28,6 @@ target_link_libraries(thread_test srslte_common) add_test(thread_test thread_test) +add_executable(band_helper_test band_helper_test.cc) +target_link_libraries(band_helper_test srslte_common) +add_test(band_helper_test band_helper_test) \ No newline at end of file diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc new file mode 100644 index 000000000..fb8064479 --- /dev/null +++ b/lib/src/common/test/band_helper_test.cc @@ -0,0 +1,48 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/band_helper.h" +#include "srslte/common/test_common.h" + +int bands_test_nr() +{ + srslte::srslte_band_helper bands; + + TESTASSERT(bands.nr_arfcn_to_freq(632628) == 3489.42e6); + + const uint32_t max_valid_nr_arfcn = 3279165; + + // Max ARFCN is 3279165 at almost 10 GHz + TESTASSERT(bands.nr_arfcn_to_freq(max_valid_nr_arfcn) == 99.99996e9); + + // Invalid ARFCN + TESTASSERT(bands.nr_arfcn_to_freq(max_valid_nr_arfcn + 1) == 0.0); + + std::vector band_vector = bands.get_bands_nr(632628); + TESTASSERT(band_vector.size() == 2); + TESTASSERT(band_vector.at(0) == 77); + TESTASSERT(band_vector.at(1) == 78); + + // Invalid configs + // For 30 kHz, 620001 is not a valid ARFCN, only every 2nd + band_vector = bands.get_bands_nr(620001, srslte::srslte_band_helper::KHZ_30); + TESTASSERT(band_vector.empty()); + + return SRSLTE_SUCCESS; +} + +int main(int argc, char** argv) +{ + TESTASSERT(bands_test_nr() == SRSLTE_SUCCESS); + + return SRSLTE_SUCCESS; +} \ No newline at end of file diff --git a/lib/src/common/test/thread_pool_test.cc b/lib/src/common/test/thread_pool_test.cc index a1a7ec077..56eaaef8f 100644 --- a/lib/src/common/test/thread_pool_test.cc +++ b/lib/src/common/test/thread_pool_test.cc @@ -30,21 +30,21 @@ class dummy_radio private: static const int radio_delay_us = 200; - srslte::log_filter* log_h = nullptr; - std::mutex mutex; + srslog::basic_logger& logger; + std::mutex mutex; uint32_t last_tti = 0; bool first = true; bool late = false; public: - dummy_radio(srslte::log_filter& log_h_) : log_h(&log_h_) { log_h->info("Dummy radio created\n"); } + explicit dummy_radio(srslog::basic_logger& logger) : logger(logger) { logger.info("Dummy radio created"); } void tx(uint32_t tti) { std::lock_guard lock(mutex); - log_h->info("Transmitting TTI %d\n", tti); + logger.info("Transmitting TTI %d", tti); // Exit if TTI was advanced if (!first && tti <= last_tti) { @@ -68,8 +68,8 @@ private: static const int sleep_time_min_us = 50; static const int sleep_time_max_us = 2000; + srslog::basic_logger& logger; srslte::tti_semaphore* tti_semaphore = nullptr; - srslte::log_filter* log_h = nullptr; dummy_radio* radio = nullptr; srslte_random_t random_gen = nullptr; uint32_t tti = 0; @@ -77,14 +77,14 @@ private: public: dummy_worker(uint32_t id, srslte::tti_semaphore* tti_semaphore_, - srslte::log_filter* log_h_, - dummy_radio* radio_) + srslog::basic_logger& logger, + dummy_radio* radio_) : + logger(logger) { tti_semaphore = tti_semaphore_; - log_h = log_h_; radio = radio_; random_gen = srslte_random_init(id); - log_h->info("Dummy worker created\n"); + logger.info("Dummy worker created"); } ~dummy_worker() { srslte_random_free(random_gen); } @@ -100,9 +100,9 @@ protected: // Inform // Actual work ;) - log_h->info("Start working for %d us.\n", sleep_time_us); + logger.info("Start working for %d us.", sleep_time_us); usleep(sleep_time_us); - log_h->info("Stopped working\n"); + logger.info("Stopped working"); // Wait for green light tti_semaphore->wait(tti); @@ -130,28 +130,15 @@ int main(int argc, char** argv) std::vector > workers; srslte::tti_semaphore tti_semaphore; - // Setup logging. - srslog::sink* s = srslog::create_stdout_sink(); - if (!s) { - return SRSLTE_ERROR; - } - srslog::log_channel* chan = srslog::create_log_channel("main_channel", *s); - if (!chan) { - return SRSLTE_ERROR; - } - srslte::srslog_wrapper logger(*chan); + // Loggers. + auto& radio_logger = srslog::fetch_basic_logger("radio", false); + radio_logger.set_level(srslog::basic_levels::none); // Start the log backend. srslog::init(); - // Loggers - srslte::log_filter radio_log("radio", &logger); - std::vector > worker_logs; - - radio_log.set_level("none"); - // Radio - dummy_radio radio(radio_log); + dummy_radio radio(radio_logger); // Create workers for (uint32_t i = 0; i < nof_workers; i++) { @@ -159,15 +146,13 @@ int main(int argc, char** argv) char log_name[32] = {}; snprintf(log_name, sizeof(log_name), "PHY%d", i); - // Create log filter - srslte::log_filter* log_filter = new srslte::log_filter(log_name, &logger); - log_filter->set_level("none"); + auto& logger = srslog::fetch_basic_logger(log_name, false); + logger.set_level(srslog::basic_levels::none); // Create worker - auto* worker = new dummy_worker(i, &tti_semaphore, log_filter, &radio); + auto* worker = new dummy_worker(i, &tti_semaphore, logger, &radio); // Push back objects - worker_logs.push_back(std::unique_ptr(log_filter)); workers.push_back(std::unique_ptr(worker)); // Init worker in pool diff --git a/lib/src/common/threads.c b/lib/src/common/threads.c index 2a72b9a2f..c4a5ad7ba 100644 --- a/lib/src/common/threads.c +++ b/lib/src/common/threads.c @@ -68,7 +68,7 @@ bool threads_new_rt_cpu(pthread_t* thread, void* (*start_routine)(void*), void* } if (pthread_attr_setschedparam(&attr, ¶m)) { perror("pthread_attr_setschedparam"); - ERROR("Error not enough privileges to set Scheduling priority\n"); + ERROR("Error not enough privileges to set Scheduling priority"); } attr_enable = true; } else if (prio_offset == -1) { @@ -82,7 +82,7 @@ bool threads_new_rt_cpu(pthread_t* thread, void* (*start_routine)(void*), void* } if (pthread_attr_setschedparam(&attr, ¶m)) { perror("pthread_attr_setschedparam"); - ERROR("Error not enough privileges to set Scheduling priority\n"); + ERROR("Error not enough privileges to set Scheduling priority"); } attr_enable = true; } else if (prio_offset == -2) { diff --git a/lib/src/common/time_prof.cc b/lib/src/common/time_prof.cc index c17955a55..dff78de5c 100644 --- a/lib/src/common/time_prof.cc +++ b/lib/src/common/time_prof.cc @@ -63,11 +63,8 @@ const char* get_tunit_str() // tprof stats avg_time_stats::avg_time_stats(const char* name_, const char* logname, size_t print_period_) : - name(name_), - log_ptr(srslte::logmap::get(logname)), - print_period(print_period_) -{ -} + name(name_), logger(srslog::fetch_basic_logger(logname)), print_period(print_period_) +{} void avg_time_stats::operator()(nanoseconds duration) { @@ -76,22 +73,19 @@ void avg_time_stats::operator()(nanoseconds duration) max_val = std::max(max_val, duration.count()); min_val = std::min(min_val, duration.count()); if (count % print_period == 0) { - log_ptr->info("%s: {mean, max, min}={%0.1f, %ld, %ld} usec, nof_samples=%ld", - name.c_str(), - avg_val / 1e3, - max_val / 1000, - min_val / 1000, - count); + logger.info("%s: {mean, max, min}={%0.1f, %ld, %ld} usec, nof_samples=%ld", + name.c_str(), + avg_val / 1e3, + max_val / 1000, + min_val / 1000, + count); } } template sliding_window_stats::sliding_window_stats(const char* name_, const char* logname, size_t print_period_) : - name(name_), - log_ptr(srslte::logmap::get(logname)), - sliding_window(print_period_) -{ -} + name(name_), logger(srslog::fetch_basic_logger(logname)), sliding_window(print_period_) +{} template void sliding_window_stats::operator()(nanoseconds duration) @@ -100,7 +94,7 @@ void sliding_window_stats::operator()(nanoseconds duration) const char* unit_str = get_tunit_str(); TUnit dur = std::chrono::duration_cast(duration); - log_ptr->debug("%s: duration=%" PRId64 " %s\n", name.c_str(), dur.count(), unit_str); + logger.debug("%s: duration=%" PRId64 " %s", name.c_str(), dur.count(), unit_str); sliding_window[window_idx++] = duration; if (window_idx == sliding_window.size()) { @@ -109,12 +103,12 @@ void sliding_window_stats::operator()(nanoseconds duration) nanoseconds tmin = *std::min_element(sliding_window.begin(), sliding_window.end()); double tmean = static_cast(duration_cast(tsum).count()) / sliding_window.size(); - log_ptr->info("%s: {mean, max, min} = {%0.2f, %" PRId64 ", %" PRId64 "} %s\n", - name.c_str(), - tmean, - duration_cast(tmax).count(), - duration_cast(tmin).count(), - unit_str); + logger.info("%s: {mean, max, min} = {%0.2f, %" PRId64 ", %" PRId64 "} %s", + name.c_str(), + tmean, + duration_cast(tmax).count(), + duration_cast(tmin).count(), + unit_str); window_idx = 0; } } diff --git a/lib/src/mac/CMakeLists.txt b/lib/src/mac/CMakeLists.txt index 32c42d4b3..3737cebc8 100644 --- a/lib/src/mac/CMakeLists.txt +++ b/lib/src/mac/CMakeLists.txt @@ -18,11 +18,7 @@ # and at http://www.gnu.org/licenses/. # -SET(SOURCES pdu.cc pdu_queue.cc) - -if (ENABLE_5GNR) - set(SOURCES ${SOURCES} mac_nr_pdu.cc) -endif(ENABLE_5GNR) +SET(SOURCES pdu.cc pdu_queue.cc mac_sch_pdu_nr.cc mac_rar_pdu_nr.cc) add_library(srslte_mac STATIC ${SOURCES}) target_link_libraries(srslte_mac srslte_common) diff --git a/lib/src/mac/mac_rar_pdu_nr.cc b/lib/src/mac/mac_rar_pdu_nr.cc new file mode 100644 index 000000000..f456101e8 --- /dev/null +++ b/lib/src/mac/mac_rar_pdu_nr.cc @@ -0,0 +1,219 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/mac/mac_rar_pdu_nr.h" +#include +#ifdef __cplusplus +extern "C" { +#include "srslte/phy/utils/bit.h" +#include "srslte/phy/utils/vector.h" +} +#endif + +namespace srslte { + +mac_rar_subpdu_nr::mac_rar_subpdu_nr(mac_rar_pdu_nr* parent_) : + parent(parent_), logger(srslog::fetch_basic_logger("MAC")) +{} + +// Return true if subPDU could be parsed correctly, false otherwise +bool mac_rar_subpdu_nr::read_subpdu(const uint8_t* ptr) +{ + E_bit = (bool)(*ptr & 0x80) ? true : false; + type = (*ptr & 0x40) ? RAPID : BACKOFF; + if (type == RAPID) { + rapid = *ptr & 0x3f; + // if PDU is not configured with SI request, extract MAC RAR + if (parent->has_si_rapid() == false) { + const uint32_t MAC_RAR_NBYTES = 7; + if (parent->get_remaining_len() >= MAC_RAR_NBYTES) { + uint8_t* rar = const_cast(ptr + 1); + // check reserved bits + if (*rar & 0x80) { + logger.error("Error parsing RAR PDU, reserved bit is set."); + return false; + } + // TA is first 7 bits of 1st + 5 bits of 2nd octet + ta = (uint16_t)(((*(rar + 0) & 0x7f) << 5 | ((*(rar + 1) & 0xf8) >> 3))); + // Extract the first 3 bits of the UL grant from the 2nd octet + ul_grant.at(0) = *(rar + 1) & 0x4 ? 1 : 0; + ul_grant.at(1) = *(rar + 1) & 0x2 ? 1 : 0; + ul_grant.at(2) = *(rar + 1) & 0x1 ? 1 : 0; + // And now the remaining 3 full octets + uint8_t* x = &ul_grant.at(3); + srslte_bit_unpack(*(rar + 2), &x, 8); + srslte_bit_unpack(*(rar + 3), &x, 8); + srslte_bit_unpack(*(rar + 4), &x, 8); + // Temp CRNTI is octet 6 + 7 + temp_crnti = ((uint16_t) * (rar + 5)) << 8 | *(rar + 6); + payload_length = MAC_RAR_NBYTES; + } else { + logger.error("Error parsing RAR PDU, remaining bytes not sufficant (%d < %d)", + parent->get_remaining_len(), + MAC_RAR_NBYTES); + return false; + } + } + } else { + // check reserved bits + if (*ptr & 0x10 || *ptr & 0x20) { + logger.error("Error parsing RAR PDU, reserved bit is set."); + return false; + } + backoff_indicator = *ptr & 0xf; + } + return true; +} + +// Return true if another subPDU follows after that +bool mac_rar_subpdu_nr::has_more_subpdus() +{ + return E_bit; +} + +// Section 6.1.2 +uint32_t mac_rar_subpdu_nr::write_subpdu(const uint8_t* start_) +{ + return 0; +} + +uint32_t mac_rar_subpdu_nr::get_total_length() +{ + return (header_length + payload_length); +} + +bool mac_rar_subpdu_nr::has_rapid() const +{ + return (type == rar_subh_type_t::RAPID); +} + +uint8_t mac_rar_subpdu_nr::get_rapid() const +{ + return rapid; +} + +uint32_t mac_rar_subpdu_nr::get_ta() const +{ + return ta; +} + +uint16_t mac_rar_subpdu_nr::get_temp_crnti() const +{ + return temp_crnti; +} + +bool mac_rar_subpdu_nr::has_backoff() const +{ + return (type == rar_subh_type_t::BACKOFF); +} + +void mac_rar_subpdu_nr::set_backoff(const uint8_t backoff_indicator_) +{ + backoff_indicator = backoff_indicator_; +} + +std::array mac_rar_subpdu_nr::get_ul_grant() const +{ + return ul_grant; +} + +std::string mac_rar_subpdu_nr::to_string() +{ + std::stringstream ss; + if (has_rapid()) { + ss << "RAPID: " << rapid << ", Temp C-RNTI: " << std::hex << temp_crnti << ", TA: " << ta << ", UL Grant: "; + } else { + ss << "Backoff Indicator: " << backoff_indicator << " "; + } + + char tmp[16] = {}; + srslte_vec_sprint_hex(tmp, sizeof(tmp), ul_grant.data(), UL_GRANT_NBITS); + ss << tmp; + + return ss.str(); +} + +mac_rar_pdu_nr::mac_rar_pdu_nr() : logger(srslog::fetch_basic_logger("MAC")) {} + +bool mac_rar_pdu_nr::pack() +{ + // not implemented yet + return false; +} + +bool mac_rar_pdu_nr::has_si_rapid() +{ + return si_rapid_set; +} + +void mac_rar_pdu_nr::set_si_rapid(uint16_t si_rapid_) +{ + si_rapid = si_rapid_; + si_rapid_set = true; +} + +// Return true if PDU could be parsed successfully +bool mac_rar_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len) +{ + bool ret = false; + bool have_more_subpdus = false; + uint32_t offset = 0; + + remaining_len = len; + + do { + mac_rar_subpdu_nr rar_subpdu(this); + ret = rar_subpdu.read_subpdu(payload + offset); + have_more_subpdus = rar_subpdu.has_more_subpdus(); + offset += rar_subpdu.get_total_length(); + remaining_len -= rar_subpdu.get_total_length(); + + // only append if subPDU could be read successfully + if (ret == true) { + subpdus.push_back(rar_subpdu); + } + // continue reading as long as subPDUs can be extracted ok and we are not overrunning the PDU length + } while (ret && have_more_subpdus && offset <= len); + + return ret; +} + +uint32_t mac_rar_pdu_nr::get_num_subpdus() +{ + return subpdus.size(); +} + +const mac_rar_subpdu_nr& mac_rar_pdu_nr::get_subpdu(const uint32_t& index) +{ + return subpdus.at(index); +} + +const std::vector& mac_rar_pdu_nr::get_subpdus() +{ + return subpdus; +} + +uint32_t mac_rar_pdu_nr::get_remaining_len() +{ + return remaining_len; +} + +std::string mac_rar_pdu_nr::to_string() +{ + std::stringstream ss; + for (auto& subpdu : subpdus) { + ss << subpdu.to_string() << " "; + } + return ss.str(); +} + +} // namespace srslte diff --git a/lib/src/mac/mac_nr_pdu.cc b/lib/src/mac/mac_sch_pdu_nr.cc similarity index 53% rename from lib/src/mac/mac_nr_pdu.cc rename to lib/src/mac/mac_sch_pdu_nr.cc index 06b0594ae..79628f905 100644 --- a/lib/src/mac/mac_nr_pdu.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -19,13 +19,13 @@ * */ -#include "srslte/mac/mac_nr_pdu.h" +#include "srslte/mac/mac_sch_pdu_nr.h" namespace srslte { -mac_nr_sch_subpdu::mac_nr_sch_subpdu(mac_nr_sch_pdu* parent_) : parent(parent_), log_h("MAC") {} +mac_sch_subpdu_nr::mac_sch_subpdu_nr(mac_sch_pdu_nr* parent_) : parent(parent_) {} -mac_nr_sch_subpdu::nr_lcid_sch_t mac_nr_sch_subpdu::get_type() +mac_sch_subpdu_nr::nr_lcid_sch_t mac_sch_subpdu_nr::get_type() { if (lcid >= 32) { return (nr_lcid_sch_t)lcid; @@ -34,25 +34,25 @@ mac_nr_sch_subpdu::nr_lcid_sch_t mac_nr_sch_subpdu::get_type() return CCCH; } -bool mac_nr_sch_subpdu::is_sdu() +bool mac_sch_subpdu_nr::is_sdu() { // for UL-SCH LCID 52 is also valid for carrying SDUs return (lcid <= 32 || (parent->is_ulsch() && lcid == 52)); } // returns false for all reserved values in Table 6.2.1-1 and 6.2.1-2 -bool mac_nr_sch_subpdu::is_valid_lcid() +bool mac_sch_subpdu_nr::is_valid_lcid() { return (lcid <= 63 && ((parent->is_ulsch() && (lcid <= 32 || lcid >= 52)) || (lcid <= 32 || lcid >= 47))); } -bool mac_nr_sch_subpdu::is_var_len_ce() +bool mac_sch_subpdu_nr::is_var_len_ce() { return false; } // return length of PDU (or SRSLTE_ERROR otherwise) -int32_t mac_nr_sch_subpdu::read_subheader(const uint8_t* ptr) +int32_t mac_sch_subpdu_nr::read_subheader(const uint8_t* ptr) { // Skip R, read F bit and LCID F_bit = (bool)(*ptr & 0x40) ? true : false; @@ -78,13 +78,13 @@ int32_t mac_nr_sch_subpdu::read_subheader(const uint8_t* ptr) } sdu = (uint8_t*)ptr; } else { - log_h->warning("Invalid LCID (%d) in MAC PDU\n", lcid); + srslog::fetch_basic_logger("MAC").warning("Invalid LCID (%d) in MAC PDU", lcid); return SRSLTE_ERROR; } return header_length; } -void mac_nr_sch_subpdu::set_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_) +void mac_sch_subpdu_nr::set_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_) { lcid = lcid_; sdu = const_cast(payload_); @@ -94,7 +94,7 @@ void mac_nr_sch_subpdu::set_sdu(const uint32_t lcid_, const uint8_t* payload_, c F_bit = false; sdu_length = sizeof_ce(lcid, parent->is_ulsch()); if (len_ != static_cast(sdu_length)) { - log_h->warning("Invalid SDU length of UL-SCH SDU (%d != %d)\n", len_, sdu_length); + srslog::fetch_basic_logger("MAC").warning("Invalid SDU length of UL-SCH SDU (%d != %d)", len_, sdu_length); } } @@ -104,7 +104,7 @@ void mac_nr_sch_subpdu::set_sdu(const uint32_t lcid_, const uint8_t* payload_, c } } -void mac_nr_sch_subpdu::set_padding(const uint32_t len_) +void mac_sch_subpdu_nr::set_padding(const uint32_t len_) { lcid = PADDING; // 1 Byte R/LCID MAC subheader @@ -112,8 +112,41 @@ void mac_nr_sch_subpdu::set_padding(const uint32_t len_) header_length = 1; } +// Turn a subPDU into a C-RNTI CE, error checking takes place in the caller +void mac_sch_subpdu_nr::set_c_rnti(const uint16_t crnti_) +{ + lcid = CRNTI; + header_length = 1; + sdu_length = sizeof_ce(lcid, parent->is_ulsch()); + sdu = ce_write_buffer.data(); + uint16_t crnti = htole32(crnti_); + ce_write_buffer.at(0) = (uint8_t)((crnti & 0xff00) >> 8); + ce_write_buffer.at(1) = (uint8_t)((crnti & 0x00ff)); +} + +// Turn a subPDU into a single entry PHR CE, error checking takes place in the caller +void mac_sch_subpdu_nr::set_se_phr(const uint8_t phr_, const uint8_t pcmax_) +{ + lcid = SE_PHR; + header_length = 1; + sdu_length = sizeof_ce(lcid, parent->is_ulsch()); + sdu = ce_write_buffer.data(); + ce_write_buffer.at(0) = (uint8_t)(phr_ & 0x3f); + ce_write_buffer.at(1) = (uint8_t)(pcmax_ & 0x3f); +} + +// Turn a subPDU into a single short BSR +void mac_sch_subpdu_nr::set_sbsr(const lcg_bsr_t bsr_) +{ + lcid = SHORT_BSR; + header_length = 1; + sdu_length = sizeof_ce(lcid, parent->is_ulsch()); + sdu = ce_write_buffer.data(); + ce_write_buffer.at(0) = ((bsr_.lcg_id & 0x07) << 5) | (bsr_.buffer_size & 0x1f); +} + // Section 6.1.2 -uint32_t mac_nr_sch_subpdu::write_subpdu(const uint8_t* start_) +uint32_t mac_sch_subpdu_nr::write_subpdu(const uint8_t* start_) { uint8_t* ptr = const_cast(start_); *ptr = (uint8_t)((F_bit ? 1 : 0) << 6) | ((uint8_t)lcid & 0x3f); @@ -133,7 +166,7 @@ uint32_t mac_nr_sch_subpdu::write_subpdu(const uint8_t* start_) } else if (header_length == 1) { // do nothing } else { - log_h->warning("Error while packing PDU. Unsupported header length (%d)\n", header_length); + srslog::fetch_basic_logger("MAC").warning("Error while packing PDU. Unsupported header length (%d)", header_length); } // copy SDU payload @@ -150,27 +183,61 @@ uint32_t mac_nr_sch_subpdu::write_subpdu(const uint8_t* start_) return ptr - start_; } -uint32_t mac_nr_sch_subpdu::get_total_length() +uint32_t mac_sch_subpdu_nr::get_total_length() { return (header_length + sdu_length); } -uint32_t mac_nr_sch_subpdu::get_sdu_length() +uint32_t mac_sch_subpdu_nr::get_sdu_length() { return sdu_length; } -uint32_t mac_nr_sch_subpdu::get_lcid() +uint32_t mac_sch_subpdu_nr::get_lcid() { return lcid; } -uint8_t* mac_nr_sch_subpdu::get_sdu() +uint8_t* mac_sch_subpdu_nr::get_sdu() { return sdu; } -uint32_t mac_nr_sch_subpdu::sizeof_ce(uint32_t lcid, bool is_ul) +uint16_t mac_sch_subpdu_nr::get_c_rnti() +{ + if (parent->is_ulsch() && lcid == CRNTI) { + return le16toh((uint16_t)sdu[0] << 8 | sdu[1]); + } + return 0; +} + +uint8_t mac_sch_subpdu_nr::get_phr() +{ + if (parent->is_ulsch() && lcid == SE_PHR) { + return sdu[0] & 0x3f; + } + return 0; +} + +uint8_t mac_sch_subpdu_nr::get_pcmax() +{ + if (parent->is_ulsch() && lcid == SE_PHR) { + return sdu[1] & 0x3f; + } + return 0; +} + +mac_sch_subpdu_nr::lcg_bsr_t mac_sch_subpdu_nr::get_sbsr() +{ + lcg_bsr_t sbsr = {}; + if (parent->is_ulsch() && lcid == SHORT_BSR) { + sbsr.lcg_id = (sdu[0] & 0xe0) >> 5; + sbsr.buffer_size = sdu[0] & 0x1f; + } + return sbsr; +} + +uint32_t mac_sch_subpdu_nr::sizeof_ce(uint32_t lcid, bool is_ul) { if (is_ul) { switch (lcid) { @@ -184,6 +251,8 @@ uint32_t mac_nr_sch_subpdu::sizeof_ce(uint32_t lcid, bool is_ul) return 1; case SHORT_BSR: return 1; + case SE_PHR: + return 2; case PADDING: return 0; } @@ -202,16 +271,16 @@ uint32_t mac_nr_sch_subpdu::sizeof_ce(uint32_t lcid, bool is_ul) return 0; } -inline bool mac_nr_sch_subpdu::is_ul_ccch() +inline bool mac_sch_subpdu_nr::is_ul_ccch() { return (parent->is_ulsch() && (lcid == CCCH_SIZE_48 || lcid == CCCH_SIZE_64)); } -void mac_nr_sch_pdu::pack() +void mac_sch_pdu_nr::pack() { - // SDUs are written in place, only add padding if needed + // SDU and CEs are written in-place, only add padding if needed if (remaining_len) { - mac_nr_sch_subpdu padding_subpdu(this); + mac_sch_subpdu_nr padding_subpdu(this); padding_subpdu.set_padding(remaining_len); padding_subpdu.write_subpdu(buffer->msg + buffer->N_bytes); @@ -222,17 +291,17 @@ void mac_nr_sch_pdu::pack() } } -void mac_nr_sch_pdu::unpack(const uint8_t* payload, const uint32_t& len) +void mac_sch_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len) { uint32_t offset = 0; while (offset < len) { - mac_nr_sch_subpdu sch_pdu(this); + mac_sch_subpdu_nr sch_pdu(this); if (sch_pdu.read_subheader(payload + offset) == SRSLTE_ERROR) { fprintf(stderr, "Error parsing NR MAC PDU (len=%d, offset=%d)\n", len, offset); return; } offset += sch_pdu.get_total_length(); - if (sch_pdu.get_lcid() == mac_nr_sch_subpdu::PADDING) { + if (sch_pdu.get_lcid() == mac_sch_subpdu_nr::PADDING) { // set SDU length to rest of PDU sch_pdu.set_padding(len - offset + 1); // One byte for Padding header will be substracted again // skip remaining bytes @@ -245,22 +314,22 @@ void mac_nr_sch_pdu::unpack(const uint8_t* payload, const uint32_t& len) } } -uint32_t mac_nr_sch_pdu::get_num_subpdus() +uint32_t mac_sch_pdu_nr::get_num_subpdus() { return subpdus.size(); } -const mac_nr_sch_subpdu& mac_nr_sch_pdu::get_subpdu(const uint32_t& index) +const mac_sch_subpdu_nr& mac_sch_pdu_nr::get_subpdu(const uint32_t& index) { return subpdus.at(index); } -bool mac_nr_sch_pdu::is_ulsch() +bool mac_sch_pdu_nr::is_ulsch() { return ulsch; } -void mac_nr_sch_pdu::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool ulsch_) +void mac_sch_pdu_nr::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool ulsch_) { buffer = buffer_; subpdus.clear(); @@ -269,7 +338,7 @@ void mac_nr_sch_pdu::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool uls ulsch = ulsch_; } -void mac_nr_sch_pdu::init_rx(bool ulsch_) +void mac_sch_pdu_nr::init_rx(bool ulsch_) { buffer = nullptr; subpdus.clear(); @@ -278,9 +347,9 @@ void mac_nr_sch_pdu::init_rx(bool ulsch_) ulsch = ulsch_; } -uint32_t mac_nr_sch_pdu::size_header_sdu(const uint32_t lcid, const uint32_t nbytes) +uint32_t mac_sch_pdu_nr::size_header_sdu(const uint32_t lcid, const uint32_t nbytes) { - if (ulsch && (lcid == mac_nr_sch_subpdu::CCCH_SIZE_48 || lcid == mac_nr_sch_subpdu::CCCH_SIZE_64)) { + if (ulsch && (lcid == mac_sch_subpdu_nr::CCCH_SIZE_48 || lcid == mac_sch_subpdu_nr::CCCH_SIZE_64)) { return 1; } else { if (nbytes < 256) { @@ -291,34 +360,60 @@ uint32_t mac_nr_sch_pdu::size_header_sdu(const uint32_t lcid, const uint32_t nby } } -uint32_t mac_nr_sch_pdu::get_remaing_len() +uint32_t mac_sch_pdu_nr::get_remaing_len() { return remaining_len; } -uint32_t mac_nr_sch_pdu::add_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_) +uint32_t mac_sch_pdu_nr::add_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_) { int header_size = size_header_sdu(lcid_, len_); - if (header_size + len_ > remaining_len) { printf("Header and SDU exceed space in PDU (%d > %d).\n", header_size + len_, remaining_len); return SRSLTE_ERROR; } - mac_nr_sch_subpdu sch_pdu(this); + mac_sch_subpdu_nr sch_pdu(this); sch_pdu.set_sdu(lcid_, payload_, len_); - uint32_t length = sch_pdu.write_subpdu(buffer->msg + buffer->N_bytes); + return add_sudpdu(sch_pdu); +} - if (length != sch_pdu.get_total_length()) { - fprintf(stderr, "Error writing subPDU (Length error: %d != %d)\n", length, sch_pdu.get_total_length()); +uint32_t mac_sch_pdu_nr::add_crnti_ce(const uint16_t crnti) +{ + mac_sch_subpdu_nr ce(this); + ce.set_c_rnti(crnti); + return add_sudpdu(ce); +} + +uint32_t mac_sch_pdu_nr::add_se_phr_ce(const uint8_t phr, const uint8_t pcmax) +{ + mac_sch_subpdu_nr ce(this); + ce.set_se_phr(phr, pcmax); + return add_sudpdu(ce); +} + +uint32_t mac_sch_pdu_nr::add_sbsr_ce(const mac_sch_subpdu_nr::lcg_bsr_t bsr_) +{ + mac_sch_subpdu_nr ce(this); + ce.set_sbsr(bsr_); + return add_sudpdu(ce); +} + +uint32_t mac_sch_pdu_nr::add_sudpdu(mac_sch_subpdu_nr& subpdu) +{ + uint32_t subpdu_len = subpdu.get_total_length(); + if (subpdu_len > remaining_len) { + logger.warning("Not enough space to add subPDU to PDU (%d > %d)", subpdu_len, remaining_len); return SRSLTE_ERROR; } - // update length and advance payload pointer - buffer->N_bytes += length; - remaining_len -= length; + // Write subPDU straigt into provided buffer + subpdu.write_subpdu(buffer->msg + buffer->N_bytes); - subpdus.push_back(sch_pdu); + // adopt buffer variables + buffer->N_bytes += subpdu_len; + remaining_len -= subpdu_len; + subpdus.push_back(subpdu); return SRSLTE_SUCCESS; } diff --git a/lib/src/mac/pdu.cc b/lib/src/mac/pdu.cc index ccd1d6ce0..5cd4e692f 100644 --- a/lib/src/mac/pdu.cc +++ b/lib/src/mac/pdu.cc @@ -227,11 +227,7 @@ void sch_pdu::parse_packet(uint8_t* ptr) if (n_sub >= 0) { subheaders[nof_subheaders - 1].set_payload_size(n_sub); } else { - if (log_h) { - log_h->warning_hex(ptr, pdu_len, "Corrupted MAC PDU (read_len=%d, pdu_len=%d)\n", read_len, pdu_len); - } else { - srslte::console("Corrupted MAC PDU (read_len=%d, pdu_len=%d)\n", read_len, pdu_len); - } + logger.warning(ptr, pdu_len, "Corrupted MAC PDU (read_len=%d, pdu_len=%d)", read_len, pdu_len); // reset PDU init_(buffer_tx, pdu_len, pdu_is_ul); @@ -241,11 +237,11 @@ void sch_pdu::parse_packet(uint8_t* ptr) uint8_t* sch_pdu::write_packet() { - return write_packet(srslte::log_ref{"MAC "}); + return write_packet(srslog::fetch_basic_logger("MAC")); } /* Writes the MAC PDU in the packet, including the MAC headers and CE payload. Section 6.1.2 */ -uint8_t* sch_pdu::write_packet(srslte::log_ref log_h) +uint8_t* sch_pdu::write_packet(srslog::basic_logger& log) { // set padding to remaining length in PDU uint32_t num_padding = rem_len; @@ -288,7 +284,7 @@ uint8_t* sch_pdu::write_packet(srslte::log_ref log_h) // make sure there is enough room for header if (buffer_tx->get_headroom() < total_header_size) { - log_h->error("Not enough headroom for MAC header (%d < %d).\n", buffer_tx->get_headroom(), total_header_size); + log.error("Not enough headroom for MAC header (%d < %d).", buffer_tx->get_headroom(), total_header_size); return nullptr; } @@ -336,7 +332,7 @@ uint8_t* sch_pdu::write_packet(srslte::log_ref log_h) } if (buffer_tx->get_tailroom() < num_padding) { - log_h->error("Not enough tailroom for MAC padding (%d < %d).\n", buffer_tx->get_tailroom(), num_padding); + log.error("Not enough tailroom for MAC padding (%d < %d).", buffer_tx->get_tailroom(), num_padding); return nullptr; } @@ -348,69 +344,53 @@ uint8_t* sch_pdu::write_packet(srslte::log_ref log_h) // Print warning if we have padding only if (nof_subheaders <= 0 && nof_subheaders < (int)max_subheaders) { - log_h->debug("Writing MAC PDU with padding only (%d B)\n", pdu_len); + log.debug("Writing MAC PDU with padding only (%d B)", pdu_len); } - // Sanity check and print if error - if (log_h) { - log_h->debug("Wrote PDU: pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, onepad=%d, multi=%d\n", - pdu_len, - header_sz + ce_payload_sz, - header_sz, - ce_payload_sz, - nof_subheaders, - last_sdu_idx, - onetwo_padding, - num_padding); - } else { - printf("Wrote PDU: pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, onepad=%d, " - "multi=%d\n", - pdu_len, - header_sz + ce_payload_sz, - header_sz, - ce_payload_sz, - nof_subheaders, - last_sdu_idx, - onetwo_padding, - num_padding); - } + log.debug("Wrote PDU: pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, onepad=%d, multi=%d", + pdu_len, + header_sz + ce_payload_sz, + header_sz, + ce_payload_sz, + nof_subheaders, + last_sdu_idx, + onetwo_padding, + num_padding); if (buffer_tx->N_bytes != pdu_len) { - if (log_h) { - srslte::console("------------------------------\n"); - srslte::console("Wrote PDU: pdu_len=%d, expected_pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, " - "onepad=%d, multi=%d\n", - buffer_tx->N_bytes, - pdu_len, - header_sz + ce_payload_sz, - header_sz, - ce_payload_sz, - nof_subheaders, - last_sdu_idx, - onetwo_padding, - num_padding); - srslte::console("------------------------------\n"); + srslte::console("------------------------------\n"); + srslte::console("Wrote PDU: pdu_len=%d, expected_pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, " + "onepad=%d, multi=%d\n", + buffer_tx->N_bytes, + pdu_len, + header_sz + ce_payload_sz, + header_sz, + ce_payload_sz, + nof_subheaders, + last_sdu_idx, + onetwo_padding, + num_padding); + srslte::console("------------------------------\n"); - log_h->error( - "Wrote PDU: pdu_len=%d, expected_pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, onepad=%d, " - "multi=%d\n", - buffer_tx->N_bytes, - pdu_len, - header_sz + ce_payload_sz, - header_sz, - ce_payload_sz, - nof_subheaders, - last_sdu_idx, - onetwo_padding, - num_padding); + log.error( + "Wrote PDU: pdu_len=%d, expected_pdu_len=%d, header_and_ce=%d (%d+%d), nof_subh=%d, last_sdu=%d, onepad=%d, " + "multi=%d", + buffer_tx->N_bytes, + pdu_len, + header_sz + ce_payload_sz, + header_sz, + ce_payload_sz, + nof_subheaders, + last_sdu_idx, + onetwo_padding, + num_padding); - for (int i = 0; i < nof_subheaders; i++) { - log_h->error("SUBH %d is_sdu=%d, head_size=%d, payload=%d\n", - i, - subheaders[i].is_sdu(), - subheaders[i].get_header_size(i == (nof_subheaders - 1)), - subheaders[i].get_payload_size()); - } + for (int i = 0; i < nof_subheaders; i++) { + log.error("SUBH %d is_sdu=%d, head_size=%d, payload=%d", + i, + subheaders[i].is_sdu(), + subheaders[i].get_header_size(i == (nof_subheaders - 1)), + subheaders[i].get_payload_size()); } return nullptr; @@ -1032,7 +1012,7 @@ std::string rar_pdu::to_string() return msg; } -rar_pdu::rar_pdu(uint32_t max_rars_, srslte::log_ref log_) : pdu(max_rars_, log_) +rar_pdu::rar_pdu(uint32_t max_rars_, srslog::basic_logger& logger) : pdu(max_rars_, logger) { backoff_indicator = 0; has_backoff_indicator = false; @@ -1081,11 +1061,7 @@ bool rar_pdu::write_packet(uint8_t* ptr) int32_t payload_len = ptr - init_ptr; int32_t pad_len = rem_len - payload_len; if (pad_len < 0) { - if (log_h) { - log_h->warning("Error packing RAR PDU (payload_len=%d, rem_len=%d)\n", payload_len, rem_len); - } else { - srslte::console("Error packing RAR PDU (payload_len=%d, rem_len=%d)\n", payload_len, rem_len); - } + logger.warning("Error packing RAR PDU (payload_len=%d, rem_len=%d)", payload_len, rem_len); return false; } else { bzero(ptr, pad_len * sizeof(uint8_t)); diff --git a/lib/src/mac/pdu_queue.cc b/lib/src/mac/pdu_queue.cc index d9304b368..63d0dbcd7 100644 --- a/lib/src/mac/pdu_queue.cc +++ b/lib/src/mac/pdu_queue.cc @@ -24,31 +24,28 @@ namespace srslte { -void pdu_queue::init(process_callback* callback_, log_ref log_h_) +void pdu_queue::init(process_callback* callback_) { callback = callback_; - log_h = log_h_; } uint8_t* pdu_queue::request(uint32_t len) { if (len > MAX_PDU_LEN) { - ERROR("Error request buffer of invalid size %d. Max bytes %d\n", len, MAX_PDU_LEN); + ERROR("Error request buffer of invalid size %d. Max bytes %d", len, MAX_PDU_LEN); return NULL; } // This function must be non-blocking. In case we run out of buffers, it shall handle the error properly pdu_t* pdu = pool.allocate("pdu_queue::request", false); if (pdu) { if ((void*)pdu->ptr != (void*)pdu) { - ERROR("Fatal error in memory alignment in struct pdu_queue::pdu_t\n"); + ERROR("Fatal error in memory alignment in struct pdu_queue::pdu_t"); exit(-1); } return pdu->ptr; } else { - if (log_h) { - log_h->error("Not enough buffers for MAC PDU\n"); - } - ERROR("Not enough buffers for MAC PDU\n"); + logger.error("Not enough buffers for MAC PDU"); + ERROR("Not enough buffers for MAC PDU"); return nullptr; } } @@ -56,7 +53,7 @@ uint8_t* pdu_queue::request(uint32_t len) void pdu_queue::deallocate(const uint8_t* pdu) { if (!pool.deallocate((pdu_t*)pdu)) { - log_h->warning("Error deallocating from buffer pool in deallocate(): buffer not created in this pool.\n"); + logger.warning("Error deallocating from buffer pool in deallocate(): buffer not created in this pool."); } } @@ -72,7 +69,7 @@ void pdu_queue::push(const uint8_t* ptr, uint32_t len, channel_t channel) pdu->channel = channel; pdu_q.push(pdu); } else { - log_h->warning("Error pushing pdu: ptr is empty\n"); + logger.warning("Error pushing pdu: ptr is empty"); } } @@ -89,9 +86,7 @@ bool pdu_queue::process_pdus() have_data = true; } if (cnt > 20) { - if (log_h) { - log_h->warning("PDU queue dispatched %d packets\n", cnt); - } + logger.warning("PDU queue dispatched %d packets", cnt); printf("Warning PDU queue dispatched %d packets\n", cnt); } return have_data; diff --git a/lib/src/phy/agc/agc.c b/lib/src/phy/agc/agc.c index 111a1cebd..9bc52e952 100644 --- a/lib/src/phy/agc/agc.c +++ b/lib/src/phy/agc/agc.c @@ -106,13 +106,13 @@ static inline void agc_enter_state_hold(srslte_agc_t* q) float gain_db = q->gain_db + q->gain_offset_db; if (gain_db < q->min_gain_db) { gain_db = q->min_gain_db; - INFO("Warning: Rx signal strength is too high. Forcing minimum Rx gain %.2fdB\n", gain_db); + INFO("Warning: Rx signal strength is too high. Forcing minimum Rx gain %.2fdB", gain_db); } else if (gain_db > q->max_gain_db) { gain_db = q->max_gain_db; - INFO("Warning: Rx signal strength is too weak. Forcing maximum Rx gain %.2fdB\n", gain_db); + INFO("Warning: Rx signal strength is too weak. Forcing maximum Rx gain %.2fdB", gain_db); } else if (isinf(gain_db) || isnan(gain_db)) { gain_db = q->default_gain_db; - INFO("Warning: AGC went to an unknown state. Setting Rx gain to %.2fdB\n", gain_db); + INFO("Warning: AGC went to an unknown state. Setting Rx gain to %.2fdB", gain_db); } // Set gain @@ -141,7 +141,6 @@ static inline void agc_run_state_init(srslte_agc_t* q) static inline void agc_run_state_measure(srslte_agc_t* q, cf_t* signal, uint32_t len) { - // Perform measurement of the frame float y = 0; float* t; @@ -154,7 +153,7 @@ static inline void agc_run_state_measure(srslte_agc_t* q, cf_t* signal, uint32_t y = t[srslte_vec_max_fi(t, 2 * len)]; // take only positive max to avoid abs() (should be similar) break; default: - ERROR("Unsupported AGC mode\n"); + ERROR("Unsupported AGC mode"); return; } @@ -171,7 +170,7 @@ static inline void agc_run_state_measure(srslte_agc_t* q, cf_t* signal, uint32_t y = q->y_tmp[srslte_vec_max_fi(q->y_tmp, q->nof_frames)]; break; default: - ERROR("Unsupported AGC mode\n"); + ERROR("Unsupported AGC mode"); return; } } @@ -186,7 +185,7 @@ static inline void agc_run_state_measure(srslte_agc_t* q, cf_t* signal, uint32_t if (q->frame_cnt == 0) { q->y_out = SRSLTE_VEC_EMA(y, q->y_out, q->bandwidth); q->gain_offset_db = srslte_convert_amplitude_to_dB(q->target) - srslte_convert_amplitude_to_dB(q->y_out); - INFO("AGC gain offset: %.2f y_out=%.3f, y=%.3f target=%.1f\n", q->gain_offset_db, q->y_out, y, q->target); + INFO("AGC gain offset: %.2f y_out=%.3f, y=%.3f target=%.1f", q->gain_offset_db, q->y_out, y, q->target); } } diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index a6f1dbae1..c3d02e650 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -38,7 +38,6 @@ #ifdef DEFAULT_FILTER_LEN static void set_default_filter(srslte_chest_dl_t* q, int filter_len) { - float fil[SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN]; for (int i = 0; i < filter_len / 2; i++) { @@ -75,13 +74,13 @@ int srslte_chest_dl_init(srslte_chest_dl_t* q, uint32_t max_prb, uint32_t nof_rx ret = srslte_refsignal_cs_init(&q->csr_refs, max_prb); if (ret != SRSLTE_SUCCESS) { - ERROR("Error initializing CSR signal (%d)\n", ret); + ERROR("Error initializing CSR signal (%d)", ret); goto clean_exit; } q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t*)); if (!q->mbsfn_refs) { - ERROR("Calloc error initializing mbsfn_refs (%d)\n", ret); + ERROR("Calloc error initializing mbsfn_refs (%d)", ret); goto clean_exit; } @@ -123,22 +122,22 @@ int srslte_chest_dl_init(srslte_chest_dl_t* q, uint32_t max_prb, uint32_t nof_rx } if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, SRSLTE_NRE * max_prb)) { - ERROR("Error initializing vector interpolator\n"); + ERROR("Error initializing vector interpolator"); goto clean_exit; } if (srslte_interp_linear_init(&q->srslte_interp_lin, 2 * max_prb, SRSLTE_NRE / 2)) { - ERROR("Error initializing interpolator\n"); + ERROR("Error initializing interpolator"); goto clean_exit; } if (srslte_interp_linear_init(&q->srslte_interp_lin_3, 4 * max_prb, SRSLTE_NRE / 4)) { - ERROR("Error initializing interpolator\n"); + ERROR("Error initializing interpolator"); goto clean_exit; } if (srslte_interp_linear_init(&q->srslte_interp_lin_mbsfn, 6 * max_prb, SRSLTE_NRE / 6)) { - ERROR("Error initializing interpolator\n"); + ERROR("Error initializing interpolator"); goto clean_exit; } @@ -146,7 +145,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t* q, uint32_t max_prb, uint32_t nof_rx if (q->wiener_dl) { srslte_wiener_dl_init(q->wiener_dl, max_prb, 2, nof_rx_antennas); } else { - ERROR("Error allocating wiener filter\n"); + ERROR("Error allocating wiener filter"); goto clean_exit; } @@ -286,25 +285,25 @@ int srslte_chest_dl_set_cell(srslte_chest_dl_t* q, srslte_cell_t cell) q->cell = cell; ret = srslte_refsignal_cs_set_cell(&q->csr_refs, cell); if (ret != SRSLTE_SUCCESS) { - ERROR("Error initializing CSR signal (%d)\n", ret); + ERROR("Error initializing CSR signal (%d)", ret); return SRSLTE_ERROR; } if (srslte_pss_generate(q->pss_signal, cell.id % 3)) { - ERROR("Error initializing PSS signal for noise estimation\n"); + ERROR("Error initializing PSS signal for noise estimation"); return SRSLTE_ERROR; } if (srslte_interp_linear_vector_resize(&q->srslte_interp_linvec, SRSLTE_NRE * q->cell.nof_prb)) { - ERROR("Error initializing vector interpolator\n"); + ERROR("Error initializing vector interpolator"); return SRSLTE_ERROR; } if (srslte_interp_linear_resize(&q->srslte_interp_lin, 2 * q->cell.nof_prb, SRSLTE_NRE / 2)) { - ERROR("Error initializing interpolator\n"); + ERROR("Error initializing interpolator"); return SRSLTE_ERROR; } if (srslte_interp_linear_resize(&q->srslte_interp_lin_3, 4 * q->cell.nof_prb, SRSLTE_NRE / 4)) { - ERROR("Error initializing interpolator\n"); + ERROR("Error initializing interpolator"); return SRSLTE_ERROR; } if (srslte_interp_linear_resize(&q->srslte_interp_lin_mbsfn, 6 * q->cell.nof_prb, SRSLTE_NRE / 6)) { @@ -631,7 +630,6 @@ static void chest_interpolate_noise_est(srslte_chest_dl_t* q, uint32_t port_id, uint32_t rxant_id) { - float filter[SRSLTE_CHEST_MAX_SMOOTH_FIL_LEN]; uint32_t filter_len = 0; uint32_t sf_idx = sf->tti % 10; @@ -644,7 +642,7 @@ static void chest_interpolate_noise_est(srslte_chest_dl_t* q, /* Estimate noise */ if (cfg->noise_alg == SRSLTE_NOISE_ALG_REFS) { if (ch_mode == SRSLTE_SF_MBSFN) { - ERROR("Warning: REFS noise estimation algorithm not supported in MBSFN subframes\n"); + ERROR("Warning: REFS noise estimation algorithm not supported in MBSFN subframes"); } q->noise_estimate[rxant_id][port_id] = estimate_noise_pilots(q, sf, port_id); @@ -683,11 +681,10 @@ static void chest_interpolate_noise_est(srslte_chest_dl_t* q, } if (ce != NULL) { - switch (cfg->filter_type) { case SRSLTE_CHEST_FILTER_GAUSS: if (ch_mode == SRSLTE_SF_MBSFN) { - ERROR("Warning: Gauss filter not supported in MBSFN subframes\n"); + ERROR("Warning: Gauss filter not supported in MBSFN subframes"); } if (cfg->filter_coef[0] <= 0) { filter_len = srslte_chest_set_smooth_filter_gauss(filter, 4, q->noise_estimate[rxant_id][port_id] * 200.0f); @@ -703,7 +700,7 @@ static void chest_interpolate_noise_est(srslte_chest_dl_t* q, } if (cfg->estimator_alg != SRSLTE_ESTIMATOR_ALG_INTERPOLATE && ch_mode == SRSLTE_SF_MBSFN) { - ERROR("Warning: Subframe interpolation must be enabled in MBSFN subframes\n"); + ERROR("Warning: Subframe interpolation must be enabled in MBSFN subframes"); } /* Smooth estimates (if applicable) and interpolate */ @@ -740,7 +737,6 @@ chest_dl_estimate_correct_sync_error(srslte_chest_dl_t* q, srslte_dl_sf_cfg_t* s // For each cell port... for (uint32_t cell_port_id = 0; cell_port_id < q->cell.nof_ports; cell_port_id++) { - uint32_t npilots = srslte_refsignal_cs_nof_re(&q->csr_refs, sf, cell_port_id); uint32_t nsymb = srslte_refsignal_cs_nof_symbols(&q->csr_refs, sf, cell_port_id); @@ -832,7 +828,7 @@ static int estimate_port_mbsfn(srslte_chest_dl_t* q, uint16_t mbsfn_area_id = cfg->mbsfn_area_id; if (!q->mbsfn_refs[mbsfn_area_id]) { - ERROR("Error in chest_dl: MBSFN area id=%d not initialized\n", cfg->mbsfn_area_id); + ERROR("Error in chest_dl: MBSFN area id=%d not initialized", cfg->mbsfn_area_id); } /* Use the known CSR signal to compute Least-squares estimates */ @@ -993,7 +989,6 @@ int srslte_chest_dl_estimate_cfg(srslte_chest_dl_t* q, cf_t* input[SRSLTE_MAX_PORTS], srslte_chest_dl_res_t* res) { - for (uint32_t rxant_id = 0; rxant_id < q->nof_rx_antennas; rxant_id++) { // Estimate and correct synchronization error if enabled if (cfg->sync_error_enable) { diff --git a/lib/src/phy/ch_estimation/chest_dl_nbiot.c b/lib/src/phy/ch_estimation/chest_dl_nbiot.c index a327d69ce..a55d6f43b 100644 --- a/lib/src/phy/ch_estimation/chest_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/chest_dl_nbiot.c @@ -178,13 +178,13 @@ static void interpolate_pilots(srslte_chest_dl_nbiot_t* q, cf_t* pilot_estimates cf_t ce_avg[2][num_ces]; // interpolate the symbols with references in the freq domain - DEBUG("Interpolating %d pilots in %d symbols at port %d.\n", nsymbols * 2, nsymbols, port_id); + DEBUG("Interpolating %d pilots in %d symbols at port %d.", nsymbols * 2, nsymbols, port_id); for (int l = 0; l < nsymbols; l++) { uint32_t fidx_offset = srslte_refsignal_dl_nbiot_fidx(q->cell, l, port_id, 0); // points to the RE of the beginning of the l'th symbol containing a ref uint32_t ce_idx = srslte_refsignal_nrs_nsymbol(l) * q->cell.base.nof_prb * SRSLTE_NRE; ce_idx += q->cell.nbiot_prb * SRSLTE_NRE; - DEBUG(" - freq.-dmn interp. in sym %d at RE %d\n", srslte_refsignal_nrs_nsymbol(l), ce_idx + fidx_offset); + DEBUG(" - freq.-dmn interp. in sym %d at RE %d", srslte_refsignal_nrs_nsymbol(l), ce_idx + fidx_offset); srslte_interp_linear_offset( &q->srslte_interp_lin, &pilot_estimates[2 * l], &ce[ce_idx], fidx_offset, SRSLTE_NRE / 2 - fidx_offset); } @@ -265,7 +265,7 @@ int srslte_chest_dl_nbiot_estimate_port(srslte_chest_dl_nbiot_t* q, uint32_t sf_idx, uint32_t port_id) { - DEBUG("x.%d: Estimating DL channel on port %d.\n", sf_idx, port_id); + DEBUG("x.%d: Estimating DL channel on port %d.", sf_idx, port_id); int nref = srslte_refsignal_nbiot_cs_nof_re(&q->cell, port_id); // Get references from the input signal diff --git a/lib/src/phy/ch_estimation/chest_sl.c b/lib/src/phy/ch_estimation/chest_sl.c index 8fdffe55c..863375daa 100644 --- a/lib/src/phy/ch_estimation/chest_sl.c +++ b/lib/src/phy/ch_estimation/chest_sl.c @@ -204,7 +204,7 @@ static void interpolate_pilots_sl_psbch(srslte_chest_sl_t* q) // make sure l_idx is at least 2 to avoid accessing array at negative index below if (l_idx < 2) { - ERROR("Couldn't interpolate PSBCH pilots. Invalid number of reference symbols.\n"); + ERROR("Couldn't interpolate PSBCH pilots. Invalid number of reference symbols."); return; } @@ -249,7 +249,6 @@ static void interpolate_pilots_sl_psbch(srslte_chest_sl_t* q) static void chest_sl_psbch_ls_estimate(srslte_chest_sl_t* q, cf_t* sf_buffer) { - uint32_t dmrs_index = 0; uint32_t k = q->cell.nof_prb * SRSLTE_NRE / 2 - 36; uint32_t sf_nsymbols = srslte_sl_get_num_symbols(q->cell.tm, q->cell.cp); @@ -396,7 +395,7 @@ static void interpolate_pilots_sl_pscch(srslte_chest_sl_t* q) // make sure l_idx is at least 2 to avoid accessing array at negative index below if (l_idx < 2) { - ERROR("Couldn't interpolate PSCCH pilots. Invalid number of reference symbols.\n"); + ERROR("Couldn't interpolate PSCCH pilots. Invalid number of reference symbols."); return; } @@ -554,7 +553,6 @@ static int chest_sl_pssch_put_dmrs(srslte_chest_sl_t* q, cf_t* sf_buffer) // Mapping to physical resources for (int i = 0; i < srslte_sl_get_num_symbols(q->cell.tm, q->cell.cp); i++) { if (srslte_pssch_is_symbol(SRSLTE_SIDELINK_DMRS_SYMBOL, q->cell.tm, i, q->cell.cp)) { - if (q->cell.tm == SRSLTE_SIDELINK_TM1 || q->cell.tm == SRSLTE_SIDELINK_TM2) { if (q->chest_sl_cfg.nof_prb <= q->sl_comm_resource_pool.prb_num) { memcpy(&sf_buffer[k + i * q->cell.nof_prb * SRSLTE_NRE], @@ -597,7 +595,6 @@ static int chest_sl_pssch_get_dmrs(srslte_chest_sl_t* q, cf_t* sf_buffer, cf_t** // Mapping to physical resources for (int i = 0; i < srslte_sl_get_num_symbols(q->cell.tm, q->cell.cp); i++) { if (srslte_pssch_is_symbol(SRSLTE_SIDELINK_DMRS_SYMBOL, q->cell.tm, i, q->cell.cp)) { - if (q->cell.tm == SRSLTE_SIDELINK_TM1 || q->cell.tm == SRSLTE_SIDELINK_TM2) { if (q->chest_sl_cfg.nof_prb <= q->sl_comm_resource_pool.prb_num) { memcpy(dmrs_received[dmrs_idx], @@ -652,7 +649,7 @@ static void interpolate_pilots_sl_pssch(srslte_chest_sl_t* q) // make sure l_idx is at least 2 to avoid accessing array at negative index below if (l_idx < 2) { - ERROR("Couldn't interpolate PSSCH pilots. Invalid number of reference symbols.\n"); + ERROR("Couldn't interpolate PSSCH pilots. Invalid number of reference symbols."); return; } @@ -661,9 +658,7 @@ static void interpolate_pilots_sl_pssch(srslte_chest_sl_t* q) } if (q->cell.tm == SRSLTE_SIDELINK_TM1 || q->cell.tm == SRSLTE_SIDELINK_TM2) { - if (q->chest_sl_cfg.nof_prb <= q->sl_comm_resource_pool.prb_num) { - k = q->chest_sl_cfg.prb_start_idx * SRSLTE_NRE; srslte_interp_linear_vector3(&q->lin_vec_sl, @@ -699,7 +694,6 @@ static void interpolate_pilots_sl_pssch(srslte_chest_sl_t* q) q->chest_sl_cfg.nof_prb * SRSLTE_NRE); } else { - // First band k = q->chest_sl_cfg.prb_start_idx * SRSLTE_NRE; @@ -777,7 +771,6 @@ static void interpolate_pilots_sl_pssch(srslte_chest_sl_t* q) } } else if (q->cell.tm == SRSLTE_SIDELINK_TM3 || q->cell.tm == SRSLTE_SIDELINK_TM4) { - k = q->chest_sl_cfg.prb_start_idx * SRSLTE_NRE; srslte_interp_linear_vector3(&q->lin_vec_sl, @@ -822,7 +815,6 @@ static void chest_sl_pssch_ls_estimate(srslte_chest_sl_t* q, cf_t* sf_buffer) srslte_vec_cf_zero(q->ce, q->sf_n_re); for (int i = 0; i < srslte_sl_get_num_symbols(q->cell.tm, q->cell.cp); i++) { if (srslte_pssch_is_symbol(SRSLTE_SIDELINK_DMRS_SYMBOL, q->cell.tm, i, q->cell.cp)) { - if (q->cell.tm == SRSLTE_SIDELINK_TM1 || q->cell.tm == SRSLTE_SIDELINK_TM2) { if (q->chest_sl_cfg.nof_prb <= q->sl_comm_resource_pool.prb_num) { srslte_vec_prod_conj_ccc(&sf_buffer[k + i * q->cell.nof_prb * SRSLTE_NRE], @@ -895,7 +887,7 @@ float srslte_chest_sl_estimate_noise(srslte_chest_sl_t* q) { uint32_t sf_nsymbols = srslte_sl_get_num_symbols(q->cell.tm, q->cell.cp); if (sf_nsymbols == 0) { - ERROR("Error estimating channel noise. Invalid number of OFDM symbols.\n"); + ERROR("Error estimating channel noise. Invalid number of OFDM symbols."); return SRSLTE_ERROR; } diff --git a/lib/src/phy/ch_estimation/chest_ul.c b/lib/src/phy/ch_estimation/chest_ul.c index 928d620d9..0496de116 100644 --- a/lib/src/phy/ch_estimation/chest_ul.c +++ b/lib/src/phy/ch_estimation/chest_ul.c @@ -85,7 +85,7 @@ int srslte_chest_ul_init(srslte_chest_ul_t* q, uint32_t max_prb) } if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, MAX_REFS_SYM)) { - ERROR("Error initializing vector interpolator\n"); + ERROR("Error initializing vector interpolator"); goto clean_exit; } @@ -95,7 +95,7 @@ int srslte_chest_ul_init(srslte_chest_ul_t* q, uint32_t max_prb) q->dmrs_signal_configured = false; if (srslte_refsignal_dmrs_pusch_pregen_init(&q->dmrs_pregen, max_prb)) { - ERROR("Error allocating memory for pregenerated signals\n"); + ERROR("Error allocating memory for pregenerated signals"); goto clean_exit; } } @@ -169,12 +169,12 @@ int srslte_chest_ul_set_cell(srslte_chest_ul_t* q, srslte_cell_t cell) q->cell = cell; ret = srslte_refsignal_ul_set_cell(&q->dmrs_signal, cell); if (ret != SRSLTE_SUCCESS) { - ERROR("Error initializing CSR signal (%d)\n", ret); + ERROR("Error initializing CSR signal (%d)", ret); return SRSLTE_ERROR; } if (srslte_interp_linear_vector_resize(&q->srslte_interp_linvec, NOF_REFS_SYM)) { - ERROR("Error initializing vector interpolator\n"); + ERROR("Error initializing vector interpolator"); return SRSLTE_ERROR; } } @@ -199,7 +199,6 @@ void srslte_chest_ul_pregen(srslte_chest_ul_t* q, /* Uses the difference between the averaged and non-averaged pilot estimates */ static float estimate_noise_pilots(srslte_chest_ul_t* q, cf_t* ce, uint32_t nslots, uint32_t nrefs, uint32_t n_prb[2]) { - float power = 0; for (int i = 0; i < nslots; i++) { power += srslte_chest_estimate_noise_pilots( @@ -319,7 +318,7 @@ static void chest_ul_estimate(srslte_chest_ul_t* q, // Check if intra-subframe frequency hopping is enabled if (n_prb[0] != n_prb[1]) { - ERROR("ERROR: intra-subframe frequency hopping not supported in the estimator!!\n"); + ERROR("ERROR: intra-subframe frequency hopping not supported in the estimator!!"); } if (res->ce != NULL) { @@ -366,14 +365,14 @@ int srslte_chest_ul_estimate_pusch(srslte_chest_ul_t* q, srslte_chest_ul_res_t* res) { if (!q->dmrs_signal_configured) { - ERROR("Error must call srslte_chest_ul_set_cfg() before using the UL estimator\n"); + ERROR("Error must call srslte_chest_ul_set_cfg() before using the UL estimator"); return SRSLTE_ERROR; } uint32_t nof_prb = cfg->grant.L_prb; if (!srslte_dft_precoding_valid_prb(nof_prb)) { - ERROR("Error invalid nof_prb=%d\n", nof_prb); + ERROR("Error invalid nof_prb=%d", nof_prb); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -398,7 +397,6 @@ int srslte_chest_ul_estimate_pusch(srslte_chest_ul_t* q, static float estimate_noise_pilots_pucch(srslte_chest_ul_t* q, cf_t* ce, uint32_t n_rs, uint32_t n_prb[SRSLTE_NOF_SLOTS_PER_SF]) { - float power = 0; for (int ns = 0; ns < SRSLTE_NOF_SLOTS_PER_SF; ns++) { for (int i = 0; i < n_rs; i++) { @@ -431,7 +429,7 @@ int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t* q, { int n_rs = srslte_refsignal_dmrs_N_rs(cfg->format, q->cell.cp); if (!n_rs) { - ERROR("Error computing N_rs\n"); + ERROR("Error computing N_rs"); return SRSLTE_ERROR; } int nrefs_sf = SRSLTE_NRE * n_rs * SRSLTE_NOF_SLOTS_PER_SF; diff --git a/lib/src/phy/ch_estimation/csi_rs.c b/lib/src/phy/ch_estimation/csi_rs.c index e9c6858bf..8aff62419 100644 --- a/lib/src/phy/ch_estimation/csi_rs.c +++ b/lib/src/phy/ch_estimation/csi_rs.c @@ -117,7 +117,7 @@ static int csi_rs_location_get_l_list(const srslte_csi_rs_resource_mapping_t* re } uint32_t csi_rs_cinit(const srslte_carrier_nr_t* carrier, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_csi_rs_nzp_resource_t* resource, uint32_t l) { @@ -127,7 +127,7 @@ uint32_t csi_rs_cinit(const srslte_carrier_nr_t* carrier, return ((SRSLTE_NSYMB_PER_SLOT_NR * n + l + 1UL) * (2UL * n_id) << 10UL) + n_id; } -bool srslte_csi_send(const srslte_csi_rs_period_and_offset_t* periodicity, const srslte_dl_slot_cfg_t* slot_cfg) +bool srslte_csi_send(const srslte_csi_rs_period_and_offset_t* periodicity, const srslte_slot_cfg_t* slot_cfg) { if (periodicity == NULL || slot_cfg == NULL) { return false; @@ -145,7 +145,6 @@ bool srslte_csi_send(const srslte_csi_rs_period_and_offset_t* periodicity, const uint32_t csi_rs_count(srslte_csi_rs_density_t density, uint32_t nprb) { switch (density) { - case srslte_csi_rs_resource_mapping_density_three: return nprb * 3; case srslte_csi_rs_resource_mapping_density_dot5_even: @@ -192,7 +191,7 @@ uint32_t csi_rs_rb_stride(const srslte_csi_rs_resource_mapping_t* m) } int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_csi_rs_nzp_resource_t* resource, cf_t* grid) { @@ -262,7 +261,7 @@ int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier, } int srslte_csi_rs_nzp_measure(const srslte_carrier_nr_t* carrier, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_csi_rs_nzp_resource_t* resource, const cf_t* grid, srslte_csi_rs_measure_t* measure) diff --git a/lib/src/phy/ch_estimation/dmrs_pdcch.c b/lib/src/phy/ch_estimation/dmrs_pdcch.c index b0fc33397..edbf167f9 100644 --- a/lib/src/phy/ch_estimation/dmrs_pdcch.c +++ b/lib/src/phy/ch_estimation/dmrs_pdcch.c @@ -125,7 +125,7 @@ static void dmrs_pdcch_put_symbol_noninterleaved(const srslte_carrier_nr_t* ca int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_dci_location_t* dci_location, cf_t* sf_symbols) { @@ -134,12 +134,12 @@ int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier, } if (coreset->mapping_type == srslte_coreset_mapping_type_interleaved) { - ERROR("Error interleaved CORESET mapping is not currently implemented\n"); + ERROR("Error interleaved CORESET mapping is not currently implemented"); return SRSLTE_ERROR; } if (coreset->duration < SRSLTE_CORESET_DURATION_MIN || coreset->duration > SRSLTE_CORESET_DURATION_MAX) { - ERROR("Error CORESET duration %d is out-of-bounds (%d,%d)\n", + ERROR("Error CORESET duration %d is out-of-bounds (%d,%d)", coreset->duration, SRSLTE_CORESET_DURATION_MIN, SRSLTE_CORESET_DURATION_MAX); @@ -159,7 +159,7 @@ int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier, // Get Cin uint32_t cinit = dmrs_pdcch_get_cinit(slot_idx, l, n_id); - DMRS_PDCCH_INFO_TX("n=%d; l=%d; cinit=%08x\n", slot_idx, l, cinit); + DMRS_PDCCH_INFO_TX("n=%d; l=%d; cinit=%08x", slot_idx, l, cinit); // Put data dmrs_pdcch_put_symbol_noninterleaved( @@ -178,7 +178,7 @@ int srslte_dmrs_pdcch_estimator_init(srslte_dmrs_pdcch_estimator_t* q, } if (coreset->duration < SRSLTE_CORESET_DURATION_MIN || coreset->duration > SRSLTE_CORESET_DURATION_MAX) { - ERROR("Error CORESET duration %d is out-of-bounds (%d,%d)\n", + ERROR("Error CORESET duration %d is out-of-bounds (%d,%d)", coreset->duration, SRSLTE_CORESET_DURATION_MIN, SRSLTE_CORESET_DURATION_MAX); @@ -210,7 +210,7 @@ int srslte_dmrs_pdcch_estimator_init(srslte_dmrs_pdcch_estimator_t* q, #else if (srslte_interp_linear_init(&q->interpolator, coreset_bw * 3, 4)) { #endif - ERROR("Initiating interpolator\n"); + ERROR("Initiating interpolator"); return SRSLTE_ERROR; } @@ -335,7 +335,7 @@ srslte_dmrs_pdcch_extract(srslte_dmrs_pdcch_estimator_t* q, uint32_t cinit, cons } int srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const cf_t* sf_symbols) { if (q == NULL || sf_symbols == NULL) { @@ -356,7 +356,7 @@ int srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, // Calculate PRN sequence initial state uint32_t cinit = dmrs_pdcch_get_cinit(slot_idx, l, n_id); - DMRS_PDCCH_INFO_RX("n=%d; l=%d; cinit=%08x\n", slot_idx, l, cinit); + DMRS_PDCCH_INFO_RX("n=%d; l=%d; cinit=%08x", slot_idx, l, cinit); // Extract pilots least square estimates srslte_dmrs_pdcch_extract(q, cinit, &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], q->lse[l]); @@ -399,13 +399,13 @@ int srslte_dmrs_pdcch_get_measure(const srslte_dmrs_pdcch_estimator_t* q, uint32_t L = 1U << dci_location->L; if (q->coreset.mapping_type == srslte_coreset_mapping_type_interleaved) { - ERROR("Error interleaved mapping not implemented\n"); + ERROR("Error interleaved mapping not implemented"); return SRSLTE_ERROR; } // Check that CORESET duration is not less than minimum if (q->coreset.duration < SRSLTE_CORESET_DURATION_MIN) { - ERROR("Invalid CORESET duration\n"); + ERROR("Invalid CORESET duration"); return SRSLTE_ERROR; } @@ -453,7 +453,7 @@ int srslte_dmrs_pdcch_get_measure(const srslte_dmrs_pdcch_estimator_t* q, measure->epre = epre / (float)q->coreset.duration; measure->cfo_hz = cfo / (2.0f * (float)M_PI * Ts); measure->sync_error_us = - (float)SRSLTE_SUBC_SPACING_NR(q->carrier.numerology) * sync_err / (4.0e-6f * (float)q->coreset.duration); + sync_err / (4.0e-6f * (float)q->coreset.duration * SRSLTE_SUBC_SPACING_NR(q->carrier.numerology)); measure->rsrp_dBfs = srslte_convert_power_to_dB(measure->rsrp); measure->epre_dBfs = srslte_convert_power_to_dB(measure->epre); @@ -464,7 +464,7 @@ int srslte_dmrs_pdcch_get_measure(const srslte_dmrs_pdcch_estimator_t* q, measure->norm_corr = 0.0f; } - DMRS_PDCCH_INFO_RX("Measure L=%d; ncce=%d; RSRP=%+.1f dBfs; EPRE=%+.1f dBfs; Corr=%.3f\n", + DMRS_PDCCH_INFO_RX("Measure L=%d; ncce=%d; RSRP=%+.1f dBfs; EPRE=%+.1f dBfs; Corr=%.3f", dci_location->L, dci_location->ncce, measure->rsrp_dBfs, @@ -484,13 +484,13 @@ int srslte_dmrs_pdcch_get_ce(const srslte_dmrs_pdcch_estimator_t* q, uint32_t L = 1U << dci_location->L; if (q->coreset.mapping_type == srslte_coreset_mapping_type_interleaved) { - ERROR("Error interleaved mapping not implemented\n"); + ERROR("Error interleaved mapping not implemented"); return SRSLTE_ERROR; } // Check that CORESET duration is not less than minimum if (q->coreset.duration < SRSLTE_CORESET_DURATION_MIN) { - ERROR("Invalid CORESET duration\n"); + ERROR("Invalid CORESET duration"); return SRSLTE_ERROR; } @@ -511,7 +511,7 @@ int srslte_dmrs_pdcch_get_ce(const srslte_dmrs_pdcch_estimator_t* q, // Double check extracted RE match ideal count ce->nof_re = (SRSLTE_NRE - 3) * 6 * L; if (count != ce->nof_re) { - ERROR("Incorrect number of extracted resources (%d != %d)\n", count, ce->nof_re); + ERROR("Incorrect number of extracted resources (%d != %d)", count, ce->nof_re); } // At the moment Noise is not calculated diff --git a/lib/src/phy/ch_estimation/dmrs_pucch.c b/lib/src/phy/ch_estimation/dmrs_pucch.c index 0bab070ca..602bbb3b1 100644 --- a/lib/src/phy/ch_estimation/dmrs_pucch.c +++ b/lib/src/phy/ch_estimation/dmrs_pucch.c @@ -90,24 +90,23 @@ static uint32_t dmrs_pucch_format1_n_pucch(const srslte_pucch_nr_resource_t* res } } - ERROR("Invalid case nof_symbols=%d and m_prime=%d\n", resource->nof_symbols, m_prime); + ERROR("Invalid case nof_symbols=%d and m_prime=%d", resource->nof_symbols, m_prime); return 0; } int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, cf_t* slot_symbols) { - if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 1 resource\n"); + ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_ERROR; } @@ -115,13 +114,13 @@ int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, uint32_t u = 0; uint32_t v = 0; if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { - ERROR("Error getting group sequence\n"); + ERROR("Error getting group sequence"); return SRSLTE_ERROR; } uint32_t n_pucch = dmrs_pucch_format1_n_pucch(resource, 0); if (n_pucch == 0) { - ERROR("Error getting number of symbols\n"); + ERROR("Error getting number of symbols"); return SRSLTE_ERROR; } @@ -137,13 +136,13 @@ int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, uint32_t alpha_idx = 0; if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < SRSLTE_SUCCESS) { - ERROR("Calculating alpha\n"); + ERROR("Calculating alpha"); } // get r_uv sequence from LUT object const cf_t* r_uv = srslte_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); if (r_uv == NULL) { - ERROR("Getting r_uv sequence\n"); + ERROR("Getting r_uv sequence"); return SRSLTE_ERROR; } @@ -164,19 +163,18 @@ int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const cf_t* slot_symbols, srslte_chest_ul_res_t* res) { - if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL || res == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 1 resource\n"); + ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_ERROR; } @@ -184,13 +182,13 @@ int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, uint32_t u = 0; uint32_t v = 0; if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { - ERROR("Error getting group sequence\n"); + ERROR("Error getting group sequence"); return SRSLTE_ERROR; } uint32_t n_pucch = dmrs_pucch_format1_n_pucch(resource, 0); if (n_pucch == 0) { - ERROR("Error getting number of symbols\n"); + ERROR("Error getting number of symbols"); return SRSLTE_ERROR; } @@ -208,13 +206,13 @@ int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, uint32_t alpha_idx = 0; if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < SRSLTE_SUCCESS) { - ERROR("Calculating alpha\n"); + ERROR("Calculating alpha"); } // get r_uv sequence from LUT object const cf_t* r_uv = srslte_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); if (r_uv == NULL) { - ERROR("Getting r_uv sequence\n"); + ERROR("Getting r_uv sequence"); return SRSLTE_ERROR; } @@ -297,19 +295,19 @@ int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, static uint32_t dmrs_pucch_format2_cinit(const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, uint32_t l) { uint32_t n = SRSLTE_SLOT_NR_MOD(slot->idx, carrier->numerology); uint32_t n_id = (cfg->scrambling_id_present) ? cfg->scambling_id : carrier->id; - return SRSLTE_SEQUENCE_MOD((((SRSLTE_NSYMB_PER_SLOT_NR * n + l + 1U) * (2U * n_id + 1U)) << 17U) + 2U * n_id); + return SRSLTE_SEQUENCE_MOD((((SRSLTE_NSYMB_PER_SLOT_NR * n + l + 1UL) * (2UL * n_id + 1UL)) << 17UL) + 2UL * n_id); } int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, cf_t* slot_symbols) { @@ -318,7 +316,7 @@ int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 1 resource\n"); + ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_ERROR; } @@ -350,7 +348,7 @@ int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const cf_t* slot_symbols, srslte_chest_ul_res_t* res) @@ -361,7 +359,7 @@ int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q, } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 1 resource\n"); + ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_ERROR; } @@ -532,7 +530,7 @@ int srslte_dmrs_pucch_format_3_4_get_symbol_idx(const srslte_pucch_nr_resource_t } break; default: - ERROR("Invalid case (%d)\n", resource->nof_symbols); + ERROR("Invalid case (%d)", resource->nof_symbols); return SRSLTE_ERROR; } diff --git a/lib/src/phy/ch_estimation/dmrs_sch.c b/lib/src/phy/ch_estimation/dmrs_sch.c index 6a386b478..d6aafd738 100644 --- a/lib/src/phy/ch_estimation/dmrs_sch.c +++ b/lib/src/phy/ch_estimation/dmrs_sch.c @@ -21,6 +21,7 @@ #include "srslte/phy/ch_estimation/dmrs_sch.h" #include "srslte/phy/common/sequence.h" +#include #include #define SRSLTE_DMRS_SCH_TYPEA_SINGLE_DURATION_MIN 3 @@ -79,13 +80,13 @@ static uint32_t srslte_dmrs_get_lse(srslte_dmrs_sch_t* q, uint32_t start_prb, uint32_t nof_prb, uint32_t delta, + float amplitude, const cf_t* symbols, cf_t* least_square_estimates) { uint32_t count = 0; switch (dmrs_type) { - case srslte_dmrs_sch_type_1: count = srslte_dmrs_get_pilots_type1(start_prb, nof_prb, delta, symbols, least_square_estimates); break; @@ -93,11 +94,11 @@ static uint32_t srslte_dmrs_get_lse(srslte_dmrs_sch_t* q, count = srslte_dmrs_get_pilots_type2(start_prb, nof_prb, delta, symbols, least_square_estimates); break; default: - ERROR("Unknown DMRS type.\n"); + ERROR("Unknown DMRS type."); } // Generate sequence for the given pilots - srslte_sequence_state_gen_f(sequence_state, M_SQRT1_2, (float*)q->temp, count * 2); + srslte_sequence_state_gen_f(sequence_state, amplitude, (float*)q->temp, count * 2); // Calculate least square estimates srslte_vec_prod_conj_ccc(least_square_estimates, q->temp, least_square_estimates, count); @@ -143,15 +144,15 @@ static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_sch_t* q, uint32_t start_prb, uint32_t nof_prb, uint32_t delta, + float amplitude, cf_t* symbols) { uint32_t count = (dmrs_type == srslte_dmrs_sch_type_1) ? nof_prb * 6 : nof_prb * 4; // Generate sequence for the given pilots - srslte_sequence_state_gen_f(sequence_state, M_SQRT1_2, (float*)q->temp, count * 2); + srslte_sequence_state_gen_f(sequence_state, amplitude, (float*)q->temp, count * 2); switch (dmrs_type) { - case srslte_dmrs_sch_type_1: count = srslte_dmrs_put_pilots_type1(start_prb, nof_prb, delta, symbols, q->temp); break; @@ -159,7 +160,7 @@ static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_sch_t* q, count = srslte_dmrs_put_pilots_type2(start_prb, nof_prb, delta, symbols, q->temp); break; default: - ERROR("Unknown DMRS type.\n"); + ERROR("Unknown DMRS type."); } return count; @@ -172,13 +173,18 @@ static int srslte_dmrs_sch_put_symbol(srslte_dmrs_sch_t* q, uint32_t delta, cf_t* symbols) { - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; - uint32_t prb_count = 0; // Counts consecutive used PRB - uint32_t prb_start = 0; // Start consecutive used PRB - uint32_t prb_skip = 0; // Number of PRB to skip - uint32_t nof_pilots_x_prb = dmrs_cfg->type == srslte_dmrs_sch_type_1 ? 6 : 4; - uint32_t pilot_count = 0; + // Get signal amplitude + float amplitude = M_SQRT1_2; + if (isnormal(grant->beta_dmrs)) { + amplitude *= grant->beta_dmrs; + } + + const srslte_dmrs_sch_cfg_t* dmrs_cfg = &pdsch_cfg->dmrs; + uint32_t prb_count = 0; // Counts consecutive used PRB + uint32_t prb_start = 0; // Start consecutive used PRB + uint32_t prb_skip = 0; // Number of PRB to skip + uint32_t nof_pilots_x_prb = dmrs_cfg->type == srslte_dmrs_sch_type_1 ? 6 : 4; + uint32_t pilot_count = 0; // Initialise sequence srslte_sequence_state_t sequence_state = {}; @@ -211,15 +217,16 @@ static int srslte_dmrs_sch_put_symbol(srslte_dmrs_sch_t* q, } // Get contiguous pilots - pilot_count += srslte_dmrs_put_pilots(q, &sequence_state, dmrs_cfg->type, prb_start, prb_count, delta, symbols); + pilot_count += + srslte_dmrs_put_pilots(q, &sequence_state, dmrs_cfg->type, prb_start, prb_count, delta, amplitude, symbols); // Reset counter prb_count = 0; } if (prb_count > 0) { - pilot_count += srslte_dmrs_put_pilots( - q, &sequence_state, dmrs_cfg->type, prb_start, prb_count, delta, &symbols[prb_start * SRSLTE_NRE]); + pilot_count += + srslte_dmrs_put_pilots(q, &sequence_state, dmrs_cfg->type, prb_start, prb_count, delta, amplitude, symbols); } return pilot_count; @@ -233,7 +240,7 @@ static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_single(const srslte_dm int count = 0; if (ld < SRSLTE_DMRS_SCH_TYPEA_SINGLE_DURATION_MIN) { - ERROR("Duration is below the minimum\n"); + ERROR("Duration is below the minimum"); return SRSLTE_ERROR; } @@ -328,7 +335,7 @@ static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(const srslte_dm // According to Table 7.4.1.1.2-4, the additional position 3 is invalid. if (dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) { - ERROR("Invalid additional DMRS (%d)\n", dmrs_cfg->additional_pos); + ERROR("Invalid additional DMRS (%d)", dmrs_cfg->additional_pos); return SRSLTE_ERROR; } @@ -359,7 +366,7 @@ static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(const srslte_dm return count; } -int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* cfg, +int srslte_dmrs_sch_get_symbols_idx(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslte_sch_grant_nr_t* grant, uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS]) { @@ -372,15 +379,12 @@ int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* cfg, ld = grant->S + grant->L; } - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; - switch (grant->mapping) { case srslte_sch_mapping_type_A: // The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal to 'pos2' if (dmrs_cfg->typeA_pos != srslte_dmrs_sch_typeA_pos_2 && dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) { ERROR("The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal " - "to 'pos2'\n"); + "to 'pos2'"); return SRSLTE_ERROR; } @@ -388,7 +392,7 @@ int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* cfg, // applicable when dmrs-TypeA-Position is equal to 'pos2 if ((ld == 3 || ld == 4) && dmrs_cfg->typeA_pos != srslte_dmrs_sch_typeA_pos_2) { ERROR("For PDSCH mapping type A, ld = 3 and ld = 4 symbols in Tables 7.4.1.1.2-3 and 7.4.1.1.2-4 respectively " - "is only applicable when dmrs-TypeA-Position is equal to 'pos2\n"); + "is only applicable when dmrs-TypeA-Position is equal to 'pos2"); return SRSLTE_ERROR; } @@ -397,7 +401,7 @@ int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* cfg, } return srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(dmrs_cfg, ld, symbols); case srslte_sch_mapping_type_B: - ERROR("Error PDSCH mapping type B not supported\n"); + ERROR("Error PDSCH mapping type B not supported"); return SRSLTE_ERROR; } @@ -426,13 +430,10 @@ int srslte_dmrs_sch_get_sc_idx(const srslte_dmrs_sch_cfg_t* cfg, uint32_t max_co return count; } -int srslte_dmrs_sch_get_N_prb(const srslte_sch_cfg_nr_t* cfg, const srslte_sch_grant_nr_t* grant) +int srslte_dmrs_sch_get_N_prb(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslte_sch_grant_nr_t* grant) { - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; - if (grant->nof_dmrs_cdm_groups_without_data < 1 || grant->nof_dmrs_cdm_groups_without_data > 3) { - ERROR("Invalid number if DMRS CDM groups without data (%d). Valid values: 1, 2 , 3\n", + ERROR("Invalid number if DMRS CDM groups without data (%d). Valid values: 1, 2 , 3", grant->nof_dmrs_cdm_groups_without_data); return SRSLTE_ERROR; } @@ -443,9 +444,9 @@ int srslte_dmrs_sch_get_N_prb(const srslte_sch_cfg_nr_t* cfg, const srslte_sch_g // Get number of symbols used for DMRS uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; - int ret = srslte_dmrs_sch_get_symbols_idx(cfg, grant, symbols); + int ret = srslte_dmrs_sch_get_symbols_idx(dmrs_cfg, grant, symbols); if (ret < SRSLTE_SUCCESS) { - ERROR("Error getting PDSCH DMRS symbol indexes\n"); + ERROR("Error getting PDSCH DMRS symbol indexes"); return SRSLTE_ERROR; } @@ -458,8 +459,7 @@ static uint32_t srslte_dmrs_sch_seed(const srslte_carrier_nr_t* carrier, uint32_t slot_idx, uint32_t symbol_idx) { - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = &cfg->dmrs; slot_idx = slot_idx % SRSLTE_NSLOTS_PER_FRAME_NR(carrier->numerology); @@ -474,19 +474,18 @@ static uint32_t srslte_dmrs_sch_seed(const srslte_carrier_nr_t* carrier, n_id = dmrs_cfg->scrambling_id1; } - return (uint32_t)(((((SRSLTE_NSYMB_PER_SLOT_NR * slot_idx + symbol_idx + 1UL) * (2UL * n_id + 1UL)) << 17UL) + - (2UL * carrier->id + n_scid)) & - (uint64_t)INT32_MAX); + return SRSLTE_SEQUENCE_MOD((((SRSLTE_NSYMB_PER_SLOT_NR * slot_idx + symbol_idx + 1UL) * (2UL * n_id + 1UL)) << 17UL) + + (2UL * n_id + n_scid)); } -int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_ue) +int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_rx) { if (q == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - if (is_ue) { - q->is_ue = true; + if (is_rx) { + q->is_rx = true; } return SRSLTE_SUCCESS; @@ -526,13 +525,13 @@ int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t* q->temp = srslte_vec_cf_malloc(q->max_nof_prb * SRSLTE_NRE); if (!q->temp) { - ERROR("malloc\n"); + ERROR("malloc"); return SRSLTE_ERROR; } } // If it is not UE, quit now - if (!q->is_ue) { + if (!q->is_rx) { return SRSLTE_SUCCESS; } @@ -555,7 +554,7 @@ int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t* // The maximum number of pilots is for Type 1 q->pilot_estimates = srslte_vec_cf_malloc(SRSLTE_DMRS_SCH_MAX_SYMBOLS * q->max_nof_prb * SRSLTE_NRE / 2); if (!q->pilot_estimates) { - ERROR("malloc\n"); + ERROR("malloc"); return SRSLTE_ERROR; } } @@ -564,7 +563,7 @@ int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t* } int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant, cf_t* sf_symbols) @@ -579,7 +578,7 @@ int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, // Get symbols indexes uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; - int nof_symbols = srslte_dmrs_sch_get_symbols_idx(pdsch_cfg, grant, symbols); + int nof_symbols = srslte_dmrs_sch_get_symbols_idx(&pdsch_cfg->dmrs, grant, symbols); if (nof_symbols < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -604,8 +603,13 @@ static int srslte_dmrs_sch_get_symbol(srslte_dmrs_sch_t* q, const cf_t* symbols, cf_t* least_square_estimates) { - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; + // Get signal amplitude + float amplitude = M_SQRT1_2; + if (isnormal(grant->beta_dmrs)) { + amplitude /= grant->beta_dmrs; + } + + const srslte_dmrs_sch_cfg_t* dmrs_cfg = &pdsch_cfg->dmrs; uint32_t prb_count = 0; // Counts consecutive used PRB uint32_t prb_start = 0; // Start consecutive used PRB @@ -650,7 +654,8 @@ static int srslte_dmrs_sch_get_symbol(srslte_dmrs_sch_t* q, prb_start, prb_count, delta, - &symbols[prb_start * SRSLTE_NRE], + amplitude, + symbols, &least_square_estimates[pilot_count]); // Reset counter @@ -664,7 +669,8 @@ static int srslte_dmrs_sch_get_symbol(srslte_dmrs_sch_t* q, prb_start, prb_count, delta, - &symbols[prb_start * SRSLTE_NRE], + amplitude, + symbols, &least_square_estimates[pilot_count]); } @@ -672,7 +678,7 @@ static int srslte_dmrs_sch_get_symbol(srslte_dmrs_sch_t* q, } int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_slot_cfg_t* slot_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant, const cf_t* sf_symbols, @@ -684,17 +690,16 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, return SRSLTE_ERROR_INVALID_INPUTS; } - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = &pdsch_cfg->dmrs; cf_t* ce = q->temp; uint32_t symbol_sz = q->carrier.nof_prb * SRSLTE_NRE; // Symbol size in resource elements // Get symbols indexes uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; - int nof_symbols = srslte_dmrs_sch_get_symbols_idx(pdsch_cfg, grant, symbols); + int nof_symbols = srslte_dmrs_sch_get_symbols_idx(&pdsch_cfg->dmrs, grant, symbols); if (nof_symbols <= SRSLTE_SUCCESS) { - ERROR("Error getting symbol indexes\n"); + ERROR("Error getting symbol indexes"); return SRSLTE_ERROR; } @@ -710,22 +715,24 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, q, pdsch_cfg, grant, cinit, delta, &sf_symbols[symbol_sz * l], &q->pilot_estimates[nof_pilots_x_symbol * i]); if (nof_pilots_x_symbol == 0) { - ERROR("Error, no pilots extracted (i=%d, l=%d)\n", i, l); + ERROR("Error, no pilots extracted (i=%d, l=%d)", i, l); return SRSLTE_ERROR; } } - float rsrp = 0.0f; - float epre = 0.0f; + // Perform Power measurements + float rsrp = 0.0f; + float epre = 0.0f; + cf_t corr[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; for (uint32_t i = 0; i < nof_symbols; i++) { - cf_t corr = + corr[i] = srslte_vec_acc_cc(&q->pilot_estimates[nof_pilots_x_symbol * i], nof_pilots_x_symbol) / nof_pilots_x_symbol; - rsrp += __real__ corr * __real__ corr + __imag__ corr * __imag__ corr; + rsrp += __real__ corr[i] * __real__ corr[i] + __imag__ corr[i] * __imag__ corr[i]; epre += srslte_vec_avg_power_cf(&q->pilot_estimates[nof_pilots_x_symbol * i], nof_pilots_x_symbol); } rsrp /= nof_symbols; epre /= nof_symbols; - rsrp = SRSLTE_MIN(rsrp, epre); + rsrp = SRSLTE_MIN(rsrp, epre - epre * 1e-7); chest_res->rsrp = rsrp; chest_res->rsrp_dbm = srslte_convert_power_to_dB(chest_res->rsrp); @@ -735,8 +742,17 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, chest_res->snr_db = chest_res->rsrp_dbm - chest_res->noise_estimate_dbm; - // Perform measurements here - // ... + // Measure CFO if more than one symbol is used + float cfo_avg = 0.0; + for (uint32_t i = 0; i < nof_symbols - 1; i++) { + float time_diff = srslte_symbol_distance_s(symbols[i], symbols[i + 1], q->carrier.numerology); + float phase_diff = cargf(corr[i + 1] * conjf(corr[i])); + + if (isnormal(time_diff)) { + cfo_avg += phase_diff / (2.0f * M_PI * time_diff * (nof_symbols - 1)); + } + } + chest_res->cfo = cfo_avg; // Average over time, only if more than one DMRS symbol for (uint32_t i = 1; i < nof_symbols; i++) { @@ -753,7 +769,7 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, if (dmrs_cfg->type == srslte_dmrs_sch_type_1) { // Prepare interpolator if (srslte_interp_linear_resize(&q->interpolator_type1, nof_pilots_x_symbol, 2) < SRSLTE_SUCCESS) { - ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;\n", nof_pilots_x_symbol, 2); + ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;", nof_pilots_x_symbol, 2); return SRSLTE_ERROR; } @@ -763,7 +779,7 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, } else { // Prepare interpolator if (srslte_interp_linear_resize(&q->interpolator_type2, nof_pilots_x_symbol, 3) < SRSLTE_SUCCESS) { - ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;\n", nof_pilots_x_symbol, 3); + ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;", nof_pilots_x_symbol, 3); return SRSLTE_ERROR; } @@ -781,7 +797,6 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, if (symbols[symbol_idx] == l) { switch (dmrs_cfg->type) { - case srslte_dmrs_sch_type_1: // Skip if there is no data to read if (grant->nof_dmrs_cdm_groups_without_data != 1) { diff --git a/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c b/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c index 3dde95b48..d0a8aaa9e 100644 --- a/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c @@ -122,7 +122,7 @@ free_and_exit: int srslte_refsignal_dl_nbiot_set_cell(srslte_refsignal_dl_nbiot_t* q, srslte_nbiot_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - INFO("Generating NRS for n_id_ncell=%d\n", cell.n_id_ncell); + INFO("Generating NRS for n_id_ncell=%d", cell.n_id_ncell); if (q != NULL && srslte_nbiot_cell_isvalid(&cell)) { ret = SRSLTE_ERROR; @@ -153,7 +153,7 @@ int srslte_refsignal_dl_nbiot_set_cell(srslte_refsignal_dl_nbiot_t* q, srslte_nb /* save signal */ int idx = SRSLTE_NBIOT_REFSIGNAL_PILOT_IDX(i, (ns % 2) * nsymbols + l, SRSLTE_NBIOT_DEFAULT_NUM_PRB_BASECELL); - DEBUG("Ref port=%d, lp=%d, ns=%d, ns/2=%d, idx=%d, i=%d, nsymbols=%d, l=%d\n", + DEBUG("Ref port=%d, lp=%d, ns=%d, ns/2=%d, idx=%d, i=%d, nsymbols=%d, l=%d", p, lp, ns, @@ -216,7 +216,7 @@ int srslte_refsignal_nrs_put_sf(srslte_nbiot_cell_t cell, uint32_t port_id, cf_t uint32_t fidx = srslte_refsignal_dl_nbiot_fidx(cell, l, port_id, m) + cell.nbiot_prb * SRSLTE_NRE; sf_symbols[SRSLTE_RE_IDX(cell.base.nof_prb, nsymbol, fidx)] = pilots[SRSLTE_NBIOT_REFSIGNAL_PILOT_IDX(m, l, 1)]; #if EXTRA_DEBUG - DEBUG("port: %d, re_idx: %d, pilot_idx: %d, %+2.2f%+2.2fi\n", + DEBUG("port: %d, re_idx: %d, pilot_idx: %d, %+2.2f%+2.2fi", port_id, SRSLTE_RE_IDX(cell.base.nof_prb, nsymbol, fidx), SRSLTE_NBIOT_REFSIGNAL_PILOT_IDX(i, l, 1), @@ -228,7 +228,7 @@ int srslte_refsignal_nrs_put_sf(srslte_nbiot_cell_t cell, uint32_t port_id, cf_t #if EXTRA_DEBUG if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE chest_nbiot_tx_after_mapping.bin: NRS after mapping\n", 0); + DEBUG("SAVED FILE chest_nbiot_tx_after_mapping.bin: NRS after mapping", 0); srslte_vec_save_file( "chest_nbiot_tx_after_mapping.bin", pilots, SRSLTE_REFSIGNAL_NUM_SF(1, port_id) * sizeof(cf_t)); } @@ -250,7 +250,7 @@ int srslte_refsignal_nrs_get_sf(srslte_nbiot_cell_t cell, uint32_t port_id, cf_t uint32_t fidx = srslte_refsignal_dl_nbiot_fidx(cell, l, port_id, m) + cell.nbiot_prb * SRSLTE_NRE; pilots[SRSLTE_NBIOT_REFSIGNAL_PILOT_IDX(m, l, 1)] = sf_symbols[SRSLTE_RE_IDX(cell.base.nof_prb, nsymbol, fidx)]; #if EXTRA_DEBUG - DEBUG("port: %d, pilot_idx: %d, re_idx: %d, %+2.2f%+2.2fi\n", + DEBUG("port: %d, pilot_idx: %d, re_idx: %d, %+2.2f%+2.2fi", port_id, SRSLTE_NBIOT_REFSIGNAL_PILOT_IDX(m, l, 1), SRSLTE_RE_IDX(cell.base.nof_prb, nsymbol, fidx), @@ -262,7 +262,7 @@ int srslte_refsignal_nrs_get_sf(srslte_nbiot_cell_t cell, uint32_t port_id, cf_t #if EXTRA_DEBUG if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE chest_nbiot_rx_after_demapping.bin: NRS after demapping\n", 0); + DEBUG("SAVED FILE chest_nbiot_rx_after_demapping.bin: NRS after demapping", 0); srslte_vec_save_file( "chest_nbiot_rx_after_demapping.bin", pilots, SRSLTE_REFSIGNAL_NUM_SF(1, port_id) * sizeof(cf_t)); } diff --git a/lib/src/phy/ch_estimation/refsignal_ul.c b/lib/src/phy/ch_estimation/refsignal_ul.c index 82d95f64c..ea1b5a07d 100644 --- a/lib/src/phy/ch_estimation/refsignal_ul.c +++ b/lib/src/phy/ch_estimation/refsignal_ul.c @@ -138,11 +138,9 @@ static int generate_srslte_sequence_hopping_v(srslte_refsignal_ul_t* q) */ int srslte_refsignal_ul_set_cell(srslte_refsignal_ul_t* q, srslte_cell_t cell) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_cell_isvalid(&cell)) { - if (cell.id != q->cell.id || q->cell.nof_prb == 0) { q->cell = cell; @@ -197,7 +195,7 @@ void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t* q, cf_t* sf_symbols) { for (uint32_t ns_idx = 0; ns_idx < 2; ns_idx++) { - INFO("Putting DMRS to n_prb: %d, L: %d, ns_idx: %d\n", + INFO("Putting DMRS to n_prb: %d, L: %d, ns_idx: %d", pusch_cfg->grant.n_prb_tilde[ns_idx], pusch_cfg->grant.L_prb, ns_idx); @@ -214,7 +212,7 @@ void srslte_refsignal_dmrs_pusch_get(srslte_refsignal_ul_t* q, cf_t* r_pusch) { for (uint32_t ns_idx = 0; ns_idx < 2; ns_idx++) { - INFO("Getting DMRS from n_prb: %d, L: %d, ns_idx: %d\n", + INFO("Getting DMRS from n_prb: %d, L: %d, ns_idx: %d", pusch_cfg->grant.n_prb_tilde[ns_idx], pusch_cfg->grant.L_prb, ns_idx); @@ -343,7 +341,6 @@ int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t* q, uint32_t cyclic_shift_for_dmrs, cf_t* r_pusch) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; if (pusch_cfg_isvalid(q, cfg, nof_prb)) { ret = SRSLTE_ERROR; @@ -382,7 +379,7 @@ uint32_t srslte_refsignal_dmrs_N_rs(srslte_pucch_format_t format, srslte_cp_t cp case SRSLTE_PUCCH_FORMAT_2B: return 2; default: - ERROR("DMRS Nof RS: Unsupported format %d\n", format); + ERROR("DMRS Nof RS: Unsupported format %d", format); return 0; } return 0; @@ -424,7 +421,7 @@ uint32_t srslte_refsignal_dmrs_pucch_symbol(uint32_t m, srslte_pucch_format_t fo } break; default: - ERROR("DMRS Symbol indexes: Unsupported format %d\n", format); + ERROR("DMRS Symbol indexes: Unsupported format %d", format); return 0; } return 0; @@ -494,7 +491,7 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t* q, w = w_arg_pucch_format2_cpnorm; break; default: - ERROR("DMRS Generator: Unsupported format %d\n", cfg->format); + ERROR("DMRS Generator: Unsupported format %d", cfg->format); return SRSLTE_ERROR; } @@ -521,12 +518,10 @@ int srslte_refsignal_dmrs_pucch_cp(srslte_refsignal_ul_t* q, { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q && source && dest) { - uint32_t nsymbols = SRSLTE_CP_ISNORM(q->cell.cp) ? SRSLTE_CP_NORM_NSYMB : SRSLTE_CP_EXT_NSYMB; uint32_t N_rs = srslte_refsignal_dmrs_N_rs(cfg->format, q->cell.cp); for (uint32_t ns = 0; ns < 2; ns++) { - // Determine n_prb uint32_t n_prb = srslte_pucch_n_prb(&q->cell, cfg, ns); @@ -808,7 +803,6 @@ static uint32_t srs_Fb(srslte_refsignal_srs_cfg_t* cfg, uint32_t b, uint32_t nof /* Returns k0: frequency-domain starting position for ue-specific SRS */ static uint32_t srs_k0_ue(srslte_refsignal_srs_cfg_t* cfg, uint32_t nof_prb, uint32_t tti) { - if (cfg->bw_cfg < 8 && cfg->B < 4 && cfg->k_tc < 2) { uint32_t k0p = srslte_refsignal_srs_rb_start_cs(cfg->bw_cfg, nof_prb) * SRSLTE_NRE + cfg->k_tc; uint32_t k0 = k0p; @@ -884,7 +878,6 @@ int srslte_refsignal_srs_gen(srslte_refsignal_ul_t* q, uint32_t M_sc = srslte_refsignal_srs_M_sc(q, cfg); for (uint32_t ns = 2 * sf_idx; ns < 2 * (sf_idx + 1); ns++) { - float alpha = 2 * M_PI * cfg->n_srs / 8; compute_r(q, pusch_cfg, M_sc / SRSLTE_NRE, ns, 0, alpha, &r_srs[(ns % 2) * M_sc]); } diff --git a/lib/src/phy/ch_estimation/test/CMakeLists.txt b/lib/src/phy/ch_estimation/test/CMakeLists.txt index d8f41da75..fef154faa 100644 --- a/lib/src/phy/ch_estimation/test/CMakeLists.txt +++ b/lib/src/phy/ch_estimation/test/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "lib;phy;chest") + ######################################################################## # Downlink Channel Estimation TEST ######################################################################## @@ -25,13 +27,13 @@ add_executable(chest_test_dl chest_test_dl.c) target_link_libraries(chest_test_dl srslte_phy) -add_test(chest_test_dl_cellid0 chest_test_dl -c 0) -add_test(chest_test_dl_cellid1 chest_test_dl -c 1) -add_test(chest_test_dl_cellid2 chest_test_dl -c 2) +add_lte_test(chest_test_dl_cellid0 chest_test_dl -c 0) +add_lte_test(chest_test_dl_cellid1 chest_test_dl -c 1) +add_lte_test(chest_test_dl_cellid2 chest_test_dl -c 2) -add_test(chest_test_dl_cellid0_50prb chest_test_dl -c 0 -r 50) -add_test(chest_test_dl_cellid1_50prb chest_test_dl -c 1 -r 50) -add_test(chest_test_dl_cellid2_50prb chest_test_dl -c 2 -r 50) +add_lte_test(chest_test_dl_cellid0_50prb chest_test_dl -c 0 -r 50) +add_lte_test(chest_test_dl_cellid1_50prb chest_test_dl -c 1 -r 50) +add_lte_test(chest_test_dl_cellid2_50prb chest_test_dl -c 2 -r 50) ######################################################################## @@ -44,9 +46,9 @@ target_link_libraries(chest_test_ul srslte_phy srslte_common) add_executable(refsignal_ul_test_all refsignal_ul_test.c) target_link_libraries(refsignal_ul_test_all srslte_phy srslte_common) -add_test(chest_test_ul_cellid0 chest_test_ul -c 0 -r 50) -add_test(chest_test_ul_cellid1 chest_test_ul -c 1 -r 50) -add_test(chest_test_ul_cellid1 chest_test_ul -c 2 -r 50) +add_lte_test(chest_test_ul_cellid0 chest_test_ul -c 0 -r 50) +add_lte_test(chest_test_ul_cellid1 chest_test_ul -c 1 -r 50) +add_lte_test(chest_test_ul_cellid2 chest_test_ul -c 2 -r 50) ######################################################################## # Uplink Sounding Reference Signals Channel Estimation TEST @@ -56,8 +58,7 @@ add_executable(chest_test_srs chest_test_srs.c) target_link_libraries(chest_test_srs srslte_phy srslte_common) foreach (cell_n_prb 6 15 25 50 75 100) - add_test(chest_test_srs_${cell_n_prb} chest_test_srs -c 2 -r ${cell_n_prb}) - set_tests_properties(chest_test_srs_${cell_n_prb} PROPERTIES LABELS "long;phy") + add_lte_test(chest_test_srs_${cell_n_prb} chest_test_srs -c 2 -r ${cell_n_prb}) endforeach(cell_n_prb 6 15 25 50 75 100) @@ -68,7 +69,7 @@ endforeach(cell_n_prb 6 15 25 50 75 100) add_executable(chest_nbiot_test_dl chest_nbiot_test_dl.c) target_link_libraries(chest_nbiot_test_dl srslte_phy) -add_test(chest_nbiot_test_dl chest_nbiot_test_dl) +add_lte_test(chest_nbiot_test_dl chest_nbiot_test_dl) ######################################################################## @@ -78,7 +79,7 @@ add_test(chest_nbiot_test_dl chest_nbiot_test_dl) add_executable(chest_test_sl chest_test_sl.c) target_link_libraries(chest_test_sl srslte_phy) -add_test(chest_test_sl_psbch chest_test_sl) +add_lte_test(chest_test_sl_psbch chest_test_sl) ######################################################################## @@ -88,7 +89,7 @@ add_test(chest_test_sl_psbch chest_test_sl) add_executable(dmrs_pdsch_test dmrs_pdsch_test.c) target_link_libraries(dmrs_pdsch_test srslte_phy) -add_test(dmrs_pdsch_test dmrs_pdsch_test) +add_lte_test(dmrs_pdsch_test dmrs_pdsch_test) ######################################################################## @@ -98,7 +99,7 @@ add_test(dmrs_pdsch_test dmrs_pdsch_test) add_executable(dmrs_pdcch_test dmrs_pdcch_test.c) target_link_libraries(dmrs_pdcch_test srslte_phy) -add_test(dmrs_pdcch_test dmrs_pdcch_test) +add_lte_test(dmrs_pdcch_test dmrs_pdcch_test) ######################################################################## @@ -108,5 +109,5 @@ add_test(dmrs_pdcch_test dmrs_pdcch_test) add_executable(csi_rs_test csi_rs_test.c) target_link_libraries(csi_rs_test srslte_phy) -add_test(csi_rs_test csi_rs_test -o 3 -S 0 -L 150 -f 3 -p 15) +add_lte_test(csi_rs_test csi_rs_test -o 3 -S 0 -L 150 -f 3 -p 15) diff --git a/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c b/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c index 21672a470..585c7c15e 100644 --- a/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c +++ b/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c @@ -137,7 +137,7 @@ int main(int argc, char** argv) } if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE chest_start.bin: channel estimates start\n"); + DEBUG("SAVED FILE chest_start.bin: channel estimates start"); srslte_vec_save_file("chest_start.bin", ce, num_re * sizeof(cf_t)); } @@ -198,10 +198,10 @@ int main(int argc, char** argv) float rsrp = srslte_chest_dl_nbiot_get_rsrp(&est); float noise = srslte_chest_dl_nbiot_get_noise_estimate(&est); float snr = srslte_chest_dl_nbiot_get_snr(&est); - DEBUG("rsrq=%4.2f, rsrp=%4.2f, noise=%4.2f, snr=%4.2f\n", rsrq, rsrp, noise, snr); + DEBUG("rsrq=%4.2f, rsrp=%4.2f, noise=%4.2f, snr=%4.2f", rsrq, rsrp, noise, snr); if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE chest_final.bin: channel after estimation\n"); + DEBUG("SAVED FILE chest_final.bin: channel after estimation"); srslte_vec_save_file("chest_final.bin", ce, num_re * sizeof(cf_t)); } diff --git a/lib/src/phy/ch_estimation/test/chest_test_dl.c b/lib/src/phy/ch_estimation/test/chest_test_dl.c index 6b77d006a..a4493e4e8 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_dl.c +++ b/lib/src/phy/ch_estimation/test/chest_test_dl.c @@ -128,13 +128,13 @@ int main(int argc, char** argv) max_cid = cell.id; } if (srslte_chest_dl_init(&est, cell.nof_prb, 1)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); goto do_exit; } while (cid <= max_cid) { cell.id = cid; if (srslte_chest_dl_set_cell(&est, cell)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); goto do_exit; } @@ -144,7 +144,6 @@ int main(int argc, char** argv) sf_cfg.tti = sf_idx; for (uint32_t n_port = 0; n_port < cell.nof_ports; n_port++) { - srslte_vec_cf_zero(input, num_re); for (i = 0; i < num_re; i++) { input[i] = 0.5 - rand() / RAND_MAX + I * (0.5 - rand() / RAND_MAX); @@ -227,7 +226,7 @@ int main(int argc, char** argv) } } cid += 10; - INFO("cid=%d\n", cid); + INFO("cid=%d", cid); } srslte_chest_dl_free(&est); ret = 0; diff --git a/lib/src/phy/ch_estimation/test/chest_test_srs.c b/lib/src/phy/ch_estimation/test/chest_test_srs.c index 073d90e62..351a3a012 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_srs.c +++ b/lib/src/phy/ch_estimation/test/chest_test_srs.c @@ -126,7 +126,7 @@ int srs_test_context_run(srs_test_context_t* q) { srslte_ul_sf_cfg_t ul_sf_cfg = {}; - INFO(" TEST: bw_cfg=%d; sf_cfg=%d; B=%d; b_hops=%d; n_srs=%d; I_srs=%d;\n", + INFO(" TEST: bw_cfg=%d; sf_cfg=%d; B=%d; b_hops=%d; n_srs=%d; I_srs=%d;", srs_cfg.bw_cfg, srs_cfg.subframe_config, srs_cfg.B, @@ -156,7 +156,7 @@ int srs_test_context_run(srs_test_context_t* q) &q->chest_ul, &ul_sf_cfg, &srs_cfg, &dmrs_pusch_cfg, q->sf_symbols, &q->chest_ul_res) == SRSLTE_SUCCESS); - INFO("RESULTS: tti=%d; snr_db=%+.1f; noise_estimate_dbm=%+.1f; ta_us=%+.1f;\n", + INFO("RESULTS: tti=%d; snr_db=%+.1f; noise_estimate_dbm=%+.1f; ta_us=%+.1f;", ul_sf_cfg.tti, q->chest_ul_res.snr_db, q->chest_ul_res.noise_estimate_dbm, @@ -196,7 +196,6 @@ void parse_args(int argc, char** argv) int main(int argc, char** argv) { - srs_test_context_t context = {}; int ret = SRSLTE_SUCCESS; diff --git a/lib/src/phy/ch_estimation/test/chest_test_ul.c b/lib/src/phy/ch_estimation/test/chest_test_ul.c index c52ffb388..e6126d373 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_ul.c +++ b/lib/src/phy/ch_estimation/test/chest_test_ul.c @@ -127,13 +127,13 @@ int main(int argc, char** argv) } printf("max_cid=%d, cid=%d, cell.id=%d\n", max_cid, cid, cell.id); if (srslte_chest_ul_init(&est, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); goto do_exit; } while (cid <= max_cid) { cell.id = cid; if (srslte_chest_ul_set_cell(&est, cell)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); goto do_exit; } @@ -142,7 +142,6 @@ int main(int argc, char** argv) for (int delta_ss = 29; delta_ss < SRSLTE_NOF_DELTA_SS; delta_ss++) { for (int cshift = 7; cshift < SRSLTE_NOF_CSHIFT; cshift++) { for (int t = 2; t < 3; t++) { - /* Setup and pregen DMRS reference signals */ srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; @@ -170,7 +169,6 @@ int main(int argc, char** argv) for (int sf_idx = 0; sf_idx < 10; sf_idx += 3) { for (int cshift_dmrs = 0; cshift_dmrs < SRSLTE_NOF_CSHIFT; cshift_dmrs += 5) { - if (SRSLTE_VERBOSE_ISINFO()) { printf("nof_prb: %d, ", nof_prb); printf("cyclic_shift: %d, ", pusch_cfg.cyclic_shift); @@ -219,7 +217,7 @@ int main(int argc, char** argv) mse += cabsf(ce[i] - h[i]); } mse /= num_re; - INFO("MSE: %f\n", mse); + INFO("MSE: %f", mse); if (mse > 4) { goto do_exit; } diff --git a/lib/src/phy/ch_estimation/test/csi_rs_test.c b/lib/src/phy/ch_estimation/test/csi_rs_test.c index 4caf4c14a..03c9973e2 100644 --- a/lib/src/phy/ch_estimation/test/csi_rs_test.c +++ b/lib/src/phy/ch_estimation/test/csi_rs_test.c @@ -40,7 +40,7 @@ static uint32_t start_rb = UINT32_MAX; static uint32_t nof_rb = UINT32_MAX; static uint32_t first_symbol = UINT32_MAX; -static int test(const srslte_dl_slot_cfg_t* slot_cfg, +static int test(const srslte_slot_cfg_t* slot_cfg, const srslte_csi_rs_nzp_resource_t* resource, srslte_channel_awgn_t* awgn, cf_t* grid) @@ -64,7 +64,7 @@ static int test(const srslte_dl_slot_cfg_t* slot_cfg, if (srslte_verbose >= SRSLTE_VERBOSE_INFO) { char str[128] = {}; srslte_csi_rs_measure_info(&measure, str, sizeof(str)); - INFO("Measure: %s\n", str); + INFO("Measure: %s", str); } TESTASSERT(fabsf(measure.rsrp_dB - rsrp_dB_gold) < 1.0f); @@ -127,7 +127,7 @@ static void parse_args(int argc, char** argv) int main(int argc, char** argv) { int ret = SRSLTE_ERROR; - srslte_dl_slot_cfg_t slot_cfg = {}; + srslte_slot_cfg_t slot_cfg = {}; srslte_csi_rs_nzp_resource_t resource = {}; srslte_channel_awgn_t awgn = {}; @@ -135,12 +135,12 @@ int main(int argc, char** argv) cf_t* grid = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(carrier.nof_prb)); if (grid == NULL) { - ERROR("Alloc\n"); + ERROR("Alloc"); goto clean_exit; } if (srslte_channel_awgn_init(&awgn, 1234) < SRSLTE_SUCCESS) { - ERROR("AWGN Init\n"); + ERROR("AWGN Init"); goto clean_exit; } @@ -158,21 +158,18 @@ int main(int argc, char** argv) for (resource.resource_mapping.first_symbol_idx = first_symbol_begin; resource.resource_mapping.first_symbol_idx <= first_symbol_end; resource.resource_mapping.first_symbol_idx++) { - // Iterate over possible power control offset float power_control_offset_begin = isnormal(power_control_offset) ? power_control_offset : -8.0f; float power_control_offset_end = isnormal(power_control_offset) ? power_control_offset : 15.0f; for (resource.power_control_offset = power_control_offset_begin; resource.power_control_offset <= power_control_offset_end; resource.power_control_offset += 1.0f) { - // Iterate over all possible starting number of PRB uint32_t start_rb_begin = (start_rb != UINT32_MAX) ? start_rb : 0; uint32_t start_rb_end = (start_rb != UINT32_MAX) ? start_rb : carrier.nof_prb - 24; for (resource.resource_mapping.freq_band.start_rb = start_rb_begin; resource.resource_mapping.freq_band.start_rb <= start_rb_end; resource.resource_mapping.freq_band.start_rb += 4) { - // Iterate over all possible number of PRB uint32_t nof_rb_begin = (nof_rb != UINT32_MAX) ? nof_rb : 24; uint32_t nof_rb_end = @@ -180,7 +177,6 @@ int main(int argc, char** argv) for (resource.resource_mapping.freq_band.nof_rb = nof_rb_begin; resource.resource_mapping.freq_band.nof_rb <= nof_rb_end; resource.resource_mapping.freq_band.nof_rb += 4) { - // Iterate for all slot numbers for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot_cfg.idx++) { // Steer Frequency allocation diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c index 4d966872a..7aa76c45e 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c @@ -72,7 +72,7 @@ static int run_test(srslte_dmrs_pdcch_estimator_t* estimator, cf_t* sf_symbols, srslte_dmrs_pdcch_ce_t* ce) { - srslte_dl_slot_cfg_t slot_cfg = {}; + srslte_slot_cfg_t slot_cfg = {}; srslte_dci_location_t dci_location = {}; dci_location.L = aggregation_level; @@ -151,10 +151,8 @@ int main(int argc, char** argv) } for (coreset.duration = 1; coreset.duration <= 3; coreset.duration++) { - - for (search_space.type = srslte_search_space_type_common; search_space.type <= srslte_search_space_type_ue; + for (search_space.type = srslte_search_space_type_common_0; search_space.type <= srslte_search_space_type_ue; search_space.type++) { - for (uint32_t i = 0; i < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; i++) { uint32_t L = 1U << i; uint32_t nof_reg = coreset.duration * nof_freq_resources * 6; @@ -164,11 +162,10 @@ int main(int argc, char** argv) for (uint32_t aggregation_level = 0; aggregation_level < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; aggregation_level++) { - srslte_dmrs_pdcch_estimator_init(&estimator, &carrier, &coreset); if (run_test(&estimator, &coreset, &search_space, aggregation_level, sf_symbols, &pdcch_ce)) { - ERROR("Test %d failed\n", test_counter); + ERROR("Test %d failed", test_counter); } else { test_passed++; } diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c index be1f667ae..63b27c637 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c @@ -177,24 +177,24 @@ static int assert_cfg(const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_gra continue; } - if (pdsch_cfg->dmrs_typeA.typeA_pos != gold[i].typeA_pos) { + if (pdsch_cfg->dmrs.typeA_pos != gold[i].typeA_pos) { continue; } - if (pdsch_cfg->dmrs_typeA.additional_pos != gold[i].additional_pos) { + if (pdsch_cfg->dmrs.additional_pos != gold[i].additional_pos) { continue; } - if (pdsch_cfg->dmrs_typeA.length != gold[i].max_length) { + if (pdsch_cfg->dmrs.length != gold[i].max_length) { continue; } - if (pdsch_cfg->dmrs_typeA.type != gold[i].type) { + if (pdsch_cfg->dmrs.type != gold[i].type) { continue; } uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; - int nof_symbols = srslte_dmrs_sch_get_symbols_idx(pdsch_cfg, grant, symbols); + int nof_symbols = srslte_dmrs_sch_get_symbols_idx(&pdsch_cfg->dmrs, grant, symbols); TESTASSERT(nof_symbols == gold[i].nof_symbols); @@ -203,7 +203,7 @@ static int assert_cfg(const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_gra } uint32_t sc[SRSLTE_NRE] = {}; - srslte_dmrs_sch_get_sc_idx(&pdsch_cfg->dmrs_typeA, SRSLTE_NRE, sc); + srslte_dmrs_sch_get_sc_idx(&pdsch_cfg->dmrs, SRSLTE_NRE, sc); for (uint32_t j = 0; j < gold[i].nof_sc; j++) { TESTASSERT(sc[j] == gold[i].sc_idx[j]); @@ -223,7 +223,7 @@ static int run_test(srslte_dmrs_sch_t* dmrs_pdsch, { TESTASSERT(assert_cfg(pdsch_cfg, grant) == SRSLTE_SUCCESS); - srslte_dl_slot_cfg_t slot_cfg = {}; + srslte_slot_cfg_t slot_cfg = {}; for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(dmrs_pdsch->carrier.numerology); slot_cfg.idx++) { TESTASSERT(srslte_dmrs_sch_put_sf(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols) == SRSLTE_SUCCESS); @@ -263,18 +263,18 @@ int main(int argc, char** argv) // Initialise object DMRS for PDSCH if (srslte_dmrs_sch_init(&dmrs_pdsch, true) != SRSLTE_SUCCESS) { - ERROR("Init\n"); + ERROR("Init"); goto clean_exit; } // Set carrier configuration if (srslte_dmrs_sch_set_carrier(&dmrs_pdsch, &carrier) != SRSLTE_SUCCESS) { - ERROR("Setting carrier\n"); + ERROR("Setting carrier"); goto clean_exit; } if (srslte_chest_dl_res_init(&chest_dl_res, carrier.nof_prb) != SRSLTE_SUCCESS) { - ERROR("Initiating channel estimation result\n"); + ERROR("Initiating channel estimation result"); goto clean_exit; } @@ -283,61 +283,50 @@ int main(int argc, char** argv) srslte_dmrs_sch_type_t type_begin = srslte_dmrs_sch_type_1; srslte_dmrs_sch_type_t type_end = srslte_dmrs_sch_type_2; - for (pdsch_cfg.dmrs_typeA.type = type_begin; pdsch_cfg.dmrs_typeA.type <= type_end; pdsch_cfg.dmrs_typeA.type++) { + for (pdsch_cfg.dmrs.type = type_begin; pdsch_cfg.dmrs.type <= type_end; pdsch_cfg.dmrs.type++) { srslte_dmrs_sch_typeA_pos_t typeA_pos_begin = srslte_dmrs_sch_typeA_pos_2; srslte_dmrs_sch_typeA_pos_t typeA_pos_end = srslte_dmrs_sch_typeA_pos_3; - for (pdsch_cfg.dmrs_typeA.typeA_pos = typeA_pos_begin; pdsch_cfg.dmrs_typeA.typeA_pos <= typeA_pos_end; - pdsch_cfg.dmrs_typeA.typeA_pos++) { + for (pdsch_cfg.dmrs.typeA_pos = typeA_pos_begin; pdsch_cfg.dmrs.typeA_pos <= typeA_pos_end; + pdsch_cfg.dmrs.typeA_pos++) { srslte_dmrs_sch_add_pos_t add_pos_begin = srslte_dmrs_sch_add_pos_2; srslte_dmrs_sch_add_pos_t add_pos_end = srslte_dmrs_sch_add_pos_3; - if (pdsch_cfg.dmrs_typeA.typeA_pos == srslte_dmrs_sch_typeA_pos_3) { + if (pdsch_cfg.dmrs.typeA_pos == srslte_dmrs_sch_typeA_pos_3) { add_pos_end = srslte_dmrs_sch_add_pos_1; } - for (pdsch_cfg.dmrs_typeA.additional_pos = add_pos_begin; pdsch_cfg.dmrs_typeA.additional_pos <= add_pos_end; - pdsch_cfg.dmrs_typeA.additional_pos++) { - + for (pdsch_cfg.dmrs.additional_pos = add_pos_begin; pdsch_cfg.dmrs.additional_pos <= add_pos_end; + pdsch_cfg.dmrs.additional_pos++) { srslte_dmrs_sch_len_t max_len_begin = srslte_dmrs_sch_len_1; srslte_dmrs_sch_len_t max_len_end = srslte_dmrs_sch_len_2; // Only single DMRS symbols can have additional positions 2 and 3 - if (pdsch_cfg.dmrs_typeA.additional_pos == srslte_dmrs_sch_add_pos_2 || - pdsch_cfg.dmrs_typeA.additional_pos == srslte_dmrs_sch_add_pos_3) { + if (pdsch_cfg.dmrs.additional_pos == srslte_dmrs_sch_add_pos_2 || + pdsch_cfg.dmrs.additional_pos == srslte_dmrs_sch_add_pos_3) { max_len_end = srslte_dmrs_sch_len_1; } - for (pdsch_cfg.dmrs_typeA.length = max_len_begin; pdsch_cfg.dmrs_typeA.length <= max_len_end; - pdsch_cfg.dmrs_typeA.length++) { - + for (pdsch_cfg.dmrs.length = max_len_begin; pdsch_cfg.dmrs.length <= max_len_end; pdsch_cfg.dmrs.length++) { for (uint32_t bw = 1; bw <= carrier.nof_prb; bw++) { - for (uint32_t i = 0; i < carrier.nof_prb; i++) { grant.prb_idx[i] = (i < bw); } for (grant.nof_dmrs_cdm_groups_without_data = 1; grant.nof_dmrs_cdm_groups_without_data <= 3; grant.nof_dmrs_cdm_groups_without_data++) { - // Load default type A grant - srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &grant); - - // Copy configuration - pdsch_cfg.dmrs_typeB = pdsch_cfg.dmrs_typeA; + srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &grant); int n = run_test(&dmrs_pdsch, &pdsch_cfg, &grant, sf_symbols, &chest_dl_res); if (n == SRSLTE_SUCCESS) { test_passed++; } else { - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant.mapping == srslte_sch_mapping_type_A ? &pdsch_cfg.dmrs_typeA : &pdsch_cfg.dmrs_typeB; - char str[64] = {}; - srslte_dmrs_sch_cfg_to_str(dmrs_cfg, str, 64); + srslte_dmrs_sch_cfg_to_str(&pdsch_cfg.dmrs, str, 64); - ERROR("Test %d failed. %s.\n", test_counter, str); + ERROR("Test %d failed. %s.", test_counter, str); } test_counter++; diff --git a/lib/src/phy/ch_estimation/test/refsignal_ul_test.c b/lib/src/phy/ch_estimation/test/refsignal_ul_test.c index dd215d534..f59c73602 100644 --- a/lib/src/phy/ch_estimation/test/refsignal_ul_test.c +++ b/lib/src/phy/ch_estimation/test/refsignal_ul_test.c @@ -85,7 +85,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (srslte_refsignal_ul_set_cell(&refs, cell)) { - ERROR("Error initializing UL reference signal\n"); + ERROR("Error initializing UL reference signal"); goto do_exit; } @@ -102,7 +102,6 @@ int main(int argc, char** argv) for (int h = 0; h < 3; h++) { for (int sf_idx = 0; sf_idx < 10; sf_idx++) { for (int cshift_dmrs = 0; cshift_dmrs < SRSLTE_NOF_CSHIFT; cshift_dmrs++) { - uint32_t nof_prb = n; pusch_cfg.cyclic_shift = cshift; pusch_cfg.delta_ss = delta_ss; diff --git a/lib/src/phy/channel/ch_awgn.c b/lib/src/phy/channel/ch_awgn.c index 2c401506f..ca4dd17ef 100644 --- a/lib/src/phy/channel/ch_awgn.c +++ b/lib/src/phy/channel/ch_awgn.c @@ -78,7 +78,7 @@ int srslte_channel_awgn_init(srslte_channel_awgn_t* q, uint32_t seed) q->table_cos = srslte_vec_f_malloc(AWGN_TABLE_ALLOC_SIZE); q->table_log = srslte_vec_f_malloc(AWGN_TABLE_ALLOC_SIZE); if (!q->table_cos || !q->table_log) { - ERROR("Malloc\n"); + ERROR("Malloc"); } // Fill tables diff --git a/lib/src/phy/channel/channel.cc b/lib/src/phy/channel/channel.cc index 30a1171be..d0e97069a 100644 --- a/lib/src/phy/channel/channel.cc +++ b/lib/src/phy/channel/channel.cc @@ -25,7 +25,8 @@ using namespace srslte; -channel::channel(const channel::args_t& channel_args, uint32_t _nof_channels) +channel::channel(const channel::args_t& channel_args, uint32_t _nof_channels, srslog::basic_logger& logger) : + logger(logger) { int ret = SRSLTE_SUCCESS; uint32_t srate_max = (uint32_t)srslte_symbol_sz(SRSLTE_MAX_PRB) * 15000; @@ -146,11 +147,6 @@ static inline cf_t local_cexpf(float phase) } } -void channel::set_logger(log_filter* _log_h) -{ - log_h = _log_h; -} - void channel::run(cf_t* in[SRSLTE_MAX_CHANNELS], cf_t* out[SRSLTE_MAX_CHANNELS], uint32_t len, @@ -223,22 +219,16 @@ void channel::run(cf_t* in[SRSLTE_MAX_CHANNELS], } } - if (log_h) { - // Logging - std::stringstream str; - - str << "t=" << t.full_secs + t.frac_secs << "s; "; - - if (delay[0]) { - str << "delay=" << delay[0]->delay_us << "us; "; - } - - if (hst) { - str << "hst=" << hst->fs_hz << "Hz; "; - } - - log_h->debug("%s\n", str.str().c_str()); + // Logging + std::stringstream str; + str << "t=" << t.full_secs + t.frac_secs << "s; "; + if (delay[0]) { + str << "delay=" << delay[0]->delay_us << "us; "; } + if (hst) { + str << "hst=" << hst->fs_hz << "Hz; "; + } + logger.debug("%s", str.str().c_str()); } void channel::set_srate(uint32_t srate) diff --git a/lib/src/phy/channel/test/awgn_channel_test.c b/lib/src/phy/channel/test/awgn_channel_test.c index a590d9f2d..d987f1b7f 100644 --- a/lib/src/phy/channel/test/awgn_channel_test.c +++ b/lib/src/phy/channel/test/awgn_channel_test.c @@ -92,7 +92,7 @@ int main(int argc, char** argv) output_buffer = srslte_vec_cf_malloc(nof_samples); if (!input_buffer || !output_buffer) { - ERROR("Error: Allocating memory\n"); + ERROR("Error: Allocating memory"); ret = SRSLTE_ERROR; } @@ -102,7 +102,7 @@ int main(int argc, char** argv) #ifdef ENABLE_GUI sdrgui_init(); sdrgui_init_title("SRS AWGN Channel"); - plot_real_t plot_fft = NULL; + plot_real_t plot_fft = NULL; plot_scatter_t plot_scatter = NULL; plot_real_init(&plot_fft); @@ -116,7 +116,7 @@ int main(int argc, char** argv) cf_t* fft_out = srslte_vec_cf_malloc(nof_samples); srslte_dft_plan_t fft = {}; if (srslte_dft_plan_c(&fft, nof_samples, SRSLTE_DFT_FORWARD)) { - ERROR("Error: init DFT\n"); + ERROR("Error: init DFT"); ret = SRSLTE_ERROR; } #endif /* ENABLE_GUI */ diff --git a/lib/src/phy/common/phy_common.c b/lib/src/phy/common/phy_common.c index 2cf94d834..53bad03a2 100644 --- a/lib/src/phy/common/phy_common.c +++ b/lib/src/phy/common/phy_common.c @@ -291,7 +291,6 @@ char* srslte_cp_string(srslte_cp_t cp) /* Returns the new time advance N_ta_new as specified in Section 4.2.3 of 36.213 */ uint32_t srslte_N_ta_new(uint32_t N_ta_old, uint32_t ta) { - ta &= 63; int n_ta_new = N_ta_old + ((float)ta - 31) * 16; if (n_ta_new < 0) { @@ -652,7 +651,7 @@ bool srslte_band_is_tdd(uint32_t band) i++; } if (i == SRSLTE_NOF_LTE_BANDS) { - ERROR("Invalid Band %d\n", band); + ERROR("Invalid Band %d", band); return false; } return lte_bands[i].ul_earfcn_offset == 0; @@ -662,7 +661,7 @@ uint8_t srslte_band_get_band(uint32_t dl_earfcn) { uint32_t i = SRSLTE_NOF_LTE_BANDS - 1; if (dl_earfcn > lte_bands[i].dl_earfcn_offset) { - ERROR("Invalid DL_EARFCN=%d\n", dl_earfcn); + ERROR("Invalid DL_EARFCN=%d", dl_earfcn); } i--; while (i > 0 && lte_bands[i].dl_earfcn_offset > dl_earfcn) { @@ -675,7 +674,7 @@ double srslte_band_fd(uint32_t dl_earfcn) { uint32_t i = SRSLTE_NOF_LTE_BANDS - 1; if (dl_earfcn > lte_bands[i].dl_earfcn_offset) { - ERROR("Invalid DL_EARFCN=%d\n", dl_earfcn); + ERROR("Invalid DL_EARFCN=%d", dl_earfcn); } i--; while (i > 0 && lte_bands[i].dl_earfcn_offset > dl_earfcn) { @@ -688,7 +687,7 @@ double srslte_band_fu(uint32_t ul_earfcn) { uint32_t i = SRSLTE_NOF_LTE_BANDS - 1; if (ul_earfcn > lte_bands[i].ul_earfcn_offset) { - ERROR("Invalid UL_EARFCN=%d\n", ul_earfcn); + ERROR("Invalid UL_EARFCN=%d", ul_earfcn); } i--; while (i > 0 && (lte_bands[i].ul_earfcn_offset > ul_earfcn || lte_bands[i].ul_earfcn_offset == 0)) { @@ -701,7 +700,7 @@ uint32_t srslte_band_ul_earfcn(uint32_t dl_earfcn) { uint32_t i = SRSLTE_NOF_LTE_BANDS - 1; if (dl_earfcn > lte_bands[i].dl_earfcn_offset) { - ERROR("Invalid DL_EARFCN=%d\n", dl_earfcn); + ERROR("Invalid DL_EARFCN=%d", dl_earfcn); } i--; while (i > 0 && lte_bands[i].dl_earfcn_offset > dl_earfcn) { @@ -728,14 +727,14 @@ int srslte_band_get_fd_band(uint32_t band, i++; } if (i >= SRSLTE_NOF_LTE_BANDS - 1) { - ERROR("Error: Invalid band %d\n", band); + ERROR("Error: Invalid band %d", band); return SRSLTE_ERROR; } if (end_earfcn == -1) { end_earfcn = lte_bands[i + 1].dl_earfcn_offset - 1; } else { if (end_earfcn > lte_bands[i + 1].dl_earfcn_offset - 1) { - ERROR("Error: Invalid end earfcn %d. Max is %d\n", end_earfcn, lte_bands[i + 1].dl_earfcn_offset - 1); + ERROR("Error: Invalid end earfcn %d. Max is %d", end_earfcn, lte_bands[i + 1].dl_earfcn_offset - 1); return SRSLTE_ERROR; } } @@ -743,7 +742,7 @@ int srslte_band_get_fd_band(uint32_t band, start_earfcn = lte_bands[i].dl_earfcn_offset; } else { if (start_earfcn < lte_bands[i].dl_earfcn_offset) { - ERROR("Error: Invalid start earfcn %d. Min is %d\n", start_earfcn, lte_bands[i].dl_earfcn_offset); + ERROR("Error: Invalid start earfcn %d. Min is %d", start_earfcn, lte_bands[i].dl_earfcn_offset); return SRSLTE_ERROR; } } @@ -803,11 +802,11 @@ uint32_t srslte_print_check(char* s, size_t max_len, uint32_t cur_len, const cha cur_len += ret; } else { // Formatting error detected - ERROR("Formatting error when printing string\n"); + ERROR("Formatting error when printing string"); exit(-1); } } else { - ERROR("Buffer full when printing string\n"); + ERROR("Buffer full when printing string"); exit(-1); } return cur_len; diff --git a/lib/src/phy/common/phy_common_nr.c b/lib/src/phy/common/phy_common_nr.c index 60648dd17..295bd61f0 100644 --- a/lib/src/phy/common/phy_common_nr.c +++ b/lib/src/phy/common/phy_common_nr.c @@ -22,6 +22,30 @@ #include "srslte/phy/common/phy_common_nr.h" #include +const char* srslte_rnti_type_str(srslte_rnti_type_t rnti_type) +{ + switch (rnti_type) { + case srslte_rnti_type_c: + return "C-RNTI"; + case srslte_rnti_type_p: + return "P-RNTI"; + case srslte_rnti_type_si: + return "SI-RNTI"; + case srslte_rnti_type_ra: + return "RA-RNTI"; + case srslte_rnti_type_tc: + return "TC-RNTI"; + case srslte_rnti_type_cs: + return "CS-RNTI"; + case srslte_rnti_type_sp_csi: + return "SP-CSI-RNTI"; + case srslte_rnti_type_mcs_c: + return "MCS-C-RNTI"; + default:; // Do nothing + } + return "unknown"; +} + uint32_t srslte_coreset_get_bw(const srslte_coreset_t* coreset) { uint32_t prb_count = 0; @@ -83,3 +107,51 @@ srslte_mcs_table_t srslte_mcs_table_from_str(const char* str) } return srslte_mcs_table_N; } + +#define PHY_COMMON_NR_NOF_VALID_SYMB_SZ 10U + +static const uint32_t phy_common_nr_valid_symbol_sz[PHY_COMMON_NR_NOF_VALID_SYMB_SZ] = + {128, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096}; + +uint32_t srslte_min_symbol_sz_rb(uint32_t nof_prb) +{ + uint32_t nof_re = nof_prb * SRSLTE_NRE; + + if (nof_re == 0) { + return 0; + } + + for (uint32_t i = 0; i < PHY_COMMON_NR_NOF_VALID_SYMB_SZ; i++) { + if (phy_common_nr_valid_symbol_sz[i] > nof_re) { + return phy_common_nr_valid_symbol_sz[i]; + } + } + + return 0; +} + +float srslte_symbol_distance_s(uint32_t l0, uint32_t l1, uint32_t numerology) +{ + // l0 must be smaller than l1 + if (l0 >= l1) { + return 0.0f; + } + + // Count number of symbols in between + uint32_t count = l1 - l0; + + // Compute at what symbol there is a longer CP + uint32_t cp_boundary = 7U << numerology; + + // Select whether extra CP shall be added + uint32_t extra_cp = 0; + if (l0 < cp_boundary && l1 >= cp_boundary) { + extra_cp = 16; + } + + // Compute reference FFT size + uint32_t N = (2048 + 144) * count + extra_cp; + + // Return symbol distance in microseconds + return (N << numerology) * SRSLTE_LTE_TS; +} diff --git a/lib/src/phy/common/phy_common_sl.c b/lib/src/phy/common/phy_common_sl.c index 0521e29a3..358d07d4b 100644 --- a/lib/src/phy/common/phy_common_sl.c +++ b/lib/src/phy/common/phy_common_sl.c @@ -108,10 +108,10 @@ uint32_t srslte_sl_get_num_symbols(srslte_sl_tm_t tm, srslte_cp_t cp) if (cp == SRSLTE_CP_NORM) { return SRSLTE_CP_NORM_SF_NSYMB; } else { - ERROR("Invalid CP\n"); + ERROR("Invalid CP"); } } else { - ERROR("Invalid TM\n"); + ERROR("Invalid TM"); } return 0; // Calling function may use return value for loop termination } diff --git a/lib/src/phy/common/sequence.c b/lib/src/phy/common/sequence.c index a0cdc35fc..90c68b1d2 100644 --- a/lib/src/phy/common/sequence.c +++ b/lib/src/phy/common/sequence.c @@ -296,7 +296,7 @@ void srslte_sequence_state_advance(srslte_sequence_state_t* s, uint32_t length) int srslte_sequence_set_LTE_pr(srslte_sequence_t* q, uint32_t len, uint32_t seed) { if (len > q->max_len) { - ERROR("Error generating pseudo-random sequence: len %d is greater than allocated len %d\n", len, q->max_len); + ERROR("Error generating pseudo-random sequence: len %d is greater than allocated len %d", len, q->max_len); return SRSLTE_ERROR; } diff --git a/lib/src/phy/common/zc_sequence.c b/lib/src/phy/common/zc_sequence.c index 10e05df21..5249f0868 100644 --- a/lib/src/phy/common/zc_sequence.c +++ b/lib/src/phy/common/zc_sequence.c @@ -240,7 +240,7 @@ static int zc_sequence_lte_r_uv_arg(uint32_t M_zc, uint32_t u, uint32_t v, cf_t* } else if (M_zc >= 36) { zc_sequence_r_uv_arg_mprb(M_zc, u, v, tmp_arg); } else { - ERROR("Invalid M_zc (%d)\n", M_zc); + ERROR("Invalid M_zc (%d)", M_zc); return SRSLTE_ERROR; } @@ -260,7 +260,7 @@ static int zc_sequence_nr_r_uv_arg(uint32_t M_zc, uint32_t u, uint32_t v, cf_t* } else if (M_zc >= 36) { zc_sequence_r_uv_arg_mprb(M_zc, u, v, tmp_arg); } else { - ERROR("Invalid M_zc (%d)\n", M_zc); + ERROR("Invalid M_zc (%d)", M_zc); return SRSLTE_ERROR; } @@ -283,7 +283,7 @@ int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alpha, uint32_ // Check U and V if (u >= SRSLTE_ZC_SEQUENCE_NOF_GROUPS || v >= SRSLTE_ZC_SEQUENCE_NOF_BASE) { - ERROR("Invalid u (%d) or v (%d)\n", u, v); + ERROR("Invalid u (%d) or v (%d)", u, v); return SRSLTE_ERROR_OUT_OF_BOUNDS; } @@ -310,7 +310,7 @@ int srslte_zc_sequence_generate_nr(uint32_t u, uint32_t v, float alpha, uint32_t // Check U and V if (u >= SRSLTE_ZC_SEQUENCE_NOF_GROUPS || v >= SRSLTE_ZC_SEQUENCE_NOF_BASE) { - ERROR("Invalid u (%d) or v (%d)\n", u, v); + ERROR("Invalid u (%d) or v (%d)", u, v); return SRSLTE_ERROR_OUT_OF_BOUNDS; } @@ -350,7 +350,7 @@ int srslte_zc_sequence_lut_init_nr(srslte_zc_sequence_lut_t* q, // Allocate sequence q->sequence[u][v] = srslte_vec_cf_malloc(nof_alphas * q->M_zc); if (q->sequence[u][v] == NULL) { - ERROR("Malloc\n"); + ERROR("Malloc"); return SRSLTE_ERROR; } @@ -358,7 +358,7 @@ int srslte_zc_sequence_lut_init_nr(srslte_zc_sequence_lut_t* q, for (uint32_t alpha_idx = 0; alpha_idx < nof_alphas; alpha_idx++) { if (srslte_zc_sequence_generate_nr(u, v, alphas[alpha_idx], m, delta, &q->sequence[u][v][alpha_idx * q->M_zc]) < SRSLTE_SUCCESS) { - ERROR("Generating sequence\n"); + ERROR("Generating sequence"); return SRSLTE_ERROR; } } diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index 1b209bda0..f75ad96df 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -147,6 +147,11 @@ int srslte_dft_replan_c(srslte_dft_plan_t* plan, const int new_dft_points) { int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; + // No change in size, skip re-planning + if (plan->size == new_dft_points) { + return 0; + } + pthread_mutex_lock(&fft_mutex); if (plan->p) { fftwf_destroy_plan(plan->p); @@ -353,7 +358,7 @@ void srslte_dft_run_guru_c(srslte_dft_plan_t* plan) if (plan->is_guru == true) { fftwf_execute(plan->p); } else { - ERROR("srslte_dft_run_guru_c: the selected plan is not guru!\n"); + ERROR("srslte_dft_run_guru_c: the selected plan is not guru!"); } } diff --git a/lib/src/phy/dft/dft_precoding.c b/lib/src/phy/dft/dft_precoding.c index e0c135aea..6c7e1a638 100644 --- a/lib/src/phy/dft/dft_precoding.c +++ b/lib/src/phy/dft/dft_precoding.c @@ -45,9 +45,9 @@ int srslte_dft_precoding_init(srslte_dft_precoding_t* q, uint32_t max_prb, bool ret = SRSLTE_ERROR; for (uint32_t i = 1; i <= max_prb; i++) { if (srslte_dft_precoding_valid_prb(i)) { - DEBUG("Initiating DFT precoding plan for %d PRBs\n", i); + DEBUG("Initiating DFT precoding plan for %d PRBs", i); if (srslte_dft_plan_c(&q->dft_plan[i], i * SRSLTE_NRE, is_tx ? SRSLTE_DFT_FORWARD : SRSLTE_DFT_BACKWARD)) { - ERROR("Error: Creating DFT plan %d\n", i); + ERROR("Error: Creating DFT plan %d", i); goto clean_exit; } srslte_dft_plan_set_norm(&q->dft_plan[i], true); @@ -113,9 +113,8 @@ uint32_t srslte_dft_precoding_get_valid_prb(uint32_t nof_prb) int srslte_dft_precoding(srslte_dft_precoding_t* q, cf_t* input, cf_t* output, uint32_t nof_prb, uint32_t nof_symbols) { - if (!srslte_dft_precoding_valid_prb(nof_prb) && nof_prb <= q->max_prb) { - ERROR("Error invalid number of PRB (%d)\n", nof_prb); + ERROR("Error invalid number of PRB (%d)", nof_prb); return SRSLTE_ERROR; } diff --git a/lib/src/phy/dft/ofdm.c b/lib/src/phy/dft/ofdm.c index bac70b92e..ab1477ae1 100644 --- a/lib/src/phy/dft/ofdm.c +++ b/lib/src/phy/dft/ofdm.c @@ -37,12 +37,11 @@ static int ofdm_init_mbsfn_(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg, srslte_dft_dir_t dir) { - // If the symbol size is not given, calculate in function of the number of resource blocks if (cfg->symbol_sz == 0) { int symbol_sz_err = srslte_symbol_sz(cfg->nof_prb); if (symbol_sz_err <= SRSLTE_SUCCESS) { - ERROR("Invalid number of PRB %d\n", cfg->nof_prb); + ERROR("Invalid number of PRB %d", cfg->nof_prb); return SRSLTE_ERROR; } cfg->symbol_sz = (uint32_t)symbol_sz_err; @@ -74,13 +73,13 @@ static int ofdm_init_mbsfn_(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg, srslte_dft if (q->fft_plan.size) { // Replan if it was initialised previously if (srslte_dft_replan(&q->fft_plan, q->cfg.symbol_sz)) { - ERROR("Reeplaning DFT plan\n"); + ERROR("Reeplaning DFT plan"); return SRSLTE_ERROR; } } else { // Create plan from zero otherwise if (srslte_dft_plan_c(&q->fft_plan, symbol_sz, dir)) { - ERROR("Creating DFT plan\n"); + ERROR("Creating DFT plan"); return SRSLTE_ERROR; } } @@ -165,7 +164,7 @@ static int ofdm_init_mbsfn_(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg, srslte_dft SRSLTE_CP_NSYMB(cp), symbol_sz + cp2, symbol_sz)) { - ERROR("Creating Guru DFT plan (%d)\n", slot); + ERROR("Creating Guru DFT plan (%d)", slot); return SRSLTE_ERROR; } } else { @@ -179,7 +178,7 @@ static int ofdm_init_mbsfn_(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg, srslte_dft SRSLTE_CP_NSYMB(cp), symbol_sz, symbol_sz + cp2)) { - ERROR("Creating Guru inverse-DFT plan (%d)\n", slot); + ERROR("Creating Guru inverse-DFT plan (%d)", slot); return SRSLTE_ERROR; } } @@ -187,9 +186,8 @@ static int ofdm_init_mbsfn_(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg, srslte_dft #endif srslte_dft_plan_set_mirror(&q->fft_plan, true); - srslte_dft_plan_set_dc(&q->fft_plan, cfg->keep_dc); - DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d\n", + DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d", dir == SRSLTE_DFT_FORWARD ? "FFT" : "iFFT", q->cfg.symbol_sz, q->nof_symbols, @@ -208,6 +206,7 @@ static int ofdm_init_mbsfn_(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg, srslte_dft // Set other parameters srslte_ofdm_set_freq_shift(q, q->cfg.freq_shift_f); srslte_dft_plan_set_norm(&q->fft_plan, q->cfg.normalize); + srslte_dft_plan_set_dc(&q->fft_plan, (!cfg->keep_dc) && (!isnormal(q->cfg.freq_shift_f))); return SRSLTE_SUCCESS; } @@ -285,15 +284,11 @@ int srslte_ofdm_tx_init(srslte_ofdm_t* q, srslte_cp_t cp, cf_t* in_buffer, cf_t* int srslte_ofdm_tx_init_cfg(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg) { - bzero(q, sizeof(srslte_ofdm_t)); - return ofdm_init_mbsfn_(q, cfg, SRSLTE_DFT_BACKWARD); } int srslte_ofdm_rx_init_cfg(srslte_ofdm_t* q, srslte_ofdm_cfg_t* cfg) { - bzero(q, sizeof(srslte_ofdm_t)); - return ofdm_init_mbsfn_(q, cfg, SRSLTE_DFT_FORWARD); } diff --git a/lib/src/phy/dft/test/ofdm_test.c b/lib/src/phy/dft/test/ofdm_test.c index 21a500bf8..4e334dd25 100644 --- a/lib/src/phy/dft/test/ofdm_test.c +++ b/lib/src/phy/dft/test/ofdm_test.c @@ -131,7 +131,7 @@ int main(int argc, char** argv) ofdm_cfg.freq_shift_f = freq_shift_f; ofdm_cfg.normalize = true; if (srslte_ofdm_tx_init_cfg(&ifft, &ofdm_cfg)) { - ERROR("Error initializing iFFT\n"); + ERROR("Error initializing iFFT"); exit(-1); } @@ -140,7 +140,7 @@ int main(int argc, char** argv) ofdm_cfg.rx_window_offset = rx_window_offset; ofdm_cfg.freq_shift_f = -freq_shift_f; if (srslte_ofdm_rx_init_cfg(&fft, &ofdm_cfg)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); exit(-1); } diff --git a/lib/src/phy/enb/enb_dl.c b/lib/src/phy/enb/enb_dl.c index 23866685f..d12d00bb6 100644 --- a/lib/src/phy/enb/enb_dl.c +++ b/lib/src/phy/enb/enb_dl.c @@ -60,7 +60,7 @@ int srslte_enb_dl_init(srslte_enb_dl_t* q, cf_t* out_buffer[SRSLTE_MAX_PORTS], u ofdm_cfg.out_buffer = out_buffer[i]; ofdm_cfg.sf_type = SRSLTE_SF_NORM; if (srslte_ofdm_tx_init_cfg(&q->ifft[i], &ofdm_cfg)) { - ERROR("Error initiating FFT (%d)\n", i); + ERROR("Error initiating FFT (%d)", i); goto clean_exit; } } @@ -69,52 +69,52 @@ int srslte_enb_dl_init(srslte_enb_dl_t* q, cf_t* out_buffer[SRSLTE_MAX_PORTS], u ofdm_cfg.out_buffer = out_buffer[0]; ofdm_cfg.sf_type = SRSLTE_SF_MBSFN; if (srslte_ofdm_tx_init_cfg(&q->ifft_mbsfn, &ofdm_cfg)) { - ERROR("Error initiating FFT \n"); + ERROR("Error initiating FFT"); goto clean_exit; } if (srslte_pbch_init(&q->pbch)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); goto clean_exit; } if (srslte_pcfich_init(&q->pcfich, 0)) { - ERROR("Error creating PCFICH object\n"); + ERROR("Error creating PCFICH object"); goto clean_exit; } if (srslte_phich_init(&q->phich, 0)) { - ERROR("Error creating PHICH object\n"); + ERROR("Error creating PHICH object"); goto clean_exit; } int mbsfn_area_id = 1; if (srslte_pmch_init(&q->pmch, max_prb, 1)) { - ERROR("Error creating PMCH object\n"); + ERROR("Error creating PMCH object"); } srslte_pmch_set_area_id(&q->pmch, mbsfn_area_id); if (srslte_pdcch_init_enb(&q->pdcch, max_prb)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); goto clean_exit; } if (srslte_pdsch_init_enb(&q->pdsch, max_prb)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); goto clean_exit; } if (srslte_refsignal_cs_init(&q->csr_signal, max_prb)) { - ERROR("Error initializing CSR signal (%d)\n", ret); + ERROR("Error initializing CSR signal (%d)", ret); goto clean_exit; } if (srslte_refsignal_mbsfn_init(&q->mbsfnr_signal, max_prb)) { - ERROR("Error initializing CSR signal (%d)\n", ret); + ERROR("Error initializing CSR signal (%d)", ret); goto clean_exit; } ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters\n"); + ERROR("Invalid parameters"); } clean_exit: @@ -160,58 +160,58 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t* q, srslte_cell_t cell) } q->cell = cell; if (srslte_regs_init(&q->regs, q->cell)) { - ERROR("Error resizing REGs\n"); + ERROR("Error resizing REGs"); return SRSLTE_ERROR; } for (int i = 0; i < q->cell.nof_ports; i++) { if (srslte_ofdm_tx_set_prb(&q->ifft[i], q->cell.cp, q->cell.nof_prb)) { - ERROR("Error re-planning iFFT (%d)\n", i); + ERROR("Error re-planning iFFT (%d)", i); return SRSLTE_ERROR; } } if (srslte_ofdm_tx_set_prb(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) { - ERROR("Error re-planning ifft_mbsfn\n"); + ERROR("Error re-planning ifft_mbsfn"); return SRSLTE_ERROR; } srslte_ofdm_set_non_mbsfn_region(&q->ifft_mbsfn, 2); if (srslte_pbch_set_cell(&q->pbch, q->cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); return SRSLTE_ERROR; } if (srslte_pcfich_set_cell(&q->pcfich, &q->regs, q->cell)) { - ERROR("Error creating PCFICH object\n"); + ERROR("Error creating PCFICH object"); return SRSLTE_ERROR; } if (srslte_phich_set_cell(&q->phich, &q->regs, q->cell)) { - ERROR("Error creating PHICH object\n"); + ERROR("Error creating PHICH object"); return SRSLTE_ERROR; } if (srslte_pdcch_set_cell(&q->pdcch, &q->regs, q->cell)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); return SRSLTE_ERROR; } if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); return SRSLTE_ERROR; } if (srslte_pmch_set_cell(&q->pmch, q->cell)) { - ERROR("Error creating PMCH object\n"); + ERROR("Error creating PMCH object"); return SRSLTE_ERROR; } if (srslte_refsignal_cs_set_cell(&q->csr_signal, q->cell)) { - ERROR("Error initializing CSR signal (%d)\n", ret); + ERROR("Error initializing CSR signal (%d)", ret); return SRSLTE_ERROR; } int mbsfn_area_id = 1; if (srslte_refsignal_mbsfn_set_cell(&q->mbsfnr_signal, q->cell, mbsfn_area_id)) { - ERROR("Error initializing MBSFNR signal (%d)\n", ret); + ERROR("Error initializing MBSFNR signal (%d)", ret); return SRSLTE_ERROR; } /* Generate PSS/SSS signals */ @@ -227,7 +227,7 @@ int srslte_enb_dl_set_cell(srslte_enb_dl_t* q, srslte_cell_t cell) ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid cell properties: Id=%d, Ports=%d, PRBs=%d\n", cell.id, cell.nof_ports, cell.nof_prb); + ERROR("Invalid cell properties: Id=%d, Ports=%d, PRBs=%d", cell.id, cell.nof_ports, cell.nof_prb); } return ret; } @@ -385,10 +385,10 @@ int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t* q, srslte_dci_cfg_t* dci_cfg, sr ZERO_OBJECT(dci_msg); if (srslte_dci_msg_pack_pdsch(&q->cell, &q->dl_sf, dci_cfg, dci_dl, &dci_msg)) { - ERROR("Error packing DL DCI\n"); + ERROR("Error packing DL DCI"); } if (srslte_pdcch_encode(&q->pdcch, &q->dl_sf, &dci_msg, q->sf_symbols)) { - ERROR("Error encoding DL DCI message\n"); + ERROR("Error encoding DL DCI message"); return SRSLTE_ERROR; } @@ -401,10 +401,10 @@ int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t* q, srslte_dci_cfg_t* dci_cfg, sr ZERO_OBJECT(dci_msg); if (srslte_dci_msg_pack_pusch(&q->cell, &q->dl_sf, dci_cfg, dci_ul, &dci_msg)) { - ERROR("Error packing UL DCI\n"); + ERROR("Error packing UL DCI"); } if (srslte_pdcch_encode(&q->pdcch, &q->dl_sf, &dci_msg, q->sf_symbols)) { - ERROR("Error encoding UL DCI message\n"); + ERROR("Error encoding UL DCI message"); return SRSLTE_ERROR; } @@ -605,7 +605,6 @@ get_ack_fdd(const srslte_uci_cfg_t* uci_cfg, const srslte_uci_value_t* uci_value bool csi_report = uci_cfg->cqi.data_enable || uci_cfg->cqi.ri_len; switch (pdsch_ack->ack_nack_feedback_mode) { - case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_NORMAL: // Get ACK from PCell only, skipping DRX enb_dl_get_ack_fdd_pcell_skip_drx(uci_value, pdsch_ack, nof_tb); @@ -655,7 +654,7 @@ void srslte_enb_dl_get_ack(const srslte_cell_t* cell, if (cell->frame_type == SRSLTE_FDD) { get_ack_fdd(uci_cfg, uci_value, pdsch_ack); } else { - ERROR("Not implemented for TDD\n"); + ERROR("Not implemented for TDD"); } } diff --git a/lib/src/phy/enb/enb_dl_nr.c b/lib/src/phy/enb/enb_dl_nr.c index aa3d8b941..fac059348 100644 --- a/lib/src/phy/enb/enb_dl_nr.c +++ b/lib/src/phy/enb/enb_dl_nr.c @@ -20,6 +20,7 @@ */ #include "srslte/phy/enb/enb_dl_nr.h" +#include static int enb_dl_alloc_prb(srslte_enb_dl_nr_t* q, uint32_t new_nof_prb) { @@ -33,7 +34,7 @@ static int enb_dl_alloc_prb(srslte_enb_dl_nr_t* q, uint32_t new_nof_prb) q->sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(q->max_prb)); if (q->sf_symbols[i] == NULL) { - ERROR("Malloc\n"); + ERROR("Malloc"); return SRSLTE_ERROR; } } @@ -49,7 +50,7 @@ int srslte_enb_dl_nr_init(srslte_enb_dl_nr_t* q, cf_t* output[SRSLTE_MAX_PORTS], } if (args->nof_tx_antennas == 0) { - ERROR("Error invalid number of antennas (%d)\n", args->nof_tx_antennas); + ERROR("Error invalid number of antennas (%d)", args->nof_tx_antennas); return SRSLTE_ERROR; } @@ -60,13 +61,13 @@ int srslte_enb_dl_nr_init(srslte_enb_dl_nr_t* q, cf_t* output[SRSLTE_MAX_PORTS], } if (enb_dl_alloc_prb(q, args->nof_max_prb) < SRSLTE_SUCCESS) { - ERROR("Error allocating\n"); + ERROR("Error allocating"); return SRSLTE_ERROR; } srslte_ofdm_cfg_t fft_cfg = {}; fft_cfg.nof_prb = args->nof_max_prb; - fft_cfg.symbol_sz = srslte_symbol_sz(args->nof_max_prb); + fft_cfg.symbol_sz = srslte_min_symbol_sz_rb(args->nof_max_prb); fft_cfg.keep_dc = true; for (uint32_t i = 0; i < q->nof_tx_antennas; i++) { @@ -76,12 +77,12 @@ int srslte_enb_dl_nr_init(srslte_enb_dl_nr_t* q, cf_t* output[SRSLTE_MAX_PORTS], } if (srslte_dmrs_sch_init(&q->dmrs, false) < SRSLTE_SUCCESS) { - ERROR("Error DMRS\n"); + ERROR("Error DMRS"); return SRSLTE_ERROR; } if (srslte_pdcch_nr_init_tx(&q->pdcch, &args->pdcch) < SRSLTE_SUCCESS) { - ERROR("Error PDCCH\n"); + ERROR("Error PDCCH"); return SRSLTE_ERROR; } @@ -117,18 +118,24 @@ int srslte_enb_dl_nr_set_carrier(srslte_enb_dl_nr_t* q, const srslte_carrier_nr_ } if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier) < SRSLTE_SUCCESS) { - ERROR("Error DMRS\n"); + ERROR("Error DMRS"); return SRSLTE_ERROR; } if (enb_dl_alloc_prb(q, carrier->nof_prb) < SRSLTE_SUCCESS) { - ERROR("Error allocating\n"); + ERROR("Error allocating"); return SRSLTE_ERROR; } if (carrier->nof_prb != q->carrier.nof_prb) { + srslte_ofdm_cfg_t fft_cfg = {}; + fft_cfg.nof_prb = carrier->nof_prb; + fft_cfg.symbol_sz = srslte_min_symbol_sz_rb(carrier->nof_prb); + fft_cfg.keep_dc = true; + for (uint32_t i = 0; i < q->nof_tx_antennas; i++) { - srslte_ofdm_tx_set_prb(&q->fft[i], SRSLTE_CP_NORM, carrier->nof_prb); + fft_cfg.in_buffer = q->sf_symbols[i]; + srslte_ofdm_tx_init_cfg(&q->fft[i], &fft_cfg); } } @@ -176,9 +183,9 @@ int srslte_enb_dl_nr_base_zero(srslte_enb_dl_nr_t* q) return SRSLTE_SUCCESS; } -int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const srslte_dci_dl_nr_t* dci_dl) +int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_dci_dl_nr_t* dci_dl) { if (q == NULL || slot_cfg == NULL || dci_dl == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -186,34 +193,33 @@ int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, // Put DMRS if (srslte_dmrs_pdcch_put(&q->carrier, &q->coreset, slot_cfg, &dci_dl->location, q->sf_symbols[0]) < SRSLTE_SUCCESS) { - ERROR("Error putting PDCCH DMRS\n"); + ERROR("Error putting PDCCH DMRS"); return SRSLTE_ERROR; } // Pack DCI srslte_dci_msg_nr_t dci_msg = {}; if (srslte_dci_nr_pack(&q->carrier, &q->coreset, dci_dl, &dci_msg) < SRSLTE_SUCCESS) { - ERROR("Error packing DL DCI\n"); + ERROR("Error packing DL DCI"); return SRSLTE_ERROR; } // PDCCH Encode if (srslte_pdcch_nr_encode(&q->pdcch, &dci_msg, q->sf_symbols[0]) < SRSLTE_SUCCESS) { - ERROR("Error encoding PDCCH\n"); + ERROR("Error encoding PDCCH"); return SRSLTE_ERROR; } - INFO("DCI DL NR: L=%d; ncce=%d;\n", dci_dl->location.L, dci_dl->location.ncce); + INFO("DCI DL NR: L=%d; ncce=%d;", dci_dl->location.L, dci_dl->location.ncce); return SRSLTE_SUCCESS; } -int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_sch_cfg_nr_t* cfg, - uint8_t* data[SRSLTE_MAX_TB]) +int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, + const srslte_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + uint8_t* data[SRSLTE_MAX_TB]) { - if (srslte_dmrs_sch_put_sf(&q->dmrs, slot, cfg, &cfg->grant, q->sf_symbols[0]) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } diff --git a/lib/src/phy/enb/enb_ul.c b/lib/src/phy/enb/enb_ul.c index b6138c560..81c4e4262 100644 --- a/lib/src/phy/enb/enb_ul.c +++ b/lib/src/phy/enb/enb_ul.c @@ -56,29 +56,29 @@ int srslte_enb_ul_init(srslte_enb_ul_t* q, cf_t* in_buffer, uint32_t max_prb) ofdm_cfg.normalize = false; ofdm_cfg.rx_window_offset = 0.5f; if (srslte_ofdm_rx_init_cfg(&q->fft, &ofdm_cfg)) { - ERROR("Error initiating FFT\n"); + ERROR("Error initiating FFT"); goto clean_exit; } if (srslte_pucch_init_enb(&q->pucch)) { - ERROR("Error creating PUCCH object\n"); + ERROR("Error creating PUCCH object"); goto clean_exit; } if (srslte_pusch_init_enb(&q->pusch, max_prb)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto clean_exit; } if (srslte_chest_ul_init(&q->chest, max_prb)) { - ERROR("Error initiating channel estimator\n"); + ERROR("Error initiating channel estimator"); goto clean_exit; } ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters\n"); + ERROR("Invalid parameters"); } clean_exit: @@ -91,7 +91,6 @@ clean_exit: void srslte_enb_ul_free(srslte_enb_ul_t* q) { if (q) { - srslte_ofdm_rx_free(&q->fft); srslte_pucch_free(&q->pucch); srslte_pusch_free(&q->pusch); @@ -119,22 +118,22 @@ int srslte_enb_ul_set_cell(srslte_enb_ul_t* q, q->cell = cell; if (srslte_ofdm_rx_set_prb(&q->fft, q->cell.cp, q->cell.nof_prb)) { - ERROR("Error initiating FFT\n"); + ERROR("Error initiating FFT"); return SRSLTE_ERROR; } if (srslte_pucch_set_cell(&q->pucch, q->cell)) { - ERROR("Error creating PUCCH object\n"); + ERROR("Error creating PUCCH object"); return SRSLTE_ERROR; } if (srslte_pusch_set_cell(&q->pusch, q->cell)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); return SRSLTE_ERROR; } if (srslte_chest_ul_set_cell(&q->chest, cell)) { - ERROR("Error initiating channel estimator\n"); + ERROR("Error initiating channel estimator"); return SRSLTE_ERROR; } @@ -144,7 +143,7 @@ int srslte_enb_ul_set_cell(srslte_enb_ul_t* q, ret = SRSLTE_SUCCESS; } } else { - ERROR("Invalid cell properties: Id=%d, Ports=%d, PRBs=%d\n", cell.id, cell.nof_ports, cell.nof_prb); + ERROR("Invalid cell properties: Id=%d, Ports=%d, PRBs=%d", cell.id, cell.nof_ports, cell.nof_prb); } return ret; } @@ -152,11 +151,11 @@ int srslte_enb_ul_set_cell(srslte_enb_ul_t* q, int srslte_enb_ul_add_rnti(srslte_enb_ul_t* q, uint16_t rnti) { if (srslte_pucch_set_rnti(&q->pucch, rnti)) { - ERROR("Error setting PUCCH rnti\n"); + ERROR("Error setting PUCCH rnti"); return -1; } if (srslte_pusch_set_rnti(&q->pusch, rnti)) { - ERROR("Error setting PUSCH rnti\n"); + ERROR("Error setting PUSCH rnti"); return -1; } return 0; @@ -187,14 +186,14 @@ static int get_pucch(srslte_enb_ul_t* q, srslte_ul_sf_cfg_t* ul_sf, srslte_pucch // Select format cfg->format = srslte_pucch_proc_select_format(&q->cell, cfg, &cfg->uci_cfg, NULL); if (cfg->format == SRSLTE_PUCCH_FORMAT_ERROR) { - ERROR("Returned Error while selecting PUCCH format\n"); + ERROR("Returned Error while selecting PUCCH format"); return SRSLTE_ERROR; } // Get possible resources int nof_resources = srslte_pucch_proc_get_resources(&q->cell, cfg, &cfg->uci_cfg, NULL, n_pucch_i); if (nof_resources < 1 || nof_resources > SRSLTE_PUCCH_CS_MAX_ACK) { - ERROR("No PUCCH resource could be calculated (%d)\n", nof_resources); + ERROR("No PUCCH resource could be calculated (%d)", nof_resources); return SRSLTE_ERROR; } @@ -210,16 +209,15 @@ static int get_pucch(srslte_enb_ul_t* q, srslte_ul_sf_cfg_t* ul_sf, srslte_pucch // Prepare configuration if (srslte_chest_ul_estimate_pucch(&q->chest, ul_sf, cfg, q->sf_symbols, &q->chest_res)) { - ERROR("Error estimating PUCCH DMRS\n"); + ERROR("Error estimating PUCCH DMRS"); return SRSLTE_ERROR; } pucch_res.snr_db = q->chest_res.snr_db; ret = srslte_pucch_decode(&q->pucch, ul_sf, cfg, &q->chest_res, q->sf_symbols, &pucch_res); if (ret < SRSLTE_SUCCESS) { - ERROR("Error decoding PUCCH\n"); + ERROR("Error decoding PUCCH"); } else { - // Get PUCCH Format 1b with channel selection if: // - At least one ACK bit needs to be received; and // - PUCCH Format 1b was used; and @@ -254,9 +252,8 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t* q, srslte_pucch_cfg_t* cfg, srslte_pucch_res_t* res) { - if (!srslte_pucch_cfg_isvalid(cfg, q->cell.nof_prb)) { - ERROR("Invalid PUCCH configuration\n"); + ERROR("Invalid PUCCH configuration"); return SRSLTE_ERROR_INVALID_INPUTS; } diff --git a/lib/src/phy/fec/block/block.c b/lib/src/phy/fec/block/block.c index 1e61c832c..822b2861b 100644 --- a/lib/src/phy/fec/block/block.c +++ b/lib/src/phy/fec/block/block.c @@ -78,7 +78,7 @@ __attribute__((constructor)) static void srslte_block_init() void srslte_block_encode(const uint8_t* input, uint32_t input_len, uint8_t* output, uint32_t output_len) { if (!input || !output) { - ERROR("Invalid inputs\n"); + ERROR("Invalid inputs"); return; } @@ -157,7 +157,7 @@ int32_t srslte_block_decode_i8(const int8_t* llr, uint32_t nof_llr, uint8_t* dat // Return invalid inputs if data is not provided if (!llr || !data) { - ERROR("Invalid inputs\n"); + ERROR("Invalid inputs"); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -175,7 +175,7 @@ int32_t srslte_block_decode_i16(const int16_t* llr, uint32_t nof_llr, uint8_t* d // Return invalid inputs if data is not provided if (!llr || !data) { - ERROR("Invalid inputs\n"); + ERROR("Invalid inputs"); return SRSLTE_ERROR_INVALID_INPUTS; } diff --git a/lib/src/phy/fec/block/test/block_test.c b/lib/src/phy/fec/block/test/block_test.c index 893bb6293..b0785fea8 100644 --- a/lib/src/phy/fec/block/test/block_test.c +++ b/lib/src/phy/fec/block/test/block_test.c @@ -118,7 +118,7 @@ int test(uint32_t block_size) double total_bits = (double)(block_size * nof_repetitions); INFO("Block size %d PASSED! Encoder: %.1f us / %.1f Mbps; 16 bit Decoder: %.1f us / %.2f Mbps; 8 bit decoder: %.1f / " - "%.2f Mbps\n", + "%.2f Mbps", block_size, t_encode_us / (double)nof_repetitions, total_bits / (double)t_encode_us, diff --git a/lib/src/phy/fec/cbsegm.c b/lib/src/phy/fec/cbsegm.c index 36b4115dd..792d7fd99 100644 --- a/lib/src/phy/fec/cbsegm.c +++ b/lib/src/phy/fec/cbsegm.c @@ -100,7 +100,7 @@ int srslte_cbsegm(srslte_cbsegm_t* s, uint32_t tbs) s->L_tb = 24; // 24 bit CRC always s->L_cb = 24; // 24 bit CRC always s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp; - INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n", + INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d", tbs, s->C, s->C1, @@ -171,7 +171,6 @@ static int cbsegm_ldpc_select_ls(uint32_t Kp, uint32_t K_b, uint32_t* Z_c, uint8 // If the lifting index is valid, save outputs and return if (i != VOID_LIFTSIZE) { - if (i_ls) { *i_ls = i; } @@ -271,7 +270,7 @@ static int srslte_cbsegm_ldpc(srslte_cbsegm_t* s, srslte_basegraph_t bg, uint32_ s->K2 = 0; s->K2_idx = 0; - INFO("LDPC CB Segmentation: TBS: %d, C=%d, K=%d, F=%d, Bp=%d\n", tbs, s->C, s->K1, s->F, Bp); + INFO("LDPC CB Segmentation: TBS: %d, C=%d, K=%d, F=%d, Bp=%d", tbs, s->C, s->K1, s->F, Bp); return SRSLTE_SUCCESS; } diff --git a/lib/src/phy/fec/convolutional/test/viterbi_test.c b/lib/src/phy/fec/convolutional/test/viterbi_test.c index 1303f73a7..3f963021c 100644 --- a/lib/src/phy/fec/convolutional/test/viterbi_test.c +++ b/lib/src/phy/fec/convolutional/test/viterbi_test.c @@ -210,7 +210,6 @@ int main(int argc, char** argv) errors_f = 0; errors_sse = 0; while (frame_cnt < nof_frames) { - /* generate data_tx */ srslte_random_t random_gen = srslte_random_init(0); for (int j = 0; j < frame_length; j++) { @@ -292,7 +291,7 @@ int main(int argc, char** argv) if (snr_points == 1) { int expected_e = get_expected_errors(nof_frames, seed, frame_length, tail_biting, ebno_db); if (expected_e == -1) { - ERROR("Test parameters not defined in test_results.h\n"); + ERROR("Test parameters not defined in test_results.h"); exit(-1); } else { printf( diff --git a/lib/src/phy/fec/convolutional/viterbi.c b/lib/src/phy/fec/convolutional/viterbi.c index 7442b1b36..679d59448 100644 --- a/lib/src/phy/fec/convolutional/viterbi.c +++ b/lib/src/phy/fec/convolutional/viterbi.c @@ -225,7 +225,7 @@ int decode37_neon(void* o, uint8_t* symbols, uint8_t* data, uint32_t frame_lengt uint32_t best_state; if (frame_length > q->framebits) { - ERROR("Initialized decoder for max frame length %d bits\n", q->framebits); + ERROR("Initialized decoder for max frame length %d bits", q->framebits); return -1; } @@ -303,7 +303,7 @@ int init37(srslte_viterbi_t* q, int poly[3], uint32_t framebits, bool tail_bitin } if ((q->ptr = create_viterbi37_port(poly, TB_ITER * framebits)) == NULL) { - ERROR("create_viterbi37 failed\n"); + ERROR("create_viterbi37 failed"); free37(q); return -1; } else { @@ -347,7 +347,7 @@ int init37_sse(srslte_viterbi_t* q, int poly[3], uint32_t framebits, bool tail_b } if ((q->ptr = create_viterbi37_sse(poly, TB_ITER * framebits)) == NULL) { - ERROR("create_viterbi37 failed\n"); + ERROR("create_viterbi37 failed"); free37(q); return -1; } else { @@ -385,7 +385,7 @@ int init37_neon(srslte_viterbi_t* q, int poly[3], uint32_t framebits, bool tail_ } if ((q->ptr = create_viterbi37_neon(poly, TB_ITER * framebits)) == NULL) { - ERROR("create_viterbi37 failed\n"); + ERROR("create_viterbi37 failed"); free37(q); return -1; } else { @@ -423,7 +423,7 @@ int init37_avx2(srslte_viterbi_t* q, int poly[3], uint32_t framebits, bool tail_ } if ((q->ptr = create_viterbi37_avx2(poly, TB_ITER * framebits)) == NULL) { - ERROR("create_viterbi37 failed\n"); + ERROR("create_viterbi37 failed"); free37(q); return -1; } else { @@ -461,7 +461,7 @@ int init37_avx2_16bit(srslte_viterbi_t* q, int poly[3], uint32_t framebits, bool } // printf("pt0\n"); if ((q->ptr = create_viterbi37_avx2_16bit(poly, TB_ITER * framebits)) == NULL) { - ERROR("create_viterbi37 failed\n"); + ERROR("create_viterbi37 failed"); free37(q); return -1; } else { @@ -509,7 +509,7 @@ int srslte_viterbi_init(srslte_viterbi_t* q, #endif #endif default: - ERROR("Decoder not implemented\n"); + ERROR("Decoder not implemented"); return -1; } } @@ -549,7 +549,7 @@ int srslte_viterbi_decode_f(srslte_viterbi_t* q, float* symbols, uint8_t* data, { uint32_t len; if (frame_length > q->framebits) { - ERROR("Initialized decoder for max frame length %d bits\n", q->framebits); + ERROR("Initialized decoder for max frame length %d bits", q->framebits); return -1; } if (q->tail_biting) { @@ -581,7 +581,7 @@ int srslte_viterbi_decode_s(srslte_viterbi_t* q, int16_t* symbols, uint8_t* data { uint32_t len; if (frame_length > q->framebits) { - ERROR("Initialized decoder for max frame length %d bits\n", q->framebits); + ERROR("Initialized decoder for max frame length %d bits", q->framebits); return -1; } if (q->tail_biting) { diff --git a/lib/src/phy/fec/crc.c b/lib/src/phy/fec/crc.c index b064575d7..57e056120 100644 --- a/lib/src/phy/fec/crc.c +++ b/lib/src/phy/fec/crc.c @@ -45,7 +45,6 @@ static void gen_crc_table(srslte_crc_t* h) uint64_t reversecrcbit(uint32_t crc, int nbits, srslte_crc_t* h) { - uint64_t m, rmask = 0x1; for (m = 0; m < nbits; m++) { @@ -59,7 +58,6 @@ uint64_t reversecrcbit(uint32_t crc, int nbits, srslte_crc_t* h) int srslte_crc_set_init(srslte_crc_t* crc_par, uint64_t crc_init_value) { - crc_par->crcinit = crc_init_value; if (crc_par->crcinit != (crc_par->crcinit & crc_par->crcmask)) { printf("ERROR(invalid crcinit in crc_set_init().\n"); @@ -70,7 +68,6 @@ int srslte_crc_set_init(srslte_crc_t* crc_par, uint64_t crc_init_value) int srslte_crc_init(srslte_crc_t* h, uint32_t crc_poly, int crc_order) { - // Set crc working default parameters h->polynom = crc_poly; h->order = crc_order; @@ -81,7 +78,7 @@ int srslte_crc_init(srslte_crc_t* h, uint32_t crc_poly, int crc_order) h->crchighbit = (uint64_t)1 << (h->order - 1); if (srslte_crc_set_init(h, h->crcinit)) { - ERROR("Error setting CRC init word\n"); + ERROR("Error setting CRC init word"); return -1; } diff --git a/lib/src/phy/fec/ldpc/CMakeLists.txt b/lib/src/phy/fec/ldpc/CMakeLists.txt index a2da10cfd..c12bad384 100644 --- a/lib/src/phy/fec/ldpc/CMakeLists.txt +++ b/lib/src/phy/fec/ldpc/CMakeLists.txt @@ -29,7 +29,17 @@ if (HAVE_AVX2) ) endif (HAVE_AVX2) -set(FEC_SOURCES ${FEC_SOURCES} ${AVX2_SOURCES} +if (HAVE_AVX512) + set(AVX512_SOURCES + ldpc/ldpc_dec_c_avx512.c + ldpc/ldpc_dec_c_avx512long.c + ldpc/ldpc_dec_c_avx512long_flood.c + ldpc/ldpc_enc_avx512.c + ldpc/ldpc_enc_avx512long.c + ) +endif (HAVE_AVX512) + +set(FEC_SOURCES ${FEC_SOURCES} ${AVX2_SOURCES} ${AVX512_SOURCES} ldpc/base_graph.c ldpc/ldpc_dec_f.c ldpc/ldpc_dec_s.c diff --git a/lib/src/phy/fec/ldpc/base_graph.c b/lib/src/phy/fec/ldpc/base_graph.c index 633d92804..aacf92a07 100644 --- a/lib/src/phy/fec/ldpc/base_graph.c +++ b/lib/src/phy/fec/ldpc/base_graph.c @@ -4478,7 +4478,7 @@ int create_compact_pcm(uint16_t* pcm, int8_t (*positions)[MAX_CNCT], srslte_base ls_index = get_ls_index(ls); if (ls_index == VOID_LIFTSIZE) { - ERROR("Invalid lifting size %d\n", ls); + ERROR("Invalid lifting size %d", ls); return -1; } const uint16_t* tmp = get_cnct_matrix(bg, ls_index); diff --git a/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h b/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h new file mode 100644 index 000000000..5251a2e4c --- /dev/null +++ b/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h @@ -0,0 +1,106 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_avx512_consts.h + * \brief Declaration of constants and masks for the AVX512-based implementation + * of the LDPC encoder and decoder. + * + * \author Jesus Gomez + * \date 2020 + * + * \copyright Software Radio Systems Limited + * + */ + +#ifndef LDPC_AVX512_CONSTS_H +#define LDPC_AVX512_CONSTS_H + +#include + +#include "../utils_avx512.h" + +/*! + * \brief Packed 8-bit zeros. + */ +static const __m512i _mm512_zero_epi8 = {0, 0, 0, 0, 0, 0, 0, 0}; // VECTOR OF 8 0's, is each occupying 64 bits + +/*! + * \brief Packed 8-bit ones. // there are 16 x 4 bits = 64 for a LongLong (LL) + */ +static const __m512i _mm512_one_epi8 = {0x0101010101010101LL, + 0x0101010101010101LL, + 0x0101010101010101LL, + 0x0101010101010101LL, + 0x0101010101010101LL, + 0x0101010101010101LL, + 0x0101010101010101LL, + 0x0101010101010101LL}; + +/*! + * \brief Packed 8-bit 127 (that is \f$2^7 - 1\f$, or 0111 1111). + */ +static const __m512i _mm512_infty8_epi8 = {0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL, + 0x7F7F7F7F7F7F7F7FLL}; +/*! + * \brief Packed 8-bit --127 (that is \f$-2^7 + 1\f$, i.e. 1000 0001). + */ +static const __m512i _mm512_neg_infty8_epi8 = {0x8181818181818181LL, // NOLINT + 0x8181818181818181LL, // NOLINT + 0x8181818181818181LL, // NOLINT + 0x8181818181818181LL, // NOLINT + 0x8181818181818181LL, // NOLINT + 0x8181818181818181LL, // NOLINT + 0x8181818181818181LL, // NOLINT + 0x8181818181818181LL}; // NOLINT + +/*! + * \brief Packed 8-bit 63 (that is \f$2^6 - 1\f$). + */ +static const __m512i _mm512_infty7_epi8 = {0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL, + 0x3F3F3F3F3F3F3F3FLL}; +/*! + * \brief Packed 8-bit --63 (that is \f$-2^6 + 1\f$). + */ +static const __m512i _mm512_neg_infty7_epi8 = {0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL, // NOLINT + 0xC1C1C1C1C1C1C1C1LL}; // NOLINT + +/*! + * \brief Identifies even-indexed 8-bit packets. + */ +static const __m512i _mm512_mask_even_epi8 = {0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF, + 0x00FF00FF00FF00FF}; // NOLINT +#endif diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_all.h b/lib/src/phy/fec/ldpc/ldpc_dec_all.h index 0a48c4d63..2e78c5717 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_all.h +++ b/lib/src/phy/fec/ldpc/ldpc_dec_all.h @@ -601,4 +601,216 @@ int update_ldpc_soft_bits_c_avx2long_flood(void* p, const int8_t (*these_var_ind */ int extract_ldpc_message_c_avx2long_flood(void* p, uint8_t* message, uint16_t liftK); +/*! + * Creates the registers used by the optimized 8-bit-based implementation of the LDPC decoder (LS > \ref + * SRSLTE_AVX512_B_SIZE). \param[in] bgN Codeword length. \param[in] bgM Number of check nodes. + * \param[in] ls Lifting size. \param[in] scaling_fctr Scaling factor of the normalized min-sum algorithm. + * \return A pointer to the created registers (an ldpc_regs_c_avx512long structure). + */ +void* create_ldpc_dec_c_avx512long(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fctr); + +/*! + * Destroys the inner registers of the optimized 8-bit integer-based LDPC decoder (LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in] p A pointer to the dismantled decoder registers (an ldpc_regs_c_avx512long structure). + */ +void delete_ldpc_dec_c_avx512long(void* p); + +/*! + * Initializes the inner registers of the optimized 8-bit integer-based LDPC decoder before + * carrying out the actual decoding (LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long structure). + * \param[in] llrs A pointer to the array of LLR values from the channel. + * \param[in] ls The lifting size. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int init_ldpc_dec_c_avx512long(void* p, const int8_t* llrs, uint16_t ls); + +/*! + * Updates the messages from variable nodes to check nodes (optimized 8-bit version, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_var_to_check_c_avx512long(void* p, int i_layer); + +/*! + * Updates the messages from check nodes to variable nodes (optimized 8-bit version, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \param[in] this_pcm A pointer to the row of the parity check matrix (i.e. base + * graph) corresponding to the selected layer. + * \param[in] these_var_indices + * Contains the indices of the variable nodes connected + * to the current layer. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_check_to_var_c_avx512long(void* p, + int i_layer, + const uint16_t* this_pcm, + const int8_t (*these_var_indices)[MAX_CNCT]); + +/*! + * Updates the current estimate of the (soft) bits of the codeword (optimized 8-bit version, LS > \ref + * SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \param[in] these_var_indices Contains the indices of the variable nodes connected to the current layer. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_soft_bits_c_avx512long(void* p, int i_layer, const int8_t (*these_var_indices)[MAX_CNCT]); + +/*! + * Returns the decoded message (hard bits) from the current soft bits (optimized 8-bit version, LS > \ref + * SRSLTE_AVX512_B_SIZE). + * \param[in] p A pointer to the decoder registers (an ldpc_regs_c_avx512long structure). + * \param[out] message A pointer to the decoded message. + * \param[in] liftK The length of the decoded message. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int extract_ldpc_message_c_avx512long(void* p, uint8_t* message, uint16_t liftK); + +/*! + * Creates the registers used by the optimized 8-bit-based implementation of the LDPC decoder (LS <= \ref + * SRSLTE_AVX512_B_SIZE). + * \param[in] bgN Codeword length. \param[in] bgM Number of check nodes. + * \param[in] ls Lifting size. \param[in] scaling_fctr Scaling factor of the normalized min-sum algorithm. + * \return A pointer to the created registers (an ldpc_regs_c_avx512 structure). + */ +void* create_ldpc_dec_c_avx512(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fctr); + +/*! + * Destroys the inner registers of the optimized 8-bit integer-based LDPC decoder (LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in] p A pointer to the dismantled decoder registers (an ldpc_regs_c_avx512 structure). + */ +void delete_ldpc_dec_c_avx512(void* p); + +/*! + * Initializes the inner registers of the optimized 8-bit integer-based LDPC decoder before + * carrying out the actual decoding (LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512 structure). + * \param[in] llrs A pointer to the array of LLR values from the channel. + * \param[in] ls The lifting size. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int init_ldpc_dec_c_avx512(void* p, const int8_t* llrs, uint16_t ls); + +/*! + * Updates the messages from variable nodes to check nodes (optimized 8-bit version, LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512 structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_var_to_check_c_avx512(void* p, int i_layer); + +/*! + * Updates the messages from check nodes to variable nodes (optimized 8-bit version, LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512 structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \param[in] this_pcm A pointer to the row of the parity check matrix (i.e. base + * graph) corresponding to the selected layer. + * \param[in] these_var_indices + * Contains the indices of the variable nodes connected + * to the current layer. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_check_to_var_c_avx512(void* p, + int i_layer, + const uint16_t* this_pcm, + const int8_t (*these_var_indices)[MAX_CNCT]); + +/*! + * Updates the current estimate of the (soft) bits of the codeword (optimized 8-bit version, LS <= \ref + * SRSLTE_AVX512_B_SIZE). \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512 structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \param[in] these_var_indices + * Contains the indices of the variable nodes connected + * to the current layer. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_soft_bits_c_avx512(void* p, int i_layer, const int8_t (*these_var_indices)[MAX_CNCT]); + +/*! + * Returns the decoded message (hard bits) from the current soft bits (optimized 8-bit version, LS <= \ref + * SRSLTE_AVX512_B_SIZE). \param[in] p A pointer to the decoder registers (an ldpc_regs_c_avx512 structure). + * \param[out] message A pointer to the decoded message. + * \param[in] liftK The length of the decoded message. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int extract_ldpc_message_c_avx512(void* p, uint8_t* message, uint16_t liftK); + +/*! + * Creates the registers used by the optimized 8-bit-based implementation of the LDPC decoder + * (flooded scheduling, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in] bgN Codeword length. + * \param[in] bgM Number of check nodes. + * \param[in] ls Lifting size. + * \param[in] scaling_fctr Scaling factor of the normalized min-sum algorithm. + * \return A pointer to the created registers (an ldpc_regs_c_avx512long_flood structure). + */ +void* create_ldpc_dec_c_avx512long_flood(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fctr); + +/*! + * Destroys the inner registers of the optimized 8-bit integer-based LDPC decoder (flooded scheduling, LS > \ref + * SRSLTE_AVX512_B_SIZE). \param[in] p A pointer to the dismantled decoder registers (an ldpc_regs_c_avx512long_flood + * structure). + */ +void delete_ldpc_dec_c_avx512long_flood(void* p); + +/*! + * Initializes the inner registers of the optimized 8-bit integer-based LDPC decoder before + * carrying out the actual decoding (flooded scheduling, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long_flood structure). + * \param[in] llrs A pointer to the array of LLR values from the channel. + * \param[in] ls The lifting size. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int init_ldpc_dec_c_avx512long_flood(void* p, const int8_t* llrs, uint16_t ls); + +/*! + * Updates the messages from variable nodes to check nodes (optimized 8-bit version, + * flooded scheduling, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long_flood structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_var_to_check_c_avx512long_flood(void* p, int i_layer); + +/*! + * Updates the messages from check nodes to variable nodes (optimized 8-bit version, + * flooded scheduling, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long_flood structure). + * \param[in] i_layer The index of the variable-to-check layer to update. + * \param[in] this_pcm A pointer to the row of the parity check matrix (i.e. base + * graph) corresponding to the selected layer. + * \param[in] these_var_indices + * Contains the indices of the variable nodes connected + * to the current layer. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_check_to_var_c_avx512long_flood(void* p, + int i_layer, + const uint16_t* this_pcm, + const int8_t (*these_var_indices)[MAX_CNCT]); + +/*! + * Updates the current estimate of the (soft) bits of the codeword (optimized 8-bit version, + * flooded scheduling, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] p A pointer to the decoder registers (an ldpc_regs_c_avx512long_flood structure). + * \param[in] these_var_indices + * Contains the indices of the variable nodes connected + * to each layer. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int update_ldpc_soft_bits_c_avx512long_flood(void* p, const int8_t (*these_var_indices)[MAX_CNCT]); + +/*! + * Returns the decoded message (hard bits) from the current soft bits (optimized 8-bit version, + * flooded scheduling, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in] p A pointer to the decoder registers (an ldpc_regs_c_avx512long_flood structure). + * \param[out] message A pointer to the decoded message. + * \param[in] liftK The length of the decoded message. + * \return An integer: 0 if the function executes correctly, -1 otherwise. + */ +int extract_ldpc_message_c_avx512long_flood(void* p, uint8_t* message, uint16_t liftK); + #endif // SRSLTE_LDPCDEC_ALL_H diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c index cad738d81..fe8f96ecc 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c @@ -277,15 +277,17 @@ int update_ldpc_check_to_var_c_avx2(void* p, __m256i* this_rotated_v2c = NULL; __m256i this_abs_v2c_epi8; - __m256i minp_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); - __m256i mins_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); - __m256i prod_v2c_epi8 = _mm256_setzero_si256(); + __m256i mask_sign_epi8; __m256i mask_min_epi8; __m256i help_min_epi8; __m256i min_ix_epi8 = _mm256_setzero_si256(); __m256i current_ix_epi8; + __m256i minp_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); + __m256i mins_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); + __m256i prod_v2c_epi8 = _mm256_setzero_si256(); + int8_t current_var_index = (*these_var_indices)[0]; for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c index 50b35dc7b..b6a648f3c 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c @@ -335,7 +335,9 @@ int update_ldpc_check_to_var_c_avx2long(void* p, __m256i* this_rotated_v2c = NULL; __m256i this_abs_v2c_epi8; +#ifndef IMPROVED __m256i mask_sign_epi8; +#endif // IMPROVED __m256i mask_min_epi8; __m256i help_min_epi8; __m256i current_ix_epi8; @@ -360,8 +362,12 @@ int update_ldpc_check_to_var_c_avx2long(void* p, for (j = 0; j < vp->n_subnodes; j++) { // mask_sign is 1 if this_v2c_epi8 is strictly negative +#ifndef IMPROVED mask_sign_epi8 = _mm256_cmpgt_epi8(zero_epi8, this_rotated_v2c[j]); vp->prod_v2c_epi8[j] = _mm256_xor_si256(vp->prod_v2c_epi8[j], mask_sign_epi8); +#else + vp->prod_v2c_epi8[j] = _mm256_xor_si256(vp->prod_v2c_epi8[j], this_rotated_v2c[j]); +#endif // IMPROVED this_abs_v2c_epi8 = _mm256_abs_epi8(this_rotated_v2c[j]); // mask_min is 1 if this_abs_v2c is strictly smaller tha minp_v2c @@ -393,9 +399,12 @@ int update_ldpc_check_to_var_c_avx2long(void* p, this_rotated_v2c = vp->rotated_v2c + i * vp->n_subnodes; for (j = 0; j < vp->n_subnodes; j++) { - // mask_sign is 1 if this_v2c_epi8 is strictly negative +// mask_sign is 1 if this_v2c_epi8 is strictly negative +#ifndef IMPROVED final_sign_epi8 = _mm256_cmpgt_epi8(zero_epi8, this_rotated_v2c[j]); final_sign_epi8 = _mm256_xor_si256(final_sign_epi8, vp->prod_v2c_epi8[j]); +#endif // IMPROVED + final_sign_epi8 = _mm256_xor_si256(this_rotated_v2c[j], vp->prod_v2c_epi8[j]); current_ix_epi8 = _mm256_set1_epi8((int8_t)i); mask_is_min_epi8 = _mm256_cmpeq_epi8(current_ix_epi8, vp->min_ix_epi8[j]); diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c new file mode 100644 index 000000000..e5f66ddd6 --- /dev/null +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c @@ -0,0 +1,463 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_dec_c_avx512.c + * \brief Definition LDPC decoder inner functions working + * with 8-bit integer-valued LLRs (AVX512 version, lifting size < 64). + * + * Even if the inner representation is based on 8 bits, check-to-variable and + * variable-to-check messages are actually represented with 7 bits, the + * remaining bit is used to represent infinity. + * + * \author Jesus Gomez + * \date 2021 + * + * \copyright Software Radio Systems Limited + * + */ + +#include + +#include +#include + +#include "../utils_avx512.h" +#include "ldpc_dec_all.h" +#include "srslte/phy/fec/ldpc/base_graph.h" +#include "srslte/phy/utils/vector.h" + +#ifdef LV_HAVE_AVX512 + +#include + +#include "ldpc_avx512_consts.h" + +#define F2I 65535 /*!< \brief Used for float to int conversion---float f is stored as (int)(f*F2I). */ + +/*! + * \brief Maximum message magnitude. + * Messages use a 7-bit quantization. Soft bits use the remaining bit to denote infinity. + */ +static const int8_t infinity7 = (1U << 6U) - 1; + +/*! + * \brief Represents a node of the base factor graph. + */ +typedef union bg_node_avx512_t { + int8_t c[SRSLTE_AVX512_B_SIZE]; /*!< Each base node may contain up to \ref SRSLTE_AVX512_B_SIZE lifted nodes. */ + __m512i v; /*!< All the lifted nodes of the current base node as a 512-bit line. */ +} bg_node_avx512_t; + +/*! + * \brief Inner registers for the LDPC decoder that works with 8-bit integer-valued LLRs. + */ +struct ldpc_regs_c_avx512 { + __m512i scaling_fctr; /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */ + + bg_node_avx512_t* soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */ + __m512i* check_to_var; /*!< \brief Check-to-variable messages. */ + __m512i* var_to_check; /*!< \brief Variable-to-check messages. */ + __m512i* var_to_check_to_free; /*!< \brief the Variable-to-check messages with one extra _mm512 allocated space. */ + __m512i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */ + + __m512i* this_c2v_epi8; /*!< \brief Helper register for the current c2v node. */ + __m512i* this_c2v_epi8_to_free; /*!< \brief Helper register for the current c2v node with one extra __m512 allocated + space. */ + + uint16_t ls; /*!< \brief Lifting size. */ + uint8_t hrr; /*!< \brief Number of variable nodes in the high-rate region (before lifting). */ + uint8_t bgM; /*!< \brief Number of check nodes (before lifting). */ + uint8_t bgN; /*!< \brief Number of variable nodes (before lifting). */ + uint16_t finalN; /*!< \brief (bgN-2)*ls */ +}; + +/*! + * Carries out the actual update of the variable-to-check messages. It basically + * consists in \f$ z = x - y \f$ (as vectors). However, first it checks whether + * \f$\lvert x[i] \rvert = 2^{7}-1 \f$ (our representation of infinity) to + * ensure it is properly propagated. Also, the subtraction is saturated between + * \f$- clip\f$ and \f$+ clip\f$. + * \param[in] x Minuend: array we subtract from (in practice, the soft bits). + * \param[in] y Subtrahend: array to be subtracted (in practice, the + * check-to-variable messages). + * \param[out] z Resulting difference array(in practice, the updated + * variable-to-check messages). + * \param[in] clip The saturation value. + * \param[in] len The length of the vectors. + */ +static void inner_var_to_check_c_avx512(const __m512i* x, const __m512i* y, __m512i* z, uint8_t clip, uint32_t len); + +/*! + * Rotate the contents of a node towards the right by \b shift chars, that is the + * \b shift * 8 most significant bits become the least significant ones. + * \param[in] mem_addr The node to rotate. + * \param[out] out The rotated node. + * \param[in] shift The order of the rotation in number of chars. + * \param[in] ls The size of the node (lifting size). + * \param[in] n_subnodes The number of subnodes in each node. + */ +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift, uint16_t ls); + +/*! + * Scale packed 8-bit integers in \b a by the scaling factor \b sf / #F2I. + * \param[in] a Vector of packed 8-bit integers. + * \param[in] sf Scaling factor. + * \return Vector of packed 8-bit integers with the scaling result. + */ +static __m512i _mm512_scalei_epi8(__m512i a, __m512i sf); + +void* create_ldpc_dec_c_avx512(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fctr) +{ + struct ldpc_regs_c_avx512* vp = NULL; + + uint8_t bgK = bgN - bgM; + uint16_t hrr = bgK + 4; + + if ((vp = srslte_vec_malloc(sizeof(struct ldpc_regs_c_avx512))) == NULL) { + return NULL; + } + + if ((vp->soft_bits = srslte_vec_malloc(bgN * sizeof(bg_node_avx512_t))) == NULL) { + free(vp); + return NULL; + } + + if ((vp->check_to_var = srslte_vec_malloc((hrr + 1) * bgM * sizeof(__m512i))) == NULL) { + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->var_to_check_to_free = srslte_vec_malloc(((hrr + 1) + 2) * sizeof(__m512i))) == NULL) { + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + vp->var_to_check = &vp->var_to_check_to_free[1]; + + if ((vp->rotated_v2c = srslte_vec_malloc((hrr + 1) * sizeof(__m512i))) == NULL) { + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->this_c2v_epi8_to_free = srslte_vec_malloc((1 + 2) * sizeof(__m512i))) == NULL) { + free(vp->rotated_v2c); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + vp->this_c2v_epi8 = + &vp->this_c2v_epi8_to_free[1]; //+1 to support reading negative position in this_c2v_epi8 at rotate_node_rigth + + vp->bgM = bgM; + vp->bgN = bgN; + vp->hrr = hrr; + vp->ls = ls; + + vp->finalN = (bgN - 2) * ls; + // correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm512_scalei_epi8 + vp->scaling_fctr = _mm512_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I)); + + return vp; +} + +void delete_ldpc_dec_c_avx512(void* p) +{ + struct ldpc_regs_c_avx512* vp = p; + + if (vp != NULL) { + free(vp->this_c2v_epi8_to_free); + free(vp->rotated_v2c); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + } +} + +int init_ldpc_dec_c_avx512(void* p, const int8_t* llrs, uint16_t ls) +{ + struct ldpc_regs_c_avx512* vp = p; + + if (p == NULL) { + return -1; + } + + int i = 0; + int k = 0; + + // First 2 punctured bits + int ini = SRSLTE_AVX512_B_SIZE + SRSLTE_AVX512_B_SIZE; + bzero(vp->soft_bits->c, ini); + + for (i = 0; i < vp->finalN; i = i + ls) { + for (k = 0; k < ls; k++) { + vp->soft_bits->c[ini + k] = llrs[i + k]; + } + // this might be removed + bzero(&vp->soft_bits->c[ini + ls], (SRSLTE_AVX512_B_SIZE - ls) * sizeof(int8_t)); + ini = ini + SRSLTE_AVX512_B_SIZE; + } + + bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * sizeof(__m512i)); + bzero(vp->var_to_check, (vp->hrr + 1) * sizeof(__m512i)); + + return 0; +} + +int extract_ldpc_message_c_avx512(void* p, uint8_t* message, uint16_t liftK) +{ + if (p == NULL) { + return -1; + } + struct ldpc_regs_c_avx512* vp = p; + + int ini = 0; + for (int i = 0; i < liftK; i = i + vp->ls) { + for (int k = 0; k < vp->ls; k++) { + message[i + k] = (vp->soft_bits->c[ini + k] < 0); + } + ini = ini + SRSLTE_AVX512_B_SIZE; + } + + return 0; +} + +int update_ldpc_var_to_check_c_avx512(void* p, int i_layer) +{ + struct ldpc_regs_c_avx512* vp = p; + + if (p == NULL) { + return -1; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1); + + // Update the high-rate region. + inner_var_to_check_c_avx512(&(vp->soft_bits[0].v), this_check_to_var, vp->var_to_check, infinity7, vp->hrr); + + if (i_layer >= 4) { + // Update the extension region. + inner_var_to_check_c_avx512(&(vp->soft_bits[0].v) + vp->hrr + i_layer - 4, + this_check_to_var + vp->hrr, + vp->var_to_check + vp->hrr, + infinity7, + 1); + } + + return 0; +} + +int update_ldpc_check_to_var_c_avx512(void* p, + int i_layer, + const uint16_t* this_pcm, + const int8_t (*these_var_indices)[MAX_CNCT]) +{ + struct ldpc_regs_c_avx512* vp = p; + + if (p == NULL) { + return -1; + } + + int i = 0; + + uint16_t shift = 0; + int i_v2c_base = 0; + + __m512i* this_rotated_v2c = NULL; + + __m512i this_abs_v2c_epi8; + + __mmask64 mask_min_epi8; + __m512i help_min_epi8; + __m512i min_ix_epi8 = _mm512_setzero_si512(); + __m512i current_ix_epi8; + + __m512i minp_v2c_epi8 = _mm512_set1_epi8(INT8_MAX); + __m512i mins_v2c_epi8 = _mm512_set1_epi8(INT8_MAX); + __m512i prod_v2c_epi8 = _mm512_setzero_si512(); + + int8_t current_var_index = (*these_var_indices)[0]; + + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + shift = this_pcm[current_var_index]; + i_v2c_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + + current_ix_epi8 = _mm512_set1_epi8((int8_t)i); + + this_rotated_v2c = vp->rotated_v2c + i; + + rotate_node_right((uint8_t*)(vp->var_to_check + i_v2c_base), this_rotated_v2c, shift, vp->ls); + + prod_v2c_epi8 = _mm512_xor_si512(prod_v2c_epi8, *this_rotated_v2c); + + this_abs_v2c_epi8 = _mm512_abs_epi8(*this_rotated_v2c); + // mask_min is 1 if this_abs_v2c is strictly smaller tha minp_v2c + mask_min_epi8 = _mm512_cmpgt_epi8_mask(minp_v2c_epi8, this_abs_v2c_epi8); + help_min_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, this_abs_v2c_epi8, minp_v2c_epi8); + minp_v2c_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, minp_v2c_epi8, this_abs_v2c_epi8); + min_ix_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, min_ix_epi8, current_ix_epi8); + + // mask_min is 1 if this_abs_v2c is strictly smaller tha mins_v2c + mask_min_epi8 = _mm512_cmpgt_epi8_mask(mins_v2c_epi8, this_abs_v2c_epi8); + mins_v2c_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, mins_v2c_epi8, help_min_epi8); + + current_var_index = (*these_var_indices)[i + 1]; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1); + + current_var_index = (*these_var_indices)[0]; + + __mmask64 mask_is_min_epi8; + __m512i* this_c2v_epi8 = vp->this_c2v_epi8; + __m512i final_sign_epi8; + + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + shift = this_pcm[current_var_index]; + i_v2c_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + + this_rotated_v2c = vp->rotated_v2c + i; + + final_sign_epi8 = _mm512_xor_si512(*this_rotated_v2c, prod_v2c_epi8); + + current_ix_epi8 = _mm512_set1_epi8((int8_t)i); + mask_is_min_epi8 = _mm512_cmpeq_epi8_mask(current_ix_epi8, min_ix_epi8); + this_c2v_epi8[0] = _mm512_mask_blend_epi8(mask_is_min_epi8, minp_v2c_epi8, mins_v2c_epi8); + this_c2v_epi8[0] = _mm512_scalei_epi8(this_c2v_epi8[0], vp->scaling_fctr); + + // does *not* do anything special for signs[i] == 0, just negative / non-negative + __mmask64 negmask = _mm512_movepi8_mask(final_sign_epi8); // transform final_sing_epi8 into a mask + + this_c2v_epi8[0] = _mm512_mask_sub_epi8(this_c2v_epi8[0], negmask, _mm512_setzero_si512(), this_c2v_epi8[0]); + + // rotating right LS - shift positions is the same as rotating left shift positions + rotate_node_right((uint8_t*)vp->this_c2v_epi8, this_check_to_var + i_v2c_base, (vp->ls - shift) % vp->ls, vp->ls); + + current_var_index = (*these_var_indices)[i + 1]; + } + + return 0; +} + +int update_ldpc_soft_bits_c_avx512(void* p, int i_layer, const int8_t (*these_var_indices)[MAX_CNCT]) +{ + struct ldpc_regs_c_avx512* vp = p; + if (p == NULL) { + return -1; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1); + + int i_bit_tmp_base = 0; + + __m512i tmp_epi8; + __mmask64 mask_epi8; + + int8_t current_var_index = (*these_var_indices)[0]; + + for (int i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + + tmp_epi8 = _mm512_adds_epi8(this_check_to_var[i_bit_tmp_base], vp->var_to_check[i_bit_tmp_base]); + + mask_epi8 = _mm512_cmpgt_epi8_mask(tmp_epi8, _mm512_infty7_epi8); + tmp_epi8 = _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_infty8_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(_mm512_neg_infty7_epi8, tmp_epi8); + + vp->soft_bits[current_var_index].v = _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_neg_infty8_epi8); + + current_var_index = (*these_var_indices)[i + 1]; + } + + return 0; +} + +static void +inner_var_to_check_c_avx512(const __m512i* x, const __m512i* y, __m512i* z, const uint8_t clip, const uint32_t len) +{ + unsigned i = 0; + + __m512i x_epi8; + __m512i y_epi8; + __m512i z_epi8; + __mmask64 mask_epi8; + __m512i help_sub_epi8; + __m512i clip_epi8 = _mm512_set1_epi8(clip); + __m512i neg_clip_epi8 = _mm512_set1_epi8((char)(-clip)); + + // len = number of subnodes of size __m512 + for (i = 0; i < len; i++) { + x_epi8 = x[i]; + y_epi8 = y[i]; + + help_sub_epi8 = _mm512_subs_epi8(x_epi8, y_epi8); // x-y + mask_epi8 = _mm512_cmpgt_epi8_mask(help_sub_epi8, clip_epi8); // saturate to clip insteaof inifinty8 + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, help_sub_epi8, clip_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(neg_clip_epi8, z_epi8); + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, z_epi8, neg_clip_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(_mm512_infty8_epi8, x_epi8); + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, _mm512_infty8_epi8, z_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(x_epi8, _mm512_neg_infty8_epi8); + z[i] = _mm512_mask_blend_epi8(mask_epi8, _mm512_neg_infty8_epi8, z_epi8); + } +} +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift, uint16_t ls) +{ + const __m512i MZERO = _mm512_set1_epi8(0); + + uint16_t shift = 0; + uint16_t _shift = 0; + uint64_t mask1 = 0; + uint64_t mask2 = 0; + + if (this_shift == 0) { + out[0] = _mm512_loadu_si512(mem_addr); + } else { // if the last is broken, take _shift bits from the end and "shift" bits from the begin. + + _shift = ls - this_shift; + shift = SRSLTE_AVX512_B_SIZE - _shift; + + mask1 = (1ULL << _shift) - 1; // i.e. 000001111 _shift =4 + mask2 = (1ULL << shift) - 1; + mask2 = mask2 << _shift; // i.e. 000110000 shift = 2, _shift = 4 + + out[0] = _mm512_mask_loadu_epi8(MZERO, mask1, mem_addr + this_shift); + out[0] = _mm512_mask_loadu_epi8(out[0], mask2, mem_addr - _shift); + } +} + +static __m512i _mm512_scalei_epi8(__m512i a, __m512i sf) +{ + __m512i even_epi16 = _mm512_and_si512(a, _mm512_mask_even_epi8); + __m512i odd_epi16 = _mm512_srli_epi16(a, 8); + + __m512i p_even_epi16 = _mm512_mulhi_epu16(even_epi16, sf); + __m512i p_odd_epi16 = _mm512_mulhi_epu16(odd_epi16, sf); + + p_odd_epi16 = _mm512_slli_epi16(p_odd_epi16, 8); + + return _mm512_xor_si512(p_even_epi16, p_odd_epi16); +} + +#endif // LV_HAVE_AVX2 diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c new file mode 100644 index 000000000..08882ae8d --- /dev/null +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c @@ -0,0 +1,557 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_dec_c_avx512long.c + * \brief Definition LDPC decoder inner functions working + * with 8-bit integer-valued LLRs (AVX512 version, large lifting size). + * + * Even if the inner representation is based on 8 bits, check-to-variable and + * variable-to-check messages are actually represented with 7 bits, the + * remaining bit is used to represent infinity. + * + * \author Jesus Gomez + * \date 2021 + * + * \copyright Software Radio Systems Limited + * + */ + +#include + +#include +#include + +#include "../utils_avx512.h" +#include "ldpc_dec_all.h" +#include "srslte/phy/fec/ldpc/base_graph.h" +#include "srslte/phy/utils/vector.h" + +#ifdef LV_HAVE_AVX512 + +#include + +#include "ldpc_avx512_consts.h" + +#define F2I 65535 /*!< \brief Used for float to int conversion---float f is stored as (int)(f*F2I). */ + +/*! + * \brief Maximum message magnitude. + * Messages use a 7-bit quantization. Soft bits use the remaining bit to denote infinity. + */ +static const int8_t infinity7 = (1U << 6U) - 1; + +/*! + * \brief Represents a node of the base factor graph. + */ +typedef union bg_node_avx512_t { + int8_t c[SRSLTE_AVX512_B_SIZE]; /*!< Each base node may contain up to \ref SRSLTE_AVX512_B_SIZE lifted nodes. */ + __m512i v; /*!< All the lifted nodes of the current base node as a 512-bit line. */ +} bg_node_avx512_t; + +/*! + * \brief Inner registers for the LDPC decoder that works with 8-bit integer-valued LLRs. + */ +struct ldpc_regs_c_avx512long { + __m512i scaling_fctr; /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */ + + bg_node_avx512_t* soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */ + __m512i* check_to_var; /*!< \brief Check-to-variable messages. */ + __m512i* var_to_check; /*!< \brief Variable-to-check messages. */ + __m512i* var_to_check_to_free; /*!< \brief the Variable-to-check messages with one extra _mm512 allocated space. */ + + __m512i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */ + __m512i* this_c2v_epi8; /*!< \brief Helper register for the current c2v node. */ + __m512i* this_c2v_epi8_to_free; /*!< \brief Helper register for the current c2v node with one extra __m512 allocated + space. */ + __m512i* minp_v2c_epi8; /*!< \brief Helper register for the minimum v2c message. */ + __m512i* mins_v2c_epi8; /*!< \brief Helper register for the second minimum v2c message. */ + __m512i* prod_v2c_epi8; /*!< \brief Helper register for the sign of the product of all v2c messages. */ + __m512i* min_ix_epi8; /*!< \brief Helper register for the index of the minimum v2c message. */ + + uint16_t ls; /*!< \brief Lifting size. */ + uint8_t hrr; /*!< \brief Number of variable nodes in the high-rate region (before lifting). */ + uint8_t bgM; /*!< \brief Number of check nodes (before lifting). */ + uint8_t bgN; /*!< \brief Number of variable nodes (before lifting). */ + uint16_t node_size; /*!< \brief Size of the node in bytes >ls */ + uint16_t finalN; /*!< \brief (bgN-2)*ls */ + uint8_t n_subnodes; /*!< \brief Number of subnodes. */ +}; + +/*! + * Carries out the actual update of the variable-to-check messages. It basically + * consists in \f$ z = x - y \f$ (as vectors). However, first it checks whether + * \f$\lvert x[i] \rvert = 2^{7}-1 \f$ (our representation of infinity) to + * ensure it is properly propagated. Also, the subtraction is saturated between + * \f$- clip\f$ and \f$+ clip\f$. + * \param[in] x Minuend: array we subtract from (in practice, the soft bits). + * \param[in] y Subtrahend: array to be subtracted (in practice, the + * check-to-variable messages). + * \param[out] z Resulting difference array(in practice, the updated + * variable-to-check messages). + * \param[in] clip The saturation value. + * \param[in] len The length of the vectors. + */ +static void inner_var_to_check_c_avx512long(const __m512i* x, const __m512i* y, __m512i* z, uint8_t clip, uint32_t len); + +/*! + * Rotate the contents of a node towards the right by \b shift chars, that is the + * \b shift * 8 most significant bits become the least significant ones. + * \param[in] mem_addr The node to rotate. + * \param[out] out The rotated node. + * \param[in] shift The order of the rotation in number of chars. + * \param[in] ls The size of the node (lifting size). + * \param[in] n_subnodes The number of subnodes in each node. + */ +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift, uint16_t ls); + +/*! + * Scale packed 8-bit integers in \b a by the scaling factor \b sf / #F2I. + * \param[in] a Vector of packed 8-bit integers. + * \param[in] sf Scaling factor. + * \return Vector of packed 8-bit integers with the scaling result. + */ +static __m512i _mm512_scalei_epi8(__m512i a, __m512i sf); + +void* create_ldpc_dec_c_avx512long(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fctr) +{ + struct ldpc_regs_c_avx512long* vp = NULL; + + uint8_t bgK = bgN - bgM; + uint16_t hrr = bgK + 4; + + if ((vp = srslte_vec_malloc(sizeof(struct ldpc_regs_c_avx512long))) == NULL) { + return NULL; + } + + // compute number of subnodes + int left_out = ls % SRSLTE_AVX512_B_SIZE; + int n_subnodes = ls / SRSLTE_AVX512_B_SIZE + (left_out > 0); + + if ((vp->soft_bits = srslte_vec_malloc(bgN * n_subnodes * sizeof(bg_node_avx512_t))) == NULL) { + free(vp); + return NULL; + } + + if ((vp->check_to_var = srslte_vec_malloc((hrr + 1) * bgM * n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->var_to_check_to_free = srslte_vec_malloc(((hrr + 1) * n_subnodes + 2) * sizeof(__m512i))) == NULL) { + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + vp->var_to_check = &vp->var_to_check_to_free[1]; + + if ((vp->minp_v2c_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->mins_v2c_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->prod_v2c_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->min_ix_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->rotated_v2c = srslte_vec_malloc((hrr + 1) * n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->min_ix_epi8); + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + + if ((vp->this_c2v_epi8_to_free = srslte_vec_malloc((n_subnodes + 2) * sizeof(__m512i))) == NULL) { + free(vp->rotated_v2c); + free(vp->min_ix_epi8); + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + return NULL; + } + vp->this_c2v_epi8 = + &vp->this_c2v_epi8_to_free[1]; //+1 to support reading negative position in this_c2v_epi8 at rotate_node_rigth + + vp->bgM = bgM; + vp->bgN = bgN; + vp->hrr = hrr; + vp->ls = ls; + + vp->n_subnodes = n_subnodes; + vp->node_size = SRSLTE_AVX512_B_SIZE * vp->n_subnodes; + vp->finalN = (bgN - 2) * ls; + // correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm512_scalei_epi8 + vp->scaling_fctr = _mm512_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I)); + return vp; +} + +void delete_ldpc_dec_c_avx512long(void* p) +{ + struct ldpc_regs_c_avx512long* vp = p; + + if (vp != NULL) { + free(vp->this_c2v_epi8_to_free); + free(vp->rotated_v2c); + free(vp->min_ix_epi8); + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp); + } +} + +int init_ldpc_dec_c_avx512long(void* p, const int8_t* llrs, uint16_t ls) +{ + struct ldpc_regs_c_avx512long* vp = p; + + int i = 0; + int k = 0; + + if (p == NULL) { + return -1; + } + // First 2 punctured bits + int node_size = vp->node_size; + + int ini = node_size + node_size; + bzero(vp->soft_bits->c, ini); + + for (i = 0; i < vp->finalN; i = i + ls) { + for (k = 0; k < ls; k++) { + vp->soft_bits->c[ini + k] = llrs[i + k]; + } + // this zero padding might be removed + bzero(&vp->soft_bits->c[ini + ls], (node_size - ls) * sizeof(int8_t)); + ini = ini + node_size; + } + + bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m512i)); + bzero(vp->var_to_check, (vp->hrr + 1) * vp->n_subnodes * sizeof(__m512i)); + + return 0; +} + +int extract_ldpc_message_c_avx512long(void* p, uint8_t* message, uint16_t liftK) +{ + if (p == NULL) { + return -1; + } + struct ldpc_regs_c_avx512long* vp = p; + + int ini = 0; + for (int i = 0; i < liftK; i = i + vp->ls) { + for (int k = 0; k < vp->ls; k++) { + message[i + k] = (vp->soft_bits->c[ini + k] < 0); + } + ini = ini + vp->node_size; + } + + return 0; +} + +int update_ldpc_var_to_check_c_avx512long(void* p, int i_layer) +{ + struct ldpc_regs_c_avx512long* vp = p; + + if (p == NULL) { + return -1; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; + + // Update the high-rate region. + inner_var_to_check_c_avx512long( + &(vp->soft_bits[0].v), this_check_to_var, vp->var_to_check, infinity7, vp->hrr * vp->n_subnodes); + + if (i_layer >= 4) { + // Update the extension region. + inner_var_to_check_c_avx512long(&(vp->soft_bits[0].v) + (vp->hrr + i_layer - 4) * vp->n_subnodes, + this_check_to_var + vp->hrr * vp->n_subnodes, + vp->var_to_check + vp->hrr * vp->n_subnodes, + infinity7, + vp->n_subnodes); + } + + return 0; +} + +int update_ldpc_check_to_var_c_avx512long(void* p, + int i_layer, + const uint16_t* this_pcm, + const int8_t (*these_var_indices)[MAX_CNCT]) +{ + struct ldpc_regs_c_avx512long* vp = p; + + if (p == NULL) { + return -1; + } + + int i = 0; + int j = 0; + + uint16_t shift = 0; + int i_v2c_base = 0; + + __m512i* this_rotated_v2c = NULL; + __m512i this_abs_v2c_epi8; + __mmask64 mask_min_epi8; + __m512i help_min_epi8; + __m512i current_ix_epi8; + + for (j = 0; j < vp->n_subnodes; j++) { + vp->minp_v2c_epi8[j] = _mm512_set1_epi8(INT8_MAX); + vp->mins_v2c_epi8[j] = _mm512_set1_epi8(INT8_MAX); + vp->prod_v2c_epi8[j] = _mm512_set1_epi8(0); + } + + int8_t current_var_index = (*these_var_indices)[0]; + + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + shift = this_pcm[current_var_index]; + i_v2c_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + i_v2c_base *= vp->n_subnodes; + + current_ix_epi8 = _mm512_set1_epi8((int8_t)i); + + this_rotated_v2c = vp->rotated_v2c + i * vp->n_subnodes; + + rotate_node_right((uint8_t*)(vp->var_to_check + i_v2c_base), this_rotated_v2c, shift, vp->ls); + + for (j = 0; j < vp->n_subnodes; j++) { + vp->prod_v2c_epi8[j] = _mm512_xor_si512(vp->prod_v2c_epi8[j], this_rotated_v2c[j]); + + this_abs_v2c_epi8 = _mm512_abs_epi8(this_rotated_v2c[j]); + // mask_min is 1 if this_abs_v2c is strictly smaller tha minp_v2c + mask_min_epi8 = _mm512_cmpgt_epi8_mask(vp->minp_v2c_epi8[j], this_abs_v2c_epi8); + help_min_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, this_abs_v2c_epi8, vp->minp_v2c_epi8[j]); + vp->minp_v2c_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->minp_v2c_epi8[j], this_abs_v2c_epi8); + vp->min_ix_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->min_ix_epi8[j], current_ix_epi8); + + // mask_min is 1 if this_abs_v2c is strictly smaller tha mins_v2c + mask_min_epi8 = _mm512_cmpgt_epi8_mask(vp->mins_v2c_epi8[j], this_abs_v2c_epi8); + vp->mins_v2c_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->mins_v2c_epi8[j], help_min_epi8); + } + + current_var_index = (*these_var_indices)[i + 1]; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; + + current_var_index = (*these_var_indices)[0]; + + __mmask64 mask_is_min_epi8; + __m512i final_sign_epi8; + + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + shift = this_pcm[current_var_index]; + i_v2c_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + i_v2c_base *= vp->n_subnodes; + + this_rotated_v2c = vp->rotated_v2c + i * vp->n_subnodes; + + for (j = 0; j < vp->n_subnodes; j++) { + final_sign_epi8 = _mm512_xor_si512(this_rotated_v2c[j], vp->prod_v2c_epi8[j]); + + current_ix_epi8 = _mm512_set1_epi8((int8_t)i); + mask_is_min_epi8 = _mm512_cmpeq_epi8_mask(current_ix_epi8, vp->min_ix_epi8[j]); + vp->this_c2v_epi8[j] = _mm512_mask_blend_epi8(mask_is_min_epi8, vp->minp_v2c_epi8[j], vp->mins_v2c_epi8[j]); + vp->this_c2v_epi8[j] = _mm512_scalei_epi8(vp->this_c2v_epi8[j], vp->scaling_fctr); + + // does *not* do anything special for signs[i] == 0, just negative / non-negative + __mmask64 negmask = _mm512_movepi8_mask(final_sign_epi8); // transform final_sing_epi8 into a mask + + vp->this_c2v_epi8[j] = + _mm512_mask_sub_epi8(vp->this_c2v_epi8[j], negmask, _mm512_setzero_si512(), vp->this_c2v_epi8[j]); + } + + // rotating right LS - shift positions is the same as rotating left shift positions + rotate_node_right((uint8_t*)vp->this_c2v_epi8, this_check_to_var + i_v2c_base, (vp->ls - shift) % vp->ls, vp->ls); + + current_var_index = (*these_var_indices)[i + 1]; + } + + return 0; +} + +int update_ldpc_soft_bits_c_avx512long(void* p, int i_layer, const int8_t (*these_var_indices)[MAX_CNCT]) +{ + struct ldpc_regs_c_avx512long* vp = p; + if (p == NULL) { + return -1; + } + + int j = 0; + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; + + int i_bit_tmp_base = 0; + int i_bit_subnode = 0; + + __m512i tmp_epi8; + __mmask64 mask_epi8; + + int8_t current_var_index = (*these_var_indices)[0]; + int current_var_index_subnode = 0; + + for (int i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + current_var_index_subnode = current_var_index * vp->n_subnodes; + for (j = 0; j < vp->n_subnodes; j++) { + i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + i_bit_subnode = i_bit_tmp_base * vp->n_subnodes + j; + + tmp_epi8 = _mm512_adds_epi8(this_check_to_var[i_bit_subnode], vp->var_to_check[i_bit_subnode]); + + mask_epi8 = _mm512_cmpgt_epi8_mask(tmp_epi8, _mm512_infty7_epi8); + tmp_epi8 = _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_infty8_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(_mm512_neg_infty7_epi8, tmp_epi8); + + vp->soft_bits[current_var_index_subnode + j].v = + _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_neg_infty8_epi8); + } + + current_var_index = (*these_var_indices)[i + 1]; + } + + return 0; +} + +static void +inner_var_to_check_c_avx512long(const __m512i* x, const __m512i* y, __m512i* z, const uint8_t clip, const uint32_t len) +{ + unsigned i = 0; + + __m512i x_epi8; + __m512i y_epi8; + __m512i z_epi8; + __mmask64 mask_epi8; + __m512i help_sub_epi8; + __m512i clip_epi8 = _mm512_set1_epi8(clip); + __m512i neg_clip_epi8 = _mm512_set1_epi8((char)(-clip)); + + for (i = 0; i < len; i++) { + x_epi8 = x[i]; + y_epi8 = y[i]; + + help_sub_epi8 = _mm512_subs_epi8(x_epi8, y_epi8); // x-y + mask_epi8 = _mm512_cmpgt_epi8_mask(help_sub_epi8, clip_epi8); // saturate to clip insteaof inifinty8 + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, help_sub_epi8, clip_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(neg_clip_epi8, z_epi8); + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, z_epi8, neg_clip_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(_mm512_infty8_epi8, x_epi8); + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, _mm512_infty8_epi8, z_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(x_epi8, _mm512_neg_infty8_epi8); + z[i] = _mm512_mask_blend_epi8(mask_epi8, _mm512_neg_infty8_epi8, z_epi8); + } +} + +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift, uint16_t ls) +{ + uint16_t shift = 0; + uint16_t _shift = 0; + uint64_t mask1 = 0; + uint64_t mask2 = 0; + + const __m512i MZERO = _mm512_set1_epi8(0); + + // the part in the middle - we simply copy. + int j = 0; + int jj = 0; + + // copy full avx512 registers from this_shift_2 + for (j = this_shift; j <= ls - SRSLTE_AVX512_B_SIZE; j = j + SRSLTE_AVX512_B_SIZE) { + out[jj] = _mm512_loadu_si512(mem_addr + j); + jj = jj + 1; + } + + // if the last is broken, take _shift bits from the end and "shift" bits from the begin. + if (ls > j) { + _shift = ls - j; + shift = SRSLTE_AVX512_B_SIZE - _shift; + mask1 = (1ULL << _shift) - 1; // i.e. 000001111 _shift =4 + mask2 = (1ULL << shift) - 1; + mask2 = mask2 << _shift; // i.e. 000110000 shift = 2, _shift = 4 + + out[jj] = _mm512_mask_loadu_epi8(MZERO, mask1, mem_addr + j); + out[jj] = _mm512_mask_loadu_epi8(out[jj], mask2, mem_addr - _shift); + + jj = jj + 1; + } + + // copy full avx512 registers from the start of mem_addr + for (j = shift; j < this_shift; j = j + SRSLTE_AVX512_B_SIZE) { + out[jj] = _mm512_loadu_si512(mem_addr + j); // the excess is filled with something arbitrary + + jj = jj + 1; + } +} + +static __m512i _mm512_scalei_epi8(__m512i a, __m512i sf) +{ + __m512i even_epi16 = _mm512_and_si512(a, _mm512_mask_even_epi8); + __m512i odd_epi16 = _mm512_srli_epi16(a, 8); + + __m512i p_even_epi16 = _mm512_mulhi_epu16(even_epi16, sf); + __m512i p_odd_epi16 = _mm512_mulhi_epu16(odd_epi16, sf); + + p_odd_epi16 = _mm512_slli_epi16(p_odd_epi16, 8); + + return _mm512_xor_si512(p_even_epi16, p_odd_epi16); +} + +#endif // LV_HAVE_AVX512 diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c new file mode 100644 index 000000000..82012ddc9 --- /dev/null +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c @@ -0,0 +1,591 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_dec_c_avx512long_flood.c + * \brief Definition LDPC decoder inner functions working + * with 8-bit integer-valued LLRs (flooded scheduling, AVX512 version, large lifting size). + * + * Even if the inner representation is based on 8 bits, check-to-variable and + * variable-to-check messages are actually represented with 7 bits, the + * remaining bit is used to represent infinity. + * + * \author Jesus Gomez + * \date 2021 + * + * \copyright Software Radio Systems Limited + * + */ + +#include +#include +#include + +#include "../utils_avx512.h" + +#include "ldpc_dec_all.h" +#include "srslte/phy/fec/ldpc/base_graph.h" +#include "srslte/phy/utils/vector.h" + +#ifdef LV_HAVE_AVX512 + +#include + +#include "ldpc_avx512_consts.h" + +#define F2I 65535 /*!< \brief Used for float to int conversion---float f is stored as (int)(f*F2I). */ + +/*! + * \brief Maximum message magnitude. + * Messages use a 7-bit quantization. Soft bits use the remaining bit to denote infinity. + */ +static const int8_t infinity7 = (1U << 6U) - 1; + +/*! + * \brief Represents a node of the base factor graph. + */ +typedef union bg_node_avx512_t { + int8_t c[SRSLTE_AVX512_B_SIZE]; /*!< Each base node may contain up to \ref SRSLTE_AVX512_B_SIZE lifted nodes. */ + __m512i v; /*!< All the lifted nodes of the current base node as a 512-bit line. */ +} bg_node_avx512_t; + +/*! + * \brief Inner registers for the LDPC decoder that works with 8-bit integer-valued LLRs. + */ +struct ldpc_regs_c_avx512long_flood { + __m512i scaling_fctr; /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */ + + bg_node_avx512_t* soft_bits; /*!< \brief A-posteriori log-likelihood ratios. */ + __m512i* llrs; /*!< \brief A-priori log-likelihood ratios. */ + __m512i* check_to_var; /*!< \brief Check-to-variable messages. */ + __m512i* var_to_check; /*!< \brief Variable-to-check messages. */ + __m512i* var_to_check_to_free; /*!< \brief Auxiliar variable-to-check messages, with 2 extra __m512 space. */ + + __m512i* rotated_v2c; /*!< \brief To store a rotated version of the variable-to-check messages. */ + __m512i* this_c2v_epi8; /*!< \brief Helper register for the current c2v node. */ + __m512i* + this_c2v_epi8_to_free; /*!< \brief Auxiliar helper register for the current c2v node, with 2 extra _mm512 space */ + __m512i* minp_v2c_epi8; /*!< \brief Helper register for the minimum v2c message. */ + __m512i* mins_v2c_epi8; /*!< \brief Helper register for the second minimum v2c message. */ + __m512i* prod_v2c_epi8; /*!< \brief Helper register for the sign of the product of all v2c messages. */ + __m512i* min_ix_epi8; /*!< \brief Helper register for the index of the minimum v2c message. */ + + uint16_t ls; /*!< \brief Lifting size. */ + uint8_t n_subnodes; /*!< \brief Number of subnodes. */ + uint8_t hrr; /*!< \brief Number of variable nodes in the high-rate region (before lifting). */ + uint8_t bgM; /*!< \brief Number of check nodes (before lifting). */ + uint8_t bgN; /*!< \brief Number of variable nodes (before lifting). */ +}; + +/*! + * Carries out the actual update of the variable-to-check messages. It basically + * consists in \f$ z = x - y \f$ (as vectors). However, first it checks whether + * \f$\lvert x[i] \rvert = 2^{7}-1 \f$ (our representation of infinity) to + * ensure it is properly propagated. Also, the subtraction is saturated between + * \f$- clip\f$ and \f$+ clip\f$. + * \param[in] x Minuend: array we subtract from (in practice, the soft bits). + * \param[in] y Subtrahend: array to be subtracted (in practice, the + * check-to-variable messages). + * \param[out] z Resulting difference array(in practice, the updated + * variable-to-check messages). + * \param[in] clip The saturation value. + * \param[in] len The length of the vectors. + */ +static void inner_var_to_check_c_avx512(const __m512i* x, const __m512i* y, __m512i* z, uint8_t clip, uint32_t len); + +/*! + * Rotate the contents of a node towards the right by \b shift chars, that is the + * \b shift * 8 most significant bits become the least significant ones. + * \param[in] mem_addr The node to rotate. + * \param[out] out The rotated node. + * \param[in] shift The order of the rotation in number of chars. + * \param[in] ls The size of the node (lifting size). + * \param[in] n_subnodes The number of subnodes in each node. + */ +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift, uint16_t ls); + +/*! + * Scale packed 8-bit integers in \b a by the scaling factor \b sf / #F2I. + * \param[in] a Vector of packed 8-bit integers. + * \param[in] sf Scaling factor. + * \return Vector of packed 8-bit integers with the scaling result. + */ +static __m512i _mm512_scalei_epi8(__m512i a, __m512i sf); + +void* create_ldpc_dec_c_avx512long_flood(uint8_t bgN, uint8_t bgM, uint16_t ls, float scaling_fctr) +{ + struct ldpc_regs_c_avx512long_flood* vp = NULL; + + uint8_t bgK = bgN - bgM; + uint16_t hrr = bgK + 4; + + if ((vp = srslte_vec_malloc(sizeof(struct ldpc_regs_c_avx512long_flood))) == NULL) { + return NULL; + } + + // compute number of subnodes + int left_out = ls % SRSLTE_AVX512_B_SIZE; + int n_subnodes = ls / SRSLTE_AVX512_B_SIZE + (left_out > 0); + + if ((vp->llrs = srslte_vec_malloc(bgN * n_subnodes * sizeof(__m512i))) == NULL) { + free(vp); + return NULL; + } + + if ((vp->soft_bits = srslte_vec_malloc(bgN * n_subnodes * sizeof(bg_node_avx512_t))) == NULL) { + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->check_to_var = srslte_vec_malloc((hrr + 1) * bgM * n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->var_to_check_to_free = srslte_vec_malloc(((hrr + 1) * bgM * n_subnodes + 2) * sizeof(__m512i))) == NULL) { + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + vp->var_to_check = &vp->var_to_check_to_free[1]; + + if ((vp->minp_v2c_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->mins_v2c_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->prod_v2c_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->min_ix_epi8 = srslte_vec_malloc(n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->rotated_v2c = srslte_vec_malloc((hrr + 1) * n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->min_ix_epi8); + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + + if ((vp->this_c2v_epi8_to_free = srslte_vec_malloc((n_subnodes + 2) * sizeof(__m512i))) == NULL) { + free(vp->rotated_v2c); + free(vp->min_ix_epi8); + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + return NULL; + } + vp->this_c2v_epi8 = &vp->this_c2v_epi8_to_free[1]; + + vp->bgM = bgM; + vp->bgN = bgN; + vp->hrr = hrr; + vp->ls = ls; + + vp->n_subnodes = n_subnodes; + + // correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm512_scalei_epi8 + vp->scaling_fctr = _mm512_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I)); + + return vp; +} + +void delete_ldpc_dec_c_avx512long_flood(void* p) +{ + struct ldpc_regs_c_avx512long_flood* vp = p; + + if (vp != NULL) { + free(vp->this_c2v_epi8_to_free); + free(vp->rotated_v2c); + free(vp->min_ix_epi8); + free(vp->prod_v2c_epi8); + free(vp->mins_v2c_epi8); + free(vp->minp_v2c_epi8); + free(vp->var_to_check_to_free); + free(vp->check_to_var); + free(vp->soft_bits); + free(vp->llrs); + free(vp); + } +} + +int init_ldpc_dec_c_avx512long_flood(void* p, const int8_t* llrs, uint16_t ls) +{ + struct ldpc_regs_c_avx512long_flood* vp = p; + int i = 0; + int j = 0; + int k = 0; + + if (p == NULL) { + return -1; + } + + for (k = 0; k < vp->n_subnodes; k++) { + vp->soft_bits[k].v = _mm512_set1_epi8(0); + vp->soft_bits[vp->n_subnodes + k].v = _mm512_set1_epi8(0); + vp->llrs[k] = _mm512_set1_epi8(0); + vp->llrs[vp->n_subnodes + k] = _mm512_set1_epi8(0); + } + for (i = 2; i < vp->bgN; i++) { + for (j = 0; j < vp->n_subnodes; j++) { + for (k = 0; (k < SRSLTE_AVX512_B_SIZE) && (j * SRSLTE_AVX512_B_SIZE + k < ls); k++) { + vp->soft_bits[i * vp->n_subnodes + j].c[k] = llrs[(i - 2) * ls + j * SRSLTE_AVX512_B_SIZE + k]; + } + vp->llrs[i * vp->n_subnodes + j] = vp->soft_bits[i * vp->n_subnodes + j].v; + } + bzero(&(vp->soft_bits[i * vp->n_subnodes + j - 1].c[k]), (SRSLTE_AVX512_B_SIZE - k) * sizeof(int8_t)); + bzero((int8_t*)(vp->llrs + i * vp->n_subnodes + j - 1) + k, (SRSLTE_AVX512_B_SIZE - k) * sizeof(int8_t)); + } + + bzero(vp->check_to_var, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m512i)); + bzero(vp->var_to_check, (vp->hrr + 1) * vp->bgM * vp->n_subnodes * sizeof(__m512i)); + return 0; +} + +int update_ldpc_var_to_check_c_avx512long_flood(void* p, int i_layer) +{ + struct ldpc_regs_c_avx512long_flood* vp = p; + + if (p == NULL) { + return -1; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; + __m512i* this_var_to_check = vp->var_to_check + i_layer * (vp->hrr + 1) * vp->n_subnodes; + + // Update the high-rate region. + inner_var_to_check_c_avx512( + &(vp->soft_bits[0].v), this_check_to_var, this_var_to_check, infinity7, vp->hrr * vp->n_subnodes); + + if (i_layer >= 4) { + // Update the extension region. + inner_var_to_check_c_avx512(&(vp->soft_bits[0].v) + (vp->hrr + i_layer - 4) * vp->n_subnodes, + this_check_to_var + vp->hrr * vp->n_subnodes, + this_var_to_check + vp->hrr * vp->n_subnodes, + infinity7, + vp->n_subnodes); + } + + return 0; +} + +int update_ldpc_check_to_var_c_avx512long_flood(void* p, + int i_layer, + const uint16_t* this_pcm, + const int8_t (*these_var_indices)[MAX_CNCT]) +{ + struct ldpc_regs_c_avx512long_flood* vp = p; + + if (p == NULL) { + return -1; + } + + int i = 0; + int j = 0; + + uint16_t shift = 0; + int i_v2c_base = 0; + + __m512i* this_rotated_v2c = NULL; + + __m512i* this_var_to_check = (vp->var_to_check + i_layer * (vp->hrr + 1) * vp->n_subnodes); + + __m512i this_abs_v2c_epi8; + __mmask64 mask_min_epi8; + __m512i help_min_epi8; + __m512i current_ix_epi8; + + for (j = 0; j < vp->n_subnodes; j++) { + vp->minp_v2c_epi8[j] = _mm512_set1_epi8(INT8_MAX); + vp->mins_v2c_epi8[j] = _mm512_set1_epi8(INT8_MAX); + vp->prod_v2c_epi8[j] = _mm512_set1_epi8(0); + } + + int8_t current_var_index = (*these_var_indices)[0]; + + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + shift = this_pcm[current_var_index]; + i_v2c_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + i_v2c_base *= vp->n_subnodes; + + current_ix_epi8 = _mm512_set1_epi8((int8_t)i); + + this_rotated_v2c = vp->rotated_v2c + i * vp->n_subnodes; + rotate_node_right((uint8_t*)(this_var_to_check + i_v2c_base), this_rotated_v2c, shift, vp->ls); + + for (j = 0; j < vp->n_subnodes; j++) { + vp->prod_v2c_epi8[j] = _mm512_xor_si512(vp->prod_v2c_epi8[j], this_rotated_v2c[j]); + + this_abs_v2c_epi8 = _mm512_abs_epi8(this_rotated_v2c[j]); + // mask_min is 1 if this_abs_v2c is strictly smaller tha minp_v2c + mask_min_epi8 = _mm512_cmpgt_epi8_mask(vp->minp_v2c_epi8[j], this_abs_v2c_epi8); + help_min_epi8 = _mm512_mask_blend_epi8(mask_min_epi8, this_abs_v2c_epi8, vp->minp_v2c_epi8[j]); + vp->minp_v2c_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->minp_v2c_epi8[j], this_abs_v2c_epi8); + vp->min_ix_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->min_ix_epi8[j], current_ix_epi8); + + // mask_min is 1 if this_abs_v2c is strictly smaller tha mins_v2c + mask_min_epi8 = _mm512_cmpgt_epi8_mask(vp->mins_v2c_epi8[j], this_abs_v2c_epi8); + vp->mins_v2c_epi8[j] = _mm512_mask_blend_epi8(mask_min_epi8, vp->mins_v2c_epi8[j], help_min_epi8); + } + + current_var_index = (*these_var_indices)[i + 1]; + } + + __m512i* this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; + current_var_index = (*these_var_indices)[0]; + + __mmask64 mask_is_min_epi8; + __m512i final_sign_epi8; + + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + shift = this_pcm[current_var_index]; + i_v2c_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + i_v2c_base *= vp->n_subnodes; + + this_rotated_v2c = vp->rotated_v2c + i * vp->n_subnodes; + + for (j = 0; j < vp->n_subnodes; j++) { + // mask_sign is 1 if this_v2c_epi8 is strictly negative + final_sign_epi8 = _mm512_xor_si512(this_rotated_v2c[j], vp->prod_v2c_epi8[j]); + + current_ix_epi8 = _mm512_set1_epi8((int8_t)i); + mask_is_min_epi8 = _mm512_cmpeq_epi8_mask(current_ix_epi8, vp->min_ix_epi8[j]); + vp->this_c2v_epi8[j] = _mm512_mask_blend_epi8(mask_is_min_epi8, vp->minp_v2c_epi8[j], vp->mins_v2c_epi8[j]); + vp->this_c2v_epi8[j] = _mm512_scalei_epi8(vp->this_c2v_epi8[j], vp->scaling_fctr); + + // does *not* do anything special for signs[i] == 0, just negative / non-negative + __mmask64 negmask = _mm512_movepi8_mask(final_sign_epi8); // transform final_sing_epi8 into a mask + + vp->this_c2v_epi8[j] = + _mm512_mask_sub_epi8(vp->this_c2v_epi8[j], negmask, _mm512_setzero_si512(), vp->this_c2v_epi8[j]); + } + // rotating right LS - shift positions is the same as rotating left shift positions + rotate_node_right((uint8_t*)vp->this_c2v_epi8, this_check_to_var + i_v2c_base, (vp->ls - shift) % vp->ls, vp->ls); + + current_var_index = (*these_var_indices)[i + 1]; + } + + return 0; +} + +int update_ldpc_soft_bits_c_avx512long_flood(void* p, const int8_t (*these_var_indices)[MAX_CNCT]) +{ + struct ldpc_regs_c_avx512long_flood* vp = p; + if (p == NULL) { + return -1; + } + + int i_layer = 0; + int i = 0; + int j = 0; + + __m512i* this_check_to_var = NULL; + + int i_bit_tmp_base = 0; + int i_bit_subnode = 0; + + __m512i tmp_epi8; + __mmask64 mask_epi8; + + int8_t current_var_index = 0; + int current_var_index_subnode = 0; + + for (i = 0; i < vp->bgN; i++) { + for (j = 0; j < vp->n_subnodes; j++) { + vp->soft_bits[i * vp->n_subnodes + j].v = vp->llrs[i * vp->n_subnodes + j]; + } + } + + for (i_layer = 0; i_layer < vp->bgM; i_layer++) { + current_var_index = these_var_indices[i_layer][0]; + + this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; + for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { + current_var_index_subnode = current_var_index * vp->n_subnodes; + for (j = 0; j < vp->n_subnodes; j++) { + i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; + i_bit_subnode = i_bit_tmp_base * vp->n_subnodes + j; + + tmp_epi8 = _mm512_adds_epi8(this_check_to_var[i_bit_subnode], vp->soft_bits[current_var_index_subnode + j].v); + + mask_epi8 = _mm512_cmpgt_epi8_mask(tmp_epi8, _mm512_infty7_epi8); + tmp_epi8 = _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_infty8_epi8); + mask_epi8 = _mm512_cmpgt_epi8_mask(_mm512_neg_infty7_epi8, tmp_epi8); + + vp->soft_bits[current_var_index_subnode + j].v = + _mm512_mask_blend_epi8(mask_epi8, tmp_epi8, _mm512_neg_infty8_epi8); + } + + current_var_index = these_var_indices[i_layer][i + 1]; + } + } + + return 0; +} + +int extract_ldpc_message_c_avx512long_flood(void* p, uint8_t* message, uint16_t liftK) +{ + if (p == NULL) { + return -1; + } + + struct ldpc_regs_c_avx512long_flood* vp = p; + + int j = 0; + int k = 0; + + for (int i = 0; i < liftK / vp->ls; i++) { + for (j = 0; j < vp->n_subnodes; j++) { + for (k = 0; (k < SRSLTE_AVX512_B_SIZE) && (j * SRSLTE_AVX512_B_SIZE + k < vp->ls); k++) { + message[i * vp->ls + j * SRSLTE_AVX512_B_SIZE + k] = (vp->soft_bits[i * vp->n_subnodes + j].c[k] < 0); + } + } + } + + return 0; +} + +static void +inner_var_to_check_c_avx512(const __m512i* x, const __m512i* y, __m512i* z, const uint8_t clip, const uint32_t len) +{ + unsigned i = 0; + + __m512i x_epi8; + __m512i y_epi8; + __m512i z_epi8; + __mmask64 mask_epi8; + __m512i help_sub_epi8; + __m512i clip_epi8 = _mm512_set1_epi8(clip); + __m512i neg_clip_epi8 = _mm512_set1_epi8((char)(-clip)); + + // len = number of subnodes of size __m512 + for (i = 0; i < len; i++) { + x_epi8 = x[i]; + y_epi8 = y[i]; + + help_sub_epi8 = _mm512_subs_epi8(x_epi8, y_epi8); // x-y + mask_epi8 = _mm512_cmpgt_epi8_mask(help_sub_epi8, clip_epi8); // saturate to clip insteaof inifinty8 + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, help_sub_epi8, clip_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(neg_clip_epi8, z_epi8); + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, z_epi8, neg_clip_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(_mm512_infty8_epi8, x_epi8); + z_epi8 = _mm512_mask_blend_epi8(mask_epi8, _mm512_infty8_epi8, z_epi8); + + mask_epi8 = _mm512_cmpgt_epi8_mask(x_epi8, _mm512_neg_infty8_epi8); + z[i] = _mm512_mask_blend_epi8(mask_epi8, _mm512_neg_infty8_epi8, z_epi8); + } +} + +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift, uint16_t ls) +{ + uint16_t shift = 0; + uint16_t _shift = 0; + uint64_t mask1 = 0; + uint64_t mask2 = 0; + + const __m512i MZERO = _mm512_set1_epi8(0); + + // the part in the middle - we simply copy. + int j = 0; + int jj = 0; + + // copy full avx512 registers from this_shift_2 + for (j = this_shift; j <= ls - SRSLTE_AVX512_B_SIZE; j = j + SRSLTE_AVX512_B_SIZE) { + out[jj] = _mm512_loadu_si512(mem_addr + j); + jj = jj + 1; + } + + // if the last is broken, take _shift bits from the end and "shift" bits from the begin. + if (ls > j) { + _shift = ls - j; + shift = SRSLTE_AVX512_B_SIZE - _shift; + mask1 = (1ULL << _shift) - 1; // i.e. 000001111 _shift =4 + mask2 = (1ULL << shift) - 1; + mask2 = mask2 << _shift; // i.e. 000110000 shift = 2, _shift = 4 + + out[jj] = _mm512_mask_loadu_epi8(MZERO, mask1, mem_addr + j); + out[jj] = _mm512_mask_loadu_epi8(out[jj], mask2, mem_addr - _shift); + + jj = jj + 1; + } + + // copy full avx512 registers from the start of mem_addr, + for (j = shift; j < this_shift; j = j + SRSLTE_AVX512_B_SIZE) { + out[jj] = _mm512_loadu_si512(mem_addr + j); // the excess is filled with something arbitrary + + jj = jj + 1; + } +} + +static __m512i _mm512_scalei_epi8(__m512i a, __m512i sf) +{ + __m512i even_epi16 = _mm512_and_si512(a, _mm512_mask_even_epi8); + __m512i odd_epi16 = _mm512_srli_epi16(a, 8); + + __m512i p_even_epi16 = _mm512_mulhi_epu16(even_epi16, sf); + __m512i p_odd_epi16 = _mm512_mulhi_epu16(odd_epi16, sf); + + p_odd_epi16 = _mm512_slli_epi16(p_odd_epi16, 8); + + return _mm512_xor_si512(p_even_epi16, p_odd_epi16); +} + +#endif // LV_HAVE_AVX512 diff --git a/lib/src/phy/fec/ldpc/ldpc_decoder.c b/lib/src/phy/fec/ldpc/ldpc_decoder.c index dd04df64d..147c750d1 100644 --- a/lib/src/phy/fec/ldpc/ldpc_decoder.c +++ b/lib/src/phy/fec/ldpc/ldpc_decoder.c @@ -32,6 +32,7 @@ #include #include "../utils_avx2.h" +#include "../utils_avx512.h" #include "ldpc_dec_all.h" #include "srslte/phy/fec/ldpc/base_graph.h" #include "srslte/phy/fec/ldpc/ldpc_decoder.h" @@ -64,13 +65,13 @@ static int decode_f(void* o, const float* llrs, uint8_t* message, uint32_t cdwd_ // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } @@ -107,7 +108,7 @@ static int init_f(srslte_ldpc_decoder_t* q) q->free = free_dec_f; if ((q->ptr = create_ldpc_dec_f(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_f(q); return -1; } @@ -142,13 +143,13 @@ static int decode_s(void* o, const int16_t* llrs, uint8_t* message, uint32_t cdw // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } @@ -185,7 +186,7 @@ static int init_s(srslte_ldpc_decoder_t* q) q->free = free_dec_s; if ((q->ptr = create_ldpc_dec_s(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_s(q); return -1; } @@ -220,13 +221,13 @@ static int decode_c(void* o, const int8_t* llrs, uint8_t* message, uint32_t cdwd // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } @@ -263,7 +264,7 @@ static int init_c(srslte_ldpc_decoder_t* q) q->free = free_dec_c; if ((q->ptr = create_ldpc_dec_c(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_c(q); return -1; } @@ -298,13 +299,13 @@ static int decode_c_flood(void* o, const int8_t* llrs, uint8_t* message, uint32_ // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } init_ldpc_dec_c_flood(q->ptr, llrs, q->ls); @@ -341,7 +342,7 @@ static int init_c_flood(srslte_ldpc_decoder_t* q) q->free = free_dec_c_flood; if ((q->ptr = create_ldpc_dec_c_flood(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_c_flood(q); return -1; } @@ -377,13 +378,13 @@ static int decode_c_avx2(void* o, const int8_t* llrs, uint8_t* message, uint32_t // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } init_ldpc_dec_c_avx2(q->ptr, llrs, q->ls); @@ -419,7 +420,7 @@ static int init_c_avx2(srslte_ldpc_decoder_t* q) q->free = free_dec_c_avx2; if ((q->ptr = create_ldpc_dec_c_avx2(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_c_avx2(q); return -1; } @@ -455,13 +456,13 @@ static int decode_c_avx2long(void* o, const int8_t* llrs, uint8_t* message, uint // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } init_ldpc_dec_c_avx2long(q->ptr, llrs, q->ls); @@ -497,7 +498,7 @@ static int init_c_avx2long(srslte_ldpc_decoder_t* q) q->free = free_dec_c_avx2long; if ((q->ptr = create_ldpc_dec_c_avx2long(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_c_avx2long(q); return -1; } @@ -533,13 +534,13 @@ static int decode_c_avx2_flood(void* o, const int8_t* llrs, uint8_t* message, ui // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } init_ldpc_dec_c_avx2_flood(q->ptr, llrs, q->ls); @@ -576,7 +577,7 @@ static int init_c_avx2_flood(srslte_ldpc_decoder_t* q) q->free = free_dec_c_avx2_flood; if ((q->ptr = create_ldpc_dec_c_avx2_flood(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_c_avx2_flood(q); return -1; } @@ -613,13 +614,13 @@ static int decode_c_avx2long_flood(void* o, const int8_t* llrs, uint8_t* message // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } init_ldpc_dec_c_avx2long_flood(q->ptr, llrs, q->ls); @@ -658,7 +659,7 @@ static int init_c_avx2long_flood(srslte_ldpc_decoder_t* q) q->free = free_dec_c_avx2long_flood; if ((q->ptr = create_ldpc_dec_c_avx2long_flood(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { - ERROR("Create_ldpc_dec failed\n"); + ERROR("Create_ldpc_dec failed"); free_dec_c_avx2long(q); return -1; } @@ -669,6 +670,250 @@ static int init_c_avx2long_flood(srslte_ldpc_decoder_t* q) } #endif // LV_HAVE_AVX2 +// AVX512 Declarations + +#ifdef LV_HAVE_AVX512 + +/*! Carries out the actual destruction of the memory allocated to the decoder, 8-bit-LLR case (AVX512 implementation). + */ +static void free_dec_c_avx512(void* o) +{ + srslte_ldpc_decoder_t* q = o; + if (q->var_indices) { + free(q->var_indices); + } + if (q->pcm) { + free(q->pcm); + } + delete_ldpc_dec_c_avx512(q->ptr); +} + +/*! Carries out the decoding with 8-bit integer-valued LLRs (AVX512 implementation). */ +static int decode_c_avx512(void* o, const int8_t* llrs, uint8_t* message, uint32_t cdwd_rm_length) +{ + srslte_ldpc_decoder_t* q = o; + + // it must be smaller than the codeword size + if (cdwd_rm_length > q->liftN - 2 * q->ls) { + cdwd_rm_length = q->liftN - 2 * q->ls; + } + // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, + // 2 variable nodes are systematically punctured by the encoder. + if (cdwd_rm_length < (q->bgK + 2) * q->ls) { + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); + cdwd_rm_length = (q->bgK + 2) * q->ls; + // return -1; + } + if (cdwd_rm_length % q->ls) { + cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); + // return -1; + } + init_ldpc_dec_c_avx512(q->ptr, llrs, q->ls); + + uint16_t* this_pcm = NULL; + int8_t(*these_var_indices)[MAX_CNCT] = NULL; + + // When computing the number of layers, we need to recall that the standard always removes + // the first two variable nodes from the final codeword. + uint8_t n_layers = cdwd_rm_length / q->ls - q->bgK + 2; + + for (int i_iteration = 0; i_iteration < MAX_ITERATIONS; i_iteration++) { + for (int i_layer = 0; i_layer < n_layers; i_layer++) { + update_ldpc_var_to_check_c_avx512(q->ptr, i_layer); + + this_pcm = q->pcm + i_layer * q->bgN; + these_var_indices = q->var_indices + i_layer; + + update_ldpc_check_to_var_c_avx512(q->ptr, i_layer, this_pcm, these_var_indices); + + update_ldpc_soft_bits_c_avx512(q->ptr, i_layer, these_var_indices); + } + } + + extract_ldpc_message_c_avx512(q->ptr, message, q->liftK); + + return 0; +} + +/*! Initializes the decoder to work with 8-bit integer-valued LLRs (AVX512 implementation). */ +static int init_c_avx512(srslte_ldpc_decoder_t* q) +{ + q->free = free_dec_c_avx512; + + if ((q->ptr = create_ldpc_dec_c_avx512(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { + ERROR("Create_ldpc_dec failed"); + free_dec_c_avx512(q); + return -1; + } + + q->decode_c = decode_c_avx512; + + return 0; +} + +/*! Carries out the actual destruction of the memory allocated to the decoder, 8-bit-LLR case (AVX512 implementation, + * large lifting size). */ +static void free_dec_c_avx512long(void* o) +{ + srslte_ldpc_decoder_t* q = o; + if (q->var_indices) { + free(q->var_indices); + } + if (q->pcm) { + free(q->pcm); + } + delete_ldpc_dec_c_avx512long(q->ptr); +} + +/*! Carries out the decoding with 8-bit integer-valued LLRs (AVX512 implementation, large lifting size). */ +static int decode_c_avx512long(void* o, const int8_t* llrs, uint8_t* message, uint32_t cdwd_rm_length) +{ + srslte_ldpc_decoder_t* q = o; + + // it must be smaller than the codeword size + if (cdwd_rm_length > q->liftN - 2 * q->ls) { + cdwd_rm_length = q->liftN - 2 * q->ls; + } + // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, + // 2 variable nodes are systematically punctured by the encoder. + if (cdwd_rm_length < (q->bgK + 2) * q->ls) { + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); + cdwd_rm_length = (q->bgK + 2) * q->ls; + // return -1; + } + if (cdwd_rm_length % q->ls) { + cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); + // return -1; + } + + init_ldpc_dec_c_avx512long(q->ptr, llrs, q->ls); + + uint16_t* this_pcm = NULL; + int8_t(*these_var_indices)[MAX_CNCT] = NULL; + + // When computing the number of layers, we need to recall that the standard always removes + // the first two variable nodes from the final codeword. + uint8_t n_layers = cdwd_rm_length / q->ls - q->bgK + 2; + + for (int i_iteration = 0; i_iteration < MAX_ITERATIONS; i_iteration++) { + for (int i_layer = 0; i_layer < n_layers; i_layer++) { + update_ldpc_var_to_check_c_avx512long(q->ptr, i_layer); + + this_pcm = q->pcm + i_layer * q->bgN; + these_var_indices = q->var_indices + i_layer; + + update_ldpc_check_to_var_c_avx512long(q->ptr, i_layer, this_pcm, these_var_indices); + + update_ldpc_soft_bits_c_avx512long(q->ptr, i_layer, these_var_indices); + } + } + extract_ldpc_message_c_avx512long(q->ptr, message, q->liftK); + + return 0; +} + +/*! Initializes the decoder to work with 8-bit integer-valued LLRs (AVX512 implementation, large lifting size). */ +static int init_c_avx512long(srslte_ldpc_decoder_t* q) +{ + q->free = free_dec_c_avx512long; + + if ((q->ptr = create_ldpc_dec_c_avx512long(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { + ERROR("Create_ldpc_dec failed"); + free_dec_c_avx512long(q); + return -1; + } + + q->decode_c = decode_c_avx512long; + + return 0; +} + +/*! Carries out the actual destruction of the memory allocated to the decoder, 8-bit-LLR case + * (flooded scheduling, AVX512 implementation, large lifting size). */ +static void free_dec_c_avx512long_flood(void* o) +{ + srslte_ldpc_decoder_t* q = o; + if (q->var_indices) { + free(q->var_indices); + } + if (q->pcm) { + free(q->pcm); + } + delete_ldpc_dec_c_avx512long_flood(q->ptr); +} + +/*! Carries out the decoding with 8-bit integer-valued LLRs (flooded scheduling, AVX512 implementation, large lifting + * size). */ +static int decode_c_avx512long_flood(void* o, const int8_t* llrs, uint8_t* message, uint32_t cdwd_rm_length) +{ + srslte_ldpc_decoder_t* q = o; + + // it must be smaller than the codeword size + if (cdwd_rm_length > q->liftN - 2 * q->ls) { + cdwd_rm_length = q->liftN - 2 * q->ls; + } + // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, + // 2 variable nodes are systematically punctured by the encoder. + if (cdwd_rm_length < (q->bgK + 2) * q->ls) { + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); + cdwd_rm_length = (q->bgK + 2) * q->ls; + // return -1; + } + if (cdwd_rm_length % q->ls) { + cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); + // return -1; + } + init_ldpc_dec_c_avx512long_flood(q->ptr, llrs, q->ls); + + uint16_t* this_pcm = NULL; + int8_t(*these_var_indices)[MAX_CNCT] = NULL; + + // When computing the number of layers, we need to recall that the standard always removes + // the first two variable nodes from the final codeword. + uint8_t n_layers = cdwd_rm_length / q->ls - q->bgK + 2; + + for (int i_iteration = 0; i_iteration < 2 * MAX_ITERATIONS; i_iteration++) { + for (int i_layer = 0; i_layer < n_layers; i_layer++) { + update_ldpc_var_to_check_c_avx512long_flood(q->ptr, i_layer); + } + + for (int i_layer = 0; i_layer < n_layers; i_layer++) { + this_pcm = q->pcm + i_layer * q->bgN; + these_var_indices = q->var_indices + i_layer; + + update_ldpc_check_to_var_c_avx512long_flood(q->ptr, i_layer, this_pcm, these_var_indices); + } + + update_ldpc_soft_bits_c_avx512long_flood(q->ptr, q->var_indices); + } + + extract_ldpc_message_c_avx512long_flood(q->ptr, message, q->liftK); + + return 0; +} + +/*! Initializes the decoder to work with 8-bit integer-valued LLRs + * (flooded scheduling, AVX512 implementation, large lifting size). */ +static int init_c_avx512long_flood(srslte_ldpc_decoder_t* q) +{ + q->free = free_dec_c_avx512long_flood; + + if ((q->ptr = create_ldpc_dec_c_avx512long_flood(q->bgN, q->bgM, q->ls, q->scaling_fctr)) == NULL) { + ERROR("Create_ldpc_dec failed"); + free_dec_c_avx512long_flood(q); + return -1; + } + + q->decode_c = decode_c_avx512long_flood; + + return 0; +} + +#endif // LV_HAVE_AVX512 + int srslte_ldpc_decoder_init(srslte_ldpc_decoder_t* q, srslte_ldpc_decoder_type_t type, srslte_basegraph_t bg, @@ -678,7 +923,7 @@ int srslte_ldpc_decoder_init(srslte_ldpc_decoder_t* q, int ls_index = get_ls_index(ls); if (ls_index == VOID_LIFTSIZE) { - ERROR("Invalid lifting size %d\n", ls); + ERROR("Invalid lifting size %d", ls); return -1; } @@ -692,7 +937,7 @@ int srslte_ldpc_decoder_init(srslte_ldpc_decoder_t* q, q->bgM = BG2M; break; default: - ERROR("Base Graph BG%d does not exist\n", bg + 1); + ERROR("Base Graph BG%d does not exist", bg + 1); return -1; } q->bg = bg; @@ -754,8 +999,19 @@ int srslte_ldpc_decoder_init(srslte_ldpc_decoder_t* q, return init_c_avx2long_flood(q); } #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + case SRSLTE_LDPC_DECODER_C_AVX512: + if (ls <= SRSLTE_AVX512_B_SIZE) { + return init_c_avx512(q); + } else { + return init_c_avx512long(q); + } + case SRSLTE_LDPC_DECODER_C_AVX512_FLOOD: + return init_c_avx512long_flood(q); +#endif // LV_HAVE_AVX2 + default: - ERROR("Unknown decoder.\n"); + ERROR("Unknown decoder."); return -1; } } diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_all.h b/lib/src/phy/fec/ldpc/ldpc_enc_all.h index bc55e7f80..d07c641af 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_all.h +++ b/lib/src/phy/fec/ldpc/ldpc_enc_all.h @@ -72,7 +72,7 @@ void encode_high_rate_case4(void* o, uint8_t* output); void encode_ext_region(srslte_ldpc_encoder_t* q, uint8_t* output, uint8_t n_layers); /*! - * Creates the inner registers required by the optimized LDPC encoder (LS <= \ref SRSLTE_AVX2_B_SIZE). + * Creates the inner registers required by the optimized LDPC encoder (LS <= \ref SRSLTE_AVX512_B_SIZE). * \param[in,out] q A pointer to an encoder. * \return A pointer to the newly created structure of registers. */ @@ -127,7 +127,8 @@ void encode_high_rate_case2_avx2(void* o); void encode_high_rate_case3_avx2(void* o); /*! Computes the high-rate parity bits for BG2 and ls_index in {3, 7} (SIMD-optimized version, LS <= \ref - * SRSLTE_AVX2_B_SIZE). \param[in,out] o A pointer to an encoder. + * SRSLTE_AVX2_B_SIZE). + * \param[in,out] o A pointer to an encoder. */ void encode_high_rate_case4_avx2(void* o); @@ -208,4 +209,212 @@ void encode_high_rate_case4_avx2long(void* o); */ void encode_ext_region_avx2long(srslte_ldpc_encoder_t* q, uint8_t n_layers); +/*! + * Creates the inner registers required by the optimized LDPC encoder (LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in,out] q A pointer to an encoder. + * \return A pointer to the newly created structure of registers. + */ +void* create_ldpc_enc_avx2(srslte_ldpc_encoder_t* q); + +/*! + * Deletes the inner registers of an optimized LDPC encoder (LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in] p A pointer to the register structure. + */ +void delete_ldpc_enc_avx2(void* p); + +/*! + * Loads the message in the opimized encoder registers (LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in] p The register structure. + * \param[in] input The message to encode. + * \param[in] msg_len Number of variable nodes in one message. + * \param[in] cdwd_len Number of variable nodes in one message. + * \param[in] ls The lifting size. + * \return Error code: 0 if correct, -1 otherwise. + */ +int load_avx2(void* p, const uint8_t* input, uint8_t msg_len, uint8_t cdwd_len, uint16_t ls); + +/*! Extracts the final codeword from the optimized encoder registers (LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in] p The register structure. + * \param[out] output The output codeword. + * \param[in] cdwd_len The number of variable nodes (after rate-matching, if enabled). + * \param[in] ls The lifting size. + * \return Error code: 0 if correct, -1 otherwise. + */ +int return_codeword_avx2(void* p, uint8_t* output, uint8_t cdwd_len, uint16_t ls); + +/*! Computes the product between the first (K - 2) columns of the PCM and the + * systematic bits (SIMD-optimized version, LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in,out] q A pointer to an encoder. + */ +void preprocess_systematic_bits_avx2(srslte_ldpc_encoder_t* q); + +/*! Computes the high-rate parity bits for BG1 and ls_index in {0, 1, 2, 3, 4, 5, 7} + * (SIMD-optimized version, LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case1_avx2(void* o); + +/*! Computes the high-rate parity bits for BG1 and ls_index in {6} (SIMD-optimized version, LS <= \ref + * SRSLTE_AVX2_B_SIZE). \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case2_avx2(void* o); + +/*! Computes the high-rate parity bits for BG2 and ls_index in {0, 1, 2, 4, 5, 6} (SIMD-optimized version, LS <= \ref + * SRSLTE_AVX2_B_SIZE). \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case3_avx2(void* o); + +/*! Computes the high-rate parity bits for BG2 and ls_index in {3, 7} (SIMD-optimized version, LS <= \ref + * SRSLTE_AVX2_B_SIZE). + \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case4_avx2(void* o); + +/*! Computes the extended-region parity bits (SIMD-optimized version, LS <= \ref SRSLTE_AVX2_B_SIZE). + * \param[in,out] q A pointer to an encoder. + * \param[in] n_layers The number of layers to process (when doing rate matching not all + * layers are needed). + */ +void encode_ext_region_avx2(srslte_ldpc_encoder_t* q, uint8_t n_layers); + +/*! + * Creates the inner registers required by the optimized LDPC encoder (for LS > \ref SRSLTE_avx512_B_SIZE). + * \param[in,out] q A pointer to an encoder. + * \return A pointer to the newly created structure of registers. + */ +void* create_ldpc_enc_avx512long(srslte_ldpc_encoder_t* q); + +/*! + * Deletes the inner registers of an optimized LDPC encoder (LS > \ref SRSLTE_avx512_B_SIZE). + * \param[in] p A pointer to the register structure. + */ +void delete_ldpc_enc_avx512long(void* p); + +/*! + * Loads the message in the optimized encoder registers (LS > \ref SRSLTE_avx512_B_SIZE). + * \param[in] p The register structure. + * \param[in] input The message to encode. + * \param[in] msg_len Number of variable nodes in one message. + * \param[in] cdwd_len Number of variable nodes in one message. + * \param[in] ls The lifting size. + * \return Error code: 0 if correct, -1 otherwise. + */ +int load_avx512long(void* p, const uint8_t* input, uint8_t msg_len, uint8_t cdwd_len, uint16_t ls); + +/*! Extracts the final codeword from the optimized encoder registers (LS > \ref SRSLTE_avx512_B_SIZE). + * \param[in] p The register structure. + * \param[out] output The output codeword. + * \param[in] cdwd_len The number of variable nodes (after rate-matching, if enabled). + * \param[in] ls The lifting size. + * \return Error code: 0 if correct, -1 otherwise. + */ +int return_codeword_avx512long(void* p, uint8_t* output, uint8_t cdwd_len, uint16_t ls); + +/*! Computes the product between the first (K - 2) columns of the PCM and the + * systematic bits (SIMD-optimized version, LS > \ref SRSLTE_avx512_B_SIZE). + * \param[in,out] q A pointer to an encoder. + */ +void preprocess_systematic_bits_avx512long(srslte_ldpc_encoder_t* q); + +/*! Computes the high-rate parity bits for BG1 and ls_index in {0, 1, 2, 3, 4, 5, 7} + * (SIMD-optimized version, LS > \ref SRSLTE_avx512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case1_avx512long(void* o); + +/*! Computes the high-rate parity bits for BG1 and ls_index in {6} (SIMD-optimized version, LS > \ref + * SRSLTE_avx512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case2_avx512long(void* o); + +/*! Computes the high-rate parity bits for BG2 and ls_index in {0, 1, 2, 4, 5, 6} (SIMD-optimized version, LS > \ref + * SRSLTE_avx512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case3_avx512long(void* o); + +/*! Computes the high-rate parity bits for BG2 and ls_index in {3, 7} (SIMD-optimized version, LS > \ref + * SRSLTE_avx512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case4_avx512long(void* o); + +/*! Computes the extended-region parity bits (SIMD-optimized version, LS > \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] q A pointer to an encoder. + * \param[in] n_layers The number of layers to process (when doing rate matching not all + * layers are needed). + */ +void encode_ext_region_avx512long(srslte_ldpc_encoder_t* q, uint8_t n_layers); + +/*! + * Creates the inner registers required by the optimized LDPC encoder (for LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] q A pointer to an encoder. + * \return A pointer to the newly created structure of registers. + */ +void* create_ldpc_enc_avx512(srslte_ldpc_encoder_t* q); + +/*! + * Deletes the inner registers of an optimized LDPC encoder (LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in] p A pointer to the register structure. + */ +void delete_ldpc_enc_avx512(void* p); + +/*! + * Loads the message in the optimized encoder registers (LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in] p The register structure. + * \param[in] input The message to encode. + * \param[in] msg_len Number of variable nodes in one message. + * \param[in] cdwd_len Number of variable nodes in one message. + * \param[in] ls The lifting size. + * \return Error code: 0 if correct, -1 otherwise. + */ +int load_avx512(void* p, const uint8_t* input, uint8_t msg_len, uint8_t cdwd_len, uint16_t ls); + +/*! Extracts the final codeword from the optimized encoder registers (LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in] p The register structure. + * \param[out] output The output codeword. + * \param[in] cdwd_len The number of variable nodes (after rate-matching, if enabled). + * \param[in] ls The lifting size. + * \return Error code: 0 if correct, -1 otherwise. + */ +int return_codeword_avx512(void* p, uint8_t* output, uint8_t cdwd_len, uint16_t ls); + +/*! Computes the product between the first (K - 2) columns of the PCM and the + * systematic bits (SIMD-optimized version, LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] q A pointer to an encoder. + */ +void preprocess_systematic_bits_avx512(srslte_ldpc_encoder_t* q); + +/*! Computes the high-rate parity bits for BG1 and ls_index in {0, 1, 2, 3, 4, 5, 7} + * (SIMD-optimized version, LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case1_avx512(void* o); + +/*! Computes the high-rate parity bits for BG1 and ls_index in {6} (SIMD-optimized version, LS <= \ref + * SRSLTE_AVX512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case2_avx512(void* o); + +/*! Computes the high-rate parity bits for BG2 and ls_index in {0, 1, 2, 4, 5, 6} (SIMD-optimized version, LS > \ref + * SRSLTE_AVX512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case3_avx512(void* o); + +/*! Computes the high-rate parity bits for BG2 and ls_index in {3, 7} (SIMD-optimized version, LS <= \ref + * SRSLTE_AVX512_B_SIZE). + * \param[in,out] o A pointer to an encoder. + */ +void encode_high_rate_case4_avx512(void* o); + +/*! Computes the extended-region parity bits (SIMD-optimized version, LS <= \ref SRSLTE_AVX512_B_SIZE). + * \param[in,out] q A pointer to an encoder. + * \param[in] n_layers The number of layers to process (when doing rate matching not all + * layers are needed). + */ +void encode_ext_region_avx512(srslte_ldpc_encoder_t* q, uint8_t n_layers); + #endif // SRSLTE_LDPCENC_ALL_H diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c index 395d6fc6a..774b295d7 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c @@ -141,16 +141,18 @@ int load_avx2(void* p, const uint8_t* input, const uint8_t msg_len, const uint8_ return -1; } - int i = 0; - int k = 0; - for (; i < msg_len; i++) { - for (k = 0; k < ls; k++) { - vp->codeword[i].c[k] = input[i * ls + k]; + int ini = 0; + int node_size = SRSLTE_AVX2_B_SIZE; + for (int i = 0; i < msg_len * ls; i = i + ls) { + for (int k = 0; k < ls; k++) { + vp->codeword->c[ini + k] = input[i + k]; } - bzero(&(vp->codeword[i].c[k]), (SRSLTE_AVX2_B_SIZE - k) * sizeof(uint8_t)); + // this zero padding can be removed + bzero(&(vp->codeword->c[ini + ls]), (node_size - ls) * sizeof(uint8_t)); + ini = ini + node_size; } - bzero(vp->codeword + i, (cdwd_len - msg_len) * sizeof(__m256i)); + bzero(vp->codeword + msg_len, (cdwd_len - msg_len) * sizeof(__m256i)); return 0; } @@ -163,11 +165,12 @@ int return_codeword_avx2(void* p, uint8_t* output, const uint8_t cdwd_len, const return -1; } - int k = 0; - for (int i = 0; i < cdwd_len - 2; i++) { - for (k = 0; k < ls; k++) { - output[i * ls + k] = vp->codeword[i + 2].c[k]; + int ini = SRSLTE_AVX2_B_SIZE + SRSLTE_AVX2_B_SIZE; + for (int i = 0; i < (cdwd_len - 2) * ls; i = i + ls) { + for (int k = 0; k < ls; k++) { + output[i + k] = vp->codeword->c[ini + k]; } + ini = ini + SRSLTE_AVX2_B_SIZE; } return 0; } diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c index 35e1e2964..94785f956 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c @@ -22,7 +22,7 @@ /*! * \file ldpc_enc_avx2long.c * \brief Definition of the LDPC encoder inner functions (AVX2 version, large lifting size). - * \author David Gregoratti + * \author David Gregoratti and Jesus Gómez * \date 2020 * * \copyright Software Radio Systems Limited @@ -63,7 +63,8 @@ struct ldpc_enc_avx2long { __m256i* rotated_node; /*!< \brief To store rotated versions of the nodes. */ __m256i* rotated_node_to_free; /*!< \brief Auxiliary pointer to store rotated versions of the nodes with extra free memory of size SRSLTE_AVX2_B_SIZE previous to rotated_node */ - uint8_t n_subnodes; /*!< \brief Number of subnodes. */ + uint8_t n_subnodes; /*!< \brief Number of subnodes. */ + uint16_t node_size; /*!< \brief Size of a node in bytes. */ }; /*! @@ -109,6 +110,7 @@ void* create_ldpc_enc_avx2long(srslte_ldpc_encoder_t* q) } vp->rotated_node = &vp->rotated_node_to_free[1]; + vp->node_size = SRSLTE_AVX2_B_SIZE * vp->n_subnodes; return vp; } @@ -132,23 +134,19 @@ int load_avx2long(void* p, const uint8_t* input, const uint8_t msg_len, const ui return -1; } - int k = 0; - int j = 0; - int i = 0; - for (; i < msg_len; i++) { - for (j = 0; j < vp->n_subnodes - 1; j++) { - for (k = 0; k < SRSLTE_AVX2_B_SIZE; k++) { - vp->codeword[i * vp->n_subnodes + j].c[k] = input[i * ls + j * SRSLTE_AVX2_B_SIZE + k]; - } + int ini = 0; + int node_size = vp->node_size; + for (int i = 0; i < msg_len * ls; i = i + ls) { + for (int k = 0; k < ls; k++) { + vp->codeword->c[ini + k] = input[i + k]; } - // j is now equal to (vp->n_subnodes - 1) - for (k = 0; k < ls - j * SRSLTE_AVX2_B_SIZE; k++) { - vp->codeword[i * vp->n_subnodes + j].c[k] = input[i * ls + j * SRSLTE_AVX2_B_SIZE + k]; - } - bzero(&(vp->codeword[i * vp->n_subnodes + j].c[k]), (SRSLTE_AVX2_B_SIZE - k) * sizeof(uint8_t)); + // this zero padding can be removed + bzero(&(vp->codeword->c[ini + ls]), (node_size - ls) * sizeof(uint8_t)); + ini = ini + node_size; } - bzero(vp->codeword + i * vp->n_subnodes, (cdwd_len - msg_len) * vp->n_subnodes * sizeof(__m256i)); + bzero(vp->codeword + msg_len * vp->n_subnodes, (cdwd_len - msg_len) * vp->n_subnodes * sizeof(__m256i)); + return 0; } @@ -160,18 +158,12 @@ int return_codeword_avx2long(void* p, uint8_t* output, const uint8_t cdwd_len, c return -1; } - int k = 0; - int j = 0; - for (int i = 0; i < cdwd_len - 2; i++) { - for (j = 0; j < vp->n_subnodes - 1; j++) { - for (k = 0; k < SRSLTE_AVX2_B_SIZE; k++) { - output[i * ls + j * SRSLTE_AVX2_B_SIZE + k] = vp->codeword[(i + 2) * vp->n_subnodes + j].c[k]; - } - } - // j is now equal to vp->n_subndes-1 - for (k = 0; k < ls - j * SRSLTE_AVX2_B_SIZE; k++) { - output[i * ls + j * SRSLTE_AVX2_B_SIZE + k] = vp->codeword[(i + 2) * vp->n_subnodes + j].c[k]; + int ini = vp->node_size + vp->node_size; + for (int i = 0; i < (cdwd_len - 2) * ls; i = i + ls) { + for (int k = 0; k < ls; k++) { + output[i + k] = vp->codeword->c[ini + k]; } + ini = ini + vp->node_size; } return 0; } diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c new file mode 100644 index 000000000..88cb559e6 --- /dev/null +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c @@ -0,0 +1,361 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_enc_avx512.c + * \brief Definition of the LDPC encoder inner functions (AVX512 version, small (<64) lifting size). + * \author Jesus Gomez + * \date 2021 + * + * \copyright Software Radio Systems Limited + * + */ + +#include + +#include "../utils_avx512.h" +#include "ldpc_enc_all.h" +#include "srslte/phy/fec/ldpc/base_graph.h" +#include "srslte/phy/fec/ldpc/ldpc_encoder.h" +#include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" + +#ifdef LV_HAVE_AVX512 + +#include + +#include "ldpc_avx512_consts.h" + +/*! + * \brief Represents a node of the base factor graph. + */ +typedef union bg_node_avx512_t { + uint8_t c[SRSLTE_AVX512_B_SIZE]; /*!< Each base node may contain up to \ref SRSLTE_AVX512_B_SIZE lifted nodes. */ + __m512i v; /*!< All the lifted nodes of the current base node as a 512-bit line. */ +} bg_node_avx512_t; + +/*! + * \brief Inner registers for the optimized LDPC encoder. + */ +struct ldpc_enc_avx512 { + bg_node_avx512_t* codeword; /*!< \brief Contains the entire codeword, before puncturing. */ + bg_node_avx512_t* codeword_to_free; /*!< \brief Auxiliary pointer with a free memory of size SRSLTE_AVX512_B_SIZE + previous to codeword. */ + __m512i* aux; /*!< \brief Auxiliary register. */ + + __m512i* rotated_node; /*!< \brief To store rotated versions of the nodes. */ + __m512i* rotated_node_to_free; /*!< \brief Auxiliary pointer to store rotated versions of the nodes with extra free + memory of size SRSLTE_AVX512_B_SIZE previous to rotated_node */ +}; + +/*! + * Rotate the contents of a node towards the right by \b shift chars, that is the + * \b shift * 8 most significant bits become the least significant ones. + * \param[in] mem_addr Address to the node to rotate. + * \param[out] out The rotated node. + * \param[in] shift The order of the rotation in number of chars. + * \param[in] ls The size of the node (lifting size). + */ +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift2, uint16_t ls); + +void* create_ldpc_enc_avx512(srslte_ldpc_encoder_t* q) +{ + struct ldpc_enc_avx512* vp = NULL; + + if ((vp = malloc(sizeof(struct ldpc_enc_avx512))) == NULL) { + return NULL; + } + + if ((vp->codeword_to_free = srslte_vec_malloc((q->bgN + 1) * sizeof(bg_node_avx512_t))) == NULL) { + free(vp); + return NULL; + } + vp->codeword = &vp->codeword_to_free[1]; + + if ((vp->aux = srslte_vec_malloc(q->bgM * sizeof(__m512i))) == NULL) { + free(vp->codeword_to_free); + free(vp); + return NULL; + } + + if ((vp->rotated_node_to_free = srslte_vec_malloc((1 + 2) * sizeof(__m512i))) == NULL) { + free(vp->aux); + free(vp->codeword_to_free); + free(vp); + return NULL; + } + vp->rotated_node = &vp->rotated_node_to_free[1]; + + return vp; +} + +void delete_ldpc_enc_avx512(void* p) +{ + struct ldpc_enc_avx512* vp = p; + + if (vp != NULL) { + free(vp->rotated_node_to_free); + free(vp->aux); + free(vp->codeword_to_free); + free(vp); + } +} + +int load_avx512(void* p, const uint8_t* input, const uint8_t msg_len, const uint8_t cdwd_len, const uint16_t ls) +{ + struct ldpc_enc_avx512* vp = p; + + if (p == NULL) { + return -1; + } + + int i = 0; + int k = 0; + for (; i < msg_len; i++) { + for (k = 0; k < ls; k++) { + vp->codeword[i].c[k] = input[i * ls + k]; + } + // This zero padding might be remove + bzero(&(vp->codeword[i].c[k]), (SRSLTE_AVX512_B_SIZE - k) * sizeof(uint8_t)); + } + + bzero(vp->codeword + i, (cdwd_len - msg_len) * sizeof(__m512i)); + + return 0; +} + +int return_codeword_avx512(void* p, uint8_t* output, const uint8_t cdwd_len, const uint16_t ls) +{ + struct ldpc_enc_avx512* vp = p; + + if (p == NULL) { + return -1; + } + + int k = 0; + for (int i = 0; i < cdwd_len - 2; i++) { + for (k = 0; k < ls; k++) { + output[i * ls + k] = vp->codeword[i + 2].c[k]; + } + } + return 0; +} + +void encode_ext_region_avx512(srslte_ldpc_encoder_t* q, uint8_t n_layers) +{ + struct ldpc_enc_avx512* vp = q->ptr; + + int m = 0; + int skip = 0; + int k = 0; + + uint16_t* this_shift = NULL; + + __m512i tmp_epi8; + + // Encode the extended region. In case of puncturing or IR-HARQ, we could focus on + // specific check nodes instead of processing all of them from m = 4 to m = M - 1. + for (m = 4; m < n_layers; m++) { + skip = q->bgK + m; + + // the systematic part has already been computed + vp->codeword[skip].v = vp->aux[m]; + + // sum the contribution due to the high-rate region, with the proper circular shifts + for (k = 0; k < 4; k++) { + this_shift = q->pcm + q->bgK + k + m * q->bgN; + if (*this_shift != NO_CNCT) { + rotate_node_right(vp->codeword[q->bgK + k].c, &tmp_epi8, *this_shift, q->ls); + vp->codeword[skip].v = _mm512_xor_si512(vp->codeword[skip].v, tmp_epi8); + } + } + } +} + +void preprocess_systematic_bits_avx512(srslte_ldpc_encoder_t* q) +{ + struct ldpc_enc_avx512* vp = q->ptr; + int N = q->bgN; + int K = q->bgK; + int M = q->bgM; + int ls = q->ls; + uint16_t* pcm = q->pcm; + + int k = 0; + int m = 0; + uint16_t* this_shift = NULL; + + __m512i tmp_epi8; + + bzero(vp->aux, M * sizeof(__m512i)); + + // split the input message into K chunks of ls bits each and, for all chunks + for (k = 0; k < K; k++) { + // for all check nodes + // NB: if looking for performance you can do the following loop only over the high-rate + // region of the PCM (m=0,1,2,3) and over the check nodes that result in a transmitted + // coded bit after puncturing or IR-HARQ (see Deliverable D1 Section 3.4). + for (m = 0; m < M; m++) { + // entry of pcm corresponding to the current input chunk and the current check node + this_shift = pcm + k + m * N; + + // xor array aux[m] with a circularly shifted version of the current input chunk, unless + // the current check node and variable node are not connected. + if (*this_shift != NO_CNCT) { + rotate_node_right(vp->codeword[k].c, &tmp_epi8, *this_shift, ls); + + tmp_epi8 = _mm512_and_si512(tmp_epi8, _mm512_one_epi8); + vp->aux[m] = _mm512_xor_si512(vp->aux[m], tmp_epi8); + } + } + } +} + +void encode_high_rate_case1_avx512(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512* vp = q->ptr; + + int ls = q->ls; + + int skip0 = q->bgK; + int skip1 = q->bgK + 1; + int skip2 = q->bgK + 2; + int skip3 = q->bgK + 3; + + // first chunk of parity bits + vp->codeword[skip0].v = _mm512_xor_si512(vp->aux[0], vp->aux[1]); + vp->codeword[skip0].v = _mm512_xor_si512(vp->codeword[skip0].v, vp->aux[2]); + vp->codeword[skip0].v = _mm512_xor_si512(vp->codeword[skip0].v, vp->aux[3]); + + __m512i tmp_epi8; + rotate_node_right(vp->codeword[skip0].c, &tmp_epi8, 1, ls); + + // second chunk of parity bits + vp->codeword[skip1].v = _mm512_xor_si512(vp->aux[0], tmp_epi8); + // fourth chunk of parity bits + vp->codeword[skip3].v = _mm512_xor_si512(vp->aux[3], tmp_epi8); + // third chunk of parity bits + vp->codeword[skip2].v = _mm512_xor_si512(vp->aux[2], vp->codeword[skip3].v); +} + +void encode_high_rate_case2_avx512(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512* vp = q->ptr; + + int ls = q->ls; + + int skip0 = q->bgK; + int skip1 = q->bgK + 1; + int skip2 = q->bgK + 2; + int skip3 = q->bgK + 3; + + // first chunk of parity bits + + __m512i* tmp_epi8 = vp->rotated_node; + *tmp_epi8 = _mm512_xor_si512(vp->aux[0], vp->aux[1]); + *tmp_epi8 = _mm512_xor_si512(*tmp_epi8, vp->aux[2]); + *tmp_epi8 = _mm512_xor_si512(*tmp_epi8, vp->aux[3]); + + rotate_node_right((uint8_t*)tmp_epi8, &(vp->codeword[skip0].v), ls - 105 % ls, ls); + + // second chunk of parity bits + vp->codeword[skip1].v = _mm512_xor_si512(vp->aux[0], vp->codeword[skip0].v); + // fourth chunk of parity bits + vp->codeword[skip3].v = _mm512_xor_si512(vp->aux[3], vp->codeword[skip0].v); + // third chunk of parity bits + vp->codeword[skip2].v = _mm512_xor_si512(vp->aux[2], vp->codeword[skip3].v); +} + +void encode_high_rate_case3_avx512(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512* vp = q->ptr; + + int ls = q->ls; + + int skip0 = q->bgK; + int skip1 = q->bgK + 1; + int skip2 = q->bgK + 2; + int skip3 = q->bgK + 3; + + // first chunk of parity bits + __m512i* tmp_epi8 = vp->rotated_node; + *tmp_epi8 = _mm512_xor_si512(vp->aux[0], vp->aux[1]); + *tmp_epi8 = _mm512_xor_si512(*tmp_epi8, vp->aux[2]); + *tmp_epi8 = _mm512_xor_si512(*tmp_epi8, vp->aux[3]); + + rotate_node_right((uint8_t*)tmp_epi8, &(vp->codeword[skip0].v), ls - 1, ls); + + // second chunk of parity bits + vp->codeword[skip1].v = _mm512_xor_si512(vp->aux[0], vp->codeword[skip0].v); + // third chunk of parity bits + vp->codeword[skip2].v = _mm512_xor_si512(vp->aux[1], vp->codeword[skip1].v); + // fourth chunk of parity bits + vp->codeword[skip3].v = _mm512_xor_si512(vp->aux[3], vp->codeword[skip0].v); +} + +void encode_high_rate_case4_avx512(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512* vp = q->ptr; + + int ls = q->ls; + + int skip0 = q->bgK; + int skip1 = q->bgK + 1; + int skip2 = q->bgK + 2; + int skip3 = q->bgK + 3; + + // first chunk of parity bits + vp->codeword[skip0].v = _mm512_xor_si512(vp->aux[0], vp->aux[1]); + vp->codeword[skip0].v = _mm512_xor_si512(vp->codeword[skip0].v, vp->aux[2]); + vp->codeword[skip0].v = _mm512_xor_si512(vp->codeword[skip0].v, vp->aux[3]); + + __m512i tmp_epi8; + rotate_node_right(vp->codeword[skip0].c, &tmp_epi8, 1, ls); + + // second chunk of parity bits + vp->codeword[skip1].v = _mm512_xor_si512(vp->aux[0], tmp_epi8); + // third chunk of parity bits + vp->codeword[skip2].v = _mm512_xor_si512(vp->aux[1], vp->codeword[skip1].v); + // fourth chunk of parity bits + vp->codeword[skip3].v = _mm512_xor_si512(vp->aux[3], tmp_epi8); +} + +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift2, uint16_t ls) +{ + const __m512i MZERO = _mm512_set1_epi8(0); + + uint16_t shift = 0; + uint16_t _shift = 0; + uint64_t mask1 = 0; + uint64_t mask2 = 0; + + if (this_shift2 == 0) { + out[0] = _mm512_loadu_si512(mem_addr); + } else { // if the last is broken, take _shift bits from the end and "shift" bits from the begin. + + _shift = ls - this_shift2; + shift = SRSLTE_AVX512_B_SIZE - _shift; + + mask1 = (1ULL << _shift) - 1; // i.e. 000001111 _shift =4 + mask2 = (1ULL << shift) - 1; + mask2 = mask2 << _shift; // i.e. 000110000 shift = 2, _shift = 4 + + out[0] = _mm512_mask_loadu_epi8(MZERO, mask1, mem_addr + this_shift2); + out[0] = _mm512_mask_loadu_epi8(out[0], mask2, mem_addr - _shift); + } +} + +#endif // LV_HAVE_AVX512 diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c new file mode 100644 index 000000000..76f69ba93 --- /dev/null +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c @@ -0,0 +1,407 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_enc_avx512long.c + * \brief Definition of the LDPC encoder inner functions (AVX512 version, large (>64) lifting size). + * \author Jesus Gomez + * \date 2021 + * + * \copyright Software Radio Systems Limited + * + */ + +#include + +#include "../utils_avx512.h" +#include "ldpc_enc_all.h" +#include "srslte/phy/fec/ldpc/base_graph.h" +#include "srslte/phy/fec/ldpc/ldpc_encoder.h" +#include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" + +#ifdef LV_HAVE_AVX512 + +#include + +#include "ldpc_avx512_consts.h" + +/*! + * \brief Represents a node of the base factor graph. + */ +typedef union bg_node_avx512_t { + uint8_t c[SRSLTE_AVX512_B_SIZE]; /*!< Each base node may contain up to \ref SRSLTE_AVX512_B_SIZE lifted nodes. */ + __m512i v; /*!< All the lifted nodes of the current base node as a 512-bit line. */ +} bg_node_avx512_t; + +/*! + * \brief Inner registers for the optimized LDPC encoder. + */ +struct ldpc_enc_avx512long { + bg_node_avx512_t* codeword; /*!< \brief Contains the entire codeword, before puncturing. */ + bg_node_avx512_t* codeword_to_free; /*!< \brief Auxiliary pointer with a free memory of size SRSLTE_AVX512_B_SIZE + previous to codeword. */ + __m512i* aux; /*!< \brief Auxiliary register. */ + __m512i* rotated_node; /*!< \brief To store rotated versions of the nodes. */ + __m512i* rotated_node_to_free; /*!< \brief Auxiliary pointer to store rotated versions of the nodes with extra free + memory of size SRSLTE_AVX512_B_SIZE previous to rotated_node */ + uint8_t n_subnodes; /*!< \brief Number of subnodes. */ + uint16_t node_size; /*!> \brief Size of a node in bytes. */ +}; + +/*! + * Rotate the contents of a node towards the right by \b shift chars, that is the + * \b shift * 8 most significant bits become the least significant ones. + * \param[in] mem_addr The address to the node to rotate. + * \param[out] out The rotated node. + * \param[in] shift The order of the rotation in number of chars. + * \param[in] ls The size of the node (lifting size). + */ +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift2, uint16_t ls); + +void* create_ldpc_enc_avx512long(srslte_ldpc_encoder_t* q) +{ + struct ldpc_enc_avx512long* vp = NULL; + + if ((vp = malloc(sizeof(struct ldpc_enc_avx512long))) == NULL) { + return NULL; + } + + int left_out = q->ls % SRSLTE_AVX512_B_SIZE; + vp->n_subnodes = q->ls / SRSLTE_AVX512_B_SIZE + (left_out > 0); + + if ((vp->codeword_to_free = srslte_vec_malloc((q->bgN * vp->n_subnodes + 1) * sizeof(bg_node_avx512_t))) == NULL) { + free(vp); + return NULL; + } + vp->codeword = &vp->codeword_to_free[1]; + + if ((vp->aux = srslte_vec_malloc(q->bgM * vp->n_subnodes * sizeof(__m512i))) == NULL) { + free(vp->codeword_to_free); + free(vp); + return NULL; + } + + if ((vp->rotated_node_to_free = srslte_vec_malloc((vp->n_subnodes + 2) * sizeof(__m512i))) == NULL) { + free(vp->aux); + free(vp->codeword_to_free); + free(vp); + return NULL; + } + vp->rotated_node = &vp->rotated_node_to_free[1]; + + vp->node_size = SRSLTE_AVX512_B_SIZE * vp->n_subnodes; + return vp; +} + +void delete_ldpc_enc_avx512long(void* p) +{ + struct ldpc_enc_avx512long* vp = p; + + if (vp != NULL) { + free(vp->rotated_node_to_free); + free(vp->aux); + free(vp->codeword_to_free); + free(vp); + } +} + +int load_avx512long(void* p, const uint8_t* input, const uint8_t msg_len, const uint8_t cdwd_len, const uint16_t ls) +{ + struct ldpc_enc_avx512long* vp = p; + + if (p == NULL) { + return -1; + } + + int ini = 0; + int node_size = vp->node_size; + for (int i = 0; i < msg_len * ls; i = i + ls) { + for (int k = 0; k < ls; k++) { + vp->codeword->c[ini + k] = input[i + k]; + } + // this zero padding is not really necessary + bzero(&(vp->codeword->c[ini + ls]), (node_size - ls) * sizeof(uint8_t)); + ini = ini + node_size; + } + + bzero(vp->codeword + msg_len * vp->n_subnodes, (cdwd_len - msg_len) * vp->n_subnodes * sizeof(__m512i)); + + return 0; +} + +int return_codeword_avx512long(void* p, uint8_t* output, const uint8_t cdwd_len, const uint16_t ls) +{ + struct ldpc_enc_avx512long* vp = p; + + if (p == NULL) { + return -1; + } + + int ini = vp->node_size + vp->node_size; + for (int i = 0; i < (cdwd_len - 2) * ls; i = i + ls) { + for (int k = 0; k < ls; k++) { + output[i + k] = vp->codeword->c[ini + k]; + } + ini = ini + vp->node_size; + } + return 0; +} + +void encode_ext_region_avx512long(srslte_ldpc_encoder_t* q, uint8_t n_layers) +{ + struct ldpc_enc_avx512long* vp = q->ptr; + int m = 0; + int skip = 0; + int k = 0; + int j = 0; + + uint16_t* this_shift = NULL; + + // Encode the extended region. In case of puncturing or IR-HARQ, we could focus on + // specific check nodes instead of processing all of them from m = 4 to m = M - 1. + for (m = 4; m < n_layers; m++) { + skip = (q->bgK + m) * vp->n_subnodes; + + // the systematic part has already been computed + for (j = 0; j < vp->n_subnodes; j++) { + vp->codeword[skip + j].v = vp->aux[m * vp->n_subnodes + j]; + } + + // sum the contribution due to the high-rate region, with the proper circular shifts + for (k = 0; k < 4; k++) { + this_shift = q->pcm + q->bgK + k + m * q->bgN; + + // xor array aux[m] with a circularly shifted version of the current input chunk, unless + // the current check node and variable node are not connected. + if (*this_shift != NO_CNCT) { + rotate_node_right(vp->codeword[(q->bgK + k) * vp->n_subnodes].c, vp->rotated_node, *this_shift, q->ls); + for (j = 0; j < vp->n_subnodes; j++) { + vp->codeword[skip + j].v = _mm512_xor_si512(vp->codeword[skip + j].v, vp->rotated_node[j]); + } + } + } + } +} + +void preprocess_systematic_bits_avx512long(srslte_ldpc_encoder_t* q) +{ + struct ldpc_enc_avx512long* vp = q->ptr; + + int N = q->bgN; + int K = q->bgK; + int M = q->bgM; + int ls = q->ls; + uint16_t* pcm = q->pcm; + + int k = 0; + int m = 0; + int j = 0; + uint16_t* this_shift = NULL; + + __m512i tmp_epi8_avx512; + + bzero(vp->aux, M * vp->n_subnodes * sizeof(__m512i)); + + // split the input message into K chunks of ls bits each and, for all chunks + for (k = 0; k < K; k++) { + // for all check nodes + // NB: if looking for performance you can do the following loop only over the high-rate + // region of the PCM (m=0,1,2,3) and over the check nodes that result in a transmitted + // coded bit after puncturing or IR-HARQ (see Deliverable D1 Section 3.4). + + for (m = 0; m < M; m++) { + // entry of pcm corresponding to the current input chunk and the current check node + this_shift = pcm + k + m * N; + + // xor array aux[m] with a circularly shifted version of the current input chunk, unless + // the current check node and variable node are not connected. + if (*this_shift != NO_CNCT) { + rotate_node_right(vp->codeword[k * vp->n_subnodes].c, vp->rotated_node, *this_shift, ls); + + for (j = 0; j < vp->n_subnodes; j++) { + tmp_epi8_avx512 = _mm512_and_si512(vp->rotated_node[j], _mm512_one_epi8); + vp->aux[m * vp->n_subnodes + j] = _mm512_xor_si512(vp->aux[m * vp->n_subnodes + j], tmp_epi8_avx512); + } + } + } // m + } // k +} + +void encode_high_rate_case1_avx512long(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512long* vp = q->ptr; + + int ls = q->ls; + int j = 0; + + int skip0 = q->bgK * vp->n_subnodes; + int skip1 = (q->bgK + 1) * vp->n_subnodes; + int skip2 = (q->bgK + 2) * vp->n_subnodes; + int skip3 = (q->bgK + 3) * vp->n_subnodes; + + // first chunk of parity bits + for (j = 0; j < vp->n_subnodes; j++) { + vp->codeword[skip0 + j].v = _mm512_xor_si512(vp->aux[j], vp->aux[vp->n_subnodes + j]); + vp->codeword[skip0 + j].v = _mm512_xor_si512(vp->codeword[skip0 + j].v, vp->aux[2 * vp->n_subnodes + j]); + vp->codeword[skip0 + j].v = _mm512_xor_si512(vp->codeword[skip0 + j].v, vp->aux[3 * vp->n_subnodes + j]); + } + + rotate_node_right(vp->codeword[skip0].c, vp->rotated_node, 1, ls); + for (j = 0; j < vp->n_subnodes; j++) { + // second chunk of parity bits + vp->codeword[skip1 + j].v = _mm512_xor_si512(vp->aux[j], vp->rotated_node[j]); + // fourth chunk of parity bits + vp->codeword[skip3 + j].v = _mm512_xor_si512(vp->aux[3 * vp->n_subnodes + j], vp->rotated_node[j]); + // third chunk of parity bits + vp->codeword[skip2 + j].v = _mm512_xor_si512(vp->aux[2 * vp->n_subnodes + j], vp->codeword[skip3 + j].v); + } +} + +void encode_high_rate_case2_avx512long(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512long* vp = q->ptr; + + int ls = q->ls; + int j = 0; + + int skip0 = q->bgK * vp->n_subnodes; + int skip1 = (q->bgK + 1) * vp->n_subnodes; + int skip2 = (q->bgK + 2) * vp->n_subnodes; + int skip3 = (q->bgK + 3) * vp->n_subnodes; + + // first chunk of parity bits + for (j = 0; j < vp->n_subnodes; j++) { + vp->rotated_node[j] = _mm512_xor_si512(vp->aux[j], vp->aux[vp->n_subnodes + j]); + vp->rotated_node[j] = _mm512_xor_si512(vp->rotated_node[j], vp->aux[2 * vp->n_subnodes + j]); + vp->rotated_node[j] = _mm512_xor_si512(vp->rotated_node[j], vp->aux[3 * vp->n_subnodes + j]); + } + rotate_node_right((uint8_t*)vp->rotated_node, &(vp->codeword[skip0].v), ls - 105 % ls, ls); + + for (j = 0; j < vp->n_subnodes; j++) { + // second chunk of parity bits + vp->codeword[skip1 + j].v = _mm512_xor_si512(vp->aux[j], vp->codeword[skip0 + j].v); + // fourth chunk of parity bits + vp->codeword[skip3 + j].v = _mm512_xor_si512(vp->aux[3 * vp->n_subnodes + j], vp->codeword[skip0 + j].v); + // third chunk of parity bits + vp->codeword[skip2 + j].v = _mm512_xor_si512(vp->aux[2 * vp->n_subnodes + j], vp->codeword[skip3 + j].v); + } +} + +void encode_high_rate_case3_avx512long(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512long* vp = q->ptr; + + int ls = q->ls; + int j = 0; + + int skip0 = q->bgK * vp->n_subnodes; + int skip1 = (q->bgK + 1) * vp->n_subnodes; + int skip2 = (q->bgK + 2) * vp->n_subnodes; + int skip3 = (q->bgK + 3) * vp->n_subnodes; + + // first chunk of parity bits + for (j = 0; j < vp->n_subnodes; j++) { + vp->rotated_node[j] = _mm512_xor_si512(vp->aux[j], vp->aux[vp->n_subnodes + j]); + vp->rotated_node[j] = _mm512_xor_si512(vp->rotated_node[j], vp->aux[2 * vp->n_subnodes + j]); + vp->rotated_node[j] = _mm512_xor_si512(vp->rotated_node[j], vp->aux[3 * vp->n_subnodes + j]); + } + rotate_node_right((uint8_t*)vp->rotated_node, &(vp->codeword[skip0].v), ls - 1, ls); + + for (j = 0; j < vp->n_subnodes; j++) { + // second chunk of parity bits + vp->codeword[skip1 + j].v = _mm512_xor_si512(vp->aux[j], vp->codeword[skip0 + j].v); + // third chunk of parity bits + vp->codeword[skip2 + j].v = _mm512_xor_si512(vp->aux[vp->n_subnodes + j], vp->codeword[skip1 + j].v); + // fourth chunk of parity bits + vp->codeword[skip3 + j].v = _mm512_xor_si512(vp->aux[3 * vp->n_subnodes + j], vp->codeword[skip0 + j].v); + } +} + +void encode_high_rate_case4_avx512long(void* o) +{ + srslte_ldpc_encoder_t* q = o; + struct ldpc_enc_avx512long* vp = q->ptr; + + int ls = q->ls; + int j = 0; + + int skip0 = q->bgK * vp->n_subnodes; + int skip1 = (q->bgK + 1) * vp->n_subnodes; + int skip2 = (q->bgK + 2) * vp->n_subnodes; + int skip3 = (q->bgK + 3) * vp->n_subnodes; + + // first chunk of parity bits + for (j = 0; j < vp->n_subnodes; j++) { + vp->codeword[skip0 + j].v = _mm512_xor_si512(vp->aux[j], vp->aux[vp->n_subnodes + j]); + vp->codeword[skip0 + j].v = _mm512_xor_si512(vp->codeword[skip0 + j].v, vp->aux[2 * vp->n_subnodes + j]); + vp->codeword[skip0 + j].v = _mm512_xor_si512(vp->codeword[skip0 + j].v, vp->aux[3 * vp->n_subnodes + j]); + } + + rotate_node_right(vp->codeword[skip0].c, vp->rotated_node, 1, ls); + + for (j = 0; j < vp->n_subnodes; j++) { + // second chunk of parity bits + vp->codeword[skip1 + j].v = _mm512_xor_si512(vp->aux[j], vp->rotated_node[j]); + // third chunk of parity bits + vp->codeword[skip2 + j].v = _mm512_xor_si512(vp->aux[vp->n_subnodes + j], vp->codeword[skip1 + j].v); + // fourth chunk of parity bits + vp->codeword[skip3 + j].v = _mm512_xor_si512(vp->aux[3 * vp->n_subnodes + j], vp->rotated_node[j]); + } +} + +static void rotate_node_right(const uint8_t* mem_addr, __m512i* out, uint16_t this_shift2, uint16_t ls) +{ + uint16_t shift = 0; + uint16_t _shift = 0; + uint64_t mask1 = 0; + uint64_t mask2 = 0; + + const __m512i MZERO = _mm512_set1_epi8(0); + + // the part in the middle - we simply copy. + int j = 0; + int jj = 0; + + // copy full avx512 registers from this_shift_2 + for (j = this_shift2; j <= ls - SRSLTE_AVX512_B_SIZE; j = j + SRSLTE_AVX512_B_SIZE) { + out[jj] = _mm512_loadu_si512(mem_addr + j); + jj = jj + 1; + } + + // if the last is broken, take _shift bits from the end and "shift" bits from the begin. + if (ls > j) { + _shift = ls - j; + shift = SRSLTE_AVX512_B_SIZE - _shift; + + mask1 = (1ULL << _shift) - 1; // i.e. 000001111 _shift =4 + mask2 = (1ULL << shift) - 1; + mask2 = mask2 << _shift; // i.e. 000110000 shift = 2, _shift = 4 + + out[jj] = _mm512_mask_loadu_epi8(MZERO, mask1, mem_addr + j); + out[jj] = _mm512_mask_loadu_epi8(out[jj], mask2, mem_addr - _shift); + + jj = jj + 1; + } + + // copy full avx512 registers from the start of mem_addr, fill with zeros after out is filled with ls + for (j = shift; j < this_shift2; j = j + SRSLTE_AVX512_B_SIZE) { + out[jj] = _mm512_loadu_si512(mem_addr + j); // the exes is filled with something arbitrary + + jj = jj + 1; + } +} + +#endif // LV_HAVE_AVX512 diff --git a/lib/src/phy/fec/ldpc/ldpc_encoder.c b/lib/src/phy/fec/ldpc/ldpc_encoder.c index 1ab8cc766..ed0c20ab3 100644 --- a/lib/src/phy/fec/ldpc/ldpc_encoder.c +++ b/lib/src/phy/fec/ldpc/ldpc_encoder.c @@ -22,7 +22,7 @@ /*! * \file ldpc_encoder.c * \brief Definition of the LDPC encoder. - * \author David Gregoratti + * \author David Gregoratti and Jesus Gomez * \date 2020 * * \copyright Software Radio Systems Limited @@ -32,6 +32,7 @@ #include #include "../utils_avx2.h" +#include "../utils_avx512.h" #include "ldpc_enc_all.h" #include "srslte/phy/fec/ldpc/base_graph.h" #include "srslte/phy/fec/ldpc/ldpc_encoder.h" @@ -56,7 +57,7 @@ static int encode_c(void* o, const uint8_t* input, uint8_t* output, uint32_t inp srslte_ldpc_encoder_t* q = o; if (input_length / q->bgK != q->ls) { - perror("Dimension mismatch.\n"); + ERROR("Dimension mismatch."); return -1; } // it must be smaller than the codeword size @@ -66,13 +67,13 @@ static int encode_c(void* o, const uint8_t* input, uint8_t* output, uint32_t inp // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } @@ -101,7 +102,7 @@ static int init_c(srslte_ldpc_encoder_t* q) int ls_index = get_ls_index(q->ls); if (ls_index == VOID_LIFTSIZE) { - ERROR("Invalid lifting size %d\n", q->ls); + ERROR("Invalid lifting size %d", q->ls); return -1; } @@ -114,7 +115,7 @@ static int init_c(srslte_ldpc_encoder_t* q) } else if (q->bg == BG2 && (ls_index == 3 || ls_index == 7)) { q->encode_high_rate = encode_high_rate_case4; } else { - ERROR("Invalid lifting size %d and/or Base Graph %d\n", q->ls, q->bg + 1); + ERROR("Invalid lifting size %d and/or Base Graph %d", q->ls, q->bg + 1); return -1; } @@ -151,7 +152,7 @@ static int encode_avx2(void* o, const uint8_t* input, uint8_t* output, uint32_t srslte_ldpc_encoder_t* q = o; if (input_length / q->bgK != q->ls) { - perror("Dimension mismatch.\n"); + ERROR("Dimension mismatch."); return -1; } @@ -162,13 +163,13 @@ static int encode_avx2(void* o, const uint8_t* input, uint8_t* output, uint32_t // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } @@ -195,7 +196,7 @@ static int init_avx2(srslte_ldpc_encoder_t* q) int ls_index = get_ls_index(q->ls); if (ls_index == VOID_LIFTSIZE) { - ERROR("Invalid lifting size %d\n", q->ls); + ERROR("Invalid lifting size %d", q->ls); return -1; } @@ -208,14 +209,14 @@ static int init_avx2(srslte_ldpc_encoder_t* q) } else if (q->bg == BG2 && (ls_index == 3 || ls_index == 7)) { q->encode_high_rate_avx2 = encode_high_rate_case4_avx2; } else { - ERROR("Invalid lifting size %d and/or Base Graph %d\n", q->ls, q->bg + 1); + ERROR("Invalid lifting size %d and/or Base Graph %d", q->ls, q->bg + 1); return -1; } q->free = free_enc_avx2; if ((q->ptr = create_ldpc_enc_avx2(q)) == NULL) { - perror("Create_ldpc_enc\n"); + ERROR("Create_ldpc_enc"); free_enc_avx2(q); return -1; } @@ -244,7 +245,7 @@ encode_avx2long(void* o, const uint8_t* input, uint8_t* output, uint32_t input_l srslte_ldpc_encoder_t* q = o; if (input_length / q->bgK != q->ls) { - perror("Dimension mismatch.\n"); + ERROR("Dimension mismatch."); return -1; } @@ -255,13 +256,13 @@ encode_avx2long(void* o, const uint8_t* input, uint8_t* output, uint32_t input_l // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, // 2 variable nodes are systematically punctured by the encoder. if (cdwd_rm_length < (q->bgK + 2) * q->ls) { - // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region.\n"); + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); cdwd_rm_length = (q->bgK + 2) * q->ls; // return -1; } if (cdwd_rm_length % q->ls) { cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; - // ERROR("The rate-matched codeword length should be a multiple of the lifting size.\n"); + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); // return -1; } load_avx2long(q->ptr, input, q->bgK, q->bgN, q->ls); @@ -287,7 +288,7 @@ static int init_avx2long(srslte_ldpc_encoder_t* q) int ls_index = get_ls_index(q->ls); if (ls_index == VOID_LIFTSIZE) { - ERROR("Invalid lifting size %d\n", q->ls); + ERROR("Invalid lifting size %d", q->ls); return -1; } @@ -300,14 +301,14 @@ static int init_avx2long(srslte_ldpc_encoder_t* q) } else if (q->bg == BG2 && (ls_index == 3 || ls_index == 7)) { q->encode_high_rate_avx2 = encode_high_rate_case4_avx2long; } else { - ERROR("Invalid lifting size %d and/or Base Graph %d\n", q->ls, q->bg + 1); + ERROR("Invalid lifting size %d and/or Base Graph %d", q->ls, q->bg + 1); return -1; } q->free = free_enc_avx2long; if ((q->ptr = create_ldpc_enc_avx2long(q)) == NULL) { - perror("Create_ldpc_enc\n"); + ERROR("Create_ldpc_enc"); free_enc_avx2long(q); return -1; } @@ -319,12 +320,199 @@ static int init_avx2long(srslte_ldpc_encoder_t* q) #endif +#ifdef LV_HAVE_AVX512 + +/*! Carries out the actual destruction of the memory allocated to the encoder. */ +static void free_enc_avx512(void* o) +{ + srslte_ldpc_encoder_t* q = o; + if (q->pcm) { + free(q->pcm); + } + if (q->ptr) { + delete_ldpc_enc_avx512(q->ptr); + } +} + +/*! Carries out the actual encoding with an optimized encoder. */ +static int encode_avx512(void* o, const uint8_t* input, uint8_t* output, uint32_t input_length, uint32_t cdwd_rm_length) +{ + srslte_ldpc_encoder_t* q = o; + + if (input_length / q->bgK != q->ls) { + ERROR("Dimension mismatch."); + return -1; + } + + // it must be smaller than the codeword size + if (cdwd_rm_length > q->liftN - 2 * q->ls) { + cdwd_rm_length = q->liftN - 2 * q->ls; + } + // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, + // 2 variable nodes are systematically punctured by the encoder. + if (cdwd_rm_length < (q->bgK + 2) * q->ls) { + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); + cdwd_rm_length = (q->bgK + 2) * q->ls; + // return -1; + } + if (cdwd_rm_length % q->ls) { + cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); + // return -1; + } + + load_avx512(q->ptr, input, q->bgK, q->bgN, q->ls); + + preprocess_systematic_bits_avx512(q); + + q->encode_high_rate_avx512(q); + + // When computing the number of layers, we need to recall that the standard always removes + // the first two variable nodes from the final codeword. + uint8_t n_layers = cdwd_rm_length / q->ls - q->bgK + 2; + + encode_ext_region_avx512(q, n_layers); + + return_codeword_avx512(q->ptr, output, n_layers + q->bgK, q->ls); + + return 0; +} + +/*! Initializes an optimized encoder. */ +static int init_avx512(srslte_ldpc_encoder_t* q) +{ + int ls_index = get_ls_index(q->ls); + + if (ls_index == VOID_LIFTSIZE) { + ERROR("Invalid lifting size %d", q->ls); + return -1; + } + + if (q->bg == BG1 && ls_index != 6) { + q->encode_high_rate_avx512 = encode_high_rate_case1_avx512; + } else if (q->bg == BG1 && ls_index == 6) { + q->encode_high_rate_avx512 = encode_high_rate_case2_avx512; + } else if (q->bg == BG2 && ls_index != 3 && ls_index != 7) { + q->encode_high_rate_avx512 = encode_high_rate_case3_avx512; + } else if (q->bg == BG2 && (ls_index == 3 || ls_index == 7)) { + q->encode_high_rate_avx512 = encode_high_rate_case4_avx512; + } else { + ERROR("Invalid lifting size %d and/or Base Graph %d", q->ls, q->bg + 1); + return -1; + } + + q->free = free_enc_avx512; + + if ((q->ptr = create_ldpc_enc_avx512(q)) == NULL) { + ERROR("Create_ldpc_enc"); + free_enc_avx512(q); + return -1; + } + + q->encode = encode_avx512; + + return 0; +} + +/*! Carries out the actual destruction of the memory allocated to the encoder. */ +static void free_enc_avx512long(void* o) +{ + srslte_ldpc_encoder_t* q = o; + if (q->pcm) { + free(q->pcm); + } + if (q->ptr) { + delete_ldpc_enc_avx512long(q->ptr); + } +} + +/*! Carries out the actual encoding with an optimized encoder. */ +static int +encode_avx512long(void* o, const uint8_t* input, uint8_t* output, uint32_t input_length, uint32_t cdwd_rm_length) +{ + srslte_ldpc_encoder_t* q = o; + + if (input_length / q->bgK != q->ls) { + ERROR("Dimension mismatch."); + return -1; + } + + // it must be smaller than the codeword size + if (cdwd_rm_length > q->liftN - 2 * q->ls) { + cdwd_rm_length = q->liftN - 2 * q->ls; + } + // We need at least q->bgK + 4 variable nodes to cover the high-rate region. However, + // 2 variable nodes are systematically punctured by the encoder. + if (cdwd_rm_length < (q->bgK + 2) * q->ls) { + // ERROR("The rate-matched codeword should have a length at least equal to the high-rate region."); + cdwd_rm_length = (q->bgK + 2) * q->ls; + // return -1; + } + if (cdwd_rm_length % q->ls) { + cdwd_rm_length = (cdwd_rm_length / q->ls + 1) * q->ls; + // ERROR("The rate-matched codeword length should be a multiple of the lifting size."); + // return -1; + } + load_avx512long(q->ptr, input, q->bgK, q->bgN, q->ls); + + preprocess_systematic_bits_avx512long(q); + + q->encode_high_rate_avx512(q); + + // When computing the number of layers, we need to recall that the standard always removes + // the first two variable nodes from the final codeword. + uint8_t n_layers = cdwd_rm_length / q->ls - q->bgK + 2; + + encode_ext_region_avx512long(q, n_layers); + + return_codeword_avx512long(q->ptr, output, n_layers + q->bgK, q->ls); + + return 0; +} + +/*! Initializes an optimized encoder. */ +static int init_avx512long(srslte_ldpc_encoder_t* q) +{ + int ls_index = get_ls_index(q->ls); + + if (ls_index == VOID_LIFTSIZE) { + ERROR("Invalid lifting size %d", q->ls); + return -1; + } + + if (q->bg == BG1 && ls_index != 6) { + q->encode_high_rate_avx512 = encode_high_rate_case1_avx512long; + } else if (q->bg == BG1 && ls_index == 6) { + q->encode_high_rate_avx512 = encode_high_rate_case2_avx512long; + } else if (q->bg == BG2 && ls_index != 3 && ls_index != 7) { + q->encode_high_rate_avx512 = encode_high_rate_case3_avx512long; + } else if (q->bg == BG2 && (ls_index == 3 || ls_index == 7)) { + q->encode_high_rate_avx512 = encode_high_rate_case4_avx512long; + } else { + ERROR("Invalid lifting size %d and/or Base Graph %d", q->ls, q->bg + 1); + return -1; + } + + q->free = free_enc_avx512long; + + if ((q->ptr = create_ldpc_enc_avx512long(q)) == NULL) { + ERROR("Create_ldpc_enc"); + free_enc_avx512long(q); + return -1; + } + + q->encode = encode_avx512long; + + return 0; +} + +#endif + int srslte_ldpc_encoder_init(srslte_ldpc_encoder_t* q, srslte_ldpc_encoder_type_t type, srslte_basegraph_t bg, uint16_t ls) { - switch (bg) { case BG1: q->bgN = BG1Nfull; @@ -335,7 +523,7 @@ int srslte_ldpc_encoder_init(srslte_ldpc_encoder_t* q, q->bgM = BG2M; break; default: - ERROR("Base Graph BG%d does not exist\n", bg + 1); + ERROR("Base Graph BG%d does not exist", bg + 1); return -1; } q->bg = bg; @@ -367,6 +555,14 @@ int srslte_ldpc_encoder_init(srslte_ldpc_encoder_t* q, return init_avx2long(q); } #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + case SRSLTE_LDPC_ENCODER_AVX512: + if (ls <= SRSLTE_AVX512_B_SIZE) { + return init_avx512(q); + } else { + return init_avx512long(q); + } +#endif // LV_HAVE_AVX512 default: return -1; } diff --git a/lib/src/phy/fec/ldpc/ldpc_rm.c b/lib/src/phy/fec/ldpc/ldpc_rm.c index b64a8f7a2..74b491ce0 100644 --- a/lib/src/phy/fec/ldpc/ldpc_rm.c +++ b/lib/src/phy/fec/ldpc/ldpc_rm.c @@ -130,13 +130,13 @@ static int init_rm(srslte_ldpc_rm_t* p, // check E smaller than MAXE if ((E > MAXE) != 0) { // - ERROR("Wrong RM codeword length (E) = %d. It must be smaller than %d for base graph %d\n", E, MAXE, bg + 1); + ERROR("Wrong RM codeword length (E) = %d. It must be smaller than %d for base graph %d", E, MAXE, bg + 1); return -1; } // check out_len is multiple of mod_order if ((E % mod_order) != 0) { // N can only be a multiple of either BASEN[0] or BASEN[1], but not both - ERROR("Wrong RM codeword length (E) = %d. It must be a multiple of modulation order = %d\n", E, mod_order); + ERROR("Wrong RM codeword length (E) = %d. It must be a multiple of modulation order = %d", E, mod_order); return -1; } @@ -429,7 +429,6 @@ int srslte_ldpc_rm_tx_init(srslte_ldpc_rm_t* p) int srslte_ldpc_rm_rx_init_f(srslte_ldpc_rm_t* p) { - if (p == NULL) { return -1; } @@ -615,7 +614,6 @@ int srslte_ldpc_rm_rx_f(srslte_ldpc_rm_t* q, const srslte_mod_t mod_type, const uint32_t Nref) { - if (init_rm(q, E, F, bg, ls, rv, mod_type, Nref) != 0) { perror("rate matcher init"); exit(-1); @@ -647,7 +645,6 @@ int srslte_ldpc_rm_rx_s(srslte_ldpc_rm_t* q, const srslte_mod_t mod_type, const uint32_t Nref) { - if (init_rm(q, E, F, bg, ls, rv, mod_type, Nref) != 0) { perror("rate matcher init"); exit(-1); @@ -680,7 +677,6 @@ int srslte_ldpc_rm_rx_c(srslte_ldpc_rm_t* q, const srslte_mod_t mod_type, const uint32_t Nref) { - if (init_rm(q, E, F, bg, ls, rv, mod_type, Nref) != 0) { perror("rate matcher init"); exit(-1); diff --git a/lib/src/phy/fec/ldpc/test/CMakeLists.txt b/lib/src/phy/fec/ldpc/test/CMakeLists.txt index 513450d1a..e08f445b4 100644 --- a/lib/src/phy/fec/ldpc/test/CMakeLists.txt +++ b/lib/src/phy/fec/ldpc/test/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "lib;phy;fec;ldpc") + add_executable(ldpc_enc_test ldpc_enc_test.c) target_link_libraries(ldpc_enc_test srslte_phy) @@ -47,10 +49,18 @@ if(HAVE_AVX2) target_link_libraries(ldpc_dec_avx2_test srslte_phy) endif(HAVE_AVX2) +if(HAVE_AVX512) + add_executable(ldpc_enc_avx512_test ldpc_enc_avx512_test.c) + target_link_libraries(ldpc_enc_avx512_test srslte_phy) + + add_executable(ldpc_dec_avx512_test ldpc_dec_avx512_test.c) + target_link_libraries(ldpc_dec_avx512_test srslte_phy) +endif(HAVE_AVX512) + ### Test LDPC libs function(ldpc_unit_tests) foreach(i IN LISTS ARGN) - add_test(NAME ${test_name}-LS${i} COMMAND ${test_command} -l${i} + add_nr_test(NAME ${test_name}-LS${i} COMMAND ${test_command} -l${i} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) endforeach() @@ -83,6 +93,55 @@ set(test_name LDPC-DEC-BG2) set(test_command ldpc_dec_test -b2) ldpc_unit_tests(${lifting_sizes}) + +if (HAVE_AVX2) + +set(test_name LDPC-ENC-AVX2-BG1) +set(test_command ldpc_enc_avx2_test -b1) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-ENC-AVX2-BG2) +set(test_command ldpc_enc_avx2_test -b2) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-DEC-AVX2-BG1) +set(test_command ldpc_dec_avx2_test -b1) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-DEC-AVX2-BG2) +set(test_command ldpc_enc_avx2_test -b2) +ldpc_unit_tests(${lifting_sizes}) + +endif (HAVE_AVX2) + +if (HAVE_AVX512) + +set(test_name LDPC-ENC-AVX512-BG1) +set(test_command ldpc_enc_avx512_test -b1) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-ENC-AVX512-BG2) +set(test_command ldpc_enc_avx512_test -b2) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-DEC-AVX512-BG1) +set(test_command ldpc_dec_avx512_test -b1) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-DEC-AVX512-BG2) +set(test_command ldpc_dec_avx512_test -b2) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-DEC-AVX512-FLOOD-BG1) +set(test_command ldpc_dec_avx512_test -x1 -b1) +ldpc_unit_tests(${lifting_sizes}) + +set(test_name LDPC-DEC-AVX512-FLOOD-BG2) +set(test_command ldpc_dec_avx512_test -x1 -b2) +ldpc_unit_tests(${lifting_sizes}) +endif (HAVE_AVX512) + + add_test(NAME LDPC-chain COMMAND ldpc_chain_test) ### Test LDPC Rate Matching UNIT tests @@ -120,36 +179,36 @@ function(ldpc_rm_unit_tests) math(EXPR tmpN "${N} - (${N} % ${Div})") math(EXPR E "${Ordval}*(${tmpN})/${Div}") #twice the rate - add_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${N} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${N} + add_nr_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${N} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${N} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) math(EXPR M "${N} / 2") # Half size buffer - add_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${M} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${M} + add_nr_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${M} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${M} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) math(EXPR Div "2*${Ordval}") math(EXPR tmpN "${N} - (${N} % ${Div})") math(EXPR E "${Ordval}*(${tmpN})/${Div}") #twice the rate - add_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${N} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${N} + add_nr_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${N} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${N} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) math(EXPR M "${N}/ 2") # Half size buffer - add_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${M} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${M} + add_nr_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${M} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${M} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) math(EXPR Div "${Ordval}") math(EXPR tmpN "2*${N} - (2*${N} % ${Div})") #Half the rate math(EXPR E "${Ordval}*(${tmpN})/${Div}") - add_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${N} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${N} + add_nr_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${N} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${N} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) math(EXPR M "${N}/ 2") # Half size buffer - add_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${M} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${M} + add_nr_test(NAME ${test_name}-b${bgval}-l${i}-e${E}-f10-m${Modval}-r${rvval}-M${M} COMMAND ${test_command} -b${bgval} -l${i} -e${E} -f10 -m${Modval} -r${rvval} -M${M} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) endforeach() @@ -162,4 +221,4 @@ set(test_name LDPC-RM) set(test_command ldpc_rm_test) ldpc_rm_unit_tests(${lifting_sizes}) -add_test(NAME LDPC-RM-chain COMMAND ldpc_rm_chain_test -E 1 -B 1) +add_nr_test(NAME LDPC-RM-chain COMMAND ldpc_rm_chain_test -E 1 -B 1) diff --git a/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c b/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c index f17f2145d..ec0893301 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c @@ -136,18 +136,20 @@ void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time */ int main(int argc, char** argv) { - uint8_t* messages_true = NULL; - uint8_t* messages_sim_f = NULL; - uint8_t* messages_sim_s = NULL; - uint8_t* messages_sim_c = NULL; - uint8_t* messages_sim_c_flood = NULL; - uint8_t* messages_sim_avx = NULL; - uint8_t* messages_sim_avx_flood = NULL; - uint8_t* codewords = NULL; - float* symbols_rm = NULL; - float* symbols = NULL; - int16_t* symbols_s = NULL; - int8_t* symbols_c = NULL; + uint8_t* messages_true = NULL; + uint8_t* messages_sim_f = NULL; + uint8_t* messages_sim_s = NULL; + uint8_t* messages_sim_c = NULL; + uint8_t* messages_sim_c_flood = NULL; + uint8_t* messages_sim_avx = NULL; + uint8_t* messages_sim_avx_flood = NULL; + uint8_t* messages_sim_avx512 = NULL; + uint8_t* messages_sim_avx512_flood = NULL; + uint8_t* codewords = NULL; + float* symbols_rm = NULL; + float* symbols = NULL; + int16_t* symbols_s = NULL; + int8_t* symbols_c = NULL; int i = 0; int j = 0; @@ -156,6 +158,12 @@ int main(int argc, char** argv) // create an LDPC encoder srslte_ldpc_encoder_t encoder; +#ifdef LV_HAVE_AVX512 + if (srslte_ldpc_encoder_init(&encoder, SRSLTE_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) { + perror("encoder init"); + exit(-1); + } +#else #ifdef LV_HAVE_AVX2 if (srslte_ldpc_encoder_init(&encoder, SRSLTE_LDPC_ENCODER_AVX2, base_graph, lift_size) != 0) { perror("encoder init"); @@ -167,6 +175,7 @@ int main(int argc, char** argv) exit(-1); } #endif // LV_HAVE_AVX2 +#endif // LV_HAVE_AVX512 // create an LDPC decoder (float) srslte_ldpc_decoder_t decoder_f; @@ -209,11 +218,30 @@ int main(int argc, char** argv) } #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + // create an LDPC decoder (8 bit, AVX512 version) + srslte_ldpc_decoder_t decoder_avx512; + if (srslte_ldpc_decoder_init(&decoder_avx512, SRSLTE_LDPC_DECODER_C_AVX512, base_graph, lift_size, MS_SF) != 0) { + perror("decoder init"); + exit(-1); + } + + // create an LDPC decoder (8 bit, flooded scheduling, AVX512 version) + srslte_ldpc_decoder_t decoder_avx512_flood; + if (srslte_ldpc_decoder_init( + &decoder_avx512_flood, SRSLTE_LDPC_DECODER_C_AVX512_FLOOD, base_graph, lift_size, MS_SF) != 0) { + perror("decoder init"); + exit(-1); + } +#endif // LV_HAVE_AVX512 // create a random generator srslte_random_t random_gen = srslte_random_init(0); uint32_t F = encoder.bgK - 5; // This value is arbitrary + finalK = encoder.liftK; + finalN = encoder.liftN - 2 * lift_size; + if (rm_length == 0) { rm_length = finalN - F; } @@ -235,23 +263,23 @@ int main(int argc, char** argv) 1.0 * (encoder.liftK - F) / rm_length); printf("\n Signal-to-Noise Ratio -> %.2f dB\n", snr); - finalK = encoder.liftK; - finalN = encoder.liftN - 2 * lift_size; - - messages_true = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_f = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_s = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_c = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_c_flood = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_avx = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_avx_flood = srslte_vec_u8_malloc(finalK * batch_size); - codewords = srslte_vec_u8_malloc(finalN * batch_size); - symbols_rm = srslte_vec_f_malloc((rm_length + F) * batch_size); - symbols = srslte_vec_f_malloc(finalN * batch_size); - symbols_s = srslte_vec_i16_malloc(finalN * batch_size); - symbols_c = srslte_vec_i8_malloc(finalN * batch_size); + messages_true = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_f = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_s = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_c = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_c_flood = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx_flood = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx512 = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx512_flood = srslte_vec_u8_malloc(finalK * batch_size); + codewords = srslte_vec_u8_malloc(finalN * batch_size); + symbols_rm = srslte_vec_f_malloc((rm_length + F) * batch_size); + symbols = srslte_vec_f_malloc(finalN * batch_size); + symbols_s = srslte_vec_i16_malloc(finalN * batch_size); + symbols_c = srslte_vec_i8_malloc(finalN * batch_size); if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || // - !messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || // + !messages_sim_avx512 || !messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx512_flood || + !messages_sim_avx_flood || // !codewords || !symbols || !symbols_s || !symbols_c) { perror("malloc"); exit(-1); @@ -276,6 +304,12 @@ int main(int argc, char** argv) int n_error_words_avx = 0; int n_error_words_avx_flood = 0; #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + double elapsed_time_dec_avx512 = 0; + int n_error_words_avx512 = 0; + double elapsed_time_dec_avx512_flood = 0; + int n_error_words_avx512_flood = 0; +#endif // lV_HAVE_AVX512 float noise_std_dev = srslte_convert_dB_to_amplitude(-snr); @@ -481,6 +515,51 @@ int main(int argc, char** argv) } } #endif // LV_HAVE_AVX2 + +#ifdef LV_HAVE_AVX512 + //////// Fixed point - 8 bit - AVX512 version + + // Recover messages + gettimeofday(&t[1], NULL); + for (j = 0; j < batch_size; j++) { + srslte_ldpc_decoder_decode_rm_c( + &decoder_avx512, symbols_c + j * finalN, messages_sim_avx512 + j * finalK, n_useful_symbols); + } + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time_dec_avx512 += t[0].tv_sec + 1e-6 * t[0].tv_usec; + + for (i = 0; i < batch_size; i++) { + for (j = 0; j < finalK; j++) { + i_bit = i * finalK + j; + if (messages_sim_avx512[i_bit] != (1U & messages_true[i_bit])) { + n_error_words_avx512++; + break; + } + } + } + + //////// Fixed point - 8 bit, flooded scheduling - AVX512 version + // Recover messages + gettimeofday(&t[1], NULL); + for (j = 0; j < batch_size; j++) { + srslte_ldpc_decoder_decode_rm_c( + &decoder_avx512_flood, symbols_c + j * finalN, messages_sim_avx512_flood + j * finalK, n_useful_symbols); + } + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time_dec_avx512_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec; + + for (i = 0; i < batch_size; i++) { + for (j = 0; j < finalK; j++) { + i_bit = i * finalK + j; + if (messages_sim_avx512_flood[i_bit] != (1U & messages_true[i_bit])) { + n_error_words_avx512_flood++; + break; + } + } + } +#endif // LV_HAVE_AVX512 } printf("\nEstimated throughput encoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", @@ -499,6 +578,15 @@ int main(int argc, char** argv) "FIXED POINT (8 bits, flooded scheduling - AVX2)", i_batch, n_error_words_avx_flood, elapsed_time_dec_avx_flood); #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512); + + print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)", + i_batch, + n_error_words_avx512_flood, + elapsed_time_dec_avx512_flood); +#endif // LV_HAVE_AVX512 + if (n_error_words_s > 10 * n_error_words_f) { perror("16-bit performance too low!"); exit(-1); @@ -507,6 +595,17 @@ int main(int argc, char** argv) perror("8-bit performance too low!"); exit(-1); } +#ifdef LV_HAVE_AVX512 + if (n_error_words_avx512 != n_error_words_avx) { + perror("The number of errors AVX512 and AVX2 differs !"); + exit(-1); + } + + if (n_error_words_avx512_flood != n_error_words_avx_flood) { + perror("The number of errors of flood AVX512 and AVX2 differs !"); + exit(-1); + } +#endif // LV_HAVE_AVX512 printf("\nTest completed successfully!\n\n"); free(symbols_c); @@ -515,7 +614,9 @@ int main(int argc, char** argv) free(codewords); free(symbols_rm); free(messages_sim_avx); + free(messages_sim_avx512); free(messages_sim_avx_flood); + free(messages_sim_avx512_flood); free(messages_sim_c_flood); free(messages_sim_c); free(messages_sim_s); @@ -525,6 +626,10 @@ int main(int argc, char** argv) #ifdef LV_HAVE_AVX2 srslte_ldpc_decoder_free(&decoder_avx); srslte_ldpc_decoder_free(&decoder_avx_flood); +#endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + srslte_ldpc_decoder_free(&decoder_avx512); + srslte_ldpc_decoder_free(&decoder_avx512_flood); #endif // LV_HAVE_AVX2 srslte_ldpc_decoder_free(&decoder_c_flood); srslte_ldpc_decoder_free(&decoder_c); diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c index 6584e224d..60b6bcb17 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c @@ -50,7 +50,8 @@ int finalK; /*!< \brief Number of uncoded bits (message int finalN; /*!< \brief Number of coded bits (codeword length). */ int scheduling = 0; /*!< \brief Message scheduling (0 for layered, 1 for flooded). */ -#define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */ +#define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */ +static int nof_reps = 1; /*!< \brief Number of times tests are repeated (for computing throughput). */ /*! * \brief Prints test help when a wrong parameter is passed as input. @@ -61,6 +62,7 @@ void usage(char* prog) printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); printf("\t-l Lifting Size [Default %d]\n", lift_size); printf("\t-x Scheduling [Default %c]\n", scheduling); + printf("\t-R Number of times tests are repeated (for computing throughput). [Default %d]\n", nof_reps); } /*! @@ -69,7 +71,7 @@ void usage(char* prog) void parse_args(int argc, char** argv) { int opt = 0; - while ((opt = getopt(argc, argv, "b:l:x:")) != -1) { + while ((opt = getopt(argc, argv, "b:l:x:R:")) != -1) { switch (opt) { case 'b': base_graph = (int)strtol(optarg, NULL, 10) - 1; @@ -80,6 +82,9 @@ void parse_args(int argc, char** argv) case 'x': scheduling = (int)strtol(optarg, NULL, 10); break; + case 'R': + nof_reps = (int)strtol(optarg, NULL, 10); + break; default: usage(argv[0]); exit(-1); @@ -147,6 +152,7 @@ int main(int argc, char** argv) int8_t* symbols = NULL; int i = 0; int j = 0; + int l = 0; FILE* ex_file = NULL; char file_name[1000]; @@ -204,14 +210,19 @@ int main(int argc, char** argv) printf("\nDecoding test messages...\n"); struct timeval t[3]; - gettimeofday(&t[1], NULL); + double elapsed_time = 0; + for (j = 0; j < NOF_MESSAGES; j++) { printf(" codeword %d\n", j); - srslte_ldpc_decoder_decode_rm_c(&decoder, symbols + j * finalN, messages_sim + j * finalK, finalN); + gettimeofday(&t[1], NULL); + for (l = 0; l < nof_reps; l++) { + srslte_ldpc_decoder_decode_rm_c(&decoder, symbols + j * finalN, messages_sim + j * finalK, finalN); + } + + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec; } - gettimeofday(&t[2], NULL); - get_time_interval(t); - double elapsed_time = t[0].tv_sec + 1e-6 * t[0].tv_usec; printf("Elapsed time: %e s\n", elapsed_time); printf("\nVerifing results...\n"); diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c new file mode 100644 index 000000000..2e58d0af2 --- /dev/null +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c @@ -0,0 +1,238 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_dec_avx512_test.c + * \brief Unit test for the LDPC decoder working with 8-bit integer-valued LLRs (AVX512 implementation). + * + * It decodes a batch of example codewords and compares the resulting messages + * with the expected ones. Reference messages and codewords are provided in + * files **examplesBG1.dat** and **examplesBG2.dat**. + * + * Synopsis: **ldpc_dec_c_test [options]** + * + * Options: + * - **-b \** Base Graph (1 or 2. Default 1). + * - **-l \** Lifting Size (according to 5GNR standard. Default 2). + */ + +#include +#include +#include +#include + +#include "srslte/phy/fec/ldpc/ldpc_common.h" +#include "srslte/phy/fec/ldpc/ldpc_decoder.h" +#include "srslte/phy/utils/debug.h" + +srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */ +int lift_size = 2; /*!< \brief Lifting Size. */ +int finalK; /*!< \brief Number of uncoded bits (message length). */ +int finalN; /*!< \brief Number of coded bits (codeword length). */ +int scheduling = 0; /*!< \brief Message scheduling (0 for layered, 1 for flooded). */ + +#define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */ +static int nof_reps = 1; /*!< \brief Number of times tests are repeated (for computing throughput). */ + +/*! + * \brief Prints test help when a wrong parameter is passed as input. + */ +void usage(char* prog) +{ + printf("Usage: %s [-bX] [-lX]\n", prog); + printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); + printf("\t-l Lifting Size [Default %d]\n", lift_size); + printf("\t-x Scheduling [Default %c]\n", scheduling); + printf("\t-R Number of times tests are repeated (for computing throughput). [Default %d]\n", nof_reps); +} + +/*! + * \brief Parses the input line. + */ +void parse_args(int argc, char** argv) +{ + int opt = 0; + while ((opt = getopt(argc, argv, "b:l:x:R:")) != -1) { + switch (opt) { + case 'b': + base_graph = (int)strtol(optarg, NULL, 10) - 1; + break; + case 'l': + lift_size = (int)strtol(optarg, NULL, 10); + break; + case 'x': + scheduling = (int)strtol(optarg, NULL, 10); + break; + case 'R': + nof_reps = (int)strtol(optarg, NULL, 10); + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +/*! + * \brief Reads the example file. + */ +void get_examples(uint8_t* messages, // + uint8_t* codewords, + FILE* ex_file) +{ + char mstr[15]; // message string + char cstr[15]; // codeword string + char tmp[15]; + int i = 0; + int j = 0; + + sprintf(mstr, "ls%dmsgs", lift_size); + sprintf(cstr, "ls%dcwds", lift_size); + do { + do { + tmp[0] = fgetc(ex_file); + } while (tmp[0] != 'l'); + fscanf(ex_file, "%[^\n]", tmp + 1); + fgetc(ex_file); // discard newline + } while (strcmp(tmp, mstr) != 0); + + // read messages + for (j = 0; j < NOF_MESSAGES; j++) { + for (i = 0; i < finalK; i++) { + int rc = fgetc(ex_file); + messages[j * finalK + i] = (uint8_t)(rc == '-' ? FILLER_BIT : rc - '0'); + } + fgetc(ex_file); // discard newline + } + + fscanf(ex_file, "%[^\n]", tmp); + if (strcmp(tmp, cstr) != 0) { + printf("Something went wrong while reading example file.\n"); + exit(-1); + } + fgetc(ex_file); // discard newline + + // read codewords + for (j = 0; j < NOF_MESSAGES; j++) { + for (i = 0; i < finalN; i++) { + int rc = fgetc(ex_file); + codewords[j * finalN + i] = (uint8_t)(rc == '-' ? FILLER_BIT : rc - '0'); + } + fgetc(ex_file); // discard newline + } +} + +/*! + * \brief Main test function. + */ +int main(int argc, char** argv) +{ + uint8_t* messages_true = NULL; + uint8_t* messages_sim = NULL; + uint8_t* codewords = NULL; + int8_t* symbols = NULL; + int i = 0; + int j = 0; + int l = 0; + + FILE* ex_file = NULL; + char file_name[1000]; + + parse_args(argc, argv); + + srslte_ldpc_decoder_type_t dectype = + (scheduling == 0) ? SRSLTE_LDPC_DECODER_C_AVX512 : SRSLTE_LDPC_DECODER_C_AVX512_FLOOD; + + // create an LDPC decoder + srslte_ldpc_decoder_t decoder; + if (srslte_ldpc_decoder_init(&decoder, dectype, base_graph, lift_size, 1) != 0) { + perror("decoder init"); + exit(-1); + } + + printf("Test LDPC decoder:\n"); + printf(" Base Graph -> BG%d\n", decoder.bg + 1); + printf(" Lifting Size -> %d\n", decoder.ls); + printf(" Protograph -> M = %d, N = %d, K = %d\n", decoder.bgM, decoder.bgN, decoder.bgK); + printf(" Lifted graph -> M = %d, N = %d, K = %d\n", decoder.liftM, decoder.liftN, decoder.liftK); + printf(" Final code rate -> K/(N-2) = %d/%d = 1/%d\n", + decoder.liftK, + decoder.liftN - 2 * lift_size, + decoder.bg == BG1 ? 3 : 5); + printf(" Scheduling: %s\n", scheduling ? "flooded" : "layered"); + + finalK = decoder.liftK; + finalN = decoder.liftN - 2 * lift_size; + + messages_true = malloc(finalK * NOF_MESSAGES * sizeof(uint8_t)); + messages_sim = malloc(finalK * NOF_MESSAGES * sizeof(uint8_t)); + codewords = malloc(finalN * NOF_MESSAGES * sizeof(uint8_t)); + symbols = malloc(finalN * NOF_MESSAGES * sizeof(int8_t)); + if (!messages_true || !messages_sim || !codewords || !symbols) { + perror("malloc"); + exit(-1); + } + + sprintf(file_name, "examplesBG%d.dat", base_graph + 1); + printf("\nReading example file %s...\n", file_name); + ex_file = fopen(file_name, "re"); + if (ex_file == NULL) { + perror("fopen"); + exit(-1); + } + + get_examples(messages_true, codewords, ex_file); + + fclose(ex_file); + + for (i = 0; i < NOF_MESSAGES * finalN; i++) { + symbols[i] = codewords[i] == 1 ? -2 : 2; + } + + printf("\nDecoding test messages...\n"); + struct timeval t[3]; + double elapsed_time = 0; + + for (j = 0; j < NOF_MESSAGES; j++) { + printf(" codeword %d\n", j); + gettimeofday(&t[1], NULL); + for (l = 0; l < nof_reps; l++) { + srslte_ldpc_decoder_decode_rm_c(&decoder, symbols + j * finalN, messages_sim + j * finalK, finalN); + } + + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec; + } + printf("Elapsed time: %e s\n", elapsed_time); + + printf("\nVerifing results...\n"); + for (i = 0; i < NOF_MESSAGES * finalK; i++) { + if ((1U & messages_sim[i]) != (1U & messages_true[i])) { + perror("wrong!!"); + exit(-1); + } + } + + printf("Estimated throughput:\n %e word/s\n %.3f Mbit/s (information)\n %.3f Mbit/s (encoded)\n", + NOF_MESSAGES / (elapsed_time / nof_reps), + NOF_MESSAGES * finalK / (elapsed_time / nof_reps) / 1e6, + NOF_MESSAGES * finalN / (elapsed_time / nof_reps) / 1e6); + + printf("\nTest completed successfully!\n\n"); + + free(symbols); + free(codewords); + free(messages_sim); + free(messages_true); + srslte_ldpc_decoder_free(&decoder); +} diff --git a/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c b/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c new file mode 100644 index 000000000..0859af576 --- /dev/null +++ b/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c @@ -0,0 +1,221 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 ldpc_enc_avx512_test.c + * \brief Unit test for the LDPC encoder (SIMD-optimized version). + * + * It encodes a batch of example messages and compares the resulting codewords + * with the expected ones. Reference messages and codewords are provided in + * files **examplesBG1.dat** and **examplesBG2.dat**. + * + * Synopsis: **ldpc_enc_test [options]** + * + * Options: + * - **-b \** Base Graph (1 or 2. Default 1). + * - **-l \** Lifting Size (according to 5GNR standard. Default 2). + * - **-R \** Number of times tests are repeated (for computing throughput). + */ + +#include +#include +#include +#include + +#include "srslte/phy/fec/ldpc/ldpc_common.h" +#include "srslte/phy/fec/ldpc/ldpc_encoder.h" +#include "srslte/phy/utils/debug.h" + +srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */ +int lift_size = 2; /*!< \brief Lifting Size. */ +int finalK; /*!< \brief Number of uncoded bits (message length). */ +int finalN; /*!< \brief Number of coded bits (codeword length). */ + +#define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */ +static int nof_reps = 1; /*!< \brief Number of times tests are repeated (for computing throughput). */ + +/*! + * \brief Prints test help when a wrong parameter is passed as input. + */ +void usage(char* prog) +{ + printf("Usage: %s [-bX] [-lX]\n", prog); + printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); + printf("\t-l Lifting Size [Default %d]\n", lift_size); + printf("\t-R Number of times tests are repeated (for computing throughput). [Default %d]\n", nof_reps); +} + +/*! + * \brief Parses the input line. + */ +void parse_args(int argc, char** argv) +{ + int opt = 0; + while ((opt = getopt(argc, argv, "b:l:R:")) != -1) { + switch (opt) { + case 'b': + base_graph = (int)strtol(optarg, NULL, 10) - 1; + break; + case 'l': + lift_size = (int)strtol(optarg, NULL, 10); + break; + case 'R': + nof_reps = (int)strtol(optarg, NULL, 10); + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +/*! + * \brief Reads the example file. + */ +void get_examples(uint8_t* messages, // + uint8_t* codewords, + FILE* ex_file) +{ + char mstr[15]; // message string + char cstr[15]; // codeword string + char tmp[15]; + int i = 0; + int j = 0; + + sprintf(mstr, "ls%dmsgs", lift_size); + sprintf(cstr, "ls%dcwds", lift_size); + do { + do { + tmp[0] = fgetc(ex_file); + } while (tmp[0] != 'l'); + fscanf(ex_file, "%[^\n]", tmp + 1); + fgetc(ex_file); // discard newline + } while (strcmp(tmp, mstr) != 0); + + // read messages + for (j = 0; j < NOF_MESSAGES; j++) { + for (i = 0; i < finalK; i++) { + int rc = fgetc(ex_file); + messages[j * finalK + i] = (uint8_t)(rc == '-' ? FILLER_BIT : rc - '0'); + } + fgetc(ex_file); // discard newline + } + + fscanf(ex_file, "%[^\n]", tmp); + if (strcmp(tmp, cstr) != 0) { + printf("Something went wrong while reading example file.\n"); + exit(-1); + } + fgetc(ex_file); // discard newline + + // read codewords + for (j = 0; j < NOF_MESSAGES; j++) { + for (i = 0; i < finalN; i++) { + int rc = fgetc(ex_file); + codewords[j * finalN + i] = (uint8_t)(rc == '-' ? FILLER_BIT : rc - '0'); + } + fgetc(ex_file); // discard newline + } +} + +/*! + * \brief Main test function. + */ +int main(int argc, char** argv) +{ + uint8_t* messages = NULL; + uint8_t* codewords_true = NULL; + uint8_t* codewords_sim = NULL; + + int i = 0; + int j = 0; + int l = 0; + + FILE* ex_file = NULL; + char file_name[1000]; + + parse_args(argc, argv); + + // create an LDPC encoder + srslte_ldpc_encoder_t encoder; + if (srslte_ldpc_encoder_init(&encoder, SRSLTE_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) { + perror("encoder init"); + exit(-1); + } + + printf("Test LDPC encoder:\n"); + printf(" Base Graph -> BG%d\n", encoder.bg + 1); + printf(" Lifting Size -> %d\n", encoder.ls); + printf(" Protograph -> M = %d, N = %d, K = %d\n", encoder.bgM, encoder.bgN, encoder.bgK); + printf(" Lifted graph -> M = %d, N = %d, K = %d\n", encoder.liftM, encoder.liftN, encoder.liftK); + printf(" Final code rate -> K/(N-2) = %d/%d = 1/%d\n", + encoder.liftK, + encoder.liftN - 2 * lift_size, + encoder.bg == BG1 ? 3 : 5); + + finalK = encoder.liftK; + finalN = encoder.liftN - 2 * lift_size; + + messages = malloc(finalK * NOF_MESSAGES * sizeof(uint8_t)); + codewords_true = malloc(finalN * NOF_MESSAGES * sizeof(uint8_t)); + codewords_sim = malloc(finalN * NOF_MESSAGES * sizeof(uint8_t)); + if (!messages || !codewords_true || !codewords_sim) { + perror("malloc"); + exit(-1); + } + + sprintf(file_name, "examplesBG%d.dat", base_graph + 1); + printf("\nReading example file %s...\n", file_name); + ex_file = fopen(file_name, "re"); + if (ex_file == NULL) { + perror("fopen"); + exit(-1); + } + + get_examples(messages, codewords_true, ex_file); + + fclose(ex_file); + + printf("\nEncoding test messages...\n"); + struct timeval t[3]; + double elapsed_time = 0; + for (j = 0; j < NOF_MESSAGES; j++) { + printf(" codeword %d\n", j); + gettimeofday(&t[1], NULL); + for (l = 0; l < nof_reps; l++) { + srslte_ldpc_encoder_encode_rm(&encoder, messages + j * finalK, codewords_sim + j * finalN, finalK, finalN); + } + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec; + } + printf("Elapsed time: %e s\n", elapsed_time / nof_reps); + + printf("Estimated throughput:\n %e word/s\n %.3f Mbit/s (information)\n %.3f Mbit/s (encoded)\n", + NOF_MESSAGES / (elapsed_time / nof_reps), + NOF_MESSAGES * finalK / (elapsed_time / nof_reps) / 1e6, + NOF_MESSAGES * finalN / (elapsed_time / nof_reps) / 1e6); + + printf("\nVerifing results...\n"); + for (i = 0; i < NOF_MESSAGES * finalN; i++) { + if (codewords_sim[i] != codewords_true[i]) { + perror("wrong!!"); + exit(-1); + } + } + printf("\nTest completed successfully!\n\n"); + + free(codewords_sim); + free(codewords_true); + free(messages); + srslte_ldpc_encoder_free(&encoder); +} diff --git a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c index aa672de79..901ec168e 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c @@ -84,7 +84,6 @@ static int req_errors = 100; /*!< \brief Minimum number of errors for a signi */ void usage(char* prog) { - printf("Usage: %s [-bX] [-lX] [-eX] [-fX] [-rX] [-mX] [-MX] [-wX] [-sX]\n", prog); printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); printf("\t-l Lifting Size [Default %d]\n", lift_size); @@ -161,22 +160,23 @@ void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time */ int main(int argc, char** argv) { - - uint8_t* messages_true = NULL; - uint8_t* messages_sim_f = NULL; - uint8_t* messages_sim_s = NULL; - uint8_t* messages_sim_c = NULL; - uint8_t* messages_sim_c_flood = NULL; - uint8_t* messages_sim_avx = NULL; - uint8_t* messages_sim_avx_flood = NULL; - uint8_t* codewords = NULL; - uint8_t* rm_codewords = NULL; - float* rm_symbols = NULL; - int16_t* rm_symbols_s = NULL; - int8_t* rm_symbols_c = NULL; - float* symbols = NULL; // unrm_symbols - int16_t* symbols_s = NULL; // unrm_symbols - int8_t* symbols_c = NULL; // unrm_symbols + uint8_t* messages_true = NULL; + uint8_t* messages_sim_f = NULL; + uint8_t* messages_sim_s = NULL; + uint8_t* messages_sim_c = NULL; + uint8_t* messages_sim_c_flood = NULL; + uint8_t* messages_sim_avx = NULL; + uint8_t* messages_sim_avx_flood = NULL; + uint8_t* messages_sim_avx512 = NULL; + uint8_t* messages_sim_avx512_flood = NULL; + uint8_t* codewords = NULL; + uint8_t* rm_codewords = NULL; + float* rm_symbols = NULL; + int16_t* rm_symbols_s = NULL; + int8_t* rm_symbols_c = NULL; + float* symbols = NULL; // unrm_symbols + int16_t* symbols_s = NULL; // unrm_symbols + int8_t* symbols_c = NULL; // unrm_symbols int i = 0; int j = 0; @@ -185,6 +185,13 @@ int main(int argc, char** argv) // create an LDPC encoder srslte_ldpc_encoder_t encoder; + +#ifdef LV_HAVE_AVX512 + if (srslte_ldpc_encoder_init(&encoder, SRSLTE_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) { + perror("encoder init"); + exit(-1); + } +#else // no AVX512 #ifdef LV_HAVE_AVX2 if (srslte_ldpc_encoder_init(&encoder, SRSLTE_LDPC_ENCODER_AVX2, base_graph, lift_size) != 0) { perror("encoder init"); @@ -196,6 +203,7 @@ int main(int argc, char** argv) exit(-1); } #endif // LV_HAVE_AVX2 +#endif // LV_HAVE_AVX512 // create a LDPC rate DeMatcher finalK = encoder.liftK; @@ -276,6 +284,23 @@ int main(int argc, char** argv) } #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + // create an LDPC decoder (8 bit, AVX2 version) + srslte_ldpc_decoder_t decoder_avx512; + if (srslte_ldpc_decoder_init(&decoder_avx512, SRSLTE_LDPC_DECODER_C_AVX512, base_graph, lift_size, MS_SF) != 0) { + perror("decoder init"); + exit(-1); + } + + // create an LDPC decoder (8 bit, flooded scheduling, AVX512 version) + srslte_ldpc_decoder_t decoder_avx512_flood; + if (srslte_ldpc_decoder_init( + &decoder_avx512_flood, SRSLTE_LDPC_DECODER_C_AVX512_FLOOD, base_graph, lift_size, MS_SF) != 0) { + perror("decoder init"); + exit(-1); + } +#endif // LV_HAVE_AVX512 + // create a random generator srslte_random_t random_gen = srslte_random_init(0); @@ -301,26 +326,28 @@ int main(int argc, char** argv) 1.0 * (encoder.liftK - F) / rm_length); printf("\n Signal-to-Noise Ratio -> %.2f dB\n", snr); - messages_true = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_f = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_s = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_c = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_c_flood = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_avx = srslte_vec_u8_malloc(finalK * batch_size); - messages_sim_avx_flood = srslte_vec_u8_malloc(finalK * batch_size); - codewords = srslte_vec_u8_malloc(finalN * batch_size); - rm_codewords = srslte_vec_u8_malloc(rm_length * batch_size); - rm_symbols = srslte_vec_f_malloc(rm_length * batch_size); - rm_symbols_s = srslte_vec_i16_malloc(rm_length * batch_size); - rm_symbols_c = srslte_vec_i8_malloc(rm_length * batch_size); + messages_true = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_f = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_s = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_c = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_c_flood = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx_flood = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx512 = srslte_vec_u8_malloc(finalK * batch_size); + messages_sim_avx512_flood = srslte_vec_u8_malloc(finalK * batch_size); + codewords = srslte_vec_u8_malloc(finalN * batch_size); + rm_codewords = srslte_vec_u8_malloc(rm_length * batch_size); + rm_symbols = srslte_vec_f_malloc(rm_length * batch_size); + rm_symbols_s = srslte_vec_i16_malloc(rm_length * batch_size); + rm_symbols_c = srslte_vec_i8_malloc(rm_length * batch_size); symbols = srslte_vec_f_malloc(finalN * batch_size); symbols_s = srslte_vec_i16_malloc(finalN * batch_size); symbols_c = srslte_vec_i8_malloc(finalN * batch_size); - if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || // - !messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || // - !codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c || !symbols || !symbols_s || - !symbols_c) { + if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || // + !messages_sim_avx || !messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || // + !messages_sim_avx512_flood || !codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c || + !symbols || !symbols_s || !symbols_c) { perror("malloc"); exit(-1); } @@ -345,6 +372,13 @@ int main(int argc, char** argv) int n_error_words_avx_flood = 0; #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + double elapsed_time_dec_avx512 = 0; + int n_error_words_avx512 = 0; + double elapsed_time_dec_avx512_flood = 0; + int n_error_words_avx512_flood = 0; +#endif // LV_HAVE_AVX512 + float noise_std_dev = srslte_convert_dB_to_amplitude(-snr); int16_t inf15 = (1U << 14U) - 1; @@ -613,6 +647,52 @@ int main(int argc, char** argv) } } #endif // LV_HAVE_AVX2 + +#ifdef LV_HAVE_AVX512 + //////// Fixed point - 8 bit - AVX512 version + + // Recover messages + gettimeofday(&t[1], NULL); + for (j = 0; j < batch_size; j++) { + srslte_ldpc_decoder_decode_rm_c( + &decoder_avx512, symbols_c + j * finalN, messages_sim_avx512 + j * finalK, finalN); + } + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time_dec_avx512 += t[0].tv_sec + 1e-6 * t[0].tv_usec; + + for (i = 0; i < batch_size; i++) { + for (j = 0; j < finalK; j++) { + i_bit = i * finalK + j; + if (messages_sim_avx512[i_bit] != (1U & messages_true[i_bit])) { + n_error_words_avx512++; + break; + } + } + } + + //////// Fixed point - 8 bit, flooded scheduling - AVX512 version + + // Recover messages + gettimeofday(&t[1], NULL); + for (j = 0; j < batch_size; j++) { + srslte_ldpc_decoder_decode_rm_c( + &decoder_avx512_flood, symbols_c + j * finalN, messages_sim_avx512_flood + j * finalK, finalN); + } + gettimeofday(&t[2], NULL); + get_time_interval(t); + elapsed_time_dec_avx512_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec; + + for (i = 0; i < batch_size; i++) { + for (j = 0; j < finalK; j++) { + i_bit = i * finalK + j; + if (messages_sim_avx512_flood[i_bit] != (1U & messages_true[i_bit])) { + n_error_words_avx512_flood++; + break; + } + } + } +#endif // LV_HAVE_AVX512 } printf("\nEstimated throughput encoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", @@ -631,6 +711,14 @@ int main(int argc, char** argv) "FIXED POINT (8 bits, flooded scheduling - AVX2)", i_batch, n_error_words_avx_flood, elapsed_time_dec_avx_flood); #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512); + print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)", + i_batch, + n_error_words_avx512_flood, + elapsed_time_dec_avx512_flood); +#endif // LV_HAVE_AVX512 + if (n_error_words_s > 10 * n_error_words_f) { perror("16-bit performance too low!"); exit(-1); @@ -639,6 +727,17 @@ int main(int argc, char** argv) perror("8-bit performance too low!"); exit(-1); } +#ifdef LV_HAVE_AVX512 + if (n_error_words_avx512 != n_error_words_avx) { + perror("The number of errors AVX512 and AVX2 differs !"); + exit(-1); + } + + if (n_error_words_avx512_flood != n_error_words_avx_flood) { + perror("The number of errors of flooded AVX512 and AVX2 differs !"); + exit(-1); + } +#endif // LV_HAVE_AVX512 printf("\nTest completed successfully!\n\n"); free(symbols); @@ -651,6 +750,8 @@ int main(int argc, char** argv) free(codewords); free(messages_sim_avx); free(messages_sim_avx_flood); + free(messages_sim_avx512); + free(messages_sim_avx512_flood); free(messages_sim_c_flood); free(messages_sim_c); free(messages_sim_s); @@ -661,6 +762,10 @@ int main(int argc, char** argv) srslte_ldpc_decoder_free(&decoder_avx); srslte_ldpc_decoder_free(&decoder_avx_flood); #endif // LV_HAVE_AVX2 +#ifdef LV_HAVE_AVX512 + srslte_ldpc_decoder_free(&decoder_avx512); + srslte_ldpc_decoder_free(&decoder_avx512_flood); +#endif // LV_HAVE_AVX512 srslte_ldpc_decoder_free(&decoder_c_flood); srslte_ldpc_decoder_free(&decoder_c); srslte_ldpc_decoder_free(&decoder_s); diff --git a/lib/src/phy/fec/polar/polar_code.c b/lib/src/phy/fec/polar/polar_code.c index 87875ad86..274f3ce97 100644 --- a/lib/src/phy/fec/polar/polar_code.c +++ b/lib/src/phy/fec/polar/polar_code.c @@ -83,7 +83,6 @@ int cmpfunc(const void* a, const void* b) return -1; } if (ai > bi) { - return 1; } @@ -96,17 +95,16 @@ int cmpfunc(const void* a, const void* b) */ int get_code_params(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, const uint8_t nMax) { - // include here also npc and nwmPC computatoins if (E > EMAX) { - ERROR("Rate-matched codeword size (E) not supported. Chose E<=8192\n"); + ERROR("Rate-matched codeword size (E) not supported. Chose E<=8192"); return -1; } switch (nMax) { case 9: // downlink // iil = true if (K < 36 || K > 164) { - ERROR("Codeblock length (K=%d) not supported for downlink transmission, choose 165 > K > 35\n", K); + ERROR("Codeblock length (K=%d) not supported for downlink transmission, choose 165 > K > 35", K); return -1; } break; @@ -114,13 +112,13 @@ int get_code_params(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, // iil = false if (K < 18 || (K > 25 && K < 31) || K > 1023) { ERROR("Codeblock length (K=%d) not supported for uplink transmission, choose K > 17 and K < 1024, " - "excluding 31 > K > 25\n", + "excluding 31 > K > 25", K); return -1; } break; default: - ERROR("nMax not supported choose 9 for downlink and 10 for uplink transmissions\n"); + ERROR("nMax not supported choose 9 for downlink and 10 for uplink transmissions"); return -1; } // number of parity check bits (nPC) and parity check bits of minimum bandwidth nWmPC @@ -134,7 +132,7 @@ int get_code_params(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, } if (K + nPC >= E) { - ERROR(" Rate-matched codeword length (E) not supported, choose E > %d\n", K + nPC); + ERROR(" Rate-matched codeword length (E) not supported, choose E > %d", K + nPC); return -1; } @@ -182,7 +180,7 @@ int get_code_params(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, uint16_t N = (1U << n); if (K >= N) { - ERROR("Codeblock length (K) not supported, choose K < N\n"); + ERROR("Codeblock length (K) not supported, choose K < N"); return -1; } @@ -222,7 +220,6 @@ int srslte_polar_code_init(srslte_polar_code_t* c) int srslte_polar_code_get(srslte_polar_code_t* c, uint16_t K, uint16_t E, uint8_t nMax) { - if (c == NULL) { return -1; } diff --git a/lib/src/phy/fec/polar/polar_decoder.c b/lib/src/phy/fec/polar/polar_decoder.c index 751a5bbfe..6fd8d86eb 100644 --- a/lib/src/phy/fec/polar/polar_decoder.c +++ b/lib/src/phy/fec/polar/polar_decoder.c @@ -151,7 +151,7 @@ static int init_ssc_f(srslte_polar_decoder_t* q) q->free = free_ssc_f; if ((q->ptr = create_polar_decoder_ssc_f(q->nMax)) == NULL) { - ERROR("create_polar_decoder_ssc_f failed\n"); + ERROR("create_polar_decoder_ssc_f failed"); free_ssc_f(q); return -1; } @@ -165,7 +165,7 @@ static int init_ssc_s(srslte_polar_decoder_t* q) q->free = free_ssc_s; if ((q->ptr = create_polar_decoder_ssc_s(q->nMax)) == NULL) { - ERROR("create_polar_decoder_ssc_s failed\n"); + ERROR("create_polar_decoder_ssc_s failed"); free_ssc_s(q); return -1; } @@ -179,7 +179,7 @@ static int init_ssc_c(srslte_polar_decoder_t* q) q->free = free_ssc_c; if ((q->ptr = create_polar_decoder_ssc_c(q->nMax)) == NULL) { - ERROR("create_polar_decoder_ssc_c failed\n"); + ERROR("create_polar_decoder_ssc_c failed"); free_ssc_c(q); return -1; } @@ -195,7 +195,7 @@ static int init_ssc_c_avx2(srslte_polar_decoder_t* q) q->free = free_ssc_c_avx2; if ((q->ptr = create_polar_decoder_ssc_c_avx2(q->nMax)) == NULL) { - ERROR("create_polar_decoder_ssc_c failed\n"); + ERROR("create_polar_decoder_ssc_c failed"); free_ssc_c_avx2(q); return -1; } @@ -218,7 +218,7 @@ int srslte_polar_decoder_init(srslte_polar_decoder_t* q, srslte_polar_decoder_ty return init_ssc_c_avx2(q); #endif default: - ERROR("Decoder not implemented\n"); + ERROR("Decoder not implemented"); return -1; } return 0; diff --git a/lib/src/phy/fec/polar/test/CMakeLists.txt b/lib/src/phy/fec/polar/test/CMakeLists.txt index 37a4f5829..6db296d50 100644 --- a/lib/src/phy/fec/polar/test/CMakeLists.txt +++ b/lib/src/phy/fec/polar/test/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "lib;phy;fec;polar") + add_library(polar_test_utils polar_sets.c subchannel_allocation.c) add_executable(polar_chain_test polar_chain_test.c) @@ -38,7 +40,7 @@ function(polar_tests_lite) list(GET listE ${num} eval) list(GET listK ${num} kval) list(GET listI ${num} ival) - add_test(NAME ${test_name}-s${S}-n${nval}-e${eval}-k${kval}-i${ival} + add_nr_test(NAME ${test_name}-s${S}-n${nval}-e${eval}-k${kval}-i${ival} COMMAND ${test_command} -s${S} -n${nval} -e${eval} -k${kval} -i${ival} ) endforeach() @@ -52,7 +54,7 @@ function(polar_tests) foreach(Kval RANGE 36 164 32) math(EXPR Emin "${Kval} + 1") foreach(Eval RANGE ${Emin} 8192 128) - add_test(NAME ${test_name}-s${S}-k${Kval}-e${Eval}-n${nval}-i0 + add_nr_test(NAME ${test_name}-s${S}-k${Kval}-e${Eval}-n${nval}-i0 COMMAND ${test_command} -s${S} -k${Kval} -e${Eval} -n${nval} -i0 ) endforeach() @@ -64,7 +66,7 @@ function(polar_tests) foreach(Kval RANGE 18 25) math(EXPR Emin "${Kval} + 3 + 1") foreach(Eval RANGE ${Emin} 8192 128) - add_test(NAME ${test_name}-s${S}-k${Kval}-e${Eval}-n${nval}-i1 + add_nr_test(NAME ${test_name}-s${S}-k${Kval}-e${Eval}-n${nval}-i1 COMMAND ${test_command} -s${S} -k${Kval} -e${Eval} -n${nval} -i1 ) endforeach() @@ -73,7 +75,7 @@ function(polar_tests) foreach(Kval RANGE 32 1023 32) math(EXPR Emin "${Kval} + 1") foreach(Eval RANGE ${Emin} 8192 128) - add_test(NAME ${test_name}-s${S}-k${Kval}-e${Eval}-n${nval}-i1 + add_nr_test(NAME ${test_name}-s${S}-k${Kval}-e${Eval}-n${nval}-i1 COMMAND ${test_command} -s${S} -k${Kval} -e${Eval} -n${nval} -i1 ) endforeach() @@ -102,4 +104,4 @@ polar_tests(101) # Polar inter-leaver test add_executable(polar_interleaver_test polar_interleaver_test.c) target_link_libraries(polar_interleaver_test srslte_phy) -add_test(polar_interleaver_test polar_interleaver_test) \ No newline at end of file +add_nr_test(polar_interleaver_test polar_interleaver_test) diff --git a/lib/src/phy/fec/test/crc_test.c b/lib/src/phy/fec/test/crc_test.c index 1d64514a9..c5274c38a 100644 --- a/lib/src/phy/fec/test/crc_test.c +++ b/lib/src/phy/fec/test/crc_test.c @@ -109,13 +109,13 @@ int main(int argc, char** argv) // generate CRC word crc_word = srslte_crc_checksum(&crc_p, data, num_bits); - INFO("checksum=%x\n", crc_word); + INFO("checksum=%x", crc_word); free(data); // check if generated word is as expected if (get_expected_word(num_bits, crc_length, crc_poly, seed, &expected_word)) { - ERROR("Test parameters not defined in test_results.h\n"); + ERROR("Test parameters not defined in test_results.h"); exit(-1); } exit(expected_word != crc_word); diff --git a/lib/src/phy/fec/turbo/rm_conv.c b/lib/src/phy/fec/turbo/rm_conv.c index 1fe7ce8bf..cd8ae10a6 100644 --- a/lib/src/phy/fec/turbo/rm_conv.c +++ b/lib/src/phy/fec/turbo/rm_conv.c @@ -42,7 +42,6 @@ uint8_t RM_PERM_CC_INV[NCOLS] = {16, 0, 24, 8, 20, 4, 28, 12, 18, 2, 26, 10, 22, */ int srslte_rm_conv_tx(uint8_t* input, uint32_t in_len, uint8_t* output, uint32_t out_len) { - uint8_t tmp[3 * NCOLS * NROWS_MAX]; int nrows, ndummy, K_p; @@ -50,7 +49,7 @@ int srslte_rm_conv_tx(uint8_t* input, uint32_t in_len, uint8_t* output, uint32_t nrows = (uint32_t)(in_len / 3 - 1) / NCOLS + 1; if (nrows > NROWS_MAX) { - ERROR("Input too large. Max input length is %d\n", 3 * NCOLS * NROWS_MAX); + ERROR("Input too large. Max input length is %d", 3 * NCOLS * NROWS_MAX); return -1; } K_p = nrows * NCOLS; @@ -93,7 +92,6 @@ int srslte_rm_conv_tx(uint8_t* input, uint32_t in_len, uint8_t* output, uint32_t */ int srslte_rm_conv_rx(float* input, uint32_t in_len, float* output, uint32_t out_len) { - int nrows, ndummy, K_p; int i, j, k; int d_i, d_j; @@ -102,7 +100,7 @@ int srslte_rm_conv_rx(float* input, uint32_t in_len, float* output, uint32_t out nrows = (uint32_t)(out_len / 3 - 1) / NCOLS + 1; if (nrows > NROWS_MAX) { - ERROR("Output too large. Max output length is %d\n", 3 * NCOLS * NROWS_MAX); + ERROR("Output too large. Max output length is %d", 3 * NCOLS * NROWS_MAX); return -1; } K_p = nrows * NCOLS; @@ -160,7 +158,6 @@ int srslte_rm_conv_rx(float* input, uint32_t in_len, float* output, uint32_t out */ int srslte_rm_conv_rx_s(int16_t* input, uint32_t in_len, int16_t* output, uint32_t out_len) { - int nrows, ndummy, K_p; int i, j, k; int d_i, d_j; @@ -169,7 +166,7 @@ int srslte_rm_conv_rx_s(int16_t* input, uint32_t in_len, int16_t* output, uint32 nrows = (uint32_t)(out_len / 3 - 1) / NCOLS + 1; if (nrows > NROWS_MAX) { - ERROR("Output too large. Max output length is %d\n", 3 * NCOLS * NROWS_MAX); + ERROR("Output too large. Max output length is %d", 3 * NCOLS * NROWS_MAX); return -1; } K_p = nrows * NCOLS; diff --git a/lib/src/phy/fec/turbo/rm_turbo.c b/lib/src/phy/fec/turbo/rm_turbo.c index 8f9cc59d4..380f22ef3 100644 --- a/lib/src/phy/fec/turbo/rm_turbo.c +++ b/lib/src/phy/fec/turbo/rm_turbo.c @@ -93,7 +93,7 @@ int deinter_table_idx_from_sb_len(uint32_t nof_subblocks) } } if (nof_subblocks != 0) { - ERROR("Error number of sub-blocks %d not supported in RM\n", nof_subblocks); + ERROR("Error number of sub-blocks %d not supported in RM", nof_subblocks); } return -1; } @@ -104,7 +104,6 @@ static uint16_t temp_table1[3 * 6176], temp_table2[3 * 6176]; static void srslte_rm_turbo_gentable_systematic(uint16_t* table_bits, int k0_vec_[4][2], uint32_t nrows, int ndummy) { - bool last_is_null = true; int k_b = 0, buff_idx = 0; for (int j = 0; j < NCOLS; j++) { @@ -131,7 +130,6 @@ static void srslte_rm_turbo_gentable_systematic(uint16_t* table_bits, int k0_vec static void srslte_rm_turbo_gentable_parity(uint16_t* table_parity, int k0_vec_[4][2], int offset, uint16_t nrows, int ndummy) { - bool last_is_null = true; int k_b = 0, buff_idx0 = 0; int K_p = nrows * NCOLS; @@ -176,7 +174,6 @@ srslte_rm_turbo_gentable_parity(uint16_t* table_parity, int k0_vec_[4][2], int o static void srslte_rm_turbo_gentable_receive(uint16_t* table, uint32_t cb_len, uint32_t rv_idx) { - int nrows = (uint32_t)(cb_len / 3 - 1) / NCOLS + 1; int ndummy = nrows * NCOLS - cb_len / 3; if (ndummy < 0) { @@ -267,7 +264,6 @@ static void interleave_table_sb(uint16_t* in, uint16_t* out, uint32_t cb_idx, ui for (int i = 0; i < out_len; i++) { // Do not change tail bit order if (in[i] < 3 * long_cb) { - // align to 32 bytes (warning: must be same alignment as in rm_turbo.c) out[i] = (in[i] % 3) * (long_cb + 32) + inter(in[i] / 3, nof_sb); } else { @@ -355,14 +351,11 @@ int srslte_rm_turbo_tx_lut(uint8_t* w_buff, uint32_t w_offset, uint32_t rv_idx) { - if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) { - int in_len = 3 * srslte_cbsegm_cbsize(cb_idx) + 12; /* Sub-block interleaver (5.1.4.1.1) and bit collection */ if (rv_idx == 0) { - // Systematic bits // srslte_bit_interleave(systematic, w_buff, interleaver_systematic_bits[cb_idx], in_len/3); srslte_bit_interleaver_run(&bit_interleavers_systematic_bits[cb_idx], systematic, w_buff, 0); @@ -414,9 +407,7 @@ int srslte_rm_turbo_rx_lut_(int16_t* input, uint32_t rv_idx, bool enable_input_tdec) { - if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) { - #if SRSLTE_TDEC_EXPECT_INPUT_SB == 1 int cb_len = srslte_cbsegm_cbsize(cb_idx); int idx = deinter_table_idx_from_sb_len(srslte_tdec_autoimp_get_subblocks(cb_len)); @@ -426,7 +417,7 @@ int srslte_rm_turbo_rx_lut_(int16_t* input, } else if (idx < NOF_DEINTER_TABLE_SB_IDX) { deinter = deinterleaver_sb[idx][cb_idx][rv_idx]; } else { - ERROR("Sub-block size index %d not supported in srslte_rm_turbo_rx_lut()\n", idx); + ERROR("Sub-block size index %d not supported in srslte_rm_turbo_rx_lut()", idx); return -1; } #else @@ -456,7 +447,6 @@ int srslte_rm_turbo_rx_lut_(int16_t* input, int srslte_rm_turbo_rx_lut_8bit(int8_t* input, int8_t* output, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx) { if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) { - #if SRSLTE_TDEC_EXPECT_INPUT_SB == 1 int cb_len = srslte_cbsegm_cbsize(cb_idx); int idx = deinter_table_idx_from_sb_len(srslte_tdec_autoimp_get_subblocks_8bit(cb_len)); @@ -466,7 +456,7 @@ int srslte_rm_turbo_rx_lut_8bit(int8_t* input, int8_t* output, uint32_t in_len, } else if (idx < NOF_DEINTER_TABLE_SB_IDX) { deinter = deinterleaver_sb[idx][cb_idx][rv_idx]; } else { - ERROR("Sub-block size index %d not supported in srslte_rm_turbo_rx_lut()\n", idx); + ERROR("Sub-block size index %d not supported in srslte_rm_turbo_rx_lut()", idx); return -1; } #else @@ -996,7 +986,6 @@ int srslte_rm_turbo_tx(uint8_t* w_buff, uint32_t out_len, uint32_t rv_idx) { - int ndummy, kidx; int nrows, K_p; @@ -1087,7 +1076,6 @@ int srslte_rm_turbo_rx(float* w_buff, uint32_t rv_idx, uint32_t nof_filler_bits) { - int nrows, ndummy, K_p, k0, N_cb, jp, kidx; int i, j, k; int d_i, d_j; @@ -1096,7 +1084,7 @@ int srslte_rm_turbo_rx(float* w_buff, nrows = (uint16_t)(out_len / 3 - 1) / NCOLS + 1; K_p = nrows * NCOLS; if (3 * K_p > w_buff_len) { - ERROR("Output too large. Max output length including dummy bits is %d (3x%dx32, in_len %d)\n", + ERROR("Output too large. Max output length including dummy bits is %d (3x%dx32, in_len %d)", w_buff_len, nrows, out_len); @@ -1104,7 +1092,7 @@ int srslte_rm_turbo_rx(float* w_buff, } if (out_len < 3) { - ERROR("Error minimum input length for rate matching is 3\n"); + ERROR("Error minimum input length for rate matching is 3"); return -1; } diff --git a/lib/src/phy/fec/turbo/tc_interl_lte.c b/lib/src/phy/fec/turbo/tc_interl_lte.c index fd4a5f7f1..02c9e2026 100644 --- a/lib/src/phy/fec/turbo/tc_interl_lte.c +++ b/lib/src/phy/fec/turbo/tc_interl_lte.c @@ -72,13 +72,13 @@ int srslte_tc_interl_LTE_gen_interl(srslte_tc_interl_t* h, uint32_t long_cb, uin uint64_t i, j; if (long_cb > h->max_long_cb) { - ERROR("Interleaver initiated for max_long_cb=%d\n", h->max_long_cb); + ERROR("Interleaver initiated for max_long_cb=%d", h->max_long_cb); return -1; } cb_table_idx = srslte_cbsegm_cbindex(long_cb); if (cb_table_idx == -1) { - ERROR("Can't find long_cb=%d in valid TC CB table\n", long_cb); + ERROR("Can't find long_cb=%d in valid TC CB table", long_cb); return -1; } diff --git a/lib/src/phy/fec/turbo/tc_interl_umts.c b/lib/src/phy/fec/turbo/tc_interl_umts.c index 0a76abdca..883a91f4d 100644 --- a/lib/src/phy/fec/turbo/tc_interl_umts.c +++ b/lib/src/phy/fec/turbo/tc_interl_umts.c @@ -97,7 +97,7 @@ int srslte_tc_interl_UMTS_gen(srslte_tc_interl_t* h, uint32_t long_cb) M_long = long_cb; if (long_cb > h->max_long_cb) { - ERROR("Interleaver initiated for max_long_cb=%d\n", h->max_long_cb); + ERROR("Interleaver initiated for max_long_cb=%d", h->max_long_cb); return -1; } diff --git a/lib/src/phy/fec/turbo/test/CMakeLists.txt b/lib/src/phy/fec/turbo/test/CMakeLists.txt index 1f8cfa9fb..2dd0aed17 100644 --- a/lib/src/phy/fec/turbo/test/CMakeLists.txt +++ b/lib/src/phy/fec/turbo/test/CMakeLists.txt @@ -18,6 +18,7 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "lib;phy;fec;turbo") ######################################################################## # RATEMATCHING TEST @@ -29,11 +30,11 @@ target_link_libraries(rm_conv_test srslte_phy) add_executable(rm_turbo_test rm_turbo_test.c) target_link_libraries(rm_turbo_test srslte_phy) -add_test(rm_conv_test_1 rm_conv_test -t 480 -r 1920) -add_test(rm_conv_test_2 rm_conv_test -t 1920 -r 480) +add_lte_test(rm_conv_test_1 rm_conv_test -t 480 -r 1920) +add_lte_test(rm_conv_test_2 rm_conv_test -t 1920 -r 480) -add_test(rm_turbo_test_1 rm_turbo_test -e 1920) -add_test(rm_turbo_test_2 rm_turbo_test -e 8192) +add_lte_test(rm_turbo_test_1 rm_turbo_test -e 1920) +add_lte_test(rm_turbo_test_2 rm_turbo_test -e 8192) ######################################################################## # Turbo Coder TEST @@ -41,11 +42,11 @@ add_test(rm_turbo_test_2 rm_turbo_test -e 8192) add_executable(turbodecoder_test turbodecoder_test.c) target_link_libraries(turbodecoder_test srslte_phy) -add_test(turbodecoder_test_504_1 turbodecoder_test -n 100 -s 1 -l 504 -e 1.0 -t) -add_test(turbodecoder_test_504_2 turbodecoder_test -n 100 -s 1 -l 504 -e 2.0 -t) -add_test(turbodecoder_test_6114_1_5 turbodecoder_test -n 100 -s 1 -l 6144 -e 1.5 -t) -add_test(turbodecoder_test_known turbodecoder_test -n 1 -s 1 -k -e 0.5) +add_lte_test(turbodecoder_test_504_1 turbodecoder_test -n 100 -s 1 -l 504 -e 1.0 -t) +add_lte_test(turbodecoder_test_504_2 turbodecoder_test -n 100 -s 1 -l 504 -e 2.0 -t) +add_lte_test(turbodecoder_test_6114_1_5 turbodecoder_test -n 100 -s 1 -l 6144 -e 1.5 -t) +add_lte_test(turbodecoder_test_known turbodecoder_test -n 1 -s 1 -k -e 0.5) add_executable(turbocoder_test turbocoder_test.c) target_link_libraries(turbocoder_test srslte_phy) -add_test(turbocoder_test_all turbocoder_test) +add_lte_test(turbocoder_test_all turbocoder_test) diff --git a/lib/src/phy/fec/turbo/test/turbodecoder_test.c b/lib/src/phy/fec/turbo/test/turbodecoder_test.c index 8ffcdae5a..da05c9a7b 100644 --- a/lib/src/phy/fec/turbo/test/turbodecoder_test.c +++ b/lib/src/phy/fec/turbo/test/turbodecoder_test.c @@ -189,7 +189,7 @@ int main(int argc, char** argv) } if (srslte_tcod_init(&tcod, frame_length)) { - ERROR("Error initiating Turbo coder\n"); + ERROR("Error initiating Turbo coder"); exit(-1); } @@ -199,7 +199,7 @@ int main(int argc, char** argv) // tdec_type = SRSLTE_TDEC_SSE_WINDOW; #endif if (srslte_tdec_init_manual(&tdec, frame_length, tdec_type)) { - ERROR("Error initiating Turbo decoder\n"); + ERROR("Error initiating Turbo decoder"); exit(-1); } @@ -220,7 +220,6 @@ int main(int argc, char** argv) snr_points = 1; } for (i = 0; i < snr_points; i++) { - mean_usec = 0; errors = 0; frame_cnt = 0; diff --git a/lib/src/phy/fec/turbo/turbocoder.c b/lib/src/phy/fec/turbo/turbocoder.c index 02e15f57e..2e4f0fbe7 100644 --- a/lib/src/phy/fec/turbo/turbocoder.c +++ b/lib/src/phy/fec/turbo/turbocoder.c @@ -48,7 +48,6 @@ static bool table_initiated = false; int srslte_tcod_init(srslte_tcod_t* h, uint32_t max_long_cb) { - h->max_long_cb = max_long_cb; h->temp = srslte_vec_malloc(max_long_cb / 8); @@ -77,7 +76,6 @@ void srslte_tcod_free(srslte_tcod_t* h) /* Expects bits (1 byte = 1 bit) and produces bits. The systematic and parity bits are interlaced in the output */ int srslte_tcod_encode(srslte_tcod_t* h, uint8_t* input, uint8_t* output, uint32_t long_cb) { - uint8_t reg1_0, reg1_1, reg1_2, reg2_0, reg2_1, reg2_2; uint32_t i, k = 0, j; uint8_t bit; @@ -85,13 +83,13 @@ int srslte_tcod_encode(srslte_tcod_t* h, uint8_t* input, uint8_t* output, uint32 uint16_t* per; if (long_cb > h->max_long_cb) { - ERROR("Turbo coder initiated for max_long_cb=%d\n", h->max_long_cb); + ERROR("Turbo coder initiated for max_long_cb=%d", h->max_long_cb); return -1; } int longcb_idx = srslte_cbsegm_cbindex(long_cb); if (longcb_idx < 0) { - ERROR("Invalid CB size %d\n", long_cb); + ERROR("Invalid CB size %d", long_cb); return -1; } @@ -199,7 +197,7 @@ int srslte_tcod_encode_lut(srslte_tcod_t* h, uint32_t long_cb = (uint32_t)srslte_cbsegm_cbsize(cblen_idx); if (long_cb % 8) { - ERROR("Turbo coder LUT implementation long_cb must be multiple of 8\n"); + ERROR("Turbo coder LUT implementation long_cb must be multiple of 8"); return -1; } @@ -376,14 +374,14 @@ void srslte_tcod_gentable() srslte_tc_interl_t interl; if (srslte_tc_interl_init(&interl, 6144)) { - ERROR("Error initiating interleave\n"); + ERROR("Error initiating interleave"); return; } for (uint32_t len = 0; len < 188; len++) { uint32_t long_cb = srslte_cbsegm_cbsize(len); if (srslte_tc_interl_LTE_gen(&interl, long_cb)) { - ERROR("Error initiating TC interleaver for long_cb=%d\n", long_cb); + ERROR("Error initiating TC interleaver for long_cb=%d", long_cb); return; } // Save fw/bw permutation tables @@ -398,7 +396,6 @@ void srslte_tcod_gentable() // Compute state transitions for (uint32_t state = 0; state < 8; state++) { for (uint32_t data = 0; data < 256; data++) { - uint8_t reg_0, reg_1, reg_2; reg_0 = (state & 4) >> 2; reg_1 = (state & 2) >> 1; diff --git a/lib/src/phy/fec/turbo/turbodecoder.c b/lib/src/phy/fec/turbo/turbodecoder.c index a0b3825d5..3174b44ab 100644 --- a/lib/src/phy/fec/turbo/turbodecoder.c +++ b/lib/src/phy/fec/turbo/turbodecoder.c @@ -196,7 +196,7 @@ int srslte_tdec_init_manual(srslte_tdec_t* h, uint32_t max_long_cb, srslte_tdec_ break; #endif /* LV_HAVE_AVX2 */ default: - ERROR("Error decoder %d not supported\n", dec_type); + ERROR("Error decoder %d not supported", dec_type); goto clean_and_exit; } @@ -403,7 +403,7 @@ static int tdec_sb_idx(uint32_t long_cb) case 0: return AUTO_16_SSE; } - ERROR("Error in tdec_sb_idx() invalid nof_sb=%d\n", nof_sb); + ERROR("Error in tdec_sb_idx() invalid nof_sb=%d", nof_sb); return 0; } @@ -436,7 +436,7 @@ static int tdec_sb_idx_8(uint32_t long_cb) case 0: return 10 + AUTO_16_SSE; } - ERROR("Error in tdec_sb_idx_8() invalid nof_sb=%d\n", nof_sb); + ERROR("Error in tdec_sb_idx_8() invalid nof_sb=%d", nof_sb); return 0; } @@ -495,7 +495,6 @@ static void tdec_iteration_16(srslte_tdec_t* h, int16_t* input) h->current_inter_idx = interleaver_idx(h->nof_blocks16[h->current_dec]); if (h->current_llr_type == SRSLTE_TDEC_8) { - h->current_inter_idx = interleaver_idx(h->nof_blocks8[h->current_dec]); if (!h->n_iter) { @@ -511,7 +510,7 @@ static void tdec_iteration_16(srslte_tdec_t* h, int16_t* input) int srslte_tdec_new_cb(srslte_tdec_t* h, uint32_t long_cb) { if (long_cb > h->max_long_cb) { - ERROR("TDEC was initialized for max_long_cb=%d\n", h->max_long_cb); + ERROR("TDEC was initialized for max_long_cb=%d", h->max_long_cb); return -1; } @@ -519,7 +518,7 @@ int srslte_tdec_new_cb(srslte_tdec_t* h, uint32_t long_cb) h->current_long_cb = long_cb; h->current_cbidx = srslte_cbsegm_cbindex(long_cb); if (h->current_cbidx < 0) { - ERROR("Invalid CB length %d\n", long_cb); + ERROR("Invalid CB length %d", long_cb); return -1; } return 0; diff --git a/lib/src/phy/fec/utils_avx512.h b/lib/src/phy/fec/utils_avx512.h new file mode 100644 index 000000000..dc650b519 --- /dev/null +++ b/lib/src/phy/fec/utils_avx512.h @@ -0,0 +1,29 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 utils_avx512.h + * \brief Declarations of AVX512-related quantities and functions. + * \author Jesus Gomez + * \date 2020 + * + * \copyright Software Radio Systems Limited + * + */ + +#ifndef SRSLTE_UTILS_AVX512_H +#define SRSLTE_UTILS_AVX512_H + +#define SRSLTE_AVX512_B_SIZE 64 /*!< \brief Number of packed bytes in an AVX512 instruction. */ +#define SRSLTE_AVX512_B_SIZE_LOG 6 /*!< \brief \f$\log_2\f$ of \ref SRSLTE_AVX512_B_SIZE. */ + +#endif // SRSLTE_UTILS_AVX512_H diff --git a/lib/src/phy/mimo/layermap.c b/lib/src/phy/mimo/layermap.c index 74ee703d1..bccd9e090 100644 --- a/lib/src/phy/mimo/layermap.c +++ b/lib/src/phy/mimo/layermap.c @@ -64,13 +64,12 @@ int srslte_layermap_multiplex(cf_t* d[SRSLTE_MAX_CODEWORDS], n[0] = nof_layers / nof_cw; n[1] = nof_layers - n[0]; if (nof_symbols[0] / n[0] == nof_symbols[1] / n[1]) { - srslte_layermap_diversity(d[0], x, n[0], nof_symbols[0]); srslte_layermap_diversity(d[1], &x[n[0]], n[1], nof_symbols[1]); return nof_symbols[0] / n[0]; } else { - ERROR("Number of symbols in codewords 0 and 1 is not consistent (%d, %d)\n", nof_symbols[0], nof_symbols[1]); + ERROR("Number of symbols in codewords 0 and 1 is not consistent (%d, %d)", nof_symbols[0], nof_symbols[1]); return -1; } } @@ -88,17 +87,16 @@ int srslte_layermap_type(cf_t* d[SRSLTE_MAX_CODEWORDS], int nof_symbols[SRSLTE_MAX_CODEWORDS], srslte_tx_scheme_t type) { - if (nof_cw > SRSLTE_MAX_CODEWORDS) { - ERROR("Maximum number of codewords is %d (nof_cw=%d)\n", SRSLTE_MAX_CODEWORDS, nof_cw); + ERROR("Maximum number of codewords is %d (nof_cw=%d)", SRSLTE_MAX_CODEWORDS, nof_cw); return -1; } if (nof_layers > SRSLTE_MAX_LAYERS) { - ERROR("Maximum number of layers is %d (nof_layers=%d)\n", SRSLTE_MAX_LAYERS, nof_layers); + ERROR("Maximum number of layers is %d (nof_layers=%d)", SRSLTE_MAX_LAYERS, nof_layers); return -1; } if (nof_layers < nof_cw) { - ERROR("Number of codewords must be lower or equal than number of layers\n"); + ERROR("Number of codewords must be lower or equal than number of layers"); return -1; } @@ -107,7 +105,7 @@ int srslte_layermap_type(cf_t* d[SRSLTE_MAX_CODEWORDS], if (nof_cw == 1 && nof_layers == 1) { return srslte_layermap_single(d[0], x[0], nof_symbols[0]); } else { - ERROR("Number of codewords and layers must be 1 for transmission on single antenna ports\n"); + ERROR("Number of codewords and layers must be 1 for transmission on single antenna ports"); return -1; } break; @@ -116,11 +114,11 @@ int srslte_layermap_type(cf_t* d[SRSLTE_MAX_CODEWORDS], if (nof_layers == 2 || nof_layers == 4) { return srslte_layermap_diversity(d[0], x, nof_layers, nof_symbols[0]); } else { - ERROR("Number of layers must be 2 or 4 for transmit diversity\n"); + ERROR("Number of layers must be 2 or 4 for transmit diversity"); return -1; } } else { - ERROR("Number of codewords must be 1 for transmit diversity\n"); + ERROR("Number of codewords must be 1 for transmit diversity"); return -1; } break; @@ -183,17 +181,16 @@ int srslte_layerdemap_type(cf_t* x[SRSLTE_MAX_LAYERS], int nof_symbols[SRSLTE_MAX_CODEWORDS], srslte_tx_scheme_t type) { - if (nof_cw > SRSLTE_MAX_CODEWORDS) { - ERROR("Maximum number of codewords is %d (nof_cw=%d)\n", SRSLTE_MAX_CODEWORDS, nof_cw); + ERROR("Maximum number of codewords is %d (nof_cw=%d)", SRSLTE_MAX_CODEWORDS, nof_cw); return -1; } if (nof_layers > SRSLTE_MAX_LAYERS) { - ERROR("Maximum number of layers is %d (nof_layers=%d)\n", SRSLTE_MAX_LAYERS, nof_layers); + ERROR("Maximum number of layers is %d (nof_layers=%d)", SRSLTE_MAX_LAYERS, nof_layers); return -1; } if (nof_layers < nof_cw) { - ERROR("Number of codewords must be lower or equal than number of layers\n"); + ERROR("Number of codewords must be lower or equal than number of layers"); return -1; } @@ -203,7 +200,7 @@ int srslte_layerdemap_type(cf_t* x[SRSLTE_MAX_LAYERS], nof_symbols[0] = srslte_layerdemap_single(x[0], d[0], nof_layer_symbols); nof_symbols[1] = 0; } else { - ERROR("Number of codewords and layers must be 1 for transmission on single antenna ports\n"); + ERROR("Number of codewords and layers must be 1 for transmission on single antenna ports"); return -1; } break; @@ -213,11 +210,11 @@ int srslte_layerdemap_type(cf_t* x[SRSLTE_MAX_LAYERS], nof_symbols[0] = srslte_layerdemap_diversity(x, d[0], nof_layers, nof_layer_symbols); nof_symbols[1] = 0; } else { - ERROR("Number of layers must be 2 or 4 for transmit diversity\n"); + ERROR("Number of layers must be 2 or 4 for transmit diversity"); return -1; } } else { - ERROR("Number of codewords must be 1 for transmit diversity\n"); + ERROR("Number of codewords must be 1 for transmit diversity"); return -1; } break; @@ -258,7 +255,7 @@ int srslte_layermap_nr(cf_t** d, int nof_cw, cf_t** x, int nof_layers, uint32_t return SRSLTE_SUCCESS; } - ERROR("Error. Incompatible number of layers (%d) and codewords (%d)\n", nof_layers, nof_cw); + ERROR("Error. Incompatible number of layers (%d) and codewords (%d)", nof_layers, nof_cw); return SRSLTE_ERROR; } @@ -291,6 +288,6 @@ int srslte_layerdemap_nr(cf_t** d, int nof_cw, cf_t** x, int nof_layers, uint32_ return SRSLTE_SUCCESS; } - ERROR("Error. Incompatible number of layers (%d) and codewords (%d)\n", nof_layers, nof_cw); + ERROR("Error. Incompatible number of layers (%d) and codewords (%d)", nof_layers, nof_cw); return SRSLTE_ERROR; } diff --git a/lib/src/phy/mimo/precoding.c b/lib/src/phy/mimo/precoding.c index ac2d53baa..caee3fe27 100644 --- a/lib/src/phy/mimo/precoding.c +++ b/lib/src/phy/mimo/precoding.c @@ -81,7 +81,6 @@ int srslte_predecoding_single_sse(cf_t* y[SRSLTE_MAX_PORTS], float scaling, float noise_estimate) { - float* xPtr = (float*)x; const float* hPtr1 = (const float*)h[0]; const float* yPtr1 = (const float*)y[0]; @@ -188,7 +187,6 @@ int srslte_predecoding_single_avx(cf_t* y[SRSLTE_MAX_PORTS], float scaling, float noise_estimate) { - float* xPtr = (float*)x; const float* hPtr1 = (const float*)h[0]; const float* yPtr1 = (const float*)y[0]; @@ -364,7 +362,6 @@ int srslte_predecoding_single(cf_t* y_, float scaling, float noise_estimate) { - cf_t* y[SRSLTE_MAX_PORTS]; cf_t* h[SRSLTE_MAX_PORTS]; y[0] = y_; @@ -500,7 +497,7 @@ int srslte_predecoding_diversity_gen_(cf_t* y[SRSLTE_MAX_PORTS], } return i; } else { - ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)\n", nof_ports); + ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)", nof_ports); return -1; } } @@ -545,7 +542,6 @@ int srslte_predecoding_diversity2_sse(cf_t* y[SRSLTE_MAX_PORTS], __m128 x0, x1; for (int i = 0; i < nof_symbols / 4; i++) { - h0Val_00 = _mm_load_ps(h0Ptr0); h0Ptr0 += 4; h0Val_10 = _mm_load_ps(h0Ptr0); @@ -776,7 +772,7 @@ int srslte_predecoding_diversity_csi(cf_t* y[SRSLTE_MAX_PORTS], } return i; } else { - ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)\n", nof_ports); + ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)", nof_ports); return -1; } } @@ -813,11 +809,9 @@ int srslte_precoding_mimo_2x2_gen(cf_t W[2][2], float scaling, float noise_estimate) { - cf_t G[2][2], Gx[2][2]; for (int i = 0; i < nof_symbols; i++) { - // G=H*W G[0][0] = h[0][0][i] * W[0][0] + h[0][1][i] * W[1][0]; G[0][1] = h[0][0][i] * W[1][0] + h[0][1][i] * W[1][1]; @@ -832,7 +826,7 @@ int srslte_precoding_mimo_2x2_gen(cf_t W[2][2], Gx[1][1] = conjf(G[1][1]); } else { // MMSE equalizer: Gx = (G'G+I) - ERROR("MMSE MIMO decoder not implemented\n"); + ERROR("MMSE MIMO decoder not implemented"); return -1; } @@ -903,7 +897,6 @@ static int srslte_predecoding_ccd_2x2_zf_csi(cf_t* y[SRSLTE_MAX_PORTS], cf_t h00, h01, h10, h11, det; for (; i < nof_symbols; i++) { - // Even precoder h00 = +h[0][0][i] + h[1][0][i]; h10 = +h[0][1][i] + h[1][1][i]; @@ -991,7 +984,6 @@ static int srslte_predecoding_ccd_2x2_zf(cf_t* y[SRSLTE_MAX_PORTS], cf_t h00, h01, h10, h11, det; for (; i < nof_symbols; i++) { - // Even precoder h00 = +h[0][0][i] + h[1][0][i]; h10 = +h[0][1][i] + h[1][1][i]; @@ -1037,13 +1029,13 @@ static int srslte_predecoding_ccd_zf(cf_t* y[SRSLTE_MAX_PORTS], return srslte_predecoding_ccd_2x2_zf(y, h, x, nof_symbols, scaling); } } else { - ERROR("Error predecoding CCD: Invalid number of layers %d\n", nof_layers); + ERROR("Error predecoding CCD: Invalid number of layers %d", nof_layers); return -1; } } else if (nof_ports == 4) { - ERROR("Error predecoding CCD: Only 2 ports supported\n"); + ERROR("Error predecoding CCD: Only 2 ports supported"); } else { - ERROR("Error predecoding CCD: Invalid combination of ports %d and rx antennax %d\n", nof_ports, nof_rxant); + ERROR("Error predecoding CCD: Invalid combination of ports %d and rx antennax %d", nof_ports, nof_rxant); } return SRSLTE_ERROR; } @@ -1108,7 +1100,6 @@ static int srslte_predecoding_ccd_2x2_mmse_csi(cf_t* y[SRSLTE_MAX_PORTS], cf_t h00, h01, h10, h11; for (; i < nof_symbols; i++) { - // Even precoder h00 = +h[0][0][i] + h[1][0][i]; h10 = +h[0][1][i] + h[1][1][i]; @@ -1183,7 +1174,6 @@ static int srslte_predecoding_ccd_2x2_mmse(cf_t* y[SRSLTE_MAX_PORTS], cf_t h00, h01, h10, h11; for (; i < nof_symbols; i++) { - // Even precoder h00 = +h[0][0][i] + h[1][0][i]; h10 = +h[0][1][i] + h[1][1][i]; @@ -1222,13 +1212,13 @@ int srslte_predecoding_ccd_mmse(cf_t* y[SRSLTE_MAX_PORTS], return srslte_predecoding_ccd_2x2_mmse(y, h, x, nof_symbols, scaling, noise_estimate); } } else { - ERROR("Error predecoding CCD: Invalid number of layers %d\n", nof_layers); + ERROR("Error predecoding CCD: Invalid number of layers %d", nof_layers); return -1; } } else if (nof_ports == 4) { - ERROR("Error predecoding CCD: Only 2 ports supported\n"); + ERROR("Error predecoding CCD: Only 2 ports supported"); } else { - ERROR("Error predecoding CCD: Invalid combination of ports %d and rx antennax %d\n", nof_ports, nof_rxant); + ERROR("Error predecoding CCD: Invalid combination of ports %d and rx antennax %d", nof_ports, nof_rxant); } return SRSLTE_ERROR; } @@ -1285,7 +1275,7 @@ static int srslte_predecoding_multiplex_2x2_zf_csi(cf_t* y[SRSLTE_MAX_PORTS], h11 = srslte_simd_cf_sub(h01i, srslte_simd_cf_mulj(h11i)); break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1327,7 +1317,7 @@ static int srslte_predecoding_multiplex_2x2_zf_csi(cf_t* y[SRSLTE_MAX_PORTS], h11 = h[0][1][i] - _Complex_I * h[1][1][i]; break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1395,7 +1385,7 @@ static int srslte_predecoding_multiplex_2x2_zf(cf_t* y[SRSLTE_MAX_PORTS], h11 = srslte_simd_cf_sub(h01i, srslte_simd_cf_mulj(h11i)); break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1434,7 +1424,7 @@ static int srslte_predecoding_multiplex_2x2_zf(cf_t* y[SRSLTE_MAX_PORTS], h11 = h[0][1][i] - _Complex_I * h[1][1][i]; break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1497,7 +1487,7 @@ static int srslte_predecoding_multiplex_2x2_mmse_csi(cf_t* y[SRSLTE_MAX_PORTS], h11 = srslte_simd_cf_sub(h01i, srslte_simd_cf_mulj(h11i)); break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1539,7 +1529,7 @@ static int srslte_predecoding_multiplex_2x2_mmse_csi(cf_t* y[SRSLTE_MAX_PORTS], h11 = h[0][1][i] - _Complex_I * h[1][1][i]; break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1601,7 +1591,7 @@ static int srslte_predecoding_multiplex_2x2_mmse(cf_t* y[SRSLTE_MAX_PORTS], h11 = srslte_simd_cf_sub(h01i, srslte_simd_cf_mulj(h11i)); break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1640,7 +1630,7 @@ static int srslte_predecoding_multiplex_2x2_mmse(cf_t* y[SRSLTE_MAX_PORTS], h11 = h[0][1][i] - _Complex_I * h[1][1][i]; break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1687,7 +1677,7 @@ static int srslte_predecoding_multiplex_2x1_mrc(cf_t* y[SRSLTE_MAX_PORTS], hx = srslte_simd_cf_sub(h0xi, srslte_simd_cf_mulj(h1xi)); break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1722,7 +1712,7 @@ static int srslte_predecoding_multiplex_2x1_mrc(cf_t* y[SRSLTE_MAX_PORTS], h1 = h[0][1][i] - _Complex_I * h[1][1][i]; break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1772,7 +1762,7 @@ static int srslte_predecoding_multiplex_2x1_mrc_csi(cf_t* y[SRSLTE_MAX_PORTS], hx = srslte_simd_cf_sub(h0xi, srslte_simd_cf_mulj(h1xi)); break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1808,7 +1798,7 @@ static int srslte_predecoding_multiplex_2x1_mrc_csi(cf_t* y[SRSLTE_MAX_PORTS], h1 = h[0][1][i] - _Complex_I * h[1][1][i]; break; default: - ERROR("Wrong codebook_idx=%d\n", codebook_idx); + ERROR("Wrong codebook_idx=%d", codebook_idx); return SRSLTE_ERROR; } @@ -1862,7 +1852,7 @@ static int srslte_predecoding_multiplex(cf_t* y[SRSLTE_MAX_PORTS], } else if (nof_ports == 4) { ERROR("Error predecoding multiplex: not implemented for %d Tx ports", nof_ports); } else { - ERROR("Error predecoding multiplex: Invalid combination of ports %d and rx antennas %d\n", nof_ports, nof_rxant); + ERROR("Error predecoding multiplex: Invalid combination of ports %d and rx antennas %d", nof_ports, nof_rxant); } return SRSLTE_ERROR; } @@ -1886,13 +1876,12 @@ int srslte_predecoding_type(cf_t* y[SRSLTE_MAX_PORTS], float scaling, float noise_estimate) { - if (nof_ports > SRSLTE_MAX_PORTS) { - ERROR("Maximum number of ports is %d (nof_ports=%d)\n", SRSLTE_MAX_PORTS, nof_ports); + ERROR("Maximum number of ports is %d (nof_ports=%d)", SRSLTE_MAX_PORTS, nof_ports); return SRSLTE_ERROR; } if (nof_layers > SRSLTE_MAX_LAYERS) { - ERROR("Maximum number of layers is %d (nof_layers=%d)\n", SRSLTE_MAX_LAYERS, nof_layers); + ERROR("Maximum number of layers is %d (nof_layers=%d)", SRSLTE_MAX_LAYERS, nof_layers); return SRSLTE_ERROR; } @@ -1907,7 +1896,7 @@ int srslte_predecoding_type(cf_t* y[SRSLTE_MAX_PORTS], y, h, x, csi, nof_rxant, nof_ports, nof_layers, nof_symbols, scaling, noise_estimate); } } else { - ERROR("Invalid number of layers %d\n", nof_layers); + ERROR("Invalid number of layers %d", nof_layers); return SRSLTE_ERROR; } return SRSLTE_ERROR; @@ -1915,7 +1904,7 @@ int srslte_predecoding_type(cf_t* y[SRSLTE_MAX_PORTS], if (nof_ports == 1 && nof_layers == 1) { return srslte_predecoding_single_multi(y, h[0], x[0], csi, nof_rxant, nof_symbols, scaling, noise_estimate); } else { - ERROR("Number of ports and layers must be 1 for transmission on single antenna ports (%d, %d)\n", + ERROR("Number of ports and layers must be 1 for transmission on single antenna ports (%d, %d)", nof_ports, nof_layers); return SRSLTE_ERROR; @@ -1924,14 +1913,14 @@ int srslte_predecoding_type(cf_t* y[SRSLTE_MAX_PORTS], if (nof_ports == nof_layers) { return srslte_predecoding_diversity_multi(y, h, x, csi, nof_rxant, nof_ports, nof_symbols, scaling); } else { - ERROR("Error number of layers must equal number of ports in transmit diversity\n"); + ERROR("Error number of layers must equal number of ports in transmit diversity"); return SRSLTE_ERROR; } case SRSLTE_TXSCHEME_SPATIALMUX: return srslte_predecoding_multiplex( y, h, x, csi, nof_rxant, nof_ports, nof_layers, codebook_idx, nof_symbols, scaling, noise_estimate); default: - ERROR("Invalid Txscheme=%d\n", type); + ERROR("Invalid Txscheme=%d", type); return SRSLTE_ERROR; } } @@ -1997,7 +1986,7 @@ int srslte_precoding_diversity(cf_t* x[SRSLTE_MAX_LAYERS], } return 4 * i; } else { - ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)\n", nof_ports); + ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)", nof_ports); return -1; } } @@ -2074,7 +2063,7 @@ int srslte_precoding_cdd(cf_t* x[SRSLTE_MAX_LAYERS], { if (nof_ports == 2) { if (nof_layers != 2) { - ERROR("Invalid number of layers %d for 2 ports\n", nof_layers); + ERROR("Invalid number of layers %d for 2 ports", nof_layers); return -1; } #ifdef LV_HAVE_AVX @@ -2087,10 +2076,10 @@ int srslte_precoding_cdd(cf_t* x[SRSLTE_MAX_LAYERS], #endif /* LV_HAVE_SSE */ #endif /* LV_HAVE_AVX */ } else if (nof_ports == 4) { - ERROR("Not implemented\n"); + ERROR("Not implemented"); return -1; } else { - ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)\n", nof_ports); + ERROR("Number of ports must be 2 or 4 for transmit diversity (nof_ports=%d)", nof_ports); return -1; } } @@ -2125,7 +2114,7 @@ int srslte_precoding_multiplex(cf_t* x[SRSLTE_MAX_LAYERS], srslte_vec_sc_prod_ccc(x[0], -_Complex_I * scaling, y[1], nof_symbols); break; default: - ERROR("Invalid multiplex combination: codebook_idx=%d, nof_layers=%d, nof_ports=%d\n", + ERROR("Invalid multiplex combination: codebook_idx=%d, nof_layers=%d, nof_ports=%d", codebook_idx, nof_layers, nof_ports); @@ -2206,7 +2195,7 @@ int srslte_precoding_multiplex(cf_t* x[SRSLTE_MAX_LAYERS], break; case 3: default: - ERROR("Invalid multiplex combination: codebook_idx=%d, nof_layers=%d, nof_ports=%d\n", + ERROR("Invalid multiplex combination: codebook_idx=%d, nof_layers=%d, nof_ports=%d", codebook_idx, nof_layers, nof_ports); @@ -2231,13 +2220,12 @@ int srslte_precoding_type(cf_t* x[SRSLTE_MAX_LAYERS], float scaling, srslte_tx_scheme_t type) { - if (nof_ports > SRSLTE_MAX_PORTS) { - ERROR("Maximum number of ports is %d (nof_ports=%d)\n", SRSLTE_MAX_PORTS, nof_ports); + ERROR("Maximum number of ports is %d (nof_ports=%d)", SRSLTE_MAX_PORTS, nof_ports); return -1; } if (nof_layers > SRSLTE_MAX_LAYERS) { - ERROR("Maximum number of layers is %d (nof_layers=%d)\n", SRSLTE_MAX_LAYERS, nof_layers); + ERROR("Maximum number of layers is %d (nof_layers=%d)", SRSLTE_MAX_LAYERS, nof_layers); return -1; } @@ -2248,7 +2236,7 @@ int srslte_precoding_type(cf_t* x[SRSLTE_MAX_LAYERS], if (nof_ports == 1 && nof_layers == 1) { return srslte_precoding_single(x[0], y[0], nof_symbols, scaling); } else { - ERROR("Number of ports and layers must be 1 for transmission on single antenna ports\n"); + ERROR("Number of ports and layers must be 1 for transmission on single antenna ports"); return -1; } break; @@ -2256,7 +2244,7 @@ int srslte_precoding_type(cf_t* x[SRSLTE_MAX_LAYERS], if (nof_ports == nof_layers) { return srslte_precoding_diversity(x, y, nof_ports, nof_symbols, scaling); } else { - ERROR("Error number of layers must equal number of ports in transmit diversity\n"); + ERROR("Error number of layers must equal number of ports in transmit diversity"); return -1; } case SRSLTE_TXSCHEME_SPATIALMUX: @@ -2276,7 +2264,6 @@ int srslte_precoding_pmi_select_1l_gen(cf_t* h[SRSLTE_MAX_PORTS][SRSLTE_MAX_ uint32_t* pmi, float sinr_list[SRSLTE_MAX_CODEBOOKS]) { - #define SQRT1_2 ((float)M_SQRT1_2) float max_sinr = 0.0; uint32_t i, count; @@ -2491,7 +2478,7 @@ int srslte_precoding_pmi_select_1l(cf_t* h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT #else ret = srslte_precoding_pmi_select_1l_gen(h, nof_symbols, noise_estimate, pmi, sinr_list); #endif /* SRSLTE_SIMD_CF_SIZE != 0 */ - INFO("Precoder PMI Select for 1 layer SINR=[%.1fdB; %.1fdB; %.1fdB; %.1fdB] PMI=%d\n", + INFO("Precoder PMI Select for 1 layer SINR=[%.1fdB; %.1fdB; %.1fdB; %.1fdB] PMI=%d", srslte_convert_power_to_dB(sinr_list[0]), srslte_convert_power_to_dB(sinr_list[1]), srslte_convert_power_to_dB(sinr_list[2]), @@ -2507,7 +2494,6 @@ int srslte_precoding_pmi_select_2l_gen(cf_t* h[SRSLTE_MAX_PORTS][SRSLTE_MAX_ uint32_t* pmi, float sinr_list[SRSLTE_MAX_CODEBOOKS]) { - float max_sinr = 0.0; uint32_t i, count; @@ -2767,7 +2753,6 @@ int srslte_precoding_pmi_select_2l(cf_t* h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT uint32_t* pmi, float sinr_list[SRSLTE_MAX_CODEBOOKS]) { - int ret; #if SRSLTE_SIMD_CF_SIZE != 0 ret = srslte_precoding_pmi_select_2l_simd(h, nof_symbols, noise_estimate, pmi, sinr_list); @@ -2775,7 +2760,7 @@ int srslte_precoding_pmi_select_2l(cf_t* h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORT ret = srslte_precoding_pmi_select_2l_gen(h, nof_symbols, noise_estimate, pmi, sinr_list); #endif /* SRSLTE_SIMD_CF_SIZE != 0 */ - INFO("Precoder PMI Select for 2 layers SINR=[%.1fdB; %.1fdB] PMI=%d\n", + INFO("Precoder PMI Select for 2 layers SINR=[%.1fdB; %.1fdB] PMI=%d", srslte_convert_power_to_dB(sinr_list[0]), srslte_convert_power_to_dB(sinr_list[1]), *pmi); @@ -2848,7 +2833,7 @@ int srslte_precoding_cn(cf_t* h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], *cn = srslte_precoding_2x2_cn_gen(h, nof_symbols); return SRSLTE_SUCCESS; } else { - ERROR("MIMO Condition Number calculation not implemented for %d×%d\n", nof_tx_antennas, nof_rx_antennas); + ERROR("MIMO Condition Number calculation not implemented for %d×%d", nof_tx_antennas, nof_rx_antennas); return SRSLTE_ERROR; } } diff --git a/lib/src/phy/mimo/test/layermap_test.c b/lib/src/phy/mimo/test/layermap_test.c index 7c970a71a..f1c3fa5d0 100644 --- a/lib/src/phy/mimo/test/layermap_test.c +++ b/lib/src/phy/mimo/test/layermap_test.c @@ -86,7 +86,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (srslte_str2mimotype(mimo_type_name, &type)) { - ERROR("Invalid MIMO type %s\n", mimo_type_name); + ERROR("Invalid MIMO type %s", mimo_type_name); exit(-1); } @@ -129,13 +129,13 @@ int main(int argc, char** argv) /* layer mapping */ if ((symbols_layer = srslte_layermap_type(d, x, nof_cw, nof_layers, nof_symb_cw, type)) < 0) { - ERROR("Error layer mapper encoder\n"); + ERROR("Error layer mapper encoder"); exit(-1); } /* layer de-mapping */ if (srslte_layerdemap_type(x, dp, nof_layers, nof_cw, nof_symbols / nof_layers, nof_symb_cw, type) < 0) { - ERROR("Error layer mapper encoder\n"); + ERROR("Error layer mapper encoder"); exit(-1); } diff --git a/lib/src/phy/mimo/test/pmi_select_test.c b/lib/src/phy/mimo/test/pmi_select_test.c index c3e9399ee..76d5eeb9c 100644 --- a/lib/src/phy/mimo/test/pmi_select_test.c +++ b/lib/src/phy/mimo/test/pmi_select_test.c @@ -90,7 +90,7 @@ int main(int argc, char** argv) } if (err > 0.1f) { - ERROR("Test case %d failed computing 1 layer SINR for codebook %d (test=%.2f; gold=%.2f)\n", + ERROR("Test case %d failed computing 1 layer SINR for codebook %d (test=%.2f; gold=%.2f)", c + 1, i, sinr_1l[i], @@ -101,7 +101,7 @@ int main(int argc, char** argv) /* Check PMI select for 1 layer*/ if (pmi[0] != gold->pmi[0]) { - ERROR("Test case %d failed computing 1 layer PMI (test=%d; gold=%d)\n", c + 1, pmi[0], gold->pmi[0]); + ERROR("Test case %d failed computing 1 layer PMI (test=%d; gold=%d)", c + 1, pmi[0], gold->pmi[0]); goto clean; } @@ -122,7 +122,7 @@ int main(int argc, char** argv) } if (err > 0.1f) { - ERROR("Test case %d failed computing 2 layer SINR for codebook %d (test=%.2f; gold=%.2f)\n", + ERROR("Test case %d failed computing 2 layer SINR for codebook %d (test=%.2f; gold=%.2f)", c + 1, i, sinr_2l[i], @@ -133,19 +133,19 @@ int main(int argc, char** argv) /* Check PMI select for 2 layer*/ if (pmi[1] != gold->pmi[1]) { - ERROR("Test case %d failed computing 2 layer PMI (test=%d; gold=%d)\n", c + 1, pmi[1], gold->pmi[1]); + ERROR("Test case %d failed computing 2 layer PMI (test=%d; gold=%d)", c + 1, pmi[1], gold->pmi[1]); goto clean; } /* Condition number */ if (srslte_precoding_cn(h, 2, 2, nof_symbols, &cn)) { - ERROR("Test case %d condition number returned error\n", c + 1); + ERROR("Test case %d condition number returned error", c + 1); goto clean; } /* Check condition number */ if (fabsf(gold->k - cn) > 0.1) { - ERROR("Test case %d failed computing condition number (test=%.2f; gold=%.2f)\n", c + 1, cn, gold->k); + ERROR("Test case %d failed computing condition number (test=%.2f; gold=%.2f)", c + 1, cn, gold->k); goto clean; } } diff --git a/lib/src/phy/mimo/test/precoder_test.c b/lib/src/phy/mimo/test/precoder_test.c index 8de1f4252..fa0e7b4be 100644 --- a/lib/src/phy/mimo/test/precoder_test.c +++ b/lib/src/phy/mimo/test/precoder_test.c @@ -182,13 +182,13 @@ int main(int argc, char** argv) /* Check input ranges */ if (nof_tx_ports > SRSLTE_MAX_PORTS || nof_rx_ports > SRSLTE_MAX_PORTS || nof_layers > SRSLTE_MAX_LAYERS) { - ERROR("Invalid number of layers or ports\n"); + ERROR("Invalid number of layers or ports"); exit(-1); } /* Parse MIMO Type */ if (srslte_str2mimotype(mimo_type_name, &type)) { - ERROR("Invalid MIMO type %s\n", mimo_type_name); + ERROR("Invalid MIMO type %s", mimo_type_name); exit(-1); } @@ -203,7 +203,7 @@ int main(int argc, char** argv) case SRSLTE_TXSCHEME_CDD: nof_re = nof_symbols * nof_tx_ports / nof_layers; if (nof_rx_ports != 2 || nof_tx_ports != 2) { - ERROR("CDD nof_tx_ports=%d nof_rx_ports=%d is not currently supported\n", nof_tx_ports, nof_rx_ports); + ERROR("CDD nof_tx_ports=%d nof_rx_ports=%d is not currently supported", nof_tx_ports, nof_rx_ports); exit(-1); } break; @@ -268,7 +268,7 @@ int main(int argc, char** argv) /* Execute Precoding (Tx) */ if (srslte_precoding_type(x, y, nof_layers, nof_tx_ports, codebook_idx, nof_symbols, scaling, type) < 0) { - ERROR("Error layer mapper encoder\n"); + ERROR("Error layer mapper encoder"); exit(-1); } diff --git a/lib/src/phy/modem/demod_soft.c b/lib/src/phy/modem/demod_soft.c index 0af53cfcb..7f77b0023 100644 --- a/lib/src/phy/modem/demod_soft.c +++ b/lib/src/phy/modem/demod_soft.c @@ -223,7 +223,6 @@ void demod_16qam_lte_b_neon(const cf_t* symbols, int8_t* llr, int nsymbols) result1n = vdupq_n_s8(0); result2n = vdupq_n_s8(0); for (int i = 0; i < nsymbols / 8; i++) { - symbol1 = vld1q_f32(symbolsPtr); symbolsPtr += 4; symbol2 = vld1q_f32(symbolsPtr); @@ -457,7 +456,6 @@ void demod_64qam_lte_s_neon(const cf_t* symbols, short* llr, int nsymbols) int16x8_t result31 = vdupq_n_s16(0); for (int i = 0; i < nsymbols / 4; i++) { - symbol1 = vld1q_f32(symbolsPtr); symbolsPtr += 4; symbol2 = vld1q_f32(symbolsPtr); @@ -520,7 +518,6 @@ void demod_64qam_lte_b_neon(const cf_t* symbols, int8_t* llr, int nsymbols) int8x16_t result31 = vdupq_n_s8(0); for (int i = 0; i < nsymbols / 8; i++) { - symbol1 = vld1q_f32(symbolsPtr); symbolsPtr += 4; symbol2 = vld1q_f32(symbolsPtr); @@ -887,7 +884,7 @@ int srslte_demod_soft_demodulate(srslte_mod_t modulation, const cf_t* symbols, f demod_256qam_lte(symbols, llr, nsymbols); break; default: - ERROR("Invalid modulation %d\n", modulation); + ERROR("Invalid modulation %d", modulation); return -1; } return 0; @@ -912,7 +909,7 @@ int srslte_demod_soft_demodulate_s(srslte_mod_t modulation, const cf_t* symbols, demod_256qam_lte_s(symbols, llr, nsymbols); break; default: - ERROR("Invalid modulation %d\n", modulation); + ERROR("Invalid modulation %d", modulation); return -1; } return 0; @@ -937,7 +934,7 @@ int srslte_demod_soft_demodulate_b(srslte_mod_t modulation, const cf_t* symbols, demod_256qam_lte_b(symbols, llr, nsymbols); break; default: - ERROR("Invalid modulation %d\n", modulation); + ERROR("Invalid modulation %d", modulation); return -1; } return 0; diff --git a/lib/src/phy/modem/mod.c b/lib/src/phy/modem/mod.c index 715345f5e..7e213930b 100644 --- a/lib/src/phy/modem/mod.c +++ b/lib/src/phy/modem/mod.c @@ -134,13 +134,12 @@ static void mod_256qam_bytes(const srslte_modem_table_t* q, const uint8_t* bits, /* Assumes packet bits as input */ int srslte_mod_modulate_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits) { - if (!q->byte_tables_init) { - ERROR("Error need to initiated modem tables for packeted bits before calling srslte_mod_modulate_bytes()\n"); + ERROR("Error need to initiated modem tables for packeted bits before calling srslte_mod_modulate_bytes()"); return SRSLTE_ERROR; } if (nbits % q->nbits_x_symbol) { - ERROR("Error modulator expects number of bits (%d) to be multiple of %d\n", nbits, q->nbits_x_symbol); + ERROR("Error modulator expects number of bits (%d) to be multiple of %d", nbits, q->nbits_x_symbol); return -1; } switch (q->nbits_x_symbol) { @@ -160,7 +159,7 @@ int srslte_mod_modulate_bytes(const srslte_modem_table_t* q, const uint8_t* bits mod_256qam_bytes(q, bits, symbols, nbits); break; default: - ERROR("srslte_mod_modulate_bytes() accepts QPSK/16QAM/64QAM modulations only\n"); + ERROR("srslte_mod_modulate_bytes() accepts QPSK/16QAM/64QAM modulations only"); return SRSLTE_ERROR; } return nbits / q->nbits_x_symbol; diff --git a/lib/src/phy/modem/test/modem_test.c b/lib/src/phy/modem/test/modem_test.c index eb1342325..53f1c48a8 100644 --- a/lib/src/phy/modem/test/modem_test.c +++ b/lib/src/phy/modem/test/modem_test.c @@ -95,7 +95,7 @@ int main(int argc, char** argv) /* initialize objects */ if (srslte_modem_table_lte(&mod, modulation)) { - ERROR("Error initializing modem table\n"); + ERROR("Error initializing modem table"); exit(-1); } @@ -103,7 +103,7 @@ int main(int argc, char** argv) /* check that num_bits is multiple of num_bits x symbol */ if (num_bits % mod.nbits_x_symbol) { - ERROR("Error num_bits must be multiple of %d\n", mod.nbits_x_symbol); + ERROR("Error num_bits must be multiple of %d", mod.nbits_x_symbol); exit(-1); } @@ -189,7 +189,7 @@ int main(int argc, char** argv) /* check errors */ for (i = 0; i < num_bits && ret == SRSLTE_SUCCESS; i++) { if (input[i] != output[i]) { - ERROR("Error in bit %d\n", i); + ERROR("Error in bit %d", i); ret = SRSLTE_ERROR; } } diff --git a/lib/src/phy/modem/test/soft_demod_test.c b/lib/src/phy/modem/test/soft_demod_test.c index 7b99c17ae..0f6d109ca 100644 --- a/lib/src/phy/modem/test/soft_demod_test.c +++ b/lib/src/phy/modem/test/soft_demod_test.c @@ -75,7 +75,7 @@ void parse_args(int argc, char** argv) break; default: ERROR("Invalid modulation %d. Possible values: " - "(1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64)\n", + "(1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64)", (int)strtol(argv[optind], NULL, 10)); break; } @@ -123,7 +123,7 @@ int main(int argc, char** argv) /* initialize objects */ if (srslte_modem_table_lte(&mod, modulation)) { - ERROR("Error initializing modem table\n"); + ERROR("Error initializing modem table"); exit(-1); } diff --git a/lib/src/phy/phch/dci.c b/lib/src/phy/phch/dci.c index 42e6e3729..23f29c842 100644 --- a/lib/src/phy/phch/dci.c +++ b/lib/src/phy/phch/dci.c @@ -72,7 +72,7 @@ int srslte_dci_rar_to_ul_dci(srslte_cell_t* cell, srslte_dci_rar_grant_t* rar, s if (!rar->hopping_flag) { dci_ul->freq_hop_fl = SRSLTE_RA_PUSCH_HOP_DISABLED; } else { - ERROR("TODO: Frequency hopping in RAR not implemented\n"); + ERROR("TODO: Frequency hopping in RAR not implemented"); dci_ul->freq_hop_fl = 1; } uint32_t riv = rar->rba; @@ -213,7 +213,6 @@ static uint32_t dci_format0_sizeof(const srslte_cell_t* cell, srslte_dl_sf_cfg_t static uint32_t dci_format1_sizeof(const srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, srslte_dci_cfg_t* cfg) { - uint32_t n = (uint32_t)ceilf((float)cell->nof_prb / srslte_ra_type0_P(cell->nof_prb)) + 5 + HARQ_PID_LEN + 1 + 2 + 2 + (cfg->cif_enabled ? 3 : 0) + (IS_TDD ? 2 : 0); if (cell->nof_prb > 10) { @@ -419,7 +418,6 @@ static int dci_format0_pack(srslte_cell_t* cell, srslte_dci_ul_t* dci, srslte_dci_msg_t* msg) { - /* pack bits */ uint8_t* y = msg->payload; uint32_t n_ul_hop; @@ -497,7 +495,6 @@ static int dci_format0_unpack(srslte_cell_t* cell, srslte_dci_msg_t* msg, srslte_dci_ul_t* dci) { - /* pack bits */ uint8_t* y = msg->payload; uint32_t n_ul_hop; @@ -508,7 +505,7 @@ static int dci_format0_unpack(srslte_cell_t* cell, } if (*y++ != 0) { - INFO("DCI message is Format1A\n"); + INFO("DCI message is Format1A"); return SRSLTE_ERROR; } @@ -611,7 +608,7 @@ static int dci_format1_pack(srslte_cell_t* cell, srslte_bit_unpack((uint32_t)dci->type1_alloc.vrb_bitmask, &y, alloc_size - (int)ceilf(log2f(P)) - 1); break; default: - ERROR("Format 1 accepts type0 or type1 resource allocation only\n"); + ERROR("Format 1 accepts type0 or type1 resource allocation only"); return SRSLTE_ERROR; } /* pack MCS */ @@ -635,7 +632,7 @@ static int dci_format1_pack(srslte_cell_t* cell, msg->nof_bits = (y - msg->payload); if (msg->nof_bits != dci_format1_sizeof(cell, sf, cfg)) { - ERROR("Invalid message length for format 1 (Cross scheduling %s)\n", dci->cif_present ? "enabled" : "disabled"); + ERROR("Invalid message length for format 1 (Cross scheduling %s)", dci->cif_present ? "enabled" : "disabled"); } return SRSLTE_SUCCESS; @@ -647,14 +644,13 @@ static int dci_format1_unpack(srslte_cell_t* cell, srslte_dci_msg_t* msg, srslte_dci_dl_t* dci) { - /* pack bits */ uint8_t* y = msg->payload; /* Make sure it's a SRSLTE_DCI_FORMAT1 message */ uint32_t msg_len = srslte_dci_format_sizeof(cell, sf, cfg, SRSLTE_DCI_FORMAT1); if (msg->nof_bits != msg_len) { - ERROR("Invalid message length (%d!=%d) for format 1\n", msg->nof_bits, msg_len); + ERROR("Invalid message length (%d!=%d) for format 1", msg->nof_bits, msg_len); return SRSLTE_ERROR; } @@ -682,7 +678,7 @@ static int dci_format1_unpack(srslte_cell_t* cell, dci->type1_alloc.vrb_bitmask = srslte_bit_pack(&y, alloc_size - (int)ceilf(log2f(P)) - 1); break; default: - ERROR("Format 1 accepts type0 or type1 resource allocation only\n"); + ERROR("Format 1 accepts type0 or type1 resource allocation only"); return SRSLTE_ERROR; } /* unpack MCS according to 7.1.7 of 36.213 */ @@ -728,7 +724,7 @@ static int dci_format1As_pack(srslte_cell_t* cell, *y++ = 1; // format differentiation if (dci->alloc_type != SRSLTE_RA_ALLOC_TYPE2) { - ERROR("Format 1A accepts type2 resource allocation only\n"); + ERROR("Format 1A accepts type2 resource allocation only"); return SRSLTE_ERROR; } @@ -789,7 +785,6 @@ static int dci_format1As_unpack(srslte_cell_t* cell, srslte_dci_msg_t* msg, srslte_dci_dl_t* dci) { - /* pack bits */ uint8_t* y = msg->payload; @@ -799,7 +794,7 @@ static int dci_format1As_unpack(srslte_cell_t* cell, } if (*y++ != 1) { - INFO("DCI message is Format0\n"); + INFO("DCI message is Format0"); return SRSLTE_ERROR; } @@ -892,7 +887,6 @@ static int dci_format1B_unpack(srslte_cell_t* cell, srslte_dci_msg_t* msg, srslte_dci_dl_t* dci) { - /* pack bits */ uint8_t* y = msg->payload; @@ -946,7 +940,6 @@ static int dci_format1Cs_pack(srslte_cell_t* cell, srslte_dci_dl_t* dci, srslte_dci_msg_t* msg) { - uint32_t nof_prb = cell->nof_prb; /* pack bits */ @@ -957,7 +950,7 @@ static int dci_format1Cs_pack(srslte_cell_t* cell, } if (dci->alloc_type != SRSLTE_RA_ALLOC_TYPE2 || dci->type2_alloc.mode != SRSLTE_RA_TYPE2_DIST) { - ERROR("Format 1C accepts distributed type2 resource allocation only\n"); + ERROR("Format 1C accepts distributed type2 resource allocation only"); return SRSLTE_ERROR; } @@ -989,7 +982,7 @@ static int dci_format1Cs_unpack(srslte_cell_t* cell, uint8_t* y = msg->payload; if (msg->nof_bits != srslte_dci_format_sizeof(cell, sf, cfg, SRSLTE_DCI_FORMAT1C)) { - ERROR("Invalid message length for format 1C\n"); + ERROR("Invalid message length for format 1C"); return SRSLTE_ERROR; } @@ -1020,7 +1013,6 @@ static int dci_format1D_unpack(srslte_cell_t* cell, srslte_dci_msg_t* msg, srslte_dci_dl_t* dci) { - /* pack bits */ uint8_t* y = msg->payload; @@ -1072,7 +1064,6 @@ static int dci_format2AB_pack(srslte_cell_t* cell, srslte_dci_dl_t* dci, srslte_dci_msg_t* msg) { - uint32_t nof_prb = cell->nof_prb; uint32_t nof_ports = cell->nof_ports; @@ -1100,7 +1091,7 @@ static int dci_format2AB_pack(srslte_cell_t* cell, srslte_bit_unpack((uint32_t)dci->type1_alloc.vrb_bitmask, &y, alloc_size - (int)ceilf(log2f(P)) - 1); break; default: - ERROR("Format 1 accepts type0 or type1 resource allocation only\n"); + ERROR("Format 1 accepts type0 or type1 resource allocation only"); return SRSLTE_ERROR; } @@ -1150,7 +1141,6 @@ static int dci_format2AB_unpack(srslte_cell_t* cell, srslte_dci_msg_t* msg, srslte_dci_dl_t* dci) { - /* pack bits */ uint8_t* y = msg->payload; @@ -1178,7 +1168,7 @@ static int dci_format2AB_unpack(srslte_cell_t* cell, dci->type1_alloc.vrb_bitmask = srslte_bit_pack(&y, alloc_size - (int)ceilf(log2f(P)) - 1); break; default: - ERROR("Format2 accepts type0 or type1 resource allocation only\n"); + ERROR("Format2 accepts type0 or type1 resource allocation only"); return SRSLTE_ERROR; } @@ -1269,7 +1259,7 @@ int srslte_dci_msg_pack_pdsch(srslte_cell_t* cell, ret = dci_format2AB_pack(cell, sf, cfg, dci, msg); break; default: - ERROR("DCI pack pdsch: Invalid DCI format %s\n", srslte_dci_format_string(msg->format)); + ERROR("DCI pack pdsch: Invalid DCI format %s", srslte_dci_format_string(msg->format)); } #if SRSLTE_DCI_HEXDEBUG @@ -1329,7 +1319,7 @@ int srslte_dci_msg_unpack_pdsch(srslte_cell_t* cell, case SRSLTE_DCI_FORMAT2B: return dci_format2AB_unpack(cell, sf, cfg, msg, dci); default: - ERROR("DCI unpack pdsch: Invalid DCI format %s\n", srslte_dci_format_string(msg->format)); + ERROR("DCI unpack pdsch: Invalid DCI format %s", srslte_dci_format_string(msg->format)); return SRSLTE_ERROR; } } @@ -1420,13 +1410,13 @@ int srslte_dci_location_set(srslte_dci_location_t* c, uint32_t L, uint32_t nCCE) if (L <= 3) { c->L = L; } else { - ERROR("Invalid L %d\n", L); + ERROR("Invalid L %d", L); return SRSLTE_ERROR; } if (nCCE <= 87) { c->ncce = nCCE; } else { - ERROR("Invalid nCCE %d\n", nCCE); + ERROR("Invalid nCCE %d", nCCE); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index 19b925650..730e97ad0 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -23,6 +23,15 @@ #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/debug.h" +static int dci_nr_format_0_0_freq_resource_size(const srslte_carrier_nr_t* carrier) +{ + if (carrier == NULL) { + return SRSLTE_ERROR; + } + + return (int)ceil(log2(carrier->nof_prb * (carrier->nof_prb + 1) / 2.0)); +} + static int dci_nr_format_1_0_freq_resource_size(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset0, srslte_rnti_type_t rnti_type) @@ -44,6 +53,27 @@ static int dci_nr_format_1_0_freq_resource_size(const srslte_carrier_nr_t* carri return (int)ceil(log2(N_DL_BWP_RB * (N_DL_BWP_RB + 1) / 2.0)); } +bool srslte_dci_nr_format_1_0_valid(const srslte_dci_msg_nr_t* dci) +{ + // Check pointer + if (dci == NULL) { + return false; + } + + // Wrong format + if (dci->format != srslte_dci_format_nr_1_0) { + return false; + } + + // The format bit is only present for these RNTI + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + return dci->payload[0] == 1; + } + + // Otherwise, the message might be format 1_0 + return true; +} + int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, const srslte_dci_dl_nr_t* dci, @@ -51,7 +81,8 @@ int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier, { // Copy DCI MSG fields msg->location = dci->location; - msg->search_space = dci->search_space.type; + msg->search_space = dci->search_space; + msg->coreset_id = dci->coreset_id; msg->rnti_type = dci->rnti_type; msg->rnti = dci->rnti; msg->format = dci->format; @@ -60,18 +91,338 @@ int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier, switch (msg->format) { case srslte_dci_format_nr_1_0: if (srslte_dci_nr_format_1_0_pack(carrier, coreset, dci, msg) < SRSLTE_SUCCESS) { - ERROR("Error packing DL DCI\n"); + ERROR("Error packing DL DCI"); return SRSLTE_ERROR; } break; default: - ERROR("Unsupported DCI format %d\n", msg->format); + ERROR("Unsupported DCI format %d", msg->format); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } +int srslte_dci_nr_format_0_0_pack(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset0, + const srslte_dci_ul_nr_t* dci, + srslte_dci_msg_nr_t* msg) +{ + uint32_t trim = 0; // hard-coded bit trimming + bool enable_hopping = false; // hard-coded PUSCH hopping + uint32_t padding = 8; // Hard-coded padding + bool supplementary_uplink = false; // Hard-coded supplementary Uplink + uint8_t* y = msg->payload; + srslte_rnti_type_t rnti_type = msg->rnti_type; + + if (carrier == NULL) { + return SRSLTE_ERROR; + } + + // Check RNTI type + if (rnti_type != srslte_rnti_type_c && rnti_type != srslte_rnti_type_cs && rnti_type != srslte_rnti_type_mcs_c) { + return SRSLTE_ERROR; + } + + // Identifier for DCI formats – 1 bits + *y = 0; + y++; + + // For PUSCH hopping with resource allocation type 1 N UL_hop MSB bits are used to indicate the frequency offset + int N_UL_hop = (enable_hopping) ? ((carrier->nof_prb < 50) ? 1 : 2) : 0; + srslte_bit_unpack(dci->frequency_offset, &y, N_UL_hop); + + // Frequency domain resource assignment + int N = dci_nr_format_0_0_freq_resource_size(carrier); + if (N < SRSLTE_SUCCESS || N - N_UL_hop <= 0) { + return SRSLTE_ERROR; + } + srslte_bit_unpack(dci->freq_domain_assigment, &y, N - N_UL_hop - trim); + + // Time domain resource assignment – 4 bits + srslte_bit_unpack(dci->time_domain_assigment, &y, 4); + + // Frequency hopping flag – 1 bit + srslte_bit_unpack(dci->freq_hopping_flag, &y, 1); + + // Modulation and coding scheme – 5 bits + srslte_bit_unpack(dci->mcs, &y, 5); + + // New data indicator – 1 bit + srslte_bit_unpack(dci->ndi, &y, 1); + + // Redundancy version – 2 bits + srslte_bit_unpack(dci->rv, &y, 2); + + // HARQ process number – 4 bits + srslte_bit_unpack(dci->pid, &y, 4); + + // TPC command for scheduled PUSCH – 2 bits + srslte_bit_unpack(dci->tpc, &y, 2); + + // Padding goes here + for (uint32_t i = 0; i < padding; i++) { + *(y++) = 0; + } + + // UL/SUL indicator – 1 bit for UEs configured with supplementaryUplink in ServingCellConfig, othwerwise 0 + if (supplementary_uplink) { + *(y++) = 0; + } + + msg->nof_bits = srslte_dci_nr_format_0_0_sizeof(carrier, coreset0, rnti_type); + if (msg->nof_bits != y - msg->payload) { + ERROR("Unpacked bits read (%d) do NOT match payload size (%d)", msg->nof_bits, (int)(y - msg->payload)); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset, + srslte_dci_msg_nr_t* msg, + srslte_dci_ul_nr_t* dci) +{ + uint32_t trim = 0; // hard-coded bit trimming + bool enable_hopping = false; // hard-coded PUSCH hopping + uint32_t padding = 8; // Hard-coded padding + bool supplementary_uplink = false; // Hard-coded supplementary Uplink + uint8_t* y = msg->payload; + srslte_rnti_type_t rnti_type = msg->rnti_type; + + // Copy DCI MSG fields + dci->location = msg->location; + dci->search_space = msg->search_space; + dci->coreset_id = msg->coreset_id; + dci->rnti_type = msg->rnti_type; + dci->rnti = msg->rnti; + dci->format = msg->format; + + if (carrier == NULL) { + return SRSLTE_ERROR; + } + + // Check RNTI type + if (rnti_type != srslte_rnti_type_c && rnti_type != srslte_rnti_type_cs && rnti_type != srslte_rnti_type_mcs_c) { + ERROR("Unsupported %s", srslte_rnti_type_str(rnti_type)); + return SRSLTE_ERROR; + } + + if (msg->nof_bits != srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type)) { + ERROR("Invalid number of bits %d, expected %d", + msg->nof_bits, + srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type)); + return SRSLTE_ERROR; + } + + // Identifier for DCI formats – 1 bits + if (*(y++) != 0) { + ERROR("Wrond DCI format"); + return SRSLTE_ERROR; + } + + // For PUSCH hopping with resource allocation type 1 N UL_hop MSB bits are used to indicate the frequency offset + int N_UL_hop = (enable_hopping) ? ((carrier->nof_prb < 50) ? 1 : 2) : 0; + dci->frequency_offset = srslte_bit_pack(&y, N_UL_hop); + + // Frequency domain resource assignment + int N = dci_nr_format_0_0_freq_resource_size(carrier); + if (N < SRSLTE_SUCCESS || N - N_UL_hop <= 0) { + return SRSLTE_ERROR; + } + dci->freq_domain_assigment = srslte_bit_pack(&y, N - N_UL_hop - trim); + + // Time domain resource assignment – 4 bits + dci->time_domain_assigment = srslte_bit_pack(&y, 4); + + // Frequency hopping flag – 1 bit + dci->freq_hopping_flag = srslte_bit_pack(&y, 1); + + // Modulation and coding scheme – 5 bits + dci->mcs = srslte_bit_pack(&y, 5); + + // New data indicator – 1 bit + dci->ndi = srslte_bit_pack(&y, 1); + + // Redundancy version – 2 bits + dci->rv = srslte_bit_pack(&y, 2); + + // HARQ process number – 4 bits + dci->pid = srslte_bit_pack(&y, 4); + + // TPC command for scheduled PUSCH – 2 bits + dci->tpc = srslte_bit_pack(&y, 2); + + // Padding goes here + for (uint32_t i = 0; i < padding; i++) { + y++; + } + + // UL/SUL indicator – 1 bit for UEs configured with supplementaryUplink in ServingCellConfig, othwerwise 0 + if (supplementary_uplink) { + y++; + } + + return SRSLTE_SUCCESS; +} + +int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrier, + const srslte_coreset_t* coreset, + srslte_rnti_type_t rnti_type) +{ + uint32_t trim = 0; // hard-coded bit trimming + bool enable_hopping = false; // hard-coded PUSCH hopping + uint32_t padding = 8; // Hard-coded padding + bool supplementary_uplink = false; // Hard-coded supplementary Uplink + int count = 0; + + // Identifier for DCI formats – 1 bits + count++; + + // For PUSCH hopping with resource allocation type 1 N UL_hop MSB bits are used to indicate the frequency offset + int N_UL_hop = (enable_hopping) ? ((carrier->nof_prb < 50) ? 1 : 2) : 0; + count += N_UL_hop; + + // Frequency domain resource assignment + int N = dci_nr_format_0_0_freq_resource_size(carrier); + if (N < SRSLTE_SUCCESS || N - N_UL_hop <= 0) { + return SRSLTE_ERROR; + } + count += N - N_UL_hop - trim; + + // Time domain resource assignment – 4 bits + count += 4; + + // Frequency hopping flag – 1 bit + count += 1; + + // Modulation and coding scheme – 5 bits + count += 5; + + // New data indicator – 1 bit + count += 1; + + // Redundancy version – 2 bits + count += 2; + + // HARQ process number – 4 bits + count += 4; + + // TPC command for scheduled PUSCH – 2 bits + count += 2; + + // Padding goes here + count += padding; + + // UL/SUL indicator – 1 bit for UEs configured with supplementaryUplink in ServingCellConfig, othwerwise 0 + if (supplementary_uplink) { + count++; + } + + return count; +} + +static int dci_nr_format_0_0_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + // Print format + len = srslte_print_check( + str, str_len, len, "rnti=%04x L=%d cce=%d dci=0_0 ", dci->rnti, dci->location.L, dci->location.ncce); + + // Frequency domain resource assignment + len = srslte_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment); + + // Time domain resource assignment – 4 bits + len = srslte_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment); + + // Frequency hopping flag – 1 bit + len = srslte_print_check(str, str_len, len, "hop=%c ", dci->freq_hopping_flag == 0 ? 'n' : 'y'); + + // Modulation and coding scheme – 5 bits + len = srslte_print_check(str, str_len, len, "mcs=%d ", dci->mcs); + + // New data indicator – 1 bit + len = srslte_print_check(str, str_len, len, "ndi=%d ", dci->ndi); + + // Redundancy version – 2 bits + len = srslte_print_check(str, str_len, len, "rv=%d ", dci->rv); + + // HARQ process number – 4 bits + len = srslte_print_check(str, str_len, len, "harq_id=%d ", dci->harq_feedback); + + // TPC command for scheduled PUSCH – 2 bits + len = srslte_print_check(str, str_len, len, "tpc=%d ", dci->tpc); + + return len; +} + +int srslte_dci_nr_rar_unpack(srslte_dci_msg_nr_t* msg, srslte_dci_ul_nr_t* dci) +{ + if (msg == NULL || dci == NULL) { + return SRSLTE_ERROR; + } + + uint8_t* y = msg->payload; + + // Copy DCI MSG fields + dci->location = msg->location; + dci->search_space = msg->search_space; + dci->coreset_id = msg->coreset_id; + dci->rnti_type = msg->rnti_type; + dci->rnti = msg->rnti; + dci->format = msg->format; + + // Frequency hopping flag - 1 bit + dci->freq_hopping_flag = srslte_bit_pack(&y, 1); + + // PUSCH frequency resource allocation - 14 bits + dci->freq_domain_assigment = srslte_bit_pack(&y, 14); + + // PUSCH time resource allocation - 4 bits + dci->time_domain_assigment = srslte_bit_pack(&y, 4); + + // MCS -4 bits + dci->mcs = srslte_bit_pack(&y, 4); + + // TPC command for PUSCH - 3 bits + dci->tpc = srslte_bit_pack(&y, 3); + + // CSI request - 1 bits + dci->csi_request = srslte_bit_pack(&y, 3); + + return SRSLTE_SUCCESS; +} + +static int dci_nr_rar_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + // Print format + len = srslte_print_check(str, str_len, len, "rnti=%04x dci=rar ", dci->rnti); + + // Frequency hopping flag + len = srslte_print_check(str, str_len, len, "hop=%d ", dci->freq_hopping_flag); + + // PUSCH frequency resource allocation + len = srslte_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment); + + // PUSCH time resource allocation + len = srslte_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment); + + // Modulation and coding scheme + len = srslte_print_check(str, str_len, len, "mcs=%d ", dci->mcs); + + // TPC command for scheduled PUSCH + len = srslte_print_check(str, str_len, len, "tpc=%d ", dci->tpc); + + // CSI request + len = srslte_print_check(str, str_len, len, "csi=%d ", dci->csi_request); + + return len; +} + int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, const srslte_dci_dl_nr_t* dci, @@ -173,7 +524,7 @@ int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier, msg->nof_bits = srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type); if (msg->nof_bits != y - msg->payload) { - ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload)); + ERROR("Unpacked bits read (%d) do NOT match payload size (%d)", msg->nof_bits, (int)(y - msg->payload)); return SRSLTE_ERROR; } @@ -188,8 +539,16 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier, uint8_t* y = msg->payload; srslte_rnti_type_t rnti_type = msg->rnti_type; + // Copy DCI MSG fields + dci->location = msg->location; + dci->search_space = msg->search_space; + dci->coreset_id = msg->coreset_id; + dci->rnti_type = msg->rnti_type; + dci->rnti = msg->rnti; + dci->format = msg->format; + if (msg->nof_bits != srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type)) { - ERROR("Invalid number of bits %d, expected %d\n", + ERROR("Invalid number of bits %d, expected %d", msg->nof_bits, srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type)); return SRSLTE_ERROR; @@ -198,11 +557,10 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier, // Identifier for DCI formats – 1 bits if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) { // The value of this bit field is always set to 1, indicating a DL DCI format - if (*y != 1) { - ERROR("Wrond DCI format\n"); + if (*(y++) != 1) { + ERROR("Wrond DCI format"); return SRSLTE_ERROR; } - y++; } if (rnti_type == srslte_rnti_type_p) { @@ -287,7 +645,7 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier, } if (msg->nof_bits != y - msg->payload) { - ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload)); + ERROR("Unpacked bits read (%d) do NOT match payload size (%d)", msg->nof_bits, (int)(y - msg->payload)); return SRSLTE_ERROR; } @@ -298,7 +656,7 @@ int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset, srslte_rnti_type_t rnti_type) { - uint32_t count = 0; + int count = 0; // Identifier for DCI formats – 1 bits if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) { @@ -387,4 +745,109 @@ int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier, } return count; -} \ No newline at end of file +} + +static int dci_nr_format_1_0_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + // Print format + len = srslte_print_check( + str, str_len, len, "rnti=%04x L=%d cce=%d dci=1_0 ", dci->rnti, dci->location.L, dci->location.ncce); + + if (dci->rnti_type == srslte_rnti_type_p) { + len = srslte_print_check(str, str_len, len, "smi=%d sm=%d ", dci->smi, dci->sm); + } + + // Frequency domain resource assignment + len = srslte_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment); + + // Time domain resource assignment – 4 bits + len = srslte_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment); + + // VRB-to-PRB mapping – 1 bit + len = srslte_print_check(str, str_len, len, "vrb_to_prb_map=%d ", dci->vrb_to_prb_mapping); + + // Modulation and coding scheme – 5 bits + len = srslte_print_check(str, str_len, len, "mcs=%d ", dci->mcs); + + // TB scaling – 2 bits + if (dci->rnti_type == srslte_rnti_type_p || dci->rnti_type == srslte_rnti_type_ra) { + len = srslte_print_check(str, str_len, len, "tb_scaling=%d ", dci->tb_scaling); + } + + // New data indicator – 1 bit + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "ndi=%d ", dci->ndi); + } + + // Redundancy version – 2 bits + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_si || + dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "rv=%d ", dci->rv); + } + + // HARQ process number – 4 bits + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "harq_id=%d ", dci->harq_feedback); + } + + // System information indicator – 1 bit + if (dci->rnti_type == srslte_rnti_type_si) { + len = srslte_print_check(str, str_len, len, "sii=%d ", dci->sii); + } + + // Downlink assignment index – 2 bits + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "sii=%d ", dci->sii); + } + + // TPC command for scheduled PUCCH – 2 bits + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "pucch_tpc=%d ", dci->tpc); + } + + // PUCCH resource indicator – 3 bits + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "pucch_res=%d ", dci->pucch_resource); + } + + // PDSCH-to-HARQ_feedback timing indicator – 3 bits + if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) { + len = srslte_print_check(str, str_len, len, "harq_feedback=%d ", dci->harq_feedback); + } + + // Reserved bits ... + if (dci->rnti_type == srslte_rnti_type_p || dci->rnti_type == srslte_rnti_type_si || + dci->rnti_type == srslte_rnti_type_ra) { + len = srslte_print_check(str, str_len, len, "reserved=0x%x ", dci->reserved); + } + + return len; +} + +int srslte_dci_ul_nr_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len) +{ + // Pack DCI + switch (dci->format) { + case srslte_dci_format_nr_0_0: + return dci_nr_format_0_0_to_str(dci, str, str_len); + case srslte_dci_format_nr_rar: + return dci_nr_rar_to_str(dci, str, str_len); + default:; // Do nothing + } + + return srslte_print_check(str, str_len, 0, "unknown"); +} + +int srslte_dci_dl_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len) +{ + // Pack DCI + switch (dci->format) { + case srslte_dci_format_nr_1_0: + return dci_nr_format_1_0_to_str(dci, str, str_len); + default:; // Do nothing + } + + return srslte_print_check(str, str_len, 0, "unknown"); +} diff --git a/lib/src/phy/phch/npbch.c b/lib/src/phy/phch/npbch.c index 3db813b74..d04e9b60b 100644 --- a/lib/src/phy/phch/npbch.c +++ b/lib/src/phy/phch/npbch.c @@ -291,7 +291,7 @@ int srslte_npbch_encode(srslte_npbch_t* q, // generate new BCH message every 64 frames if ((frame_idx % SRSLTE_NPBCH_NUM_FRAMES) == 0) { - INFO("Encoding new NPBCH signal in frame %d.\n", frame_idx); + INFO("Encoding new NPBCH signal in frame %d.", frame_idx); memcpy(q->data, bch_payload, sizeof(uint8_t) * SRSLTE_MIB_NB_LEN); @@ -306,7 +306,7 @@ int srslte_npbch_encode(srslte_npbch_t* q, // Scramble and modulate a new block every 8 frames if (frame_idx % SRSLTE_NPBCH_NUM_REP == 0) { - INFO("Modulating MIB-NB block %d in frame %d.\n", block_idx, frame_idx); + INFO("Modulating MIB-NB block %d in frame %d.", block_idx, frame_idx); srslte_scrambling_b_offset(&q->seq, &q->rm_b[block_idx * nof_bits], block_idx * nof_bits, nof_bits); srslte_mod_modulate(&q->mod, &q->rm_b[block_idx * nof_bits], q->d, nof_bits); @@ -322,12 +322,12 @@ int srslte_npbch_encode(srslte_npbch_t* q, // Write exactly SRSLTE_NPBCH_NUM_RE (assumes symbols have been modulated before) for (int i = 0; i < q->cell.nof_ports; i++) { if (q->cell.is_r14) { - DEBUG("Applying phase rotation on port %d in frame %d.\n", i, frame_idx); + DEBUG("Applying phase rotation on port %d in frame %d.", i, frame_idx); srslte_npbch_rotate(q, frame_idx, q->symbols[i], q->symbols[i], q->nof_symbols, false); } - DEBUG("Putting MIB-NB block %d on port %d in frame %d.\n", block_idx, i, frame_idx); + DEBUG("Putting MIB-NB block %d on port %d in frame %d.", block_idx, i, frame_idx); if (srslte_npbch_cp(q->symbols[i], sf[i], q->cell, true) != SRSLTE_NPBCH_NUM_RE) { - INFO("Error while mapping NPBCH symbols.\n"); + INFO("Error while mapping NPBCH symbols."); return SRSLTE_ERROR; } } @@ -346,7 +346,7 @@ int srslte_npbch_rotate(srslte_npbch_t* q, bool back) { // Generate frame specific scrambling sequence for symbol rotation - DEBUG("%sotating NPBCH in SFN=%d\n", back ? "De-R" : "R", nf); + DEBUG("%sotating NPBCH in SFN=%d", back ? "De-R" : "R", nf); for (int i = 0; i < num_samples; i++) { int c_2i = q->seq_r14[nf % 8].c[2 * i]; @@ -452,7 +452,7 @@ int srslte_npbch_decode_nf(srslte_npbch_t* q, } do { if (nant != 3) { - DEBUG("Trying %d TX antennas with %d frames\n", nant, q->frame_idx); + DEBUG("Trying %d TX antennas with %d frames", nant, q->frame_idx); // in control channels, only diversity is supported if (nant == 1) { @@ -467,7 +467,7 @@ int srslte_npbch_decode_nf(srslte_npbch_t* q, srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, &q->llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols); // only one subframe - DEBUG("Trying to decode NPBCH ..\n"); + DEBUG("Trying to decode NPBCH .."); // TODO: simplified decoding only using first MIB block ret = srslte_npbch_decode_frame(q, 0, nf, 1, nof_bits, nant); @@ -481,7 +481,7 @@ int srslte_npbch_decode_nf(srslte_npbch_t* q, if (bch_payload) { memcpy(bch_payload, q->data, sizeof(uint8_t) * SRSLTE_MIB_NB_LEN); } - INFO("Successfully decoded NPBCH sfn_offset=%d\n", q->frame_idx - 1); + INFO("Successfully decoded NPBCH sfn_offset=%d", q->frame_idx - 1); q->frame_idx = 0; return ret; } diff --git a/lib/src/phy/phch/npdcch.c b/lib/src/phy/phch/npdcch.c index 3b3c0e725..9ca62fc27 100644 --- a/lib/src/phy/phch/npdcch.c +++ b/lib/src/phy/phch/npdcch.c @@ -52,7 +52,7 @@ int srslte_npdcch_init(srslte_npdcch_t* q) q->max_bits = SRSLTE_CP_NORM_SF_NSYMB * SRSLTE_NRE * 2; q->ncce_bits = q->max_bits / 2; - INFO("Init NPDCCH: Max bits: %d, %d ports.\n", q->max_bits, q->cell.nof_ports); + INFO("Init NPDCCH: Max bits: %d, %d ports.", q->max_bits, q->cell.nof_ports); if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; @@ -248,7 +248,7 @@ int srslte_npdcch_decode_msg(srslte_npdcch_t* q, // Get the right softbits for this aggregation level float* llr = (location->L == 1) ? q->llr[0] : q->llr[1]; if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("LLR:\n"); + DEBUG("LLR:"); srslte_vec_fprint_f(stdout, llr, q->max_bits); } @@ -272,7 +272,7 @@ int srslte_npdcch_decode_msg(srslte_npdcch_t* q, fprintf(stderr, "Error calling npdcch_dci_decode\n"); } if (crc_rem) { - DEBUG("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x\n", + DEBUG("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x", location->ncce, location->L, srslte_dci_format_string(msg->format), @@ -281,7 +281,7 @@ int srslte_npdcch_decode_msg(srslte_npdcch_t* q, *crc_rem); } } else { - DEBUG("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f\n", location->ncce, location->L, nof_bits, mean); + DEBUG("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f", location->ncce, location->L, nof_bits, mean); } ret = SRSLTE_SUCCESS; } else { @@ -333,7 +333,7 @@ int srslte_npdcch_extract_llr(srslte_npdcch_t* q, } num_symbols = e_bits / 2; - DEBUG("Extracting LLRs for NPDCCH %s: E: %d, SF: %d\n", srslte_npdcch_format_text[i], e_bits, sf_idx); + DEBUG("Extracting LLRs for NPDCCH %s: E: %d, SF: %d", srslte_npdcch_format_text[i], e_bits, sf_idx); if (i != SRSLTE_NPDCCH_FORMAT0_UPPER_HALF) { // don't overwrite lower half LLRs @@ -355,7 +355,7 @@ int srslte_npdcch_extract_llr(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_rx_mapping_output.bin: NPDCCH after extracting symbols\n"); + DEBUG("SAVED FILE npdcch_rx_mapping_output.bin: NPDCCH after extracting symbols"); srslte_vec_save_file("npdcch_rx_mapping_output.bin", q->symbols[0], n * sizeof(cf_t)); } #endif @@ -380,7 +380,7 @@ int srslte_npdcch_extract_llr(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_rx_predecode_output.bin: NPDCCH after predecoding symbols\n"); + DEBUG("SAVED FILE npdcch_rx_predecode_output.bin: NPDCCH after predecoding symbols"); srslte_vec_save_file("npdcch_rx_predecode_output.bin", q->d, q->num_decoded_symbols * sizeof(cf_t)); } #endif @@ -393,7 +393,7 @@ int srslte_npdcch_extract_llr(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_rx_descramble_output.bin: NPDCCH after de-scrambling\n"); + DEBUG("SAVED FILE npdcch_rx_descramble_output.bin: NPDCCH after de-scrambling"); srslte_vec_save_file("npdcch_rx_descramble_output.bin", llr, e_bits); } #endif @@ -407,9 +407,9 @@ int srslte_npdcch_extract_llr(srslte_npdcch_t* q, static void crc_set_mask_rnti(uint8_t* crc, uint16_t rnti) { uint8_t mask[16] = {}; - uint8_t* r = mask; + uint8_t* r = mask; - DEBUG("Mask CRC with RNTI 0x%x\n", rnti); + DEBUG("Mask CRC with RNTI 0x%x", rnti); srslte_bit_unpack(rnti, &r, 16); for (uint32_t i = 0; i < 16; i++) { @@ -435,7 +435,7 @@ void srslte_npdcch_dci_encode_conv(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_tx_convcoder_input.bin: NPDCCH before convolution coding\n"); + DEBUG("SAVED FILE npdcch_tx_convcoder_input.bin: NPDCCH before convolution coding"); srslte_vec_save_file("npdcch_tx_convcoder_input.bin", data, nof_bits + 16); } #endif @@ -481,12 +481,12 @@ int srslte_npdcch_encode(srslte_npdcch_t* q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && sf_symbols != NULL && nsubframe < 10 && srslte_nbiot_dci_location_isvalid(&location)) { - ret = SRSLTE_ERROR; + ret = SRSLTE_ERROR; uint32_t e_bits = q->nof_cce * q->ncce_bits; uint32_t nof_symbols = e_bits / 2; if (msg->nof_bits < SRSLTE_DCI_MAX_BITS - 16) { - DEBUG("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x, sf_idx: %d\n", + DEBUG("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x, sf_idx: %d", msg->nof_bits, e_bits, location.ncce, @@ -508,7 +508,7 @@ int srslte_npdcch_encode(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_tx_scramble_input.bin: NPDCCH before scrambling\n"); + DEBUG("SAVED FILE npdcch_tx_scramble_input.bin: NPDCCH before scrambling"); srslte_vec_save_file("npdcch_tx_scramble_input.bin", q->e, e_bits); } #endif @@ -517,7 +517,7 @@ int srslte_npdcch_encode(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_tx_mod_input.bin: NPDCCH before modulation\n"); + DEBUG("SAVED FILE npdcch_tx_mod_input.bin: NPDCCH before modulation"); srslte_vec_save_file("npdcch_tx_mod_input.bin", q->e, e_bits); } #endif @@ -526,7 +526,7 @@ int srslte_npdcch_encode(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_tx_precode_input.bin: NPDCCH before precoding symbols\n"); + DEBUG("SAVED FILE npdcch_tx_precode_input.bin: NPDCCH before precoding symbols"); srslte_vec_save_file("npdcch_tx_precode_input.bin", q->d, nof_symbols * sizeof(cf_t)); } #endif @@ -541,7 +541,7 @@ int srslte_npdcch_encode(srslte_npdcch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdcch_tx_mapping_input.bin: NPDCCH before mapping to resource elements\n"); + DEBUG("SAVED FILE npdcch_tx_mapping_input.bin: NPDCCH before mapping to resource elements"); srslte_vec_save_file("npdcch_tx_mapping_input.bin", q->symbols[0], nof_symbols * sizeof(cf_t)); } #endif diff --git a/lib/src/phy/phch/npdsch.c b/lib/src/phy/phch/npdsch.c index c9a82e4db..87c4e315d 100644 --- a/lib/src/phy/phch/npdsch.c +++ b/lib/src/phy/phch/npdsch.c @@ -191,7 +191,7 @@ int srslte_npdsch_init(srslte_npdsch_t* q) q->max_re = SRSLTE_NPDSCH_MAX_RE * SRSLTE_NPDSCH_MAX_NOF_SF; q->rnti_is_set = false; - INFO("Init NPDSCH: max_re's: %d\n", q->max_re); + INFO("Init NPDSCH: max_re's: %d", q->max_re); if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; @@ -301,7 +301,7 @@ int srslte_npdsch_set_cell(srslte_npdsch_t* q, srslte_nbiot_cell_t cell) if (q != NULL && srslte_nbiot_cell_isvalid(&cell)) { q->cell = cell; - INFO("NPDSCH: Cell config n_id_ncell=%d, %d ports, %d PRBs base cell, max_symbols: %d\n", + INFO("NPDSCH: Cell config n_id_ncell=%d, %d ports, %d PRBs base cell, max_symbols: %d", q->cell.n_id_ncell, q->cell.nof_ports, q->cell.base.nof_prb, @@ -376,7 +376,7 @@ int srslte_npdsch_decode_rnti(srslte_npdsch_t* q, cf_t* x[SRSLTE_MAX_LAYERS]; if (q != NULL && sf_symbols != NULL && data != NULL && cfg != NULL) { - INFO("%d.x: Decoding NPDSCH: RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d * %d, NofBitsE: %d * %d\n", + INFO("%d.x: Decoding NPDSCH: RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d * %d, NofBitsE: %d * %d", sfn, rnti, srslte_mod_string(cfg->grant.mcs[0].mod), @@ -420,7 +420,7 @@ int srslte_npdsch_decode_rnti(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_rx_mapping_output.bin: NPDSCH after extracting symbols\n", 0); + DEBUG("SAVED FILE npdsch_rx_mapping_output.bin: NPDSCH after extracting symbols", 0); srslte_vec_save_file( "npdsch_rx_mapping_output.bin", q->symbols[0], cfg->grant.nof_sf * cfg->nbits.nof_re * sizeof(cf_t)); } @@ -440,7 +440,7 @@ int srslte_npdsch_decode_rnti(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_rx_predecode_output.bin: NPDSCH after predecoding symbols\n", 0); + DEBUG("SAVED FILE npdsch_rx_predecode_output.bin: NPDSCH after predecoding symbols", 0); srslte_vec_save_file( "npdsch_rx_predecode_output.bin", q->d, cfg->grant.nof_sf * cfg->nbits.nof_re * sizeof(cf_t)); } @@ -451,10 +451,10 @@ int srslte_npdsch_decode_rnti(srslte_npdsch_t* q, #if DUMP_SIGNALS uint8_t demodbuf[320]; - hard_qpsk_demod(q->d,demodbuf,cfg->nbits.nof_re); + hard_qpsk_demod(q->d, demodbuf, cfg->nbits.nof_re); if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_rx_demod_output.bin: NPDSCH after (hard) de-modulation\n",0); + DEBUG("SAVED FILE npdsch_rx_demod_output.bin: NPDSCH after (hard) de-modulation", 0); srslte_vec_save_file("npdsch_rx_demod_output.bin", demodbuf, cfg->nbits.nof_bits); } #endif @@ -491,7 +491,7 @@ int srslte_npdsch_decode_rnti(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_rx_descramble_output.bin: NPDSCH after de-scrambling\n", 0); + DEBUG("SAVED FILE npdsch_rx_descramble_output.bin: NPDSCH after de-scrambling", 0); srslte_vec_save_file("npdsch_rx_descramble_output.bin", q->llr, cfg->nbits.nof_bits); } #endif @@ -518,7 +518,7 @@ int srslte_npdsch_rm_and_decode(srslte_npdsch_t* q, srslte_npdsch_cfg_t* cfg, fl #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_rx_viterbidecode_output.bin: NPDSCH after viterbi decoding\n", 0); + DEBUG("SAVED FILE npdsch_rx_viterbidecode_output.bin: NPDSCH after viterbi decoding", 0); srslte_vec_save_file("npdsch_rx_viterbidecode_output.bin", q->temp, cfg->grant.mcs[0].tbs + SRSLTE_NPDSCH_CRC_LEN); } #endif @@ -633,7 +633,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, // make sure to run run full NPDSCH procedure only once if (!cfg->is_encoded) { - INFO("Encoding NPDSCH: Mod %s, NofBits: %d, NofSymbols: %d * %d, NofBitsE: %d * %d\n", + INFO("Encoding NPDSCH: Mod %s, NofBits: %d, NofSymbols: %d * %d, NofBitsE: %d * %d", srslte_mod_string(cfg->grant.mcs[0].mod), cfg->grant.mcs[0].tbs, cfg->grant.nof_sf, @@ -658,7 +658,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_tx_convcoder_input.bin: NPDSCH before convolution coding\n", 0); + DEBUG("SAVED FILE npdsch_tx_convcoder_input.bin: NPDSCH before convolution coding", 0); srslte_vec_save_file("npdsch_tx_convcoder_input.bin", q->data, len); } #endif @@ -673,7 +673,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_tx_scramble_input.bin: NPDSCH before scrambling\n", 0); + DEBUG("SAVED FILE npdsch_tx_scramble_input.bin: NPDSCH before scrambling", 0); srslte_vec_save_file("npdsch_tx_scramble_input.bin", q->rm_b, len); } #endif @@ -683,7 +683,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_tx_mod_input.bin: NPDSCH before modulation\n", 0); + DEBUG("SAVED FILE npdsch_tx_mod_input.bin: NPDSCH before modulation", 0); srslte_vec_save_file("npdsch_tx_mod_input.bin", q->rm_b, len); } #endif @@ -694,7 +694,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_tx_precode_input.bin: NPDSCH before precoding symbols\n", 0); + DEBUG("SAVED FILE npdsch_tx_precode_input.bin: NPDSCH before precoding symbols", 0); srslte_vec_save_file("npdsch_tx_precode_input.bin", q->d, len * sizeof(cf_t)); } #endif @@ -709,7 +709,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, #if DUMP_SIGNALS if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_tx_mapping_input.bin: NPDSCH before mapping to resource elements\n", 0); + DEBUG("SAVED FILE npdsch_tx_mapping_input.bin: NPDSCH before mapping to resource elements", 0); srslte_vec_save_file("npdsch_tx_mapping_input.bin", q->tx_syms[0], len * sizeof(cf_t)); } #endif @@ -719,7 +719,7 @@ int srslte_npdsch_encode_seq(srslte_npdsch_t* q, // mapping to resource elements if (cfg->is_encoded) { - INFO("Mapping %d NPDSCH REs, sf_idx=%d/%d rep=%d/%d total=%d/%d\n", + INFO("Mapping %d NPDSCH REs, sf_idx=%d/%d rep=%d/%d total=%d/%d", cfg->nbits.nof_re, cfg->sf_idx + 1, cfg->grant.nof_sf, diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index c95e472e1..678311071 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -428,7 +428,7 @@ int decode_frame(srslte_pbch_t* q, uint32_t src, uint32_t dst, uint32_t n, uint3 return SRSLTE_SUCCESS; } } else { - ERROR("Error in PBCH decoder: Invalid frame pointers dst=%d, src=%d, n=%d\n", src, dst, n); + ERROR("Error in PBCH decoder: Invalid frame pointers dst=%d, src=%d, n=%d", src, dst, n); return -1; } } @@ -474,14 +474,14 @@ int srslte_pbch_decode(srslte_pbch_t* q, /* extract symbols */ if (q->nof_symbols != srslte_pbch_get(slot1_symbols, q->symbols[0], q->cell)) { - ERROR("There was an error getting the PBCH symbols\n"); + ERROR("There was an error getting the PBCH symbols"); return SRSLTE_ERROR; } /* extract channel estimates */ for (i = 0; i < q->cell.nof_ports; i++) { if (q->nof_symbols != srslte_pbch_get(ce_slot1[i], q->ce[i], q->cell)) { - ERROR("There was an error getting the PBCH symbols\n"); + ERROR("There was an error getting the PBCH symbols"); return SRSLTE_ERROR; } } @@ -500,7 +500,7 @@ int srslte_pbch_decode(srslte_pbch_t* q, do { if (nant != 3) { - DEBUG("Trying %d TX antennas with %d frames\n", nant, frame_idx); + DEBUG("Trying %d TX antennas with %d frames", nant, frame_idx); /* in control channels, only diversity is supported */ if (nant == 1) { @@ -532,7 +532,7 @@ int srslte_pbch_decode(srslte_pbch_t* q, if (bch_payload) { memcpy(bch_payload, q->data, sizeof(uint8_t) * SRSLTE_BCH_PAYLOAD_LEN); } - INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d\n", + INFO("Decoded PBCH: src=%d, dst=%d, nb=%d, sfn_offset=%d", src, dst, nb + 1, diff --git a/lib/src/phy/phch/pcfich.c b/lib/src/phy/phch/pcfich.c index 39e4df07f..8b7a92314 100644 --- a/lib/src/phy/phch/pcfich.c +++ b/lib/src/phy/phch/pcfich.c @@ -159,7 +159,6 @@ int srslte_pcfich_decode(srslte_pcfich_t* q, cf_t* sf_symbols[SRSLTE_MAX_PORTS], float* corr_result) { - /* Set pointers for layermapping & precoding */ int i; cf_t* x[SRSLTE_MAX_LAYERS]; @@ -178,7 +177,7 @@ int srslte_pcfich_decode(srslte_pcfich_t* q, /* extract symbols */ for (int j = 0; j < q->nof_rx_antennas; j++) { if (q->nof_symbols != srslte_regs_pcfich_get(q->regs, sf_symbols[j], q->symbols[j])) { - ERROR("There was an error getting the PCFICH symbols\n"); + ERROR("There was an error getting the PCFICH symbols"); return SRSLTE_ERROR; } @@ -187,7 +186,7 @@ int srslte_pcfich_decode(srslte_pcfich_t* q, /* extract channel estimates */ for (i = 0; i < q->cell.nof_ports; i++) { if (q->nof_symbols != srslte_regs_pcfich_get(q->regs, channel->ce[i][j], q->ce[i][j])) { - ERROR("There was an error getting the PCFICH symbols\n"); + ERROR("There was an error getting the PCFICH symbols"); return SRSLTE_ERROR; } q_ce[i][j] = q->ce[i][j]; @@ -229,7 +228,6 @@ int srslte_pcfich_encode(srslte_pcfich_t* q, srslte_dl_sf_cfg_t* sf, cf_t* slot_ int i; if (q != NULL && slot_symbols != NULL) { - uint32_t sf_idx = sf->tti % 10; /* Set pointers for layermapping & precoding */ @@ -263,7 +261,7 @@ int srslte_pcfich_encode(srslte_pcfich_t* q, srslte_dl_sf_cfg_t* sf, cf_t* slot_ /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { if (srslte_regs_pcfich_put(q->regs, q->symbols[i], slot_symbols[i]) < 0) { - ERROR("Error putting PCHICH resource elements\n"); + ERROR("Error putting PCHICH resource elements"); return SRSLTE_ERROR; } } diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index 51c545c11..85f958e97 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -61,7 +61,7 @@ static int pdcch_init(srslte_pdcch_t* q, uint32_t max_prb, uint32_t nof_rx_anten /* Allocate memory for the maximum number of PDCCH bits (CFI=3) */ q->max_bits = max_prb * 3 * 12 * 2; - INFO("Init PDCCH: Max bits: %d\n", q->max_bits); + INFO("Init PDCCH: Max bits: %d", q->max_bits); if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; @@ -132,7 +132,6 @@ int srslte_pdcch_init_ue(srslte_pdcch_t* q, uint32_t max_prb, uint32_t nof_rx_an void srslte_pdcch_free(srslte_pdcch_t* q) { - if (q->e) { free(q->e); } @@ -185,10 +184,9 @@ int srslte_pdcch_set_cell(srslte_pdcch_t* q, srslte_regs_t* regs, srslte_cell_t int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && regs != NULL && srslte_cell_isvalid(&cell)) { - srslte_pdcch_set_regs(q, regs); - INFO("PDCCH: Cell config PCI=%d, %d ports.\n", q->cell.id, q->cell.nof_ports); + INFO("PDCCH: Cell config PCI=%d, %d ports.", q->cell.id, q->cell.nof_ports); if (q->cell.id != cell.id || q->cell.nof_prb == 0) { q->cell = cell; @@ -236,7 +234,6 @@ uint32_t srslte_pdcch_ue_locations_ncce_L(uint32_t nof_cce, uint16_t rnti, int Ls) { - int l; // this must be int because of the for(;;--) loop uint32_t i, k, L, m; uint32_t Yk, ncce; @@ -274,7 +271,7 @@ uint32_t srslte_pdcch_ue_locations_ncce_L(uint32_t nof_cce, c[k].L = l; c[k].ncce = ncce; - DEBUG("UE-specific SS Candidate %d: nCCE: %d, L: %d\n", k, c[k].ncce, c[k].L); + DEBUG("UE-specific SS Candidate %d: nCCE: %d, L: %d", k, c[k].ncce, c[k].L); k++; } @@ -283,7 +280,7 @@ uint32_t srslte_pdcch_ue_locations_ncce_L(uint32_t nof_cce, } } - DEBUG("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x, sf_idx=%d, nof_cce=%d\n", + DEBUG("Initiated %d candidate(s) in the UE-specific search space for C-RNTI: 0x%x, sf_idx=%d, nof_cce=%d", k, rnti, sf_idx, @@ -318,13 +315,13 @@ uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_locatio if (k < max_candidates && ncce + L <= nof_cce) { c[k].L = l; c[k].ncce = ncce; - DEBUG("Common SS Candidate %d: nCCE: %d/%d, L: %d\n", k, c[k].ncce, nof_cce, c[k].L); + DEBUG("Common SS Candidate %d: nCCE: %d/%d, L: %d", k, c[k].ncce, nof_cce, c[k].L); k++; } } } - INFO("Initiated %d candidate(s) in the Common search space\n", k); + INFO("Initiated %d candidate(s) in the Common search space", k); return k; } @@ -337,7 +334,6 @@ uint32_t srslte_pdcch_common_locations_ncce(uint32_t nof_cce, srslte_dci_locatio */ int srslte_pdcch_dci_decode(srslte_pdcch_t* q, float* e, uint8_t* data, uint32_t E, uint32_t nof_bits, uint16_t* crc) { - uint16_t p_bits, crc_res; uint8_t* x; @@ -363,7 +359,7 @@ int srslte_pdcch_dci_decode(srslte_pdcch_t* q, float* e, uint8_t* data, uint32_t return SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters: E: %d, max_bits: %d, nof_bits: %d\n", E, q->max_bits, nof_bits); + ERROR("Invalid parameters: E: %d, max_bits: %d, nof_bits: %d", E, q->max_bits, nof_bits); return SRSLTE_ERROR_INVALID_INPUTS; } } else { @@ -382,7 +378,7 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t* q, srslte_dl_sf_cfg_t* sf, srslte_dc int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && msg != NULL && srslte_dci_location_isvalid(&msg->location)) { if (msg->location.ncce * 72 + PDCCH_FORMAT_NOF_BITS(msg->location.L) > NOF_CCE(sf->cfi) * 72) { - ERROR("Invalid location: nCCE: %d, L: %d, NofCCE: %d\n", msg->location.ncce, msg->location.L, NOF_CCE(sf->cfi)); + ERROR("Invalid location: nCCE: %d, L: %d, NofCCE: %d", msg->location.ncce, msg->location.L, NOF_CCE(sf->cfi)); } else { ret = SRSLTE_SUCCESS; @@ -403,9 +399,9 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t* q, srslte_dl_sf_cfg_t* sf, srslte_dc msg->format = (msg->payload[dci_cfg->cif_enabled ? 3 : 0] == 0) ? SRSLTE_DCI_FORMAT0 : SRSLTE_DCI_FORMAT1A; } } else { - ERROR("Error calling pdcch_dci_decode\n"); + ERROR("Error calling pdcch_dci_decode"); } - INFO("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x\n", + INFO("Decoded DCI: nCCE=%d, L=%d, format=%s, msg_len=%d, mean=%f, crc_rem=0x%x", msg->location.ncce, msg->location.L, srslte_dci_format_string(msg->format), @@ -413,12 +409,11 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t* q, srslte_dl_sf_cfg_t* sf, srslte_dc mean, msg->rnti); } else { - INFO( - "Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f\n", msg->location.ncce, msg->location.L, nof_bits, mean); + INFO("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f", msg->location.ncce, msg->location.L, nof_bits, mean); } } } else { - ERROR("Invalid parameters, location=%d,%d\n", msg->location.ncce, msg->location.L); + ERROR("Invalid parameters, location=%d,%d", msg->location.ncce, msg->location.L); } return ret; } @@ -431,7 +426,6 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t* q, srslte_chest_dl_res_t* channel, cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; /* Set pointers for layermapping & precoding */ @@ -439,13 +433,12 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t* q, cf_t* x[SRSLTE_MAX_LAYERS]; if (q != NULL && sf->cfi > 0 && sf->cfi < 4) { - uint32_t e_bits = 72 * NOF_CCE(sf->cfi); nof_symbols = e_bits / 2; ret = SRSLTE_ERROR; srslte_vec_f_zero(q->llr, q->max_bits); - DEBUG("Extracting LLRs: E: %d, SF: %d, CFI: %d\n", e_bits, sf->tti % 10, sf->cfi); + DEBUG("Extracting LLRs: E: %d, SF: %d, CFI: %d", e_bits, sf->tti % 10, sf->cfi); /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { @@ -457,7 +450,7 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t* q, for (int j = 0; j < q->nof_rx_antennas; j++) { int n = srslte_regs_pdcch_get(q->regs, sf->cfi, sf_symbols[j], q->symbols[j]); if (nof_symbols != n) { - ERROR("Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); + ERROR("Expected %d PDCCH symbols but got %d symbols", nof_symbols, n); return ret; } @@ -465,7 +458,7 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t* q, for (i = 0; i < q->cell.nof_ports; i++) { n = srslte_regs_pdcch_get(q->regs, sf->cfi, channel->ce[i][j], q->ce[i][j]); if (nof_symbols != n) { - ERROR("Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); + ERROR("Expected %d PDCCH symbols but got %d symbols", nof_symbols, n); return ret; } } @@ -499,7 +492,7 @@ static void crc_set_mask_rnti(uint8_t* crc, uint16_t rnti) uint8_t mask[16]; uint8_t* r = mask; - DEBUG("Mask CRC with RNTI 0x%x\n", rnti); + DEBUG("Mask CRC with RNTI 0x%x", rnti); srslte_bit_unpack(rnti, &r, 16); for (i = 0; i < 16; i++) { @@ -534,7 +527,6 @@ int srslte_pdcch_dci_encode(srslte_pdcch_t* q, uint8_t* data, uint8_t* e, uint32 uint8_t tmp[3 * (SRSLTE_DCI_MAX_BITS + 16)]; if (q != NULL && data != NULL && e != NULL && nof_bits < SRSLTE_DCI_MAX_BITS && E < q->max_bits) { - srslte_pdcch_dci_encode_conv(q, data, nof_bits, tmp, rnti); DEBUG("CConv output: "); @@ -563,21 +555,19 @@ int srslte_pdcch_encode(srslte_pdcch_t* q, srslte_dci_msg_t* msg, cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t i; cf_t* x[SRSLTE_MAX_LAYERS]; uint32_t nof_symbols; if (q != NULL && sf_symbols != NULL && sf->cfi > 0 && sf->cfi < 4 && srslte_dci_location_isvalid(&msg->location)) { - uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(msg->location.L); nof_symbols = e_bits / 2; ret = SRSLTE_ERROR; if (msg->location.ncce + PDCCH_FORMAT_NOF_CCE(msg->location.L) <= NOF_CCE(sf->cfi) && msg->nof_bits < SRSLTE_DCI_MAX_BITS - 16) { - DEBUG("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", + DEBUG("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x", msg->nof_bits, e_bits, msg->location.ncce, @@ -622,14 +612,14 @@ int srslte_pdcch_encode(srslte_pdcch_t* q, ret = SRSLTE_SUCCESS; } else { - ERROR("Illegal DCI message nCCE: %d, L: %d, nof_cce: %d, nof_bits=%d\n", + ERROR("Illegal DCI message nCCE: %d, L: %d, nof_cce: %d, nof_bits=%d", msg->location.ncce, msg->location.L, NOF_CCE(sf->cfi), msg->nof_bits); } } else { - ERROR("Invalid parameters: cfi=%d, L=%d, nCCE=%d\n", sf->cfi, msg->location.L, msg->location.ncce); + ERROR("Invalid parameters: cfi=%d, L=%d, nCCE=%d", sf->cfi, msg->location.L, msg->location.ncce); } return ret; } diff --git a/lib/src/phy/phch/pdcch_nr.c b/lib/src/phy/phch/pdcch_nr.c index 48bd70492..7893639cd 100644 --- a/lib/src/phy/phch/pdcch_nr.c +++ b/lib/src/phy/phch/pdcch_nr.c @@ -62,7 +62,7 @@ static int srslte_pdcch_nr_get_ncce(const srslte_coreset_t* coreset, uint32_t candidate) { if (aggregation_level >= SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR) { - ERROR("Invalid aggregation level %d;\n", aggregation_level); + ERROR("Invalid aggregation level %d;", aggregation_level); return SRSLTE_ERROR; } @@ -72,7 +72,7 @@ static int srslte_pdcch_nr_get_ncce(const srslte_coreset_t* coreset, uint32_t M = search_space->nof_candidates[aggregation_level]; // Number of aggregation levels if (M == 0) { - ERROR("Invalid number of candidates %d for aggregation level %d\n", M, aggregation_level); + ERROR("Invalid number of candidates %d for aggregation level %d", M, aggregation_level); return SRSLTE_ERROR; } @@ -81,7 +81,7 @@ static int srslte_pdcch_nr_get_ncce(const srslte_coreset_t* coreset, uint32_t N_cce = srslte_coreset_get_bw(coreset) * coreset->duration / 6; if (N_cce < L) { - ERROR("Error number of CCE %d is lower than the aggregation level %d\n", N_cce, L); + ERROR("Error number of CCE %d is lower than the aggregation level %d", N_cce, L); return SRSLTE_ERROR; } @@ -343,7 +343,6 @@ static uint32_t pdcch_nr_c_init(const srslte_pdcch_nr_t* q, const srslte_dci_msg int srslte_pdcch_nr_encode(srslte_pdcch_nr_t* q, const srslte_dci_msg_nr_t* dci_msg, cf_t* slot_symbols) { - if (q == NULL || dci_msg == NULL || slot_symbols == NULL) { return SRSLTE_ERROR; } @@ -363,7 +362,7 @@ int srslte_pdcch_nr_encode(srslte_pdcch_nr_t* q, const srslte_dci_msg_nr_t* dci_ if (srslte_polar_code_get(&q->code, q->K, q->E, 9U) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } - PDCCH_INFO_TX("K=%d; E=%d; M=%d; n=%d; cinit=%08x;\n", q->K, q->E, q->M, q->code.n, cinit); + PDCCH_INFO_TX("K=%d; E=%d; M=%d; n=%d; cinit=%08x;", q->K, q->E, q->M, q->code.n, cinit); // Set first L bits to ones, c will have an offset of 24 bits uint8_t* c = q->c; @@ -375,7 +374,7 @@ int srslte_pdcch_nr_encode(srslte_pdcch_nr_t* q, const srslte_dci_msg_nr_t* dci_ // Append CRC srslte_crc_attach(&q->crc24c, q->c, q->K); - PDCCH_INFO_TX("Append CRC %06x\n", (uint32_t)srslte_crc_checksum_get(&q->crc24c)); + PDCCH_INFO_TX("Append CRC %06x", (uint32_t)srslte_crc_checksum_get(&q->crc24c)); // Unpack RNTI uint8_t unpacked_rnti[16] = {}; @@ -423,7 +422,7 @@ int srslte_pdcch_nr_encode(srslte_pdcch_nr_t* q, const srslte_dci_msg_nr_t* dci_ // Put symbols in grid uint32_t m = pdcch_nr_cp(q, &dci_msg->location, slot_symbols, q->symbols, true); if (q->M != m) { - ERROR("Unmatch number of RE (%d != %d)\n", m, q->M); + ERROR("Unmatch number of RE (%d != %d)", m, q->M); return SRSLTE_ERROR; } @@ -436,7 +435,7 @@ int srslte_pdcch_nr_encode(srslte_pdcch_nr_t* q, const srslte_dci_msg_nr_t* dci_ if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { char str[128] = {}; srslte_pdcch_nr_info(q, NULL, str, sizeof(str)); - PDCCH_INFO_TX("%s\n", str); + PDCCH_INFO_TX("%s", str); } return SRSLTE_SUCCESS; @@ -464,7 +463,7 @@ int srslte_pdcch_nr_decode(srslte_pdcch_nr_t* q, // Check number of estimates is correct if (ce->nof_re != q->M) { - ERROR("Invalid number of channel estimates (%d != %d)\n", q->M, ce->nof_re); + ERROR("Invalid number of channel estimates (%d != %d)", q->M, ce->nof_re); return SRSLTE_ERROR; } @@ -472,12 +471,12 @@ int srslte_pdcch_nr_decode(srslte_pdcch_nr_t* q, if (srslte_polar_code_get(&q->code, q->K, q->E, 9U) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } - PDCCH_INFO_RX("K=%d; E=%d; M=%d; n=%d;\n", q->K, q->E, q->M, q->code.n); + PDCCH_INFO_RX("K=%d; E=%d; M=%d; n=%d;", q->K, q->E, q->M, q->code.n); // Get symbols from grid uint32_t m = pdcch_nr_cp(q, &dci_msg->location, slot_symbols, q->symbols, false); if (q->M != m) { - ERROR("Unmatch number of RE (%d != %d)\n", m, q->M); + ERROR("Unmatch number of RE (%d != %d)", m, q->M); return SRSLTE_ERROR; } @@ -583,7 +582,7 @@ int srslte_pdcch_nr_decode(srslte_pdcch_nr_t* q, if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { char str[128] = {}; srslte_pdcch_nr_info(q, res, str, sizeof(str)); - PDCCH_INFO_RX("%s\n", str); + PDCCH_INFO_RX("%s", str); } return SRSLTE_SUCCESS; diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 25f36b381..62b86d6e0 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -160,7 +160,6 @@ static int srslte_pdsch_cp(const srslte_pdsch_t* q, // Iterate over PRB for (uint32_t n = 0; n < q->cell.nof_prb; n++) { - // If this PRB is assigned if (grant->prb_idx[s][n]) { bool skip = pdsch_cp_skip_symbol(&q->cell, grant, sf_idx, s, l, n); @@ -260,7 +259,6 @@ static int pdsch_init(srslte_pdsch_t* q, uint32_t max_prb, bool is_ue, uint32_t int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - bzero(q, sizeof(srslte_pdsch_t)); ret = SRSLTE_ERROR; @@ -268,7 +266,7 @@ static int pdsch_init(srslte_pdsch_t* q, uint32_t max_prb, bool is_ue, uint32_t q->is_ue = is_ue; q->nof_rx_antennas = nof_antennas; - INFO("Init PDSCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); + INFO("Init PDSCH: %d PRBs, max_symbols: %d", max_prb, q->max_re); for (int i = 0; i < SRSLTE_MOD_NITEMS; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { @@ -298,7 +296,7 @@ static int pdsch_init(srslte_pdsch_t* q, uint32_t max_prb, bool is_ue, uint32_t if (is_ue) { q->evm_buffer[i] = srslte_evm_buffer_alloc(srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, 6)); if (!q->evm_buffer[i]) { - ERROR("Allocating EVM buffer\n"); + ERROR("Allocating EVM buffer"); goto clean; } } @@ -426,7 +424,6 @@ void srslte_pdsch_free(srslte_pdsch_t* q) srslte_pdsch_disable_coworker(q); for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { - if (q->e[i]) { free(q->e[i]); } @@ -499,7 +496,7 @@ int srslte_pdsch_set_cell(srslte_pdsch_t* q, srslte_cell_t cell) } } - INFO("PDSCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d\n", + INFO("PDSCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d", q->cell.id, q->cell.nof_ports, q->cell.nof_prb, @@ -522,7 +519,7 @@ int srslte_pdsch_set_rnti(srslte_pdsch_t* q, uint16_t rnti) // If the sequence is not allocated generate q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t)); if (!q->users[rnti_idx]) { - ERROR("Alocating PDSCH user\n"); + ERROR("Alocating PDSCH user"); return SRSLTE_ERROR; } } else if (q->users[rnti_idx]->sequence_generated && q->users[rnti_idx]->cell_id == q->cell.id && !q->is_ue) { @@ -543,7 +540,7 @@ int srslte_pdsch_set_rnti(srslte_pdsch_t* q, uint16_t rnti) SRSLTE_NOF_SLOTS_PER_SF * sf_idx, q->cell.id, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_256QAM))) { - ERROR("Error initializing PDSCH scrambling sequence\n"); + ERROR("Error initializing PDSCH scrambling sequence"); srslte_pdsch_free_rnti(q, rnti); return SRSLTE_ERROR; } @@ -574,7 +571,6 @@ void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) } static float apply_power_allocation(srslte_pdsch_t* q, srslte_pdsch_cfg_t* cfg, cf_t* sf_symbols_m[SRSLTE_MAX_PORTS]) { - uint32_t nof_symbols_slot = cfg->grant.nof_symb_slot[0]; uint32_t nof_re_symbol = SRSLTE_NRE * q->cell.nof_prb; @@ -627,10 +623,8 @@ get_user_sequence(srslte_pdsch_t* q, uint16_t rnti, uint32_t codeword_idx, uint3 static void csi_correction(srslte_pdsch_t* q, srslte_pdsch_cfg_t* cfg, uint32_t codeword_idx, uint32_t tb_idx, void* e) { - uint32_t qm = 0; switch (cfg->grant.tb[tb_idx].mod) { - case SRSLTE_MOD_BPSK: qm = 1; break; @@ -752,7 +746,7 @@ static void pdsch_decode_debug(srslte_pdsch_t* q, ERROR("Generating file name"); break; } - DEBUG("SAVED FILE %s: received subframe symbols\n", filename); + DEBUG("SAVED FILE %s: received subframe symbols", filename); srslte_vec_save_file(filename, sf_symbols[j], SRSLTE_NOF_RE(q->cell) * sizeof(cf_t)); for (int i = 0; i < q->cell.nof_ports; i++) { @@ -760,7 +754,7 @@ static void pdsch_decode_debug(srslte_pdsch_t* q, ERROR("Generating file name"); break; } - DEBUG("SAVED FILE %s: channel estimates for Tx %d and Rx %d\n", filename, j, i); + DEBUG("SAVED FILE %s: channel estimates for Tx %d and Rx %d", filename, j, i); srslte_vec_save_file(filename, ce[i][j], SRSLTE_NOF_RE(q->cell) * sizeof(cf_t)); } } @@ -769,14 +763,14 @@ static void pdsch_decode_debug(srslte_pdsch_t* q, ERROR("Generating file name"); break; } - DEBUG("SAVED FILE %s: symbols after equalization\n", filename); + DEBUG("SAVED FILE %s: symbols after equalization", filename); srslte_vec_save_file(filename, q->d[i], cfg->grant.nof_re * sizeof(cf_t)); if (snprintf(filename, FILENAME_MAX, "llr_%d.dat", i) < 0) { ERROR("Generating file name"); break; } - DEBUG("SAVED FILE %s: LLR estimates after demodulation and descrambling\n", filename); + DEBUG("SAVED FILE %s: LLR estimates after demodulation and descrambling", filename); srslte_vec_save_file(filename, q->e[i], cfg->grant.tb[0].nof_bits * sizeof(int16_t)); } } @@ -799,7 +793,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t* q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (softbuffer && data && ack && cfg->grant.tb[tb_idx].nof_bits && cfg->grant.nof_re) { - INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d", sf->tti % 10, codeword_idx, tb_idx, @@ -840,7 +834,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t* q, srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, codeword_idx, sf->tti % 10, cfg->grant.tb[tb_idx].nof_bits); if (!seq) { - ERROR("Error getting user sequence for rnti=0x%x\n", cfg->rnti); + ERROR("Error getting user sequence for rnti=0x%x", cfg->rnti); return -1; } @@ -868,7 +862,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t* q, ret = SRSLTE_ERROR; } } else { - ERROR("Invalid parameters in TB%d &softbuffer=%p &data=%p &ack=%p, nbits=%d, nof_re=%d\n", + ERROR("Invalid parameters in TB%d &softbuffer=%p &data=%p &ack=%p, nbits=%d, nof_re=%d", codeword_idx, softbuffer, (void*)data, @@ -884,7 +878,7 @@ static void* srslte_pdsch_decode_thread(void* arg) { srslte_pdsch_coworker_t* q = (srslte_pdsch_coworker_t*)arg; - INFO("[PDSCH Coworker] waiting for data\n"); + INFO("[PDSCH Coworker] waiting for data"); sem_wait(&q->start); while (!q->quit) { @@ -911,13 +905,11 @@ int srslte_pdsch_decode(srslte_pdsch_t* q, cf_t* sf_symbols[SRSLTE_MAX_PORTS], srslte_pdsch_res_t data[SRSLTE_MAX_CODEWORDS]) { - /* Set pointers for layermapping & precoding */ uint32_t i; cf_t** x; if (q != NULL && sf_symbols != NULL && data != NULL && cfg != NULL) { - struct timeval t[3]; if (cfg->meas_time_en) { gettimeofday(&t[1], NULL); @@ -939,7 +931,7 @@ int srslte_pdsch_decode(srslte_pdsch_t* q, float noise_estimate = cfg->decoder_type == SRSLTE_MIMO_DECODER_ZF ? 0 : channel->noise_estimate; - INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mod=%s, nof_layers=%d, nof_tb=%d\n", + INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mod=%s, nof_layers=%d, nof_tb=%d", sf->tti % 10, cfg->rnti, cfg->grant.nof_re, @@ -953,21 +945,21 @@ int srslte_pdsch_decode(srslte_pdsch_t* q, for (int j = 0; j < q->nof_rx_antennas; j++) { int n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, lstart, sf->tti % 10); if (n != cfg->grant.nof_re) { - ERROR("Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); + ERROR("Error expecting %d symbols but got %d", cfg->grant.nof_re, n); return SRSLTE_ERROR; } for (i = 0; i < q->cell.nof_ports; i++) { n = srslte_pdsch_get(q, channel->ce[i][j], q->ce[i][j], &cfg->grant, lstart, sf->tti % 10); if (n != cfg->grant.nof_re) { - ERROR("Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); + ERROR("Error expecting %d symbols but got %d", cfg->grant.nof_re, n); return SRSLTE_ERROR; } } } if (cfg->grant.nof_layers == 0 || cfg->grant.nof_layers > SRSLTE_MAX_LAYERS) { - ERROR("PDSCH Number of layers (%d) is out-of-bounds\n", cfg->grant.nof_layers); + ERROR("PDSCH Number of layers (%d) is out-of-bounds", cfg->grant.nof_layers); return SRSLTE_ERROR_OUT_OF_BOUNDS; } @@ -998,7 +990,7 @@ int srslte_pdsch_decode(srslte_pdsch_t* q, cfg->grant.tx_scheme, pdsch_scaling, noise_estimate) < 0) { - ERROR("Error predecoding\n"); + ERROR("Error predecoding"); return SRSLTE_ERROR; } @@ -1009,7 +1001,6 @@ int srslte_pdsch_decode(srslte_pdsch_t* q, /* Codeword decoding: Implementation of 3GPP 36.212 Table 5.3.3.1.5-1 and Table 5.3.3.1.5-2 */ for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) { - /* Decode only if transport block is enabled and the default ACK is not true */ if (cfg->grant.tb[tb_idx].enabled) { if (!data[tb_idx].crc) { @@ -1074,7 +1065,7 @@ int srslte_pdsch_decode(srslte_pdsch_t* q, return SRSLTE_SUCCESS; } else { - ERROR("Invalid inputs\n"); + ERROR("Invalid inputs"); return SRSLTE_ERROR_INVALID_INPUTS; } } @@ -1099,7 +1090,7 @@ static int srslte_pdsch_codeword_encode(srslte_pdsch_t* q, if (cfg->grant.tb[tb_idx].enabled) { if (cfg->rnti != SRSLTE_SIRNTI) { - INFO("Encoding PDSCH SF: %d (TB%d -> CW%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + INFO("Encoding PDSCH SF: %d (TB%d -> CW%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d", sf->tti % 10, tb_idx, codeword_idx, @@ -1120,7 +1111,7 @@ static int srslte_pdsch_codeword_encode(srslte_pdsch_t* q, srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, codeword_idx, sf->tti % 10, cfg->grant.tb[tb_idx].nof_bits); if (!seq) { - ERROR("Error getting user sequence for rnti=0x%x\n", cfg->rnti); + ERROR("Error getting user sequence for rnti=0x%x", cfg->rnti); return -1; } @@ -1144,7 +1135,6 @@ int srslte_pdsch_encode(srslte_pdsch_t* q, uint8_t* data[SRSLTE_MAX_CODEWORDS], cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { - int i; /* Set pointers for layermapping & precoding */ cf_t* x[SRSLTE_MAX_LAYERS]; @@ -1160,19 +1150,19 @@ int srslte_pdsch_encode(srslte_pdsch_t* q, for (i = 0; i < q->cell.nof_ports; i++) { if (sf_symbols[i] == NULL) { - ERROR("Error NULL pointer in sf_symbols[%d]\n", i); + ERROR("Error NULL pointer in sf_symbols[%d]", i); return SRSLTE_ERROR_INVALID_INPUTS; } } /* If both transport block size is zero return error */ if (!nof_tb) { - ERROR("Error number of TB is zero\n"); + ERROR("Error number of TB is zero"); return SRSLTE_ERROR_INVALID_INPUTS; } if (cfg->grant.nof_re > q->max_re) { - ERROR("Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", + ERROR("Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)", cfg->grant.nof_re, q->max_re, q->cell.nof_prb); @@ -1196,7 +1186,7 @@ int srslte_pdsch_encode(srslte_pdsch_t* q, } if (cfg->rnti != SRSLTE_SIRNTI) { - INFO("Encoding PDSCH SF: %d rho_a=%f, nof_ports=%d, nof_layers=%d, nof_tb=%d, pmi=%d, tx_scheme=%s\n", + INFO("Encoding PDSCH SF: %d rho_a=%f, nof_ports=%d, nof_layers=%d, nof_tb=%d, pmi=%d, tx_scheme=%s", sf->tti % 10, rho_a, q->cell.nof_ports, @@ -1296,7 +1286,6 @@ uint32_t srslte_pdsch_grant_rx_info(srslte_pdsch_grant_t* grant, char* str, uint32_t str_len) { - uint32_t len = srslte_ra_dl_info(grant, str, str_len); len = srslte_print_check(str, str_len, len, ", crc={", 0); @@ -1341,7 +1330,7 @@ srslte_pdsch_rx_info(srslte_pdsch_cfg_t* cfg, srslte_pdsch_res_t res[SRSLTE_MAX_ } if (cfg->meas_time_en) { - len = srslte_print_check(str, str_len, len, ", t=%d us\n", cfg->meas_time_value); + len = srslte_print_check(str, str_len, len, ", t=%d us", cfg->meas_time_value); } return len; @@ -1349,7 +1338,6 @@ srslte_pdsch_rx_info(srslte_pdsch_cfg_t* cfg, srslte_pdsch_res_t res[SRSLTE_MAX_ uint32_t srslte_pdsch_tx_info(srslte_pdsch_cfg_t* cfg, char* str, uint32_t str_len) { - uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti); len += srslte_ra_dl_info(&cfg->grant, &str[len], str_len); diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index 627c8ce39..07f64ef6d 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -30,7 +30,7 @@ int pdsch_nr_init_common(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* arg { for (srslte_mod_t mod = SRSLTE_MOD_BPSK; mod < SRSLTE_MOD_NITEMS; mod++) { if (srslte_modem_table_lte(&q->modem_tables[mod], mod) < SRSLTE_SUCCESS) { - ERROR("Error initialising modem table for %s\n", srslte_mod_string(mod)); + ERROR("Error initialising modem table for %s", srslte_mod_string(mod)); return SRSLTE_ERROR; } if (args->measure_evm) { @@ -52,7 +52,7 @@ int srslte_pdsch_nr_init_enb(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* } if (srslte_sch_nr_init_tx(&q->sch, &args->sch)) { - ERROR("Initialising SCH\n"); + ERROR("Initialising SCH"); return SRSLTE_ERROR; } @@ -70,14 +70,14 @@ int srslte_pdsch_nr_init_ue(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* } if (srslte_sch_nr_init_rx(&q->sch, &args->sch)) { - ERROR("Initialising SCH\n"); + ERROR("Initialising SCH"); return SRSLTE_ERROR; } if (args->measure_evm) { q->evm_buffer = srslte_evm_buffer_alloc(8); if (q->evm_buffer == NULL) { - ERROR("Initialising EVM\n"); + ERROR("Initialising EVM"); return SRSLTE_ERROR; } } @@ -291,8 +291,7 @@ static uint32_t srslte_pdsch_nr_cp_dmrs(const srslte_pdsch_nr_t* q, { uint32_t count = 0; - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = &cfg->dmrs; switch (dmrs_cfg->type) { case srslte_dmrs_sch_type_1: @@ -364,7 +363,7 @@ static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q, uint32_t dmrs_l_count = 0; // Get symbol indexes carrying DMRS - int32_t nof_dmrs_symbols = srslte_dmrs_sch_get_symbols_idx(cfg, grant, dmrs_l_idx); + int32_t nof_dmrs_symbols = srslte_dmrs_sch_get_symbols_idx(&cfg->dmrs, grant, dmrs_l_idx); if (nof_dmrs_symbols < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -421,7 +420,7 @@ pdsch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf } uint32_t cinit = (((uint32_t)rnti) << 15U) + (cw_idx << 14U) + n_id; - INFO("PDSCH: RNTI=%d (0x%x); nid=%d; cinit=%d (0x%x);\n", rnti, rnti, n_id, cinit, cinit); + INFO("PDSCH: RNTI=%d (0x%x); nid=%d; cinit=%d (0x%x);", rnti, rnti, n_id, cinit, cinit); return cinit; } @@ -439,19 +438,19 @@ static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q, // Check codeword index if (tb->cw_idx >= q->max_cw) { - ERROR("Unsupported codeword index %d\n", tb->cw_idx); + ERROR("Unsupported codeword index %d", tb->cw_idx); return SRSLTE_ERROR; } // Check modulation if (tb->mod >= SRSLTE_MOD_NITEMS) { - ERROR("Invalid modulation %s\n", srslte_mod_string(tb->mod)); + ERROR("Invalid modulation %s", srslte_mod_string(tb->mod)); return SRSLTE_ERROR_OUT_OF_BOUNDS; } // Encode SCH if (srslte_dlsch_nr_encode(&q->sch, &cfg->sch_cfg, tb, data, q->b[tb->cw_idx]) < SRSLTE_SUCCESS) { - ERROR("Error in DL-SCH encoding\n"); + ERROR("Error in DL-SCH encoding"); return SRSLTE_ERROR; } @@ -481,7 +480,6 @@ int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, uint8_t* data[SRSLTE_MAX_TB], cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { - // Check input pointers if (!q || !cfg || !grant || !data || !sf_symbols) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -494,7 +492,7 @@ int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, // Check number of layers if (q->max_layers < grant->nof_layers) { - ERROR("Error number of layers (%d) exceeds configured maximum (%d)\n", grant->nof_layers, q->max_layers); + ERROR("Error number of layers (%d) exceeds configured maximum (%d)", grant->nof_layers, q->max_layers); return SRSLTE_ERROR; } @@ -504,7 +502,7 @@ int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, nof_cw += grant->tb[tb].enabled ? 1 : 0; if (pdsch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb], grant->rnti) < SRSLTE_SUCCESS) { - ERROR("Error encoding TB %d\n", tb); + ERROR("Error encoding TB %d", tb); return SRSLTE_ERROR; } } @@ -525,12 +523,12 @@ int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, // 7.3.1.6 Mapping from virtual to physical resource blocks int n = srslte_pdsch_nr_put(q, cfg, grant, x[0], sf_symbols[0]); if (n < SRSLTE_SUCCESS) { - ERROR("Putting NR PDSCH resources\n"); + ERROR("Putting NR PDSCH resources"); return SRSLTE_ERROR; } if (n != grant->tb[0].nof_re) { - ERROR("Unmatched number of RE (%d != %d)\n", n, grant->tb[0].nof_re); + ERROR("Unmatched number of RE (%d != %d)", n, grant->tb[0].nof_re); return SRSLTE_ERROR; } @@ -556,13 +554,13 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q, // Check codeword index if (tb->cw_idx >= q->max_cw) { - ERROR("Unsupported codeword index %d\n", tb->cw_idx); + ERROR("Unsupported codeword index %d", tb->cw_idx); return SRSLTE_ERROR; } // Check modulation if (tb->mod >= SRSLTE_MOD_NITEMS) { - ERROR("Invalid modulation %s\n", srslte_mod_string(tb->mod)); + ERROR("Invalid modulation %s", srslte_mod_string(tb->mod)); return SRSLTE_ERROR_OUT_OF_BOUNDS; } @@ -597,7 +595,7 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q, // Decode SCH if (srslte_dlsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { - ERROR("Error in DL-SCH encoding\n"); + ERROR("Error in DL-SCH encoding"); return SRSLTE_ERROR; } @@ -629,14 +627,14 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(cfg, grant); if (channel->nof_re != nof_re) { - ERROR("Inconsistent number of RE (%d!=%d)\n", channel->nof_re, nof_re); + ERROR("Inconsistent number of RE (%d!=%d)", channel->nof_re, nof_re); return SRSLTE_ERROR; } // Demapping from virtual to physical resource blocks uint32_t nof_re_get = srslte_pdsch_nr_get(q, cfg, grant, q->x[0], sf_symbols[0]); if (nof_re_get != nof_re) { - ERROR("Inconsistent number of RE (%d!=%d)\n", nof_re_get, nof_re); + ERROR("Inconsistent number of RE (%d!=%d)", nof_re_get, nof_re); return SRSLTE_ERROR; } @@ -665,7 +663,7 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, nof_cw += grant->tb[tb].enabled ? 1 : 0; if (pdsch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSLTE_SUCCESS) { - ERROR("Error encoding TB %d\n", tb); + ERROR("Error encoding TB %d", tb); return SRSLTE_ERROR; } } @@ -687,12 +685,23 @@ static uint32_t srslte_pdsch_nr_grant_info(const srslte_sch_cfg_nr_t* cfg, uint32_t len = 0; len = srslte_print_check(str, str_len, len, "rnti=0x%x", grant->rnti); + char freq_str[SRSLTE_MAX_PRB_NR + 1] = {}; + for (uint32_t i = 0, nof_prb = 0; i < SRSLTE_MAX_PRB_NR && nof_prb < grant->nof_prb; i++) { + if (grant->prb_idx[i]) { + freq_str[i] = '1'; + nof_prb++; + } else { + freq_str[i] = '0'; + } + } + // Append time-domain resource mapping len = srslte_print_check(str, str_len, len, - ",k0=%d,S=%d,L=%d,mapping=%s", - grant->k0, + ",k0=%d,freq=%s,symb=%d:%d,mapping=%s", + grant->k, + freq_str, grant->S, grant->L, srslte_sch_mapping_type_to_str(grant->mapping)); @@ -721,7 +730,6 @@ uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, char* str, uint32_t str_len) { - uint32_t len = 0; len += srslte_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len); @@ -757,7 +765,7 @@ uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, } if (q->meas_time_en) { - len = srslte_print_check(str, str_len, len, ", t=%d us\n", q->meas_time_us); + len = srslte_print_check(str, str_len, len, ", t=%d us", q->meas_time_us); } return len; @@ -769,13 +777,12 @@ uint32_t srslte_pdsch_nr_tx_info(const srslte_pdsch_nr_t* q, char* str, uint32_t str_len) { - uint32_t len = 0; len += srslte_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len); if (q->meas_time_en) { - len = srslte_print_check(str, str_len, len, ", t=%d us\n", q->meas_time_us); + len = srslte_print_check(str, str_len, len, ", t=%d us", q->meas_time_us); } return len; diff --git a/lib/src/phy/phch/phich.c b/lib/src/phy/phch/phich.c index 11d439a49..18293b303 100644 --- a/lib/src/phy/phch/phich.c +++ b/lib/src/phy/phch/phich.c @@ -75,7 +75,6 @@ int srslte_phich_init(srslte_phich_t* q, uint32_t nof_rx_antennas) int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - bzero(q, sizeof(srslte_phich_t)); ret = SRSLTE_ERROR; @@ -113,7 +112,6 @@ int srslte_phich_set_cell(srslte_phich_t* q, srslte_regs_t* regs, srslte_cell_t int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && regs != NULL && srslte_cell_isvalid(&cell)) { - q->regs = regs; if (cell.id != q->cell.id || q->cell.nof_prb == 0) { @@ -139,7 +137,7 @@ void srslte_phich_calc(srslte_phich_t* q, srslte_phich_grant_t* grant, srslte_ph n_phich->nseq = ((grant->n_prb_lowest / Ngroups) + grant->n_dmrs) % (2 * srslte_phich_nsf(q)); } } else { - ERROR("PHICH: Error computing PHICH groups. Ngroups is zero\n"); + ERROR("PHICH: Error computing PHICH groups. Ngroups is zero"); } } @@ -160,7 +158,7 @@ uint8_t srslte_phich_ack_decode(float bits[SRSLTE_PHICH_NBITS], float* distance) for (i = 0; i < 2; i++) { float corr = srslte_vec_dot_prod_fff(ack_table[i], bits, SRSLTE_PHICH_NBITS) / SRSLTE_PHICH_NBITS; - INFO("Corr%d=%f\n", i, corr); + INFO("Corr%d=%f", i, corr); if (corr > max_corr) { max_corr = corr; if (distance) { @@ -187,7 +185,6 @@ int srslte_phich_decode(srslte_phich_t* q, cf_t* sf_symbols[SRSLTE_MAX_PORTS], srslte_phich_res_t* result) { - /* Set pointers for layermapping & precoding */ int i, j; cf_t* x[SRSLTE_MAX_LAYERS]; @@ -199,27 +196,27 @@ int srslte_phich_decode(srslte_phich_t* q, uint32_t sf_idx = sf->tti % 10; if (sf_idx >= SRSLTE_NOF_SF_X_FRAME) { - ERROR("Invalid nslot %d\n", sf_idx); + ERROR("Invalid nslot %d", sf_idx); return SRSLTE_ERROR_INVALID_INPUTS; } if (SRSLTE_CP_ISEXT(q->cell.cp)) { if (n_phich.nseq >= SRSLTE_PHICH_EXT_NSEQUENCES) { - ERROR("Invalid nseq %d\n", n_phich.nseq); + ERROR("Invalid nseq %d", n_phich.nseq); return SRSLTE_ERROR_INVALID_INPUTS; } } else { if (n_phich.nseq >= SRSLTE_PHICH_NORM_NSEQUENCES) { - ERROR("Invalid nseq %d\n", n_phich.nseq); + ERROR("Invalid nseq %d", n_phich.nseq); return SRSLTE_ERROR_INVALID_INPUTS; } } if (n_phich.ngroup >= srslte_regs_phich_ngroups(q->regs)) { - ERROR("Invalid ngroup %d\n", n_phich.ngroup); + ERROR("Invalid ngroup %d", n_phich.ngroup); return SRSLTE_ERROR_INVALID_INPUTS; } - DEBUG("Decoding PHICH Ngroup: %d, Nseq: %d\n", n_phich.ngroup, n_phich.nseq); + DEBUG("Decoding PHICH Ngroup: %d, Nseq: %d", n_phich.ngroup, n_phich.nseq); /* number of layers equals number of ports */ for (i = 0; i < SRSLTE_MAX_PORTS; i++) { @@ -232,7 +229,7 @@ int srslte_phich_decode(srslte_phich_t* q, /* extract symbols */ for (int j = 0; j < q->nof_rx_antennas; j++) { if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, sf_symbols[j], q->sf_symbols[j], n_phich.ngroup)) { - ERROR("There was an error getting the phich symbols\n"); + ERROR("There was an error getting the phich symbols"); return SRSLTE_ERROR; } q_sf_symbols[j] = q->sf_symbols[j]; @@ -240,7 +237,7 @@ int srslte_phich_decode(srslte_phich_t* q, /* extract channel estimates */ for (i = 0; i < q->cell.nof_ports; i++) { if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, channel->ce[i][j], q->ce[i][j], n_phich.ngroup)) { - ERROR("There was an error getting the phich symbols\n"); + ERROR("There was an error getting the phich symbols"); return SRSLTE_ERROR; } q_ce[i][j] = q->ce[i][j]; @@ -257,7 +254,7 @@ int srslte_phich_decode(srslte_phich_t* q, q_sf_symbols, q_ce, x, NULL, q->nof_rx_antennas, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, 1.0f); srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); } - DEBUG("Recv!!: \n"); + DEBUG("Recv!!: "); DEBUG("d0: "); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB); @@ -332,23 +329,23 @@ int srslte_phich_encode(srslte_phich_t* q, uint32_t sf_idx = sf->tti % 10; if (sf_idx >= SRSLTE_NOF_SF_X_FRAME) { - ERROR("Invalid nslot %d\n", sf_idx); + ERROR("Invalid nslot %d", sf_idx); return SRSLTE_ERROR_INVALID_INPUTS; } if (SRSLTE_CP_ISEXT(q->cell.cp)) { if (n_phich.nseq >= SRSLTE_PHICH_EXT_NSEQUENCES) { - ERROR("Invalid nseq %d\n", n_phich.nseq); + ERROR("Invalid nseq %d", n_phich.nseq); return SRSLTE_ERROR_INVALID_INPUTS; } } else { if (n_phich.nseq >= SRSLTE_PHICH_NORM_NSEQUENCES) { - ERROR("Invalid nseq %d\n", n_phich.nseq); + ERROR("Invalid nseq %d", n_phich.nseq); return SRSLTE_ERROR_INVALID_INPUTS; } } if (n_phich.ngroup >= srslte_regs_phich_ngroups(q->regs)) { - ERROR("Invalid ngroup %d\n", n_phich.ngroup); + ERROR("Invalid ngroup %d", n_phich.ngroup); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -428,7 +425,7 @@ int srslte_phich_encode(srslte_phich_t* q, /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { if (srslte_regs_phich_add(q->regs, q->sf_symbols[i], n_phich.ngroup, sf_symbols[i]) < 0) { - ERROR("Error putting PCHICH resource elements\n"); + ERROR("Error putting PCHICH resource elements"); return SRSLTE_ERROR; } } diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index eae780fa0..86b50da84 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -128,7 +128,6 @@ int srslte_pmch_init(srslte_pmch_t* q, uint32_t max_prb, uint32_t nof_rx_antenna int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && nof_rx_antennas <= SRSLTE_MAX_PORTS) { - bzero(q, sizeof(srslte_pmch_t)); ret = SRSLTE_ERROR; @@ -137,7 +136,7 @@ int srslte_pmch_init(srslte_pmch_t* q, uint32_t max_prb, uint32_t nof_rx_antenna q->max_re = max_prb * MAX_PMCH_RE; q->nof_rx_antennas = nof_rx_antennas; - INFO("Init PMCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); + INFO("Init PMCH: %d PRBs, max_symbols: %d", max_prb, q->max_re); for (int i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { @@ -241,7 +240,7 @@ int srslte_pmch_set_cell(srslte_pmch_t* q, srslte_cell_t cell) q->cell = cell; q->max_re = q->cell.nof_prb * MAX_PMCH_RE; - INFO("PMCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d\n", + INFO("PMCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d", q->cell.nof_ports, q->cell.id, q->cell.nof_prb, @@ -292,14 +291,13 @@ int srslte_pmch_decode(srslte_pmch_t* q, cf_t* sf_symbols[SRSLTE_MAX_PORTS], srslte_pdsch_res_t* out) { - /* Set pointers for layermapping & precoding */ uint32_t i, n; cf_t* x[SRSLTE_MAX_LAYERS]; if (q != NULL && sf_symbols != NULL && out != NULL && cfg != NULL) { INFO("Decoding PMCH SF: %d, MBSFN area ID: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d, " - "C_prb=%d, cfi=%d\n", + "C_prb=%d, cfi=%d", sf->tti % 10, cfg->area_id, srslte_mod_string(cfg->pdsch_cfg.grant.tb[0].mod), @@ -321,8 +319,7 @@ int srslte_pmch_decode(srslte_pmch_t* q, /* extract symbols */ n = pmch_get(q, sf_symbols[j], q->symbols[j], lstart); if (n != cfg->pdsch_cfg.grant.nof_re) { - - ERROR("PMCH 1 extract symbols error expecting %d symbols but got %d, lstart %d\n", + ERROR("PMCH 1 extract symbols error expecting %d symbols but got %d, lstart %d", cfg->pdsch_cfg.grant.nof_re, n, lstart); @@ -333,7 +330,7 @@ int srslte_pmch_decode(srslte_pmch_t* q, for (i = 0; i < q->cell.nof_ports; i++) { n = pmch_get(q, channel->ce[i][j], q->ce[i][j], lstart); if (n != cfg->pdsch_cfg.grant.nof_re) { - ERROR("PMCH 2 extract chest error expecting %d symbols but got %d\n", cfg->pdsch_cfg.grant.nof_re, n); + ERROR("PMCH 2 extract chest error expecting %d symbols but got %d", cfg->pdsch_cfg.grant.nof_re, n); return SRSLTE_ERROR; } } @@ -350,16 +347,16 @@ int srslte_pmch_decode(srslte_pmch_t* q, channel->noise_estimate); if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE subframe.dat: received subframe symbols\n"); + DEBUG("SAVED FILE subframe.dat: received subframe symbols"); srslte_vec_save_file("subframe2.dat", q->symbols[0], cfg->pdsch_cfg.grant.nof_re * sizeof(cf_t)); - DEBUG("SAVED FILE hest0.dat: channel estimates for port 4\n"); + DEBUG("SAVED FILE hest0.dat: channel estimates for port 4"); printf("nof_prb=%d, cp=%d, nof_re=%d, grant_re=%d\n", q->cell.nof_prb, q->cell.cp, SRSLTE_NOF_RE(q->cell), cfg->pdsch_cfg.grant.nof_re); srslte_vec_save_file("hest2.dat", channel->ce[0][0], SRSLTE_NOF_RE(q->cell) * sizeof(cf_t)); - DEBUG("SAVED FILE pmch_symbols.dat: symbols after equalization\n"); + DEBUG("SAVED FILE pmch_symbols.dat: symbols after equalization"); srslte_vec_save_file("pmch_symbols.bin", q->d, cfg->pdsch_cfg.grant.nof_re * sizeof(cf_t)); } @@ -373,7 +370,7 @@ int srslte_pmch_decode(srslte_pmch_t* q, srslte_scrambling_s_offset(&q->seqs[cfg->area_id]->seq[sf->tti % 10], q->e, 0, cfg->pdsch_cfg.grant.tb[0].nof_bits); if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n"); + DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling"); srslte_vec_save_file("llr.dat", q->e, cfg->pdsch_cfg.grant.tb[0].nof_bits * sizeof(int16_t)); } out[0].crc = (srslte_dlsch_decode(&q->dl_sch, &cfg->pdsch_cfg, q->e, out[0].payload) == 0); @@ -412,7 +409,6 @@ int srslte_pmch_encode(srslte_pmch_t* q, uint8_t* data, cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { - int i; /* Set pointers for layermapping & precoding */ cf_t* x[SRSLTE_MAX_LAYERS]; @@ -429,14 +425,14 @@ int srslte_pmch_encode(srslte_pmch_t* q, } if (cfg->pdsch_cfg.grant.nof_re > q->max_re) { - ERROR("Error too many RE per subframe (%d). PMCH configured for %d RE (%d PRB)\n", + ERROR("Error too many RE per subframe (%d). PMCH configured for %d RE (%d PRB)", cfg->pdsch_cfg.grant.nof_re, q->max_re, q->cell.nof_prb); return SRSLTE_ERROR_INVALID_INPUTS; } - INFO("Encoding PMCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + INFO("Encoding PMCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d", sf->tti % 10, srslte_mod_string(cfg->pdsch_cfg.grant.tb[0].mod), cfg->pdsch_cfg.grant.tb[0].tbs, @@ -452,7 +448,7 @@ int srslte_pmch_encode(srslte_pmch_t* q, // TODO: use tb_encode directly if (srslte_dlsch_encode(&q->dl_sch, &cfg->pdsch_cfg, data, q->e)) { - ERROR("Error encoding TB\n"); + ERROR("Error encoding TB"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index 3ff1d98a9..283074c89 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -19,7 +19,6 @@ * */ -#include "srslte/srslte.h" #include #include #include @@ -31,8 +30,6 @@ #include "prach_tables.h" -float save_corr[4096]; - // PRACH detection threshold is PRACH_DETECT_FACTOR*average #define PRACH_DETECT_FACTOR 18 #define SUCCESSIVE_CANCELLATION_ITS 4 @@ -47,6 +44,61 @@ float save_corr[4096]; //#define PRACH_CANCELLATION_HARD #define PRACH_AMP 1.0 +// Comment following line for disabling complex exponential look-up table +#define PRACH_USE_CEXP_LUT + +#ifdef PRACH_USE_CEXP_LUT + +// Define read-only complex exponential tables for two possibles size of sequences, common for all possible PRACH +// objects +#define PRACH_N_ZC_LONG_LUT_SIZE (2 * SRSLTE_PRACH_N_ZC_LONG) +static cf_t cexp_table_long[PRACH_N_ZC_LONG_LUT_SIZE] = {}; +#define PRACH_N_ZC_SHORT_LUT_SIZE (2 * SRSLTE_PRACH_N_ZC_SHORT) +static cf_t cexp_table_short[PRACH_N_ZC_SHORT_LUT_SIZE] = {}; + +// Use constructor attribute for writing complex exponential tables +__attribute__((constructor)) static void prach_cexp_init() +{ + for (uint32_t i = 0; i < PRACH_N_ZC_LONG_LUT_SIZE; i++) { + cexp_table_long[i] = cexpf(-I * 2.0f * M_PI * (float)i / (float)PRACH_N_ZC_LONG_LUT_SIZE); + } + for (uint32_t i = 0; i < PRACH_N_ZC_SHORT_LUT_SIZE; i++) { + cexp_table_short[i] = cexpf(-I * 2.0f * M_PI * (float)i / (float)PRACH_N_ZC_SHORT_LUT_SIZE); + } +} + +#endif // PRACH_USE_CEXP_LUT + +// Generate ZC sequence using either look-up tables or conventional cexp function +static void prach_cexp(uint32_t N_zc, uint32_t u, cf_t* root) +{ +#ifdef PRACH_USE_CEXP_LUT + // Use long N_zc table (839 length) + if (N_zc == SRSLTE_PRACH_N_ZC_LONG) { + for (int j = 0; j < SRSLTE_PRACH_N_ZC_LONG; j++) { + uint32_t phase_idx = u * j * (j + 1); + root[j] = cexp_table_long[phase_idx % PRACH_N_ZC_LONG_LUT_SIZE]; + } + return; + } + + // Use short N_zc table (139 length) + if (N_zc == SRSLTE_PRACH_N_ZC_SHORT) { + for (int j = 0; j < SRSLTE_PRACH_N_ZC_SHORT; j++) { + uint32_t phase_idx = u * j * (j + 1); + root[j] = cexp_table_short[phase_idx % PRACH_N_ZC_SHORT_LUT_SIZE]; + } + return; + } +#endif // PRACH_USE_CEXP_LUT + + // If the N_zc does not match any of the tables, use conventional exponential function + for (int j = 0; j < N_zc; j++) { + double phase = -M_PI * u * j * (j + 1) / N_zc; + root[j] = cexp(phase * I); + } +} + int srslte_prach_set_cell_(srslte_prach_t* p, uint32_t N_ifft_ul, srslte_prach_cfg_t* cfg, @@ -108,7 +160,7 @@ uint32_t srslte_prach_nof_f_idx_tdd(uint32_t config_idx, uint32_t tdd_ul_dl_conf if (config_idx < 64 && tdd_ul_dl_config < 7) { return prach_tdd_loc_table[config_idx][tdd_ul_dl_config].nof_elems; } else { - ERROR("PRACH: Invalid parmeters config_idx=%d, tdd_ul_config=%d\n", config_idx, tdd_ul_dl_config); + ERROR("PRACH: Invalid parmeters config_idx=%d, tdd_ul_config=%d", config_idx, tdd_ul_dl_config); return 0; } } @@ -118,7 +170,7 @@ uint32_t srslte_prach_f_id_tdd(uint32_t config_idx, uint32_t tdd_ul_dl_config, u if (config_idx < 64 && tdd_ul_dl_config < 7) { return prach_tdd_loc_table[config_idx][tdd_ul_dl_config].elems[prach_idx].f; } else { - ERROR("PRACH: Invalid parmeters config_idx=%d, tdd_ul_config=%d\n", config_idx, tdd_ul_dl_config); + ERROR("PRACH: Invalid parmeters config_idx=%d, tdd_ul_config=%d", config_idx, tdd_ul_dl_config); return 0; } } @@ -130,9 +182,8 @@ uint32_t srslte_prach_f_ra_tdd(uint32_t config_idx, uint32_t prach_offset, uint32_t n_rb_ul) { - if (config_idx >= 64 || tdd_ul_dl_config >= 7) { - ERROR("PRACH: Invalid parameters config_idx=%d, tdd_ul_config=%d\n", config_idx, tdd_ul_dl_config); + ERROR("PRACH: Invalid parameters config_idx=%d, tdd_ul_config=%d", config_idx, tdd_ul_dl_config); return 0; } uint32_t f_ra = prach_tdd_loc_table[config_idx][tdd_ul_dl_config].elems[prach_idx].f; @@ -169,7 +220,7 @@ bool srslte_prach_tti_opportunity_config_tdd(uint32_t config_idx, uint32_t* prach_idx) { if (config_idx >= 64 || tdd_ul_dl_config >= 7) { - ERROR("PRACH: Invalid parameters config_idx=%d, tdd_ul_config=%d\n", config_idx, tdd_ul_dl_config); + ERROR("PRACH: Invalid parameters config_idx=%d, tdd_ul_config=%d", config_idx, tdd_ul_dl_config); return 0; } @@ -253,7 +304,6 @@ int srslte_prach_gen_seqs(srslte_prach_t* p) // Generate our 64 preamble sequences for (int i = 0; i < N_SEQS; i++) { - if (v > v_max) { // Get a new root sequence if (4 == p->f) { @@ -262,10 +312,9 @@ int srslte_prach_gen_seqs(srslte_prach_t* p) u = prach_zc_roots[(p->rsi + p->N_roots) % 838]; } - for (int j = 0; j < p->N_zc; j++) { - double phase = -M_PI * u * j * (j + 1) / p->N_zc; - root[j] = cexp(phase * I); - } + // Generate actual sequence + prach_cexp(p->N_zc, u, root); + p->root_seqs_idx[p->N_roots++] = i; // Determine v_max @@ -329,9 +378,13 @@ int srslte_prach_gen_seqs(srslte_prach_t* p) } else { C_v = v * p->N_cs; } - for (int j = 0; j < p->N_zc; j++) { - p->seqs[i][j] = root[(j + C_v) % p->N_zc]; - } + + // Copy shifted sequence, equivalent to: + // for (int j = 0; j < p->N_zc; j++) { + // p->seqs[i][j] = root[(j + C_v) % p->N_zc]; + // } + srslte_vec_cf_copy(p->seqs[i], &root[C_v], p->N_zc - C_v); + srslte_vec_cf_copy(&p->seqs[i][p->N_zc - C_v], root, C_v); v++; } @@ -352,20 +405,20 @@ int srslte_prach_init(srslte_prach_t* p, uint32_t max_N_ifft_ul) p->max_N_ifft_ul = max_N_ifft_ul; // Set up containers - p->prach_bins = srslte_vec_cf_malloc(MAX_N_zc); - p->corr_spec = srslte_vec_cf_malloc(MAX_N_zc); - p->corr = srslte_vec_f_malloc(MAX_N_zc); - p->cross = srslte_vec_cf_malloc(MAX_N_zc); - p->corr_freq = srslte_vec_cf_malloc(MAX_N_zc); + p->prach_bins = srslte_vec_cf_malloc(SRSLTE_PRACH_N_ZC_LONG); + p->corr_spec = srslte_vec_cf_malloc(SRSLTE_PRACH_N_ZC_LONG); + p->corr = srslte_vec_f_malloc(SRSLTE_PRACH_N_ZC_LONG); + p->cross = srslte_vec_cf_malloc(SRSLTE_PRACH_N_ZC_LONG); + p->corr_freq = srslte_vec_cf_malloc(SRSLTE_PRACH_N_ZC_LONG); // Set up ZC FFTS - if (srslte_dft_plan(&p->zc_fft, MAX_N_zc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { + if (srslte_dft_plan(&p->zc_fft, SRSLTE_PRACH_N_ZC_LONG, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&p->zc_fft, false); srslte_dft_plan_set_norm(&p->zc_fft, true); - if (srslte_dft_plan(&p->zc_ifft, MAX_N_zc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { + if (srslte_dft_plan(&p->zc_ifft, SRSLTE_PRACH_N_ZC_LONG, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&p->zc_ifft, false); @@ -376,20 +429,20 @@ int srslte_prach_init(srslte_prach_t* p, uint32_t max_N_ifft_ul) p->ifft_in = srslte_vec_cf_malloc(fft_size_alloc); p->ifft_out = srslte_vec_cf_malloc(fft_size_alloc); if (srslte_dft_plan(&p->ifft, fft_size_alloc, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error creating DFT plan\n"); + ERROR("Error creating DFT plan"); return -1; } srslte_dft_plan_set_mirror(&p->ifft, true); srslte_dft_plan_set_norm(&p->ifft, true); if (srslte_dft_plan(&p->fft, fft_size_alloc, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error creating DFT plan\n"); + ERROR("Error creating DFT plan"); return -1; } p->signal_fft = srslte_vec_cf_malloc(fft_size_alloc); if (!p->signal_fft) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return -1; } @@ -398,7 +451,7 @@ int srslte_prach_init(srslte_prach_t* p, uint32_t max_N_ifft_ul) ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters\n"); + ERROR("Invalid parameters"); } return ret; @@ -412,7 +465,7 @@ int srslte_prach_set_cell_(srslte_prach_t* p, int ret = SRSLTE_ERROR; if (p != NULL && N_ifft_ul < 2049 && cfg->config_idx < 64 && cfg->root_seq_idx < MAX_ROOTS) { if (N_ifft_ul > p->max_N_ifft_ul) { - ERROR("PRACH: Error in set_cell(): N_ifft_ul must be lower or equal max_N_ifft_ul in init()\n"); + ERROR("PRACH: Error in set_cell(): N_ifft_ul must be lower or equal max_N_ifft_ul in init()"); return -1; } @@ -439,33 +492,33 @@ int srslte_prach_set_cell_(srslte_prach_t* p, // Determine N_zc and N_cs if (4 == preamble_format) { if (p->zczc < 7) { - p->N_zc = 139; + p->N_zc = SRSLTE_PRACH_N_ZC_SHORT; p->N_cs = prach_Ncs_format4[p->zczc]; } else { - ERROR("Invalid zeroCorrelationZoneConfig=%d for format4\n", p->zczc); + ERROR("Invalid zeroCorrelationZoneConfig=%d for format4", p->zczc); return SRSLTE_ERROR; } } else { - p->N_zc = MAX_N_zc; + p->N_zc = SRSLTE_PRACH_N_ZC_LONG; if (p->hs) { if (p->zczc < 15) { p->N_cs = prach_Ncs_restricted[p->zczc]; } else { - ERROR("Invalid zeroCorrelationZoneConfig=%d for restricted set\n", p->zczc); + ERROR("Invalid zeroCorrelationZoneConfig=%d for restricted set", p->zczc); return SRSLTE_ERROR; } } else { if (p->zczc < 16) { p->N_cs = prach_Ncs_unrestricted[p->zczc]; } else { - ERROR("Invalid zeroCorrelationZoneConfig=%d\n", p->zczc); + ERROR("Invalid zeroCorrelationZoneConfig=%d", p->zczc); return SRSLTE_ERROR; } } } // Set up ZC FFTS - if (p->N_zc != MAX_N_zc) { + if (p->N_zc != SRSLTE_PRACH_N_ZC_LONG) { if (srslte_dft_replan(&p->zc_fft, p->N_zc)) { return SRSLTE_ERROR; } @@ -501,11 +554,11 @@ int srslte_prach_set_cell_(srslte_prach_t* p, }*/ if (srslte_dft_replan(&p->ifft, p->N_ifft_prach)) { - ERROR("Error creating DFT plan\n"); + ERROR("Error creating DFT plan"); return -1; } if (srslte_dft_replan(&p->fft, p->N_ifft_prach)) { - ERROR("Error creating DFT plan\n"); + ERROR("Error creating DFT plan"); return -1; } @@ -523,7 +576,7 @@ int srslte_prach_set_cell_(srslte_prach_t* p, } ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters N_ifft_ul=%d; config_idx=%d; root_seq_idx=%d;\n", + ERROR("Invalid parameters N_ifft_ul=%d; config_idx=%d; root_seq_idx=%d;", N_ifft_ul, cfg->config_idx, cfg->root_seq_idx); @@ -543,16 +596,12 @@ int srslte_prach_gen(srslte_prach_t* p, uint32_t seq_index, uint32_t freq_offset uint32_t begin = PHI + (K * k_0) + (p->is_nr ? 1 : (K / 2)); if (6 + freq_offset > N_rb_ul) { - ERROR("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", freq_offset, N_rb_ul); + ERROR("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d", freq_offset, N_rb_ul); return ret; } - DEBUG("N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d\n", - p->N_zc, - p->N_cp, - p->N_seq, - p->N_ifft_prach, - begin); + DEBUG( + "N_zc: %d, N_cp: %d, N_seq: %d, N_ifft_prach=%d begin: %d", p->N_zc, p->N_cp, p->N_seq, p->N_ifft_prach, begin); // Map dft-precoded sequence to ifft bins memset(p->ifft_in, 0, begin * sizeof(cf_t)); @@ -634,7 +683,7 @@ float srslte_prach_calculate_time_offset_secs(srslte_prach_t* p, cf_t* cross) { // calculate the phase of the cross correlation float freq_domain_phase = cargf(srslte_vec_acc_cc(cross, p->N_zc)); - float ratio = (float)(p->N_ifft_ul * DELTA_F) / (float)(MAX_N_zc * DELTA_F_RA); + float ratio = (float)(p->N_ifft_ul * DELTA_F) / (float)(SRSLTE_PRACH_N_ZC_LONG * DELTA_F_RA); // converting from phase to number of samples float num_samples = roundf((ratio * freq_domain_phase * p->N_zc) / (2 * M_PI)); @@ -762,9 +811,8 @@ int srslte_prach_detect_offset(srslte_prach_t* p, { int ret = SRSLTE_ERROR; if (p != NULL && signal != NULL && sig_len > 0 && indices != NULL) { - if (sig_len < p->N_ifft_prach) { - ERROR("srslte_prach_detect: Signal length is %d and should be %d\n", sig_len, p->N_ifft_prach); + ERROR("srslte_prach_detect: Signal length is %d and should be %d", sig_len, p->N_ifft_prach); return SRSLTE_ERROR_INVALID_INPUTS; } int cancellation_idx = -2; diff --git a/lib/src/phy/phch/prach_tables.h b/lib/src/phy/phch/prach_tables.h index 33a67abd5..533d42525 100644 --- a/lib/src/phy/phch/prach_tables.h +++ b/lib/src/phy/phch/prach_tables.h @@ -34,8 +34,6 @@ uint32_t prach_Tseq[5] = {24576, 24576, 2 * 24576, 2 * 24576, 4096}; // Table 5.7.2-2 - N_cs values for unrestricted sets uint32_t prach_Ncs_unrestricted[16] = {0, 13, 15, 18, 22, 26, 32, 38, 46, 59, 76, 93, 119, 167, 279, 419}; -#define MAX_N_zc 839 - // Table 5.7.2-2 - N_cs values for restricted sets uint32_t prach_Ncs_restricted[15] = {15, 18, 22, 26, 32, 38, 46, 55, 68, 82, 100, 128, 158, 202, 237}; diff --git a/lib/src/phy/phch/psbch.c b/lib/src/phy/phch/psbch.c index 0c548d983..1bf5cc8a3 100644 --- a/lib/src/phy/phch/psbch.c +++ b/lib/src/phy/phch/psbch.c @@ -62,19 +62,19 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs q->c = srslte_vec_u8_malloc(q->sl_bch_tb_crc_len); if (!q->c) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->d = srslte_vec_u8_malloc(q->sl_bch_encoded_len); if (!q->d) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->d_16 = srslte_vec_i16_malloc(q->sl_bch_encoded_len); if (!q->d_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } @@ -86,7 +86,7 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs q->crc_temp = srslte_vec_u8_malloc(SRSLTE_SL_BCH_CRC_LEN); if (!q->crc_temp) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } @@ -108,84 +108,84 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs q->e = srslte_vec_u8_malloc(q->E); if (!q->e) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->e_16 = srslte_vec_i16_malloc(q->E); if (!q->e_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->e_bytes = srslte_vec_u8_malloc(q->E / 8); if (!q->e_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Scrambling bzero(&q->seq, sizeof(srslte_sequence_t)); if (srslte_sequence_LTE_pr(&q->seq, q->E, N_sl_id) != SRSLTE_SUCCESS) { - ERROR("Error srslte_sequence_LTE_pr\n"); + ERROR("Error srslte_sequence_LTE_pr"); return SRSLTE_ERROR; } q->codeword = srslte_vec_u8_malloc(q->E); if (!q->codeword) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->codeword_bytes = srslte_vec_u8_malloc(q->E / 8); if (!q->codeword_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Interleaving q->interleaver_lut = srslte_vec_u32_malloc(q->E); if (!q->interleaver_lut) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Modulation QPSK if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK) != SRSLTE_SUCCESS) { - ERROR("Error srslte_modem_table_lte\n"); + ERROR("Error srslte_modem_table_lte"); return SRSLTE_ERROR; } q->mod_symbols = srslte_vec_cf_malloc(q->nof_data_re); if (!q->mod_symbols) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Soft-demod q->llr = srslte_vec_i16_malloc(q->E); if (!q->llr) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Transform precoding q->precoding_scaling = 1.0f; if (srslte_dft_precoding_init_tx(&q->dft_precoder, SRSLTE_PSBCH_NOF_PRB) != SRSLTE_SUCCESS) { - ERROR("Error srslte_dft_precoding_init\n"); + ERROR("Error srslte_dft_precoding_init"); return SRSLTE_ERROR; } q->scfdma_symbols = srslte_vec_cf_malloc(q->nof_data_re); if (!q->scfdma_symbols) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } ///< Make sure last bits are zero as they are not considered during unpack srslte_vec_cf_zero(q->scfdma_symbols, q->nof_data_re); if (srslte_dft_precoding_init_rx(&q->idft_precoder, SRSLTE_PSBCH_NOF_PRB) != SRSLTE_SUCCESS) { - ERROR("Error srslte_idft_precoding_init\n"); + ERROR("Error srslte_idft_precoding_init"); return SRSLTE_ERROR; } @@ -195,7 +195,7 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs int srslte_psbch_encode(srslte_psbch_t* q, uint8_t* input, uint32_t input_len, cf_t* sf_buffer) { if (input == NULL || input_len > q->sl_bch_tb_len) { - ERROR("Can't encode PSBCH, input too long (%d > %d)\n", input_len, q->sl_bch_tb_len); + ERROR("Can't encode PSBCH, input too long (%d > %d)", input_len, q->sl_bch_tb_len); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -247,13 +247,13 @@ int srslte_psbch_encode(srslte_psbch_t* q, uint8_t* input, uint32_t input_len, c int srslte_psbch_decode(srslte_psbch_t* q, cf_t* equalized_sf_syms, uint8_t* output, uint32_t max_output_len) { if (max_output_len < q->sl_bch_tb_len) { - ERROR("Can't decode PSBCH, provided buffer too small (%d < %d)\n", max_output_len, q->sl_bch_tb_len); + ERROR("Can't decode PSBCH, provided buffer too small (%d < %d)", max_output_len, q->sl_bch_tb_len); return SRSLTE_ERROR; } // RE extraction if (q->nof_tx_re != srslte_psbch_get(q, equalized_sf_syms, q->scfdma_symbols)) { - ERROR("There was an error getting the PSBCH symbols\n"); + ERROR("There was an error getting the PSBCH symbols"); return SRSLTE_ERROR; } @@ -309,7 +309,7 @@ int srslte_psbch_reset(srslte_psbch_t* q, uint32_t N_sl_id) // Regen scrambling sequence if (srslte_sequence_LTE_pr(&q->seq, q->E, N_sl_id) != SRSLTE_SUCCESS) { - ERROR("Error srslte_sequence_LTE_pr\n"); + ERROR("Error srslte_sequence_LTE_pr"); return SRSLTE_ERROR; } } diff --git a/lib/src/phy/phch/pscch.c b/lib/src/phy/phch/pscch.c index 4de30bf88..ca5a5ea3c 100644 --- a/lib/src/phy/phch/pscch.c +++ b/lib/src/phy/phch/pscch.c @@ -49,12 +49,12 @@ int srslte_pscch_init(srslte_pscch_t* q, uint32_t max_prb) } q->c = srslte_vec_u8_malloc(SRSLTE_SCI_MAX_LEN + SRSLTE_SCI_CRC_LEN); if (!q->c) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->sci_crc = srslte_vec_u8_malloc(SRSLTE_SCI_CRC_LEN); if (!q->sci_crc) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } @@ -69,50 +69,50 @@ int srslte_pscch_init(srslte_pscch_t* q, uint32_t max_prb) memcpy(q->encoder.poly, poly, 3 * sizeof(int)); q->d = srslte_vec_u8_malloc(E_max); if (!q->d) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_u8_zero(q->d, E_max); q->d_16 = srslte_vec_i16_malloc(E_max); if (!q->d_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_viterbi_init( &q->dec, SRSLTE_VITERBI_37, q->encoder.poly, SRSLTE_SCI_MAX_LEN + SRSLTE_SCI_CRC_LEN, q->encoder.tail_biting); - q->e = srslte_vec_u8_malloc(E_max); + q->e = srslte_vec_u8_malloc(E_max); if (!q->e) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->e_16 = srslte_vec_i16_malloc(E_max); if (!q->e_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->e_bytes = srslte_vec_u8_malloc(E_max / 8); if (!q->e_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->interleaver_lut = srslte_vec_u32_malloc(E_max); if (!q->interleaver_lut) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->codeword = srslte_vec_u8_malloc(E_max); if (!q->codeword) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->codeword_bytes = srslte_vec_u8_malloc(E_max / 8); if (!q->codeword_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } @@ -127,14 +127,14 @@ int srslte_pscch_init(srslte_pscch_t* q, uint32_t max_prb) q->mod_symbols = srslte_vec_cf_malloc(E_max / SRSLTE_PSCCH_QM); if (!q->mod_symbols) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(q->mod_symbols, E_max / SRSLTE_PSCCH_QM); q->llr = srslte_vec_i16_malloc(E_max); if (!q->llr) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } @@ -144,7 +144,7 @@ int srslte_pscch_init(srslte_pscch_t* q, uint32_t max_prb) } q->scfdma_symbols = srslte_vec_cf_malloc(E_max / SRSLTE_PSCCH_QM); if (!q->scfdma_symbols) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(q->scfdma_symbols, E_max / SRSLTE_PSCCH_QM); diff --git a/lib/src/phy/phch/pssch.c b/lib/src/phy/phch/pssch.c index 3fd400d53..63118979c 100644 --- a/lib/src/phy/phch/pssch.c +++ b/lib/src/phy/phch/pssch.c @@ -49,57 +49,57 @@ int srslte_pssch_init(srslte_pssch_t* q, srslte_cell_sl_t cell, srslte_sl_comm_r if (cell.cp == SRSLTE_CP_NORM) { q->nof_data_symbols = SRSLTE_PSSCH_TM34_NUM_DATA_SYMBOLS; } else { - ERROR("Invalid CP for PSSCH, SL TM 3/4\n"); + ERROR("Invalid CP for PSSCH, SL TM 3/4"); return SRSLTE_ERROR_INVALID_INPUTS; } } else { - ERROR("Invalid SL TM\n"); + ERROR("Invalid SL TM"); return SRSLTE_ERROR_INVALID_INPUTS; } // Transport Block q->b = srslte_vec_u8_malloc(SRSLTE_SL_SCH_MAX_TB_LEN + SRSLTE_PSSCH_CRC_LEN); if (!q->b) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Transport Block CRC if (srslte_crc_init(&q->tb_crc, SRSLTE_LTE_CRC24A, SRSLTE_PSSCH_CRC_LEN)) { - ERROR("Error Transport Block CRC init\n"); + ERROR("Error Transport Block CRC init"); return SRSLTE_ERROR; } q->tb_crc_temp = srslte_vec_u8_malloc(SRSLTE_PSSCH_CRC_LEN); if (!q->tb_crc_temp) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Code Block Segmentation q->c_r = srslte_vec_u8_malloc(SRSLTE_TCOD_MAX_LEN_CB); if (!q->c_r) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->f_16 = srslte_vec_i16_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->f_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->c_r_bytes = srslte_vec_u8_malloc(SRSLTE_TCOD_MAX_LEN_CB / 8); if (!q->c_r_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Code Block CRC if (srslte_crc_init(&q->cb_crc, SRSLTE_LTE_CRC24B, SRSLTE_PSSCH_CRC_LEN)) { - ERROR("Error Code Block CRC init\n"); + ERROR("Error Code Block CRC init"); return SRSLTE_ERROR; } q->cb_crc_temp = srslte_vec_u8_malloc(SRSLTE_PSSCH_CRC_LEN); if (!q->cb_crc_temp) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } @@ -107,32 +107,32 @@ int srslte_pssch_init(srslte_pssch_t* q, srslte_cell_sl_t cell, srslte_sl_comm_r srslte_tcod_init(&q->tcod, SRSLTE_TCOD_MAX_LEN_CB); q->d_r = srslte_vec_u8_malloc(SRSLTE_PSSCH_MAX_CODED_BITS); if (!q->d_r) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_tdec_init(&q->tdec, SRSLTE_TCOD_MAX_LEN_CB); srslte_tdec_force_not_sb(&q->tdec); q->d_r_16 = srslte_vec_i16_malloc(SRSLTE_PSSCH_MAX_CODED_BITS); if (!q->d_r_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Rate Matching q->e_r = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->e_r) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->buff_b = srslte_vec_u8_malloc(SRSLTE_PSSCH_MAX_CODED_BITS); if (!q->buff_b) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_u8_zero(q->buff_b, SRSLTE_PSSCH_MAX_CODED_BITS); q->e_r_16 = srslte_vec_i16_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->e_r_16) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_rm_turbo_gentables(); @@ -140,19 +140,19 @@ int srslte_pssch_init(srslte_pssch_t* q, srslte_cell_sl_t cell, srslte_sl_comm_r // Code Block Concatenation q->f = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->f) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Interleaving q->f_bytes = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN / 8); if (!q->f_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->interleaver_lut = srslte_vec_u32_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->interleaver_lut) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_u32_zero(q->interleaver_lut, SRSLTE_MAX_CODEWORD_LEN); @@ -160,37 +160,37 @@ int srslte_pssch_init(srslte_pssch_t* q, srslte_cell_sl_t cell, srslte_sl_comm_r // Scrambling q->codeword = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->codeword) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->codeword_bytes = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN / 8); if (!q->codeword_bytes) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Modulation q->symbols = srslte_vec_cf_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->symbols) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(q->symbols, SRSLTE_MAX_CODEWORD_LEN); q->bits_after_demod = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->bits_after_demod) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } q->bytes_after_demod = srslte_vec_u8_malloc(SRSLTE_MAX_CODEWORD_LEN / 8); if (!q->bytes_after_demod) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } for (int i = 0; i < SRSLTE_MOD_NITEMS; i++) { if (srslte_modem_table_lte(&q->mod[i], (srslte_mod_t)i)) { - ERROR("Error initiating modem tables\n"); + ERROR("Error initiating modem tables"); return SRSLTE_ERROR; } } @@ -198,22 +198,22 @@ int srslte_pssch_init(srslte_pssch_t* q, srslte_cell_sl_t cell, srslte_sl_comm_r // Demodulation q->llr = srslte_vec_i16_malloc(SRSLTE_MAX_CODEWORD_LEN); if (!q->llr) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } // Transform Precoding q->scfdma_symbols = srslte_vec_cf_malloc(q->nof_data_symbols * SRSLTE_NRE * SRSLTE_MAX_PRB); if (!q->scfdma_symbols) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } if (srslte_dft_precoding_init(&q->dft_precoder, SRSLTE_MAX_PRB, true)) { - ERROR("Error DFT precoder init\n"); + ERROR("Error DFT precoder init"); return SRSLTE_ERROR; } if (srslte_dft_precoding_init(&q->idft_precoder, SRSLTE_MAX_PRB, false)) { - ERROR("Error in DFT precoder init\n"); + ERROR("Error in DFT precoder init"); return SRSLTE_ERROR; } @@ -259,7 +259,7 @@ int srslte_pssch_set_cfg(srslte_pssch_t* q, srslte_pssch_cfg_t pssch_cfg) int srslte_pssch_encode(srslte_pssch_t* q, uint8_t* input, uint32_t input_len, cf_t* sf_buffer) { if (!input || input_len > q->sl_sch_tb_len) { - ERROR("Can't encode PSSCH, input too long (%d > %d)\n", input_len, q->sl_sch_tb_len); + ERROR("Can't encode PSSCH, input too long (%d > %d)", input_len, q->sl_sch_tb_len); return SRSLTE_ERROR; } @@ -283,7 +283,6 @@ int srslte_pssch_encode(srslte_pssch_t* q, uint8_t* input, uint32_t input_len, c srslte_crc_attach(&q->tb_crc, q->b, q->sl_sch_tb_len); for (int r = 0; r < q->cb_segm.C; r++) { - // Code block segmentation if (r < q->cb_segm.C2) { K_r = q->cb_segm.K2; @@ -365,7 +364,7 @@ int srslte_pssch_encode(srslte_pssch_t* q, uint8_t* input, uint32_t input_len, c // RE mapping if (q->nof_tx_re != srslte_pssch_put(q, sf_buffer, q->scfdma_symbols)) { - ERROR("There was an error mapping the PSSCH symbols\n"); + ERROR("There was an error mapping the PSSCH symbols"); return SRSLTE_ERROR; } @@ -375,13 +374,13 @@ int srslte_pssch_encode(srslte_pssch_t* q, uint8_t* input, uint32_t input_len, c int srslte_pssch_decode(srslte_pssch_t* q, cf_t* equalized_sf_syms, uint8_t* output, uint32_t output_len) { if (output_len < q->sl_sch_tb_len) { - ERROR("Can't decode PSSCH, provided buffer too small (%d < %d)\n", output_len, q->sl_sch_tb_len); + ERROR("Can't decode PSSCH, provided buffer too small (%d < %d)", output_len, q->sl_sch_tb_len); return SRSLTE_ERROR; } // RE extraction if (q->nof_tx_re != srslte_pssch_get(q, equalized_sf_syms, q->scfdma_symbols)) { - ERROR("There was an error getting the PSSCH symbols\n"); + ERROR("There was an error getting the PSSCH symbols"); return SRSLTE_ERROR; } @@ -452,7 +451,6 @@ int srslte_pssch_decode(srslte_pssch_t* q, cf_t* equalized_sf_syms, uint8_t* out srslte_bit_unpack_vector(q->c_r_bytes, q->c_r, K_r); if (q->cb_segm.C > 1) { - // Copy received crc to temp memcpy(q->cb_crc_temp, &q->c_r[(K_r - L)], sizeof(uint8_t) * L); @@ -498,7 +496,6 @@ int srslte_pssch_put(srslte_pssch_t* q, cf_t* sf_buffer, cf_t* symbols) uint32_t k = q->pssch_cfg.prb_start_idx * SRSLTE_NRE; for (int i = 0; i < srslte_sl_get_num_symbols(q->cell.tm, q->cell.cp); i++) { if (srslte_pssch_is_symbol(SRSLTE_SIDELINK_DATA_SYMBOL, q->cell.tm, i, q->cell.cp)) { - if (q->cell.tm == SRSLTE_SIDELINK_TM1 || q->cell.tm == SRSLTE_SIDELINK_TM2) { if (q->pssch_cfg.nof_prb <= q->sl_comm_resource_pool.prb_num) { k = q->pssch_cfg.prb_start_idx * SRSLTE_NRE; diff --git a/lib/src/phy/phch/pucch.c b/lib/src/phy/phch/pucch.c index 9c260096b..a26454bf4 100644 --- a/lib/src/phy/phch/pucch.c +++ b/lib/src/phy/phch/pucch.c @@ -130,7 +130,6 @@ int srslte_pucch_set_cell(srslte_pucch_t* q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_cell_isvalid(&cell)) { - if (cell.id != q->cell.id || q->cell.nof_prb == 0) { q->cell = cell; @@ -172,7 +171,7 @@ int srslte_pucch_set_rnti(srslte_pucch_t* q, uint16_t rnti) // If the sequence is not allocated generate q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t)); if (!q->users[rnti_idx]) { - ERROR("Alocating PDSCH user\n"); + ERROR("Alocating PDSCH user"); return SRSLTE_ERROR; } } else if (q->users[rnti_idx]->sequence_generated && q->users[rnti_idx]->cell_id == q->cell.id && !q->is_ue) { @@ -187,7 +186,7 @@ int srslte_pucch_set_rnti(srslte_pucch_t* q, uint16_t rnti) for (int sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) { if (srslte_sequence_pucch( &q->users[rnti_idx]->seq_f2[sf_idx], rnti, SRSLTE_NOF_SLOTS_PER_SF * sf_idx, q->cell.id)) { - ERROR("Error initializing PUCCH scrambling sequence\n"); + ERROR("Error initializing PUCCH scrambling sequence"); srslte_pucch_free_rnti(q, rnti); return SRSLTE_ERROR; } @@ -239,13 +238,13 @@ static srslte_sequence_t* get_user_sequence(srslte_pucch_t* q, uint16_t rnti, ui return &q->users[rnti_idx]->seq_f2[sf_idx]; } else { if (srslte_sequence_pucch(&q->tmp_seq, rnti, 2 * sf_idx, q->cell.id)) { - ERROR("Error computing PUCCH Format 2 scrambling sequence\n"); + ERROR("Error computing PUCCH Format 2 scrambling sequence"); return NULL; } return &q->tmp_seq; } } else { - ERROR("Invalid RNTI=0x%x\n", rnti); + ERROR("Invalid RNTI=0x%x", rnti); return NULL; } } @@ -277,7 +276,7 @@ uci_mod_bits(srslte_pucch_t* q, srslte_ul_sf_cfg_t* sf, srslte_pucch_cfg_t* cfg, srslte_scrambling_b_offset(seq, q->bits_scram, 0, SRSLTE_PUCCH2_NOF_BITS); srslte_mod_modulate(&q->mod, q->bits_scram, q->d, SRSLTE_PUCCH2_NOF_BITS); } else { - ERROR("Error modulating PUCCH2 bits: could not generate sequence\n"); + ERROR("Error modulating PUCCH2 bits: could not generate sequence"); return -1; } break; @@ -288,12 +287,12 @@ uci_mod_bits(srslte_pucch_t* q, srslte_ul_sf_cfg_t* sf, srslte_pucch_cfg_t* cfg, srslte_scrambling_b_offset(seq, q->bits_scram, 0, SRSLTE_PUCCH3_NOF_BITS); srslte_mod_modulate(&q->mod, q->bits_scram, q->d, SRSLTE_PUCCH3_NOF_BITS); } else { - ERROR("Error modulating PUCCH3 bits: rnti not set\n"); + ERROR("Error modulating PUCCH3 bits: rnti not set"); return SRSLTE_ERROR; } break; default: - ERROR("PUCCH format %s not supported\n", srslte_pucch_format_text(cfg->format)); + ERROR("PUCCH format %s not supported", srslte_pucch_format_text(cfg->format)); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -449,7 +448,7 @@ static int pucch_cp(srslte_pucch_t* q, n_re += SRSLTE_NRE; } } else { - ERROR("Invalid PUCCH n_prb=%d\n", n_prb); + ERROR("Invalid PUCCH n_prb=%d", n_prb); return SRSLTE_ERROR; } } @@ -477,7 +476,7 @@ static int encode_signal_format12(srslte_pucch_t* q, { if (!signal_only) { if (uci_mod_bits(q, sf, cfg, bits)) { - ERROR("Error encoding PUCCH bits\n"); + ERROR("Error encoding PUCCH bits"); return SRSLTE_ERROR; } } else { @@ -490,7 +489,7 @@ static int encode_signal_format12(srslte_pucch_t* q, uint32_t sf_idx = sf->tti % SRSLTE_NOF_SF_X_FRAME; for (uint32_t ns = SRSLTE_NOF_SLOTS_PER_SF * sf_idx; ns < SRSLTE_NOF_SLOTS_PER_SF * (sf_idx + 1); ns++) { uint32_t N_sf = get_N_sf(cfg->format, ns % 2, sf->shortened); - DEBUG("ns=%d, N_sf=%d\n", ns, N_sf); + DEBUG("ns=%d, N_sf=%d", ns, N_sf); // Get group hopping number u uint32_t f_gh = 0; if (cfg->group_hopping_en) { @@ -514,11 +513,11 @@ static int encode_signal_format12(srslte_pucch_t* q, uint32_t n_prime_ns = 0; uint32_t n_oc = 0; float alpha = srslte_pucch_alpha_format1(q->n_cs_cell, cfg, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns); - float S_ns = 0; + float S_ns = 0; if (n_prime_ns % 2) { S_ns = M_PI / 2; } - DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n", + DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d", __real__ q->d[0], __imag__ q->d[0], alpha, @@ -545,7 +544,7 @@ static int encode_signal_format3(srslte_pucch_t* q, { if (!signal_only) { if (uci_mod_bits(q, sf, cfg, bits)) { - ERROR("Error encoding PUCCH bits\n"); + ERROR("Error encoding PUCCH bits"); return SRSLTE_ERROR; } } else { @@ -650,7 +649,7 @@ static int decode_signal_format3(srslte_pucch_t* q, return (int)srslte_block_decode_i16(q->llr, SRSLTE_PUCCH3_NOF_BITS, bits, SRSLTE_UCI_MAX_ACK_SR_BITS); } else { - ERROR("Error modulating PUCCH3 bits: rnti not set\n"); + ERROR("Error modulating PUCCH3 bits: rnti not set"); return SRSLTE_ERROR; } @@ -689,7 +688,7 @@ static int encode_bits(srslte_pucch_cfg_t* cfg, uint8_t buff[SRSLTE_CQI_MAX_BITS]; int uci_cqi_len = srslte_cqi_value_pack(&cfg->uci_cfg.cqi, &uci_data->cqi, buff); if (uci_cqi_len < 0) { - ERROR("Error encoding CQI\n"); + ERROR("Error encoding CQI"); return SRSLTE_ERROR; } srslte_uci_encode_cqi_pucch(buff, (uint32_t)uci_cqi_len, pucch_bits); @@ -736,7 +735,7 @@ static bool decode_signal(srslte_pucch_t* q, if (corr >= cfg->threshold_format1) { detected = true; } - DEBUG("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, cfg->threshold_format1); + DEBUG("format1 corr=%f, nof_re=%d, th=%f", corr, nof_re, cfg->threshold_format1); break; case SRSLTE_PUCCH_FORMAT_1A: detected = 0; @@ -751,7 +750,7 @@ static bool decode_signal(srslte_pucch_t* q, if (corr_max > cfg->threshold_format1) { // check with format1 in case ack+sr because ack only is binary detected = true; } - DEBUG("format1a b=%d, corr=%f, nof_re=%d\n", b, corr, nof_re); + DEBUG("format1a b=%d, corr=%f, nof_re=%d", b, corr, nof_re); } corr = corr_max; pucch_bits[0] = b_max; @@ -772,7 +771,7 @@ static bool decode_signal(srslte_pucch_t* q, if (corr_max > cfg->threshold_format1) { // check with format1 in case ack+sr because ack only is binary detected = true; } - DEBUG("format1b b=%d, corr=%f, nof_re=%d\n", b, corr, nof_re); + DEBUG("format1b b=%d, corr=%f, nof_re=%d", b, corr, nof_re); } } corr = corr_max; @@ -803,7 +802,7 @@ static bool decode_signal(srslte_pucch_t* q, } detected = true; } else { - ERROR("Decoding PUCCH2: could not generate sequence\n"); + ERROR("Decoding PUCCH2: could not generate sequence"); return -1; } break; @@ -812,7 +811,7 @@ static bool decode_signal(srslte_pucch_t* q, detected = corr > cfg->threshold_data_valid_format3; break; default: - ERROR("PUCCH format %d not implemented\n", cfg->format); + ERROR("PUCCH format %d not implemented", cfg->format); return SRSLTE_ERROR; } if (correlation) { @@ -878,7 +877,7 @@ int srslte_pucch_encode(srslte_pucch_t* q, } if (pucch_put(q, sf, cfg, q->z, sf_symbols) < 0) { - ERROR("Error putting PUCCH symbols\n"); + ERROR("Error putting PUCCH symbols"); return SRSLTE_ERROR; } ret = SRSLTE_SUCCESS; @@ -901,18 +900,17 @@ int srslte_pucch_decode(srslte_pucch_t* q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && cfg != NULL && channel != NULL && data != NULL) { - uint32_t nof_cqi_bits = srslte_cqi_size(&cfg->uci_cfg.cqi); uint32_t nof_uci_bits = cfg->uci_cfg.cqi.ri_len ? cfg->uci_cfg.cqi.ri_len : nof_cqi_bits; int nof_re = pucch_get(q, sf, cfg, sf_symbols, q->z_tmp); if (nof_re < 0) { - ERROR("Error getting PUCCH symbols\n"); + ERROR("Error getting PUCCH symbols"); return SRSLTE_ERROR; } if (pucch_get(q, sf, cfg, channel->ce, q->ce) < 0) { - ERROR("Error getting PUCCH symbols\n"); + ERROR("Error getting PUCCH symbols"); return SRSLTE_ERROR; } @@ -971,7 +969,6 @@ char* srslte_pucch_format_text(srslte_pucch_format_t format) char* ret = NULL; switch (format) { - case SRSLTE_PUCCH_FORMAT_1: ret = "Format 1"; break; @@ -1006,7 +1003,6 @@ char* srslte_pucch_format_text_short(srslte_pucch_format_t format) char* ret = NULL; switch (format) { - case SRSLTE_PUCCH_FORMAT_1: ret = "1"; break; @@ -1042,7 +1038,6 @@ uint32_t srslte_pucch_nof_ack_format(srslte_pucch_format_t format) uint32_t ret = 0; switch (format) { - case SRSLTE_PUCCH_FORMAT_1A: case SRSLTE_PUCCH_FORMAT_2A: ret = 1; @@ -1168,7 +1163,6 @@ int srslte_pucch_collision(const srslte_cell_t* cell, const srslte_pucch_cfg_t* uint32_t n_prime2 = 0; switch (cfg1->format) { - case SRSLTE_PUCCH_FORMAT_1: case SRSLTE_PUCCH_FORMAT_1A: case SRSLTE_PUCCH_FORMAT_1B: @@ -1293,7 +1287,7 @@ float srslte_pucch_alpha_format1(const uint32_t n_cs_cell[SRSLTE_NSLO n_cs = (n_cs_cell[ns][l] + (n_prime * cfg->delta_pucch_shift + n_oc / n_oc_div) % N_prime) % SRSLTE_NRE; } - DEBUG("n_cs=%d, N_prime=%d, delta_pucch=%d, n_prime=%d, ns=%d, l=%d, ns_cs_cell=%d\n", + DEBUG("n_cs=%d, N_prime=%d, delta_pucch=%d, n_prime=%d, ns=%d, l=%d, ns_cs_cell=%d", n_cs, N_prime, cfg->delta_pucch_shift, @@ -1328,7 +1322,7 @@ float srslte_pucch_alpha_format2(const uint32_t n_cs_cell[SRSLTE_NSLO } uint32_t n_cs = (n_cs_cell[ns][l] + n_prime) % SRSLTE_NRE; float alpha = 2 * M_PI * (n_cs) / SRSLTE_NRE; - DEBUG("n_pucch: %d, ns: %d, l: %d, n_prime: %d, n_cs: %d, alpha=%f\n", cfg->n_pucch, ns, l, n_prime, n_cs, alpha); + DEBUG("n_pucch: %d, ns: %d, l: %d, n_prime: %d, n_cs: %d, alpha=%f", cfg->n_pucch, ns, l, n_prime, n_cs, alpha); return alpha; } diff --git a/lib/src/phy/phch/pucch_cfg_nr.c b/lib/src/phy/phch/pucch_cfg_nr.c index 88e5f5aa4..af9d98c5f 100644 --- a/lib/src/phy/phch/pucch_cfg_nr.c +++ b/lib/src/phy/phch/pucch_cfg_nr.c @@ -26,23 +26,23 @@ static int pucch_nr_cfg_format0_resource_valid(const srslte_pucch_nr_resource_t* resource) { if (resource->format != SRSLTE_PUCCH_NR_FORMAT_0) { - ERROR("Invalid format (%d)\n", resource->format); + ERROR("Invalid format (%d)", resource->format); return SRSLTE_ERROR; } if (resource->nof_symbols < SRSLTE_PUCCH_NR_FORMAT0_MIN_NSYMB || resource->nof_symbols > SRSLTE_PUCCH_NR_FORMAT0_MAX_NSYMB) { - ERROR("Invalid number of symbols (%d)\n", resource->nof_symbols); + ERROR("Invalid number of symbols (%d)", resource->nof_symbols); return SRSLTE_ERROR; } if (resource->initial_cyclic_shift > SRSLTE_PUCCH_NR_FORMAT0_MAX_CS) { - ERROR("Invalid initial cyclic shift (%d)\n", resource->initial_cyclic_shift); + ERROR("Invalid initial cyclic shift (%d)", resource->initial_cyclic_shift); return SRSLTE_ERROR; } if (resource->start_symbol_idx > SRSLTE_PUCCH_NR_FORMAT0_MAX_STARTSYMB) { - ERROR("Invalid initial start symbol idx (%d)\n", resource->start_symbol_idx); + ERROR("Invalid initial start symbol idx (%d)", resource->start_symbol_idx); return SRSLTE_ERROR; } @@ -52,28 +52,28 @@ static int pucch_nr_cfg_format0_resource_valid(const srslte_pucch_nr_resource_t* static int pucch_nr_cfg_format1_resource_valid(const srslte_pucch_nr_resource_t* resource) { if (resource->format != SRSLTE_PUCCH_NR_FORMAT_1) { - ERROR("Invalid format (%d)\n", resource->format); + ERROR("Invalid format (%d)", resource->format); return SRSLTE_ERROR; } if (resource->nof_symbols < SRSLTE_PUCCH_NR_FORMAT1_MIN_NSYMB || resource->nof_symbols > SRSLTE_PUCCH_NR_FORMAT1_MAX_NSYMB) { - ERROR("Invalid number of symbols (%d)\n", resource->nof_symbols); + ERROR("Invalid number of symbols (%d)", resource->nof_symbols); return SRSLTE_ERROR; } if (resource->initial_cyclic_shift > SRSLTE_PUCCH_NR_FORMAT1_MAX_CS) { - ERROR("Invalid initial cyclic shift (%d)\n", resource->initial_cyclic_shift); + ERROR("Invalid initial cyclic shift (%d)", resource->initial_cyclic_shift); return SRSLTE_ERROR; } if (resource->start_symbol_idx > SRSLTE_PUCCH_NR_FORMAT1_MAX_STARTSYMB) { - ERROR("Invalid initial start symbol idx (%d)\n", resource->start_symbol_idx); + ERROR("Invalid initial start symbol idx (%d)", resource->start_symbol_idx); return SRSLTE_ERROR; } if (resource->time_domain_occ > SRSLTE_PUCCH_NR_FORMAT1_MAX_TOCC) { - ERROR("Invalid time domain occ (%d)\n", resource->time_domain_occ); + ERROR("Invalid time domain occ (%d)", resource->time_domain_occ); return SRSLTE_ERROR; } @@ -83,23 +83,23 @@ static int pucch_nr_cfg_format1_resource_valid(const srslte_pucch_nr_resource_t* static int pucch_nr_cfg_format2_resource_valid(const srslte_pucch_nr_resource_t* resource) { if (resource->format != SRSLTE_PUCCH_NR_FORMAT_2) { - ERROR("Invalid format (%d)\n", resource->format); + ERROR("Invalid format (%d)", resource->format); return SRSLTE_ERROR; } if (resource->nof_symbols < SRSLTE_PUCCH_NR_FORMAT2_MIN_NSYMB || resource->nof_symbols > SRSLTE_PUCCH_NR_FORMAT2_MAX_NSYMB) { - ERROR("Invalid number of symbols (%d)\n", resource->nof_symbols); + ERROR("Invalid number of symbols (%d)", resource->nof_symbols); return SRSLTE_ERROR; } if (resource->nof_prb < SRSLTE_PUCCH_NR_FORMAT2_MIN_NPRB || resource->nof_prb > SRSLTE_PUCCH_NR_FORMAT2_MAX_NPRB) { - ERROR("Invalid number of prb (%d)\n", resource->nof_prb); + ERROR("Invalid number of prb (%d)", resource->nof_prb); return SRSLTE_ERROR; } if (resource->start_symbol_idx > SRSLTE_PUCCH_NR_FORMAT2_MAX_STARTSYMB) { - ERROR("Invalid initial start symbol idx (%d)\n", resource->start_symbol_idx); + ERROR("Invalid initial start symbol idx (%d)", resource->start_symbol_idx); return SRSLTE_ERROR; } @@ -109,23 +109,23 @@ static int pucch_nr_cfg_format2_resource_valid(const srslte_pucch_nr_resource_t* static int pucch_nr_cfg_format3_resource_valid(const srslte_pucch_nr_resource_t* resource) { if (resource->format != SRSLTE_PUCCH_NR_FORMAT_3) { - ERROR("Invalid format (%d)\n", resource->format); + ERROR("Invalid format (%d)", resource->format); return SRSLTE_ERROR; } if (resource->nof_symbols < SRSLTE_PUCCH_NR_FORMAT3_MIN_NSYMB || resource->nof_symbols > SRSLTE_PUCCH_NR_FORMAT3_MAX_NSYMB) { - ERROR("Invalid number of symbols (%d)\n", resource->nof_symbols); + ERROR("Invalid number of symbols (%d)", resource->nof_symbols); return SRSLTE_ERROR; } if (resource->nof_prb < SRSLTE_PUCCH_NR_FORMAT3_MIN_NPRB || resource->nof_prb > SRSLTE_PUCCH_NR_FORMAT3_MAX_NPRB) { - ERROR("Invalid number of prb (%d)\n", resource->nof_prb); + ERROR("Invalid number of prb (%d)", resource->nof_prb); return SRSLTE_ERROR; } if (resource->start_symbol_idx > SRSLTE_PUCCH_NR_FORMAT3_MAX_STARTSYMB) { - ERROR("Invalid initial start symbol idx (%d)\n", resource->start_symbol_idx); + ERROR("Invalid initial start symbol idx (%d)", resource->start_symbol_idx); return SRSLTE_ERROR; } @@ -135,23 +135,23 @@ static int pucch_nr_cfg_format3_resource_valid(const srslte_pucch_nr_resource_t* static int pucch_nr_cfg_format4_resource_valid(const srslte_pucch_nr_resource_t* resource) { if (resource->format != SRSLTE_PUCCH_NR_FORMAT_4) { - ERROR("Invalid format (%d)\n", resource->format); + ERROR("Invalid format (%d)", resource->format); return SRSLTE_ERROR; } if (resource->nof_symbols < SRSLTE_PUCCH_NR_FORMAT4_MIN_NSYMB || resource->nof_symbols > SRSLTE_PUCCH_NR_FORMAT4_MAX_NSYMB) { - ERROR("Invalid number of symbols (%d)\n", resource->nof_symbols); + ERROR("Invalid number of symbols (%d)", resource->nof_symbols); return SRSLTE_ERROR; } if (resource->start_symbol_idx > SRSLTE_PUCCH_NR_FORMAT4_MAX_STARTSYMB) { - ERROR("Invalid initial start symbol idx (%d)\n", resource->start_symbol_idx); + ERROR("Invalid initial start symbol idx (%d)", resource->start_symbol_idx); return SRSLTE_ERROR; } if (resource->occ_lenth != 2 && resource->occ_lenth != 4) { - ERROR("Invalid OCC length (%d)\n", resource->occ_lenth); + ERROR("Invalid OCC length (%d)", resource->occ_lenth); return SRSLTE_ERROR; } @@ -170,7 +170,7 @@ int srslte_pucch_nr_cfg_resource_valid(const srslte_pucch_nr_resource_t* resourc } if (resource->intra_slot_hopping) { - ERROR("Intra-slot hopping is not implemented\n"); + ERROR("Intra-slot hopping is not implemented"); return SRSLTE_ERROR; } @@ -179,7 +179,7 @@ int srslte_pucch_nr_cfg_resource_valid(const srslte_pucch_nr_resource_t* resourc } if (resource->max_code_rate > SRSLTE_PUCCH_NR_MAX_CODE_RATE) { - ERROR("Invalid maximum code rate (%d)\n", resource->max_code_rate); + ERROR("Invalid maximum code rate (%d)", resource->max_code_rate); return SRSLTE_ERROR; } @@ -196,7 +196,7 @@ int srslte_pucch_nr_cfg_resource_valid(const srslte_pucch_nr_resource_t* resourc return pucch_nr_cfg_format4_resource_valid(resource); case SRSLTE_PUCCH_NR_FORMAT_ERROR: default: - ERROR("Invalid case\n"); + ERROR("Invalid case"); break; } diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 4ddf2cd8d..ac50df13f 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -40,15 +40,14 @@ int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t* carrier, uint32_t n_id = cfg->hopping_id_present ? cfg->hopping_id : carrier->id; switch (cfg->group_hopping) { - case SRSLTE_PUCCH_NR_GROUP_HOPPING_NEITHER: f_ss = n_id % SRSLTE_ZC_SEQUENCE_NOF_GROUPS; break; case SRSLTE_PUCCH_NR_GROUP_HOPPING_ENABLE: - ERROR("Group hopping is not implemented\n"); + ERROR("Group hopping is not implemented"); return SRSLTE_ERROR; case SRSLTE_PUCCH_NR_GROUP_HOPPING_DISABLE: - ERROR("Hopping is not implemented\n"); + ERROR("Hopping is not implemented"); return SRSLTE_ERROR; } @@ -69,7 +68,7 @@ int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t* carrier, // Implements TS 38.211 clause 6.3.2.2.2 Cyclic shift hopping int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, uint32_t l, uint32_t l_prime, uint32_t m0, @@ -92,7 +91,7 @@ int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier, // Create n_cs parameter uint32_t n_cs = 0; for (uint32_t m = 0; m < 8; m++) { - n_cs += cs[SRSLTE_NSYMB_PER_SLOT_NR * n_slot + (l + l_prime) * 8 + m] << m; + n_cs += cs[(SRSLTE_NSYMB_PER_SLOT_NR * n_slot + (l + l_prime)) * 8 + m] << m; } *alpha_idx = (m0 + m_cs + n_cs) % SRSLTE_NRE; @@ -135,13 +134,13 @@ int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* arg // Initialise BPSK modulation table if (srslte_modem_table_lte(&q->bpsk, SRSLTE_MOD_BPSK) < SRSLTE_SUCCESS) { - ERROR("Initiating modem table\n"); + ERROR("Initiating modem table"); return SRSLTE_ERROR; } // Initialise QPSK modulation table if (srslte_modem_table_lte(&q->qpsk, SRSLTE_MOD_QPSK) < SRSLTE_SUCCESS) { - ERROR("Initiating modem table\n"); + ERROR("Initiating modem table"); return SRSLTE_ERROR; } @@ -155,7 +154,7 @@ int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* arg } if (srslte_uci_nr_init(&q->uci, &args->uci) < SRSLTE_SUCCESS) { - ERROR("Initiating UCI encoder/decoder\n"); + ERROR("Initiating UCI encoder/decoder"); return SRSLTE_ERROR; } @@ -163,21 +162,21 @@ int srslte_pucch_nr_init(srslte_pucch_nr_t* q, const srslte_pucch_nr_args_t* arg uint32_t max_encoded_bits = q->max_prb * SRSLTE_NRE * 2 * SRSLTE_NSYMB_PER_SLOT_NR; // Assumes QPSK (Qm = 2) q->b = srslte_vec_u8_malloc(max_encoded_bits); if (q->b == NULL) { - ERROR("Malloc\n"); + ERROR("Malloc"); return SRSLTE_ERROR; } // Allocate encoded symbols d q->d = srslte_vec_cf_malloc(max_encoded_bits / 2); if (q->d == NULL) { - ERROR("Malloc\n"); + ERROR("Malloc"); return SRSLTE_ERROR; } // Allocate temporal channel estimates q->ce = srslte_vec_cf_malloc(max_encoded_bits / 2); if (q->ce == NULL) { - ERROR("Malloc\n"); + ERROR("Malloc"); return SRSLTE_ERROR; } @@ -213,7 +212,7 @@ void srslte_pucch_nr_free(srslte_pucch_nr_t* q) int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, uint32_t m_cs, cf_t* slot_symbols) @@ -223,14 +222,14 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 0 resource\n"); + ERROR("Invalid PUCCH format 0 resource"); return SRSLTE_SUCCESS; } uint32_t u = 0; uint32_t v = 0; if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { - ERROR("Error getting group sequence\n"); + ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -246,7 +245,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, // get r_uv sequence from LUT object const cf_t* r_uv = srslte_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); if (r_uv == NULL) { - ERROR("Getting r_uv sequence\n"); + ERROR("Getting r_uv sequence"); return SRSLTE_ERROR; } @@ -263,7 +262,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, srslte_pucch_nr_resource_t* resource, uint32_t m_cs, const cf_t* slot_symbols, @@ -274,14 +273,14 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 0 resource\n"); + ERROR("Invalid PUCCH format 0 resource"); return SRSLTE_SUCCESS; } uint32_t u = 0; uint32_t v = 0; if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { - ERROR("Error getting group sequence\n"); + ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -299,7 +298,7 @@ int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, // get r_uv sequence from LUT object const cf_t* r_uv = srslte_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); if (r_uv == NULL) { - ERROR("Getting r_uv sequence\n"); + ERROR("Getting r_uv sequence"); return SRSLTE_ERROR; } @@ -353,15 +352,15 @@ static uint32_t pucch_nr_format1_n_pucch(const srslte_pucch_nr_resource_t* resou cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n_pucch, uint32_t i, uint32_t m) { if (n_pucch < 1 || n_pucch > SRSLTE_PUCCH_NR_FORMAT1_N_MAX) { - ERROR("Invalid n_pucch\n"); + ERROR("Invalid n_pucch"); return NAN; } if (i >= SRSLTE_PUCCH_NR_FORMAT1_N_MAX) { - ERROR("Invalid i\n"); + ERROR("Invalid i"); return NAN; } if (m >= SRSLTE_PUCCH_NR_FORMAT1_N_MAX) { - ERROR("Invalid m\n"); + ERROR("Invalid m"); return NAN; } @@ -372,25 +371,23 @@ cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n_pucch, uin int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, uint8_t* b, uint32_t nof_bits, cf_t* slot_symbols) { - uint32_t m_cs = 0; - if (carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || b == NULL || slot_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 1 resource\n"); + ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_SUCCESS; } if (nof_bits > SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS) { - ERROR("Invalid number of bits (%d)\n", nof_bits); + ERROR("Invalid number of bits (%d)", nof_bits); return SRSLTE_ERROR; } @@ -406,7 +403,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, uint32_t u = 0; uint32_t v = 0; if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { - ERROR("Error getting group sequence\n"); + ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -420,7 +417,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, // Get Alpha index uint32_t alpha_idx = 0; - if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < + if (srslte_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -428,7 +425,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, // get r_uv sequence from LUT object const cf_t* r_uv = srslte_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); if (r_uv == NULL) { - ERROR("Getting r_uv sequence\n"); + ERROR("Getting r_uv sequence"); return SRSLTE_ERROR; } @@ -453,7 +450,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, srslte_chest_ul_res_t* chest_res, cf_t* slot_symbols, @@ -463,12 +460,12 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, uint32_t m_cs = 0; if (srslte_pucch_nr_cfg_resource_valid(resource) < SRSLTE_SUCCESS) { - ERROR("Invalid PUCCH format 1 resource\n"); + ERROR("Invalid PUCCH format 1 resource"); return SRSLTE_SUCCESS; } if (nof_bits > SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS) { - ERROR("Invalid number of bits (%d)\n", nof_bits); + ERROR("Invalid number of bits (%d)", nof_bits); return SRSLTE_ERROR; } @@ -479,7 +476,7 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, uint32_t u = 0; uint32_t v = 0; if (srslte_pucch_nr_group_sequence(carrier, cfg, &u, &v) < SRSLTE_SUCCESS) { - ERROR("Error getting group sequence\n"); + ERROR("Error getting group sequence"); return SRSLTE_ERROR; } @@ -506,7 +503,7 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, // get r_uv sequence from LUT object const cf_t* r_uv = srslte_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); if (r_uv == NULL) { - ERROR("Getting r_uv sequence\n"); + ERROR("Getting r_uv sequence"); return SRSLTE_ERROR; } // Get w_i_m @@ -532,10 +529,12 @@ int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, return SRSLTE_SUCCESS; } -static uint32_t pucch_nr_format2_cinit(const srslte_pucch_nr_common_cfg_t* pucch_cfg, +static uint32_t pucch_nr_format2_cinit(const srslte_carrier_nr_t* carrier, + const srslte_pucch_nr_common_cfg_t* pucch_cfg, const srslte_uci_cfg_nr_t* uci_cfg) { - uint32_t n_id = (pucch_cfg->scrambling_id_present) ? pucch_cfg->scrambling_id_present : uci_cfg->rnti; + uint32_t n_id = (pucch_cfg->scrambling_id_present) ? pucch_cfg->scrambling_id_present : carrier->id; + return ((uint32_t)uci_cfg->rnti << 15U) + n_id; } @@ -556,7 +555,7 @@ static int pucch_nr_format2_encode(srslte_pucch_nr_t* q, uint32_t E = srslte_uci_nr_pucch_format_2_3_4_E(resource); // 6.3.2.5.1 Scrambling - uint32_t cinit = pucch_nr_format2_cinit(cfg, uci_cfg); + uint32_t cinit = pucch_nr_format2_cinit(carrier, cfg, uci_cfg); srslte_sequence_apply_bit(q->b, q->b, E, cinit); // 6.3.2.5.2 Modulation @@ -622,18 +621,18 @@ static int pucch_nr_format2_decode(srslte_pucch_nr_t* q, // Equalise if (srslte_predecoding_single(q->d, q->ce, q->d, NULL, E, 1.0f, chest_res->noise_estimate) < SRSLTE_SUCCESS) { - ERROR("Error Pre-decoding\n"); + ERROR("Error Pre-decoding"); return SRSLTE_ERROR; } // Soft-demodulate if (srslte_demod_soft_demodulate_b(SRSLTE_MOD_QPSK, q->d, llr, E) < SRSLTE_SUCCESS) { - ERROR("Error soft-demodulate\n"); + ERROR("Error soft-demodulate"); return SRSLTE_ERROR; } // Undo Scrambling - uint32_t cinit = pucch_nr_format2_cinit(cfg, uci_cfg); + uint32_t cinit = pucch_nr_format2_cinit(carrier, cfg, uci_cfg); srslte_sequence_apply_c(llr, llr, E, cinit); return SRSLTE_SUCCESS; @@ -642,7 +641,7 @@ static int pucch_nr_format2_decode(srslte_pucch_nr_t* q, int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const srslte_uci_cfg_nr_t* uci_cfg, const srslte_uci_value_nr_t* uci_value, @@ -656,7 +655,7 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, // Encode PUCCH message if (srslte_uci_nr_encode_pucch(&q->uci, resource, uci_cfg, uci_value, q->b) < SRSLTE_SUCCESS) { - ERROR("Error encoding UCI\n"); + ERROR("Error encoding UCI"); return SRSLTE_ERROR; } @@ -666,11 +665,11 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, return pucch_nr_format2_encode(q, carrier, cfg, resource, uci_cfg, slot_symbols); case SRSLTE_PUCCH_NR_FORMAT_3: case SRSLTE_PUCCH_NR_FORMAT_4: - ERROR("Not implemented\n"); + ERROR("Not implemented"); return SRSLTE_ERROR; default: case SRSLTE_PUCCH_NR_FORMAT_ERROR: - ERROR("Invalid format\n"); + ERROR("Invalid format"); } return SRSLTE_ERROR; @@ -679,7 +678,7 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_pucch_nr_common_cfg_t* cfg, - const srslte_dl_slot_cfg_t* slot, + const srslte_slot_cfg_t* slot, const srslte_pucch_nr_resource_t* resource, const srslte_uci_cfg_nr_t* uci_cfg, srslte_chest_ul_res_t* chest_res, @@ -697,24 +696,78 @@ int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, switch (resource->format) { case SRSLTE_PUCCH_NR_FORMAT_2: if (pucch_nr_format2_decode(q, carrier, cfg, resource, uci_cfg, chest_res, slot_symbols, llr) < SRSLTE_SUCCESS) { - ERROR("Demodulating PUCCH format 2\n"); + ERROR("Demodulating PUCCH format 2"); return SRSLTE_ERROR; } break; case SRSLTE_PUCCH_NR_FORMAT_3: case SRSLTE_PUCCH_NR_FORMAT_4: - ERROR("Not implemented\n"); + ERROR("Not implemented"); return SRSLTE_ERROR; default: case SRSLTE_PUCCH_NR_FORMAT_ERROR: - ERROR("Invalid format\n"); + ERROR("Invalid format"); } // Decode PUCCH message if (srslte_uci_nr_decode_pucch(&q->uci, resource, uci_cfg, llr, uci_value) < SRSLTE_SUCCESS) { - ERROR("Error encoding UCI\n"); + ERROR("Error encoding UCI"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; -} \ No newline at end of file +} + +static uint32_t pucch_nr_resource_info(const srslte_pucch_nr_resource_t* r, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + uint32_t nof_prb = 1; + if (r->format == SRSLTE_PUCCH_NR_FORMAT_2 || r->format == SRSLTE_PUCCH_NR_FORMAT_3) { + nof_prb = r->nof_prb; + } + + len = srslte_print_check(str, + str_len, + len, + "f=%d, prb=%d:%d, symb=%d:%d", + (int)r->format, + r->starting_prb, + nof_prb, + r->start_symbol_idx, + r->nof_symbols); + + if (r->intra_slot_hopping) { + len = srslte_print_check(str, str_len, len, ", hop=%d", r->second_hop_prb); + } + + if (r->format == SRSLTE_PUCCH_NR_FORMAT_0 || r->format == SRSLTE_PUCCH_NR_FORMAT_1) { + len = srslte_print_check(str, str_len, len, ", cs=%d", r->initial_cyclic_shift); + } + + if (r->format == SRSLTE_PUCCH_NR_FORMAT_1) { + len = srslte_print_check(str, str_len, len, ", occ=%d", r->time_domain_occ); + } + + if (r->format == SRSLTE_PUCCH_NR_FORMAT_4) { + len = srslte_print_check(str, str_len, len, ", occ=%d:%d", r->occ_index, r->occ_lenth); + } + + return len; +} + +uint32_t srslte_pucch_nr_tx_info(const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data, + char* str, + uint32_t str_len) +{ + uint32_t len = 0; + + len += pucch_nr_resource_info(resource, &str[len], str_len - len); + + len = srslte_print_check(str, str_len, len, ", "); + + len += srslte_uci_nr_info(uci_data, &str[len], str_len - len); + + return len; +} diff --git a/lib/src/phy/phch/pucch_proc.c b/lib/src/phy/phch/pucch_proc.c index b5ab0b477..d4f15dc50 100644 --- a/lib/src/phy/phch/pucch_proc.c +++ b/lib/src/phy/phch/pucch_proc.c @@ -59,7 +59,7 @@ srslte_pucch_format_t srslte_pucch_proc_select_format(const srslte_cell_t* else if (pucch_proc_tx_sr(uci_cfg, uci_value)) { format = SRSLTE_PUCCH_FORMAT_1; } else { - ERROR("Error selecting PUCCH format: Unsupported number of ACK bits %d\n", total_ack); + ERROR("Error selecting PUCCH format: Unsupported number of ACK bits %d", total_ack); } } // CQI data @@ -82,7 +82,7 @@ srslte_pucch_format_t srslte_pucch_proc_select_format(const srslte_cell_t* } } if (format == SRSLTE_PUCCH_FORMAT_ERROR) { - ERROR("Returned Error while selecting PUCCH format\n"); + ERROR("Returned Error while selecting PUCCH format"); } return format; @@ -225,7 +225,7 @@ int srslte_pucch_cs_get_ack(const srslte_pucch_cfg_t* cfg, break; default: // Unhandled case - ERROR("Unexpected number of ACK (%d)\n", nof_ack); + ERROR("Unexpected number of ACK (%d)", nof_ack); ret = SRSLTE_ERROR; } } @@ -265,7 +265,7 @@ static uint32_t n_pucch_i_tdd(uint32_t ncce, uint32_t N_pucch_1, uint32_t nof_pr return npucch; } } - ERROR("Could not find Np value for ncce=%d\n", ncce); + ERROR("Could not find Np value for ncce=%d", ncce); return 0; } @@ -291,7 +291,7 @@ int srslte_pucch_proc_get_resources(const srslte_cell_t* cell, uint32_t* n_pucch_i) { if (!cfg || !cell || !uci_cfg || !n_pucch_i) { - ERROR("pucch_resource_selection(): Invalid parameters\n"); + ERROR("pucch_resource_selection(): Invalid parameters"); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -327,7 +327,7 @@ int srslte_pucch_proc_get_resources(const srslte_cell_t* cell, } // Otherwise an error shall be prompt - ERROR("Unhandled PUCCH format mode %s\n", srslte_ack_nack_feedback_mode_string(cfg->ack_nack_feedback_mode)); + ERROR("Unhandled PUCCH format mode %s", srslte_ack_nack_feedback_mode_string(cfg->ack_nack_feedback_mode)); return SRSLTE_ERROR; } @@ -430,7 +430,7 @@ static uint32_t get_npucch_cs(const srslte_pucch_cfg_t* cfg, } break; default: - ERROR("Too many (%d) ACK for this CS mode\n", srslte_uci_cfg_total_ack(uci_cfg)); + ERROR("Too many (%d) ACK for this CS mode", srslte_uci_cfg_total_ack(uci_cfg)); } return n_pucch; @@ -456,7 +456,7 @@ static void set_b01(uint8_t* b, uint8_t x) b[1] = 1; break; default: - ERROR("Unhandled case (%d)\n", x); + ERROR("Unhandled case (%d)", x); } } diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index 31360e35b..3da59bd00 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -64,7 +64,7 @@ static int pusch_cp(srslte_pusch_t* q, if (is_shortened && slot == 1) { N_srs = 1; } - INFO("%s PUSCH %d PRB to index %d at slot %d\n", + INFO("%s PUSCH %d PRB to index %d at slot %d", advance_input ? "Allocating" : "Getting", grant->L_prb, grant->n_prb_tilde[slot], @@ -110,12 +110,11 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue) int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - bzero(q, sizeof(srslte_pusch_t)); ret = SRSLTE_ERROR; q->max_re = max_prb * MAX_PUSCH_RE(SRSLTE_CP_NORM); - INFO("Init PUSCH: %d PRBs\n", max_prb); + INFO("Init PUSCH: %d PRBs", max_prb); for (srslte_mod_t i = 0; i < SRSLTE_MOD_NITEMS; i++) { if (srslte_modem_table_lte(&q->mod[i], i)) { @@ -139,7 +138,7 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue) srslte_sch_init(&q->ul_sch); if (srslte_dft_precoding_init(&q->dft_precoding, max_prb, is_ue)) { - ERROR("Error initiating DFT transform precoding\n"); + ERROR("Error initiating DFT transform precoding"); goto clean; } @@ -168,7 +167,7 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue) q->evm_buffer = srslte_evm_buffer_alloc(srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, 6)); if (!q->evm_buffer) { - ERROR("Allocating EVM buffer\n"); + ERROR("Allocating EVM buffer"); goto clean; } } @@ -246,7 +245,6 @@ int srslte_pusch_set_cell(srslte_pusch_t* q, srslte_cell_t cell) int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_cell_isvalid(&cell)) { - // Resize EVM buffer, only for eNb if (!q->is_ue && q->evm_buffer) { srslte_evm_buffer_resize(q->evm_buffer, srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, cell.nof_prb)); @@ -271,7 +269,7 @@ int srslte_pusch_set_rnti(srslte_pusch_t* q, uint16_t rnti) // If the sequence is not allocated generate q->users[rnti_idx] = calloc(1, sizeof(srslte_pdsch_user_t)); if (!q->users[rnti_idx]) { - ERROR("Alocating PDSCH user\n"); + ERROR("Alocating PDSCH user"); return SRSLTE_ERROR; } } else if (q->users[rnti_idx]->sequence_generated && q->users[rnti_idx]->cell_id == q->cell.id && !q->is_ue) { @@ -289,7 +287,7 @@ int srslte_pusch_set_rnti(srslte_pusch_t* q, uint16_t rnti) SRSLTE_NOF_SLOTS_PER_SF * sf_idx, q->cell.id, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { - ERROR("Error initializing PUSCH scrambling sequence\n"); + ERROR("Error initializing PUSCH scrambling sequence"); srslte_pusch_free_rnti(q, rnti); return SRSLTE_ERROR; } @@ -305,7 +303,6 @@ int srslte_pusch_set_rnti(srslte_pusch_t* q, uint16_t rnti) void srslte_pusch_free_rnti(srslte_pusch_t* q, uint16_t rnti) { - uint32_t rnti_idx = q->is_ue ? 0 : rnti; if (q->users[rnti_idx]) { @@ -329,13 +326,13 @@ static srslte_sequence_t* get_user_sequence(srslte_pusch_t* q, uint16_t rnti, ui return &q->users[rnti_idx]->seq[sf_idx]; } else { if (srslte_sequence_pusch(&q->tmp_seq, rnti, 2 * sf_idx, q->cell.id, len)) { - ERROR("Error generating temporal scrambling sequence\n"); + ERROR("Error generating temporal scrambling sequence"); return NULL; } return &q->tmp_seq; } } else { - ERROR("Invalid RNTI=0x%x\n", rnti); + ERROR("Invalid RNTI=0x%x", rnti); return NULL; } } @@ -371,7 +368,6 @@ int srslte_pusch_encode(srslte_pusch_t* q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && cfg != NULL) { - /* Limit UL modulation if not supported by the UE or disabled by higher layers */ if (!cfg->enable_64qam) { if (cfg->grant.tb.mod >= SRSLTE_MOD_64QAM) { @@ -381,7 +377,7 @@ int srslte_pusch_encode(srslte_pusch_t* q, } if (cfg->grant.nof_re > q->max_re) { - ERROR("Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)\n", + ERROR("Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)", cfg->grant.nof_re, q->max_re, q->cell.nof_prb); @@ -393,7 +389,7 @@ int srslte_pusch_encode(srslte_pusch_t* q, return err; } - INFO("Encoding PUSCH SF: %d, Mod %s, RNTI: %d, TBS: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n", + INFO("Encoding PUSCH SF: %d, Mod %s, RNTI: %d, TBS: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d", sf->tti % 10, srslte_mod_string(cfg->grant.tb.mod), cfg->rnti, @@ -405,7 +401,7 @@ int srslte_pusch_encode(srslte_pusch_t* q, bzero(q->q, cfg->grant.tb.nof_bits); if ((ret = srslte_ulsch_encode(&q->ul_sch, cfg, data->ptr, &data->uci, q->g, q->q)) < 0) { - ERROR("Error encoding TB\n"); + ERROR("Error encoding TB"); return SRSLTE_ERROR; } @@ -414,7 +410,7 @@ int srslte_pusch_encode(srslte_pusch_t* q, // Generate scrambling sequence if not pre-generated srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, sf->tti % 10, cfg->grant.tb.nof_bits); if (!seq) { - ERROR("Error getting user sequence for rnti=0x%x\n", cfg->rnti); + ERROR("Error getting user sequence for rnti=0x%x", cfg->rnti); return -1; } @@ -448,7 +444,7 @@ int srslte_pusch_encode(srslte_pusch_t* q, // Mapping to resource elements uint32_t n = pusch_put(q, &cfg->grant, q->z, sf_symbols, sf->shortened); if (n != cfg->grant.nof_re) { - ERROR("Error trying to allocate %d symbols but %d were allocated (tti=%d, short=%d, L=%d)\n", + ERROR("Error trying to allocate %d symbols but %d were allocated (tti=%d, short=%d, L=%d)", cfg->grant.nof_re, n, sf->tti, @@ -475,7 +471,6 @@ int srslte_pusch_decode(srslte_pusch_t* q, uint32_t n; if (q != NULL && sf_symbols != NULL && out != NULL && cfg != NULL) { - struct timeval t[3]; if (cfg->meas_time_en) { gettimeofday(&t[1], NULL); @@ -489,7 +484,7 @@ int srslte_pusch_decode(srslte_pusch_t* q, } } - INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n", + INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d", sf->tti % 10, srslte_mod_string(cfg->grant.tb.mod), cfg->grant.tb.tbs, @@ -501,7 +496,7 @@ int srslte_pusch_decode(srslte_pusch_t* q, /* extract symbols */ n = pusch_get(q, &cfg->grant, sf_symbols, q->d, sf->shortened); if (n != cfg->grant.nof_re) { - ERROR("Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); + ERROR("Error expecting %d symbols but got %d", cfg->grant.nof_re, n); return SRSLTE_ERROR; } @@ -515,7 +510,7 @@ int srslte_pusch_decode(srslte_pusch_t* q, /* extract channel estimates */ n = pusch_get(q, &cfg->grant, channel->ce, q->ce, sf->shortened); if (n != cfg->grant.nof_re) { - ERROR("Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); + ERROR("Error expecting %d symbols but got %d", cfg->grant.nof_re, n); return SRSLTE_ERROR; } @@ -545,7 +540,7 @@ int srslte_pusch_decode(srslte_pusch_t* q, // Generate scrambling sequence if not pre-generated srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, sf->tti % 10, cfg->grant.tb.nof_bits); if (!seq) { - ERROR("Error getting user sequence for rnti=0x%x\n", cfg->rnti); + ERROR("Error getting user sequence for rnti=0x%x", cfg->rnti); return -1; } @@ -586,7 +581,6 @@ uint32_t srslte_pusch_grant_tx_info(srslte_pusch_grant_t* grant, char* str, uint32_t str_len) { - uint32_t len = srslte_ra_ul_info(grant, str, str_len); if (uci_data) { @@ -598,7 +592,6 @@ uint32_t srslte_pusch_grant_tx_info(srslte_pusch_grant_t* grant, uint32_t srslte_pusch_tx_info(srslte_pusch_cfg_t* cfg, srslte_uci_value_t* uci_data, char* str, uint32_t str_len) { - uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti); len += srslte_pusch_grant_tx_info(&cfg->grant, &cfg->uci_cfg, uci_data, &str[len], str_len - len); @@ -615,7 +608,6 @@ uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, char* str, uint32_t str_len) { - uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti); len += srslte_ra_ul_info(&cfg->grant, &str[len], str_len); diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index c34e50b24..e597112a0 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -29,7 +29,7 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg { for (srslte_mod_t mod = SRSLTE_MOD_BPSK; mod < SRSLTE_MOD_NITEMS; mod++) { if (srslte_modem_table_lte(&q->modem_tables[mod], mod) < SRSLTE_SUCCESS) { - ERROR("Error initialising modem table for %s\n", srslte_mod_string(mod)); + ERROR("Error initialising modem table for %s", srslte_mod_string(mod)); return SRSLTE_ERROR; } if (args->measure_evm) { @@ -40,7 +40,7 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg return SRSLTE_SUCCESS; } -int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) +int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) { if (q == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -51,14 +51,14 @@ int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* } if (srslte_sch_nr_init_tx(&q->sch, &args->sch)) { - ERROR("Initialising SCH\n"); + ERROR("Initialising SCH"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } -int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) +int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) { if (q == NULL || args == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -69,14 +69,14 @@ int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* } if (srslte_sch_nr_init_rx(&q->sch, &args->sch)) { - ERROR("Initialising SCH\n"); + ERROR("Initialising SCH"); return SRSLTE_ERROR; } if (args->measure_evm) { q->evm_buffer = srslte_evm_buffer_alloc(8); if (q->evm_buffer == NULL) { - ERROR("Initialising EVM\n"); + ERROR("Initialising EVM"); return SRSLTE_ERROR; } } @@ -290,8 +290,7 @@ static uint32_t srslte_pusch_nr_cp_dmrs(const srslte_pusch_nr_t* q, { uint32_t count = 0; - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = &cfg->dmrs; switch (dmrs_cfg->type) { case srslte_dmrs_sch_type_1: @@ -363,7 +362,7 @@ static int srslte_pusch_nr_cp(const srslte_pusch_nr_t* q, uint32_t dmrs_l_count = 0; // Get symbol indexes carrying DMRS - int32_t nof_dmrs_symbols = srslte_dmrs_sch_get_symbols_idx(cfg, grant, dmrs_l_idx); + int32_t nof_dmrs_symbols = srslte_dmrs_sch_get_symbols_idx(&cfg->dmrs, grant, dmrs_l_idx); if (nof_dmrs_symbols < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -420,7 +419,7 @@ pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cf } uint32_t cinit = (((uint32_t)rnti) << 15U) + (cw_idx << 14U) + n_id; - INFO("PUSCH: RNTI=%d (0x%x); nid=%d; cinit=%d (0x%x);\n", rnti, rnti, n_id, cinit, cinit); + INFO("PUSCH: RNTI=%d (0x%x); nid=%d; cinit=%d (0x%x);", rnti, rnti, n_id, cinit, cinit); return cinit; } @@ -438,19 +437,19 @@ static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, // Check codeword index if (tb->cw_idx >= q->max_cw) { - ERROR("Unsupported codeword index %d\n", tb->cw_idx); + ERROR("Unsupported codeword index %d", tb->cw_idx); return SRSLTE_ERROR; } // Check modulation if (tb->mod >= SRSLTE_MOD_NITEMS) { - ERROR("Invalid modulation %s\n", srslte_mod_string(tb->mod)); + ERROR("Invalid modulation %s", srslte_mod_string(tb->mod)); return SRSLTE_ERROR_OUT_OF_BOUNDS; } // Encode SCH if (srslte_ulsch_nr_encode(&q->sch, &cfg->sch_cfg, tb, data, q->b[tb->cw_idx]) < SRSLTE_SUCCESS) { - ERROR("Error in DL-SCH encoding\n"); + ERROR("Error in DL-SCH encoding"); return SRSLTE_ERROR; } @@ -480,7 +479,6 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, uint8_t* data[SRSLTE_MAX_TB], cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { - // Check input pointers if (!q || !cfg || !grant || !data || !sf_symbols) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -493,7 +491,7 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, // Check number of layers if (q->max_layers < grant->nof_layers) { - ERROR("Error number of layers (%d) exceeds configured maximum (%d)\n", grant->nof_layers, q->max_layers); + ERROR("Error number of layers (%d) exceeds configured maximum (%d)", grant->nof_layers, q->max_layers); return SRSLTE_ERROR; } @@ -503,7 +501,7 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, nof_cw += grant->tb[tb].enabled ? 1 : 0; if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb], grant->rnti) < SRSLTE_SUCCESS) { - ERROR("Error encoding TB %d\n", tb); + ERROR("Error encoding TB %d", tb); return SRSLTE_ERROR; } } @@ -524,12 +522,12 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, // 7.3.1.6 Mapping from virtual to physical resource blocks int n = srslte_pusch_nr_put(q, cfg, grant, x[0], sf_symbols[0]); if (n < SRSLTE_SUCCESS) { - ERROR("Putting NR PUSCH resources\n"); + ERROR("Putting NR PUSCH resources"); return SRSLTE_ERROR; } if (n != grant->tb[0].nof_re) { - ERROR("Unmatched number of RE (%d != %d)\n", n, grant->tb[0].nof_re); + ERROR("Unmatched number of RE (%d != %d)", n, grant->tb[0].nof_re); return SRSLTE_ERROR; } @@ -555,13 +553,13 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, // Check codeword index if (tb->cw_idx >= q->max_cw) { - ERROR("Unsupported codeword index %d\n", tb->cw_idx); + ERROR("Unsupported codeword index %d", tb->cw_idx); return SRSLTE_ERROR; } // Check modulation if (tb->mod >= SRSLTE_MOD_NITEMS) { - ERROR("Invalid modulation %s\n", srslte_mod_string(tb->mod)); + ERROR("Invalid modulation %s", srslte_mod_string(tb->mod)); return SRSLTE_ERROR_OUT_OF_BOUNDS; } @@ -596,7 +594,7 @@ static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, // Decode SCH if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { - ERROR("Error in DL-SCH encoding\n"); + ERROR("Error in DL-SCH encoding"); return SRSLTE_ERROR; } @@ -628,14 +626,14 @@ int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(cfg, grant); if (channel->nof_re != nof_re) { - ERROR("Inconsistent number of RE (%d!=%d)\n", channel->nof_re, nof_re); + ERROR("Inconsistent number of RE (%d!=%d)", channel->nof_re, nof_re); return SRSLTE_ERROR; } // Demapping from virtual to physical resource blocks uint32_t nof_re_get = srslte_pusch_nr_get(q, cfg, grant, q->x[0], sf_symbols[0]); if (nof_re_get != nof_re) { - ERROR("Inconsistent number of RE (%d!=%d)\n", nof_re_get, nof_re); + ERROR("Inconsistent number of RE (%d!=%d)", nof_re_get, nof_re); return SRSLTE_ERROR; } @@ -664,7 +662,7 @@ int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, nof_cw += grant->tb[tb].enabled ? 1 : 0; if (pusch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSLTE_SUCCESS) { - ERROR("Error encoding TB %d\n", tb); + ERROR("Error encoding TB %d", tb); return SRSLTE_ERROR; } } @@ -686,12 +684,23 @@ static uint32_t srslte_pusch_nr_grant_info(const srslte_sch_cfg_nr_t* cfg, uint32_t len = 0; len = srslte_print_check(str, str_len, len, "rnti=0x%x", grant->rnti); + char freq_str[SRSLTE_MAX_PRB_NR + 1] = {}; + for (uint32_t i = 0, nof_prb = 0; i < SRSLTE_MAX_PRB_NR && nof_prb < grant->nof_prb; i++) { + if (grant->prb_idx[i]) { + freq_str[i] = '1'; + nof_prb++; + } else { + freq_str[i] = '0'; + } + } + // Append time-domain resource mapping len = srslte_print_check(str, str_len, len, - ",k0=%d,S=%d,L=%d,mapping=%s", - grant->k0, + ",k2=%d,freq=%s,S=%d,L=%d,mapping=%s", + grant->k, + freq_str, grant->S, grant->L, srslte_sch_mapping_type_to_str(grant->mapping)); @@ -720,7 +729,6 @@ uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q, char* str, uint32_t str_len) { - uint32_t len = 0; len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); @@ -756,7 +764,7 @@ uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q, } if (q->meas_time_en) { - len = srslte_print_check(str, str_len, len, ", t=%d us\n", q->meas_time_us); + len = srslte_print_check(str, str_len, len, ", t=%d us", q->meas_time_us); } return len; @@ -768,13 +776,12 @@ uint32_t srslte_pusch_nr_tx_info(const srslte_pusch_nr_t* q, char* str, uint32_t str_len) { - uint32_t len = 0; len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); if (q->meas_time_en) { - len = srslte_print_check(str, str_len, len, ", t=%d us\n", q->meas_time_us); + len = srslte_print_check(str, str_len, len, ", t=%d us", q->meas_time_us); } return len; diff --git a/lib/src/phy/phch/ra_dl.c b/lib/src/phy/phch/ra_dl.c index 3ee5ba10c..195618155 100644 --- a/lib/src/phy/phch/ra_dl.c +++ b/lib/src/phy/phch/ra_dl.c @@ -41,7 +41,6 @@ const int tbs_format1c_table[32] = {40, 56, 72, 120, 136, 144, 176, 208 /* Returns the number of RE in a PRB in a slot and subframe */ uint32_t ra_re_x_prb(const srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, uint32_t slot, uint32_t prb_idx) { - uint32_t subframe = sf->tti % 10; uint32_t nof_ctrl_symbols = SRSLTE_NOF_CTRL_SYMBOLS((*cell), sf->cfi); @@ -197,7 +196,7 @@ int srslte_ra_dl_grant_to_grant_prb_allocation(const srslte_dci_dl_t* dci, case SRSLTE_RA_ALLOC_TYPE1: // Make sure the rbg_subset is valid if (dci->type1_alloc.rbg_subset >= P) { - ERROR("Invalid RBG subset=%d for nof_prb=%d where P=%d\n", dci->type1_alloc.rbg_subset, nof_prb, P); + ERROR("Invalid RBG subset=%d for nof_prb=%d where P=%d", dci->type1_alloc.rbg_subset, nof_prb, P); return SRSLTE_ERROR; } n_rb_type1 = srslte_ra_type1_N_rb(nof_prb); @@ -218,7 +217,7 @@ int srslte_ra_dl_grant_to_grant_prb_allocation(const srslte_dci_dl_t* dci, grant->prb_idx[0][idx] = true; grant->nof_prb++; } else { - ERROR("Invalid idx=%d in Type1 RA, nof_prb=%d\n", idx, nof_prb); + ERROR("Invalid idx=%d in Type1 RA, nof_prb=%d", idx, nof_prb); return SRSLTE_ERROR; } } @@ -369,25 +368,25 @@ static int dl_dci_compute_tb(bool pdsch_use_tbs_index_alt, const srslte_dci_dl_t i_tbs = dci->tb[0].mcs_idx; tbs = srslte_ra_tbs_from_idx(i_tbs, n_prb); if (tbs < 0) { - ERROR("Invalid TBS_index=%d or n_prb=%d\n", i_tbs, n_prb); + ERROR("Invalid TBS_index=%d or n_prb=%d", i_tbs, n_prb); return SRSLTE_ERROR; } } else if (dci->format == SRSLTE_DCI_FORMAT1C) { if (dci->tb[0].mcs_idx < 32) { tbs = tbs_format1c_table[dci->tb[0].mcs_idx]; } else { - ERROR("Error decoding DCI: Invalid mcs_idx=%d in Format1C\n", dci->tb[0].mcs_idx); + ERROR("Error decoding DCI: Invalid mcs_idx=%d in Format1C", dci->tb[0].mcs_idx); return SRSLTE_ERROR; } } else { - ERROR("Error decoding DCI: P/SI/RA-RNTI supports Format1A/1C only\n"); + ERROR("Error decoding DCI: P/SI/RA-RNTI supports Format1A/1C only"); return SRSLTE_ERROR; } grant->tb[0].mod = SRSLTE_MOD_QPSK; if (tbs >= 0) { grant->tb[0].tbs = (uint32_t)tbs; } else { - ERROR("Invalid TBS=%d\n", tbs); + ERROR("Invalid TBS=%d", tbs); return SRSLTE_ERROR; } } else { @@ -402,7 +401,7 @@ static int dl_dci_compute_tb(bool pdsch_use_tbs_index_alt, const srslte_dci_dl_t if (grant->tb[i].tbs < 0) { char str[128]; srslte_dci_dl_info(dci, str, sizeof(str)); - INFO("Error computing TBS from %s\n", str); + INFO("Error computing TBS from %s", str); return SRSLTE_ERROR; } } else { @@ -457,7 +456,7 @@ config_mimo_type(const srslte_cell_t* cell, srslte_tm_t tm, const srslte_dci_dl_ grant->tx_scheme = SRSLTE_TXSCHEME_PORT0; } if (nof_tb != 1) { - ERROR("Wrong number of transport blocks (%d) for %s.\n", nof_tb, srslte_mimotype2str(grant->tx_scheme)); + ERROR("Wrong number of transport blocks (%d) for %s.", nof_tb, srslte_mimotype2str(grant->tx_scheme)); valid_config = false; } break; @@ -467,7 +466,7 @@ config_mimo_type(const srslte_cell_t* cell, srslte_tm_t tm, const srslte_dci_dl_ } else if (nof_tb == 2) { grant->tx_scheme = SRSLTE_TXSCHEME_CDD; } else { - ERROR("Invalid number of transport blocks (%d) for TM3\n", nof_tb); + ERROR("Invalid number of transport blocks (%d) for TM3", nof_tb); valid_config = false; } break; @@ -477,7 +476,7 @@ config_mimo_type(const srslte_cell_t* cell, srslte_tm_t tm, const srslte_dci_dl_ } else if (nof_tb == 2) { grant->tx_scheme = SRSLTE_TXSCHEME_SPATIALMUX; } else { - ERROR("Invalid number of transport blocks (%d) for TM4\n", nof_tb); + ERROR("Invalid number of transport blocks (%d) for TM4", nof_tb); valid_config = false; } break; @@ -487,12 +486,12 @@ config_mimo_type(const srslte_cell_t* cell, srslte_tm_t tm, const srslte_dci_dl_ case SRSLTE_TM6: case SRSLTE_TM7: case SRSLTE_TM8: - ERROR("Not implemented Tx mode (%d)\n", tm + 1); + ERROR("Not implemented Tx mode (%d)", tm + 1); break; /* Error cases */ default: - ERROR("Wrong Tx mode (%d)\n", tm + 1); + ERROR("Wrong Tx mode (%d)", tm + 1); } return valid_config ? SRSLTE_SUCCESS : SRSLTE_ERROR; } @@ -535,14 +534,14 @@ static int config_mimo_layers(const srslte_cell_t* cell, const srslte_dci_dl_t* switch (grant->tx_scheme) { case SRSLTE_TXSCHEME_PORT0: if (nof_tb != 1) { - ERROR("Wrong number of transport blocks (%d) for single antenna.\n", nof_tb); + ERROR("Wrong number of transport blocks (%d) for single antenna.", nof_tb); return SRSLTE_ERROR; } grant->nof_layers = 1; break; case SRSLTE_TXSCHEME_DIVERSITY: if (nof_tb != 1) { - ERROR("Wrong number of transport blocks (%d) for transmit diversity.\n", nof_tb); + ERROR("Wrong number of transport blocks (%d) for transmit diversity.", nof_tb); return SRSLTE_ERROR; } grant->nof_layers = cell->nof_ports; @@ -553,17 +552,17 @@ static int config_mimo_layers(const srslte_cell_t* cell, const srslte_dci_dl_t* } else if (nof_tb == 2) { grant->nof_layers = 2; } else { - ERROR("Wrong number of transport blocks (%d) for spatial multiplexing.\n", nof_tb); + ERROR("Wrong number of transport blocks (%d) for spatial multiplexing.", nof_tb); return SRSLTE_ERROR; } - INFO("PDSCH configured for Spatial Multiplex; nof_codewords=%d; nof_layers=%d; pmi=%d\n", + INFO("PDSCH configured for Spatial Multiplex; nof_codewords=%d; nof_layers=%d; pmi=%d", nof_tb, grant->nof_layers, grant->pmi); break; case SRSLTE_TXSCHEME_CDD: if (nof_tb != 2) { - ERROR("Wrong number of transport blocks (%d) for CDD.\n", nof_tb); + ERROR("Wrong number of transport blocks (%d) for CDD.", nof_tb); return SRSLTE_ERROR; } grant->nof_layers = 2; @@ -575,19 +574,18 @@ static int config_mimo_layers(const srslte_cell_t* cell, const srslte_dci_dl_t* static int config_mimo(const srslte_cell_t* cell, srslte_tm_t tm, const srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant) { - if (config_mimo_type(cell, tm, dci, grant)) { - ERROR("Configuring MIMO type\n"); + ERROR("Configuring MIMO type"); return -1; } if (config_mimo_pmi(cell, dci, grant)) { - ERROR("Configuring MIMO PMI\n"); + ERROR("Configuring MIMO PMI"); return -1; } if (config_mimo_layers(cell, dci, grant)) { - ERROR("Configuring MIMO layers\n"); + ERROR("Configuring MIMO layers"); return -1; } @@ -627,11 +625,11 @@ int srslte_ra_dl_dci_to_grant(const srslte_cell_t* cell, } } } else { - INFO("Configuring TB Info\n"); + INFO("Configuring TB Info"); return SRSLTE_ERROR; } } else { - ERROR("Configuring resource allocation\n"); + ERROR("Configuring resource allocation"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/ra_dl_nr.c b/lib/src/phy/phch/ra_dl_nr.c index d7170be11..b00a02956 100644 --- a/lib/src/phy/phch/ra_dl_nr.c +++ b/lib/src/phy/phch/ra_dl_nr.c @@ -19,43 +19,31 @@ * */ #include "srslte/phy/phch/ra_dl_nr.h" +#include "ra_helper.h" #include "srslte/phy/utils/debug.h" -static void sliv_to_s_and_l(uint32_t sliv, uint32_t* S, uint32_t* L) -{ - // S values can be 0 to 3 - uint32_t low = sliv % 14; - if (low < 7) { - *S = low; - *L = sliv / 14 + 1; - } else { - *S = 14 - 1 - low; - *L = 14 - sliv / 14 + 1; - } -} - // Validate S and L combination for TypeA time domain resource allocation static bool check_time_ra_typeA(uint32_t* S, uint32_t* L) { // Check values using Table 5.1.2.1-1 if (*S > 3) { - ERROR("S (%d) is out-of-range {0,1,2,3}\n", *S); + ERROR("S (%d) is out-of-range {0,1,2,3}", *S); return false; } if (*L < 3 || *L > 14) { - ERROR("L (%d) is out-of-range {3,...,14}\n", *L); + ERROR("L (%d) is out-of-range {3,...,14}", *L); return false; } uint32_t sum = *S + *L; if (sum < 3) { - ERROR("The sum of S (%d) and L (%d) is lower than 3\n", *S, *L); + ERROR("The sum of S (%d) and L (%d) is lower than 3", *S, *L); return false; } if (sum > 14) { - ERROR("The sum of S (%d) and L (%d) is greater than 14\n", *S, *L); + ERROR("The sum of S (%d) and L (%d) is greater than 14", *S, *L); return false; } @@ -64,7 +52,7 @@ static bool check_time_ra_typeA(uint32_t* S, uint32_t* L) static bool check_time_ra_typeB(uint32_t* S, uint32_t* L) { - ERROR("Not implemented\n"); + ERROR("Not implemented"); return false; } @@ -84,12 +72,12 @@ int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_ } if (m >= SRSLTE_MAX_NOF_DL_ALLOCATION) { - ERROR("m (%d) is out-of-range\n", m); + ERROR("m (%d) is out-of-range", m); return SRSLTE_ERROR_INVALID_INPUTS; } // Select k0 - grant->k0 = 0; + grant->k = 0; // Select PDSCH mapping static srslte_sch_mapping_type_t pdsch_mapping_lut[16] = {srslte_sch_mapping_type_A, @@ -117,7 +105,6 @@ int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_ // Select start symbol (S) and length (L) switch (dmrs_typeA_pos) { - case srslte_dmrs_sch_typeA_pos_2: grant->S = S_pos2[m]; grant->L = L_pos2[m]; @@ -127,71 +114,104 @@ int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_ grant->L = L_pos3[m]; break; default: - ERROR("Undefined case (%d)\n", dmrs_typeA_pos); + ERROR("Undefined case (%d)", dmrs_typeA_pos); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } -void srslte_ra_dl_nr_time_hl(const srslte_pdsch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant) +static void ra_dl_nr_time_hl(const srslte_sch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant) { // Compute S and L from SLIV from higher layers - sliv_to_s_and_l(hl_ra_cfg->sliv, &grant->S, &grant->L); - grant->k0 = hl_ra_cfg->k0; + ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L); + + grant->k = hl_ra_cfg->k; grant->mapping = hl_ra_cfg->mapping_type; } -int srslte_ra_dl_nr_time(const srslte_sch_cfg_nr_t* cfg, +int srslte_ra_dl_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, const srslte_rnti_type_t rnti_type, const srslte_search_space_type_t ss_type, + const uint32_t coreset_id, const uint8_t m, srslte_sch_grant_nr_t* grant) { - if (cfg == NULL || grant == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } if (m >= SRSLTE_MAX_NOF_DL_ALLOCATION) { - ERROR("m (%d) is out-of-range\n", m); + ERROR("m (%d) is out-of-range", m); return SRSLTE_ERROR_INVALID_INPUTS; } - // Determine which PDSCH Time domain RA configuration to apply (Table 5.1.2.1.1-1) - if (cfg->pdsch_time_is_default) { - // Note: Only Default A is supported, which corresponds SS/PBCH block and coreset mux pattern 1 - srslte_ra_dl_nr_time_default_A(m, cfg->dmrs_typeA.typeA_pos, grant); + // Determine which PDSCH Time domain RA configuration to apply (TS 38.214 Table 5.1.2.1.1-1) + if (rnti_type == srslte_rnti_type_si && ss_type == srslte_search_space_type_common_0) { + // Row 1 + ERROR("Row not implemented"); + } else if (rnti_type == srslte_rnti_type_si && ss_type == srslte_search_space_type_common_0A) { + // Row 2 + ERROR("Row not implemented"); + } else if ((rnti_type == srslte_rnti_type_ra || rnti_type == srslte_rnti_type_tc) && + ss_type == srslte_search_space_type_common_1) { + // Row 3 + if (cfg->nof_common_time_ra > 0) { + ra_dl_nr_time_hl(&cfg->common_time_ra[m], grant); + } else { + // Note: Only Default A is supported, which corresponds SS/PBCH block and coreset mux pattern 1 + srslte_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant); + } + } else if (rnti_type == srslte_rnti_type_p && ss_type == srslte_search_space_type_common_2) { + // Row 4 + ERROR("Row not implemented"); + } else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c || + rnti_type == srslte_rnti_type_cs) && + SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id == 0) { + // Row 5 + if (cfg->nof_common_time_ra > 0) { + ra_dl_nr_time_hl(&cfg->common_time_ra[m], grant); + } else { + srslte_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant); + } + } else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c || + rnti_type == srslte_rnti_type_cs) && + ((SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id != 0) || ss_type == srslte_search_space_type_ue)) { + // Row 6 + if (cfg->nof_dedicated_time_ra > 0) { + ra_dl_nr_time_hl(&cfg->dedicated_time_ra[m], grant); + } else if (cfg->nof_common_time_ra > 0) { + ra_dl_nr_time_hl(&cfg->common_time_ra[m], grant); + } else { + srslte_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant); + } } else { - srslte_ra_dl_nr_time_hl(&cfg->pdsch_time_ra[m], grant); + ERROR("Unhandled case"); } // Validate S and L parameters if (!srslte_ra_dl_nr_time_validate(grant)) { - ERROR("Invalid Time RA\n"); + ERROR("Invalid Time RA S=%d; L=%d; m=%d", grant->S, grant->L, m); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } -int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_sch_cfg_nr_t* pdsch_cfg, - srslte_sch_grant_nr_t* grant) +int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_dmrs_sch_cfg_t* cfg, + srslte_sch_grant_nr_t* grant) { - if (pdsch_cfg == NULL || grant == NULL) { + if (cfg == NULL || grant == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - const srslte_dmrs_sch_cfg_t* dmrs_cfg = - grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; - /* According to TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility: * When receiving PDSCH scheduled by DCI format 1_0, the UE shall assume the number of DM-RS CDM groups without data - * is 1 which corresponds to CDM group 0 for the case of PDSCH with allocation duration of 2 symbols, and the UE shall - * assume that the number of DM-RS CDM groups without data is 2 which corresponds to CDM group {0,1} for all other - * cases. + * is 1 which corresponds to CDM group 0 for the case of PDSCH with allocation duration of 2 symbols, and the UE + * shall assume that the number of DM-RS CDM groups without data is 2 which corresponds to CDM group {0,1} for all + * other cases. */ - if (dmrs_cfg->length == srslte_dmrs_sch_len_2) { + if (cfg->length == srslte_dmrs_sch_len_2) { grant->nof_dmrs_cdm_groups_without_data = 1; } else { grant->nof_dmrs_cdm_groups_without_data = 2; @@ -214,10 +234,10 @@ uint32_t srslte_ra_dl_nr_type0_P(uint32_t bwp_size, bool config_is_1) } } -static int ra_freq_type0(const srslte_carrier_nr_t* carrier, - const srslte_sch_cfg_nr_t* cfg, - const srslte_dci_dl_nr_t* dci_dl, - srslte_sch_grant_nr_t* grant) +static int ra_freq_type0(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_sch_grant_nr_t* grant) { uint32_t P = srslte_ra_dl_nr_type0_P(carrier->nof_prb, cfg->rbg_size_cfg_1); @@ -243,23 +263,22 @@ static int ra_freq_type0(const srslte_carrier_nr_t* carrier, return 0; } -int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier, - const srslte_sch_cfg_nr_t* cfg, - const srslte_dci_dl_nr_t* dci_dl, - srslte_sch_grant_nr_t* grant) +int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_sch_grant_nr_t* grant) { - if (cfg == NULL || grant == NULL || dci_dl == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } // RA scheme if (dci_dl->format == srslte_dci_format_nr_1_0) { - ra_freq_type0(carrier, cfg, dci_dl, grant); - } else { - ERROR("Only DCI Format 1_0 is supported\n"); - return SRSLTE_ERROR; + // when the scheduling grant is received with DCI format 1_0 , then downlink resource allocation type 1 is used. + return ra_helper_freq_type1(carrier->nof_prb, dci_dl->freq_domain_assigment, grant); } - return SRSLTE_SUCCESS; + ra_freq_type0(carrier, cfg, dci_dl, grant); + ERROR("Only DCI Format 1_0 is supported"); + return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/ra_helper.h b/lib/src/phy/phch/ra_helper.h new file mode 100644 index 000000000..0e27b6216 --- /dev/null +++ b/lib/src/phy/phch/ra_helper.h @@ -0,0 +1,59 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_RA_HELPER_H +#define SRSLTE_RA_HELPER_H + +#include "srslte/phy/utils/debug.h" +#include + +static inline void ra_helper_compute_s_and_l(uint32_t N, uint32_t v, uint32_t* S, uint32_t* L) +{ + uint32_t low = v % N; + uint32_t high = v / N; + if (high + 1 + low <= N) { + *S = low; + *L = high + 1; + } else { + *S = N - 1 - low; + *L = N - high + 1; + } +} + +static int ra_helper_freq_type1(uint32_t N_bwp_size, uint32_t riv, srslte_sch_grant_nr_t* grant) +{ + uint32_t start = 0; + uint32_t len = 0; + ra_helper_compute_s_and_l(N_bwp_size, riv, &start, &len); + + if (start + len > N_bwp_size) { + ERROR("RIV 0x%x for BWP size %d resulted in freq=%d:%d", riv, N_bwp_size, start, len); + return SRSLTE_ERROR; + } + + for (uint32_t i = 0; i < start; i++) { + grant->prb_idx[i] = false; + } + + for (uint32_t i = start; i < start + len; i++) { + grant->prb_idx[i] = true; + } + + for (uint32_t i = start + len; i < SRSLTE_MAX_PRB_NR; i++) { + grant->prb_idx[i] = false; + } + grant->nof_prb = len; + + return SRSLTE_SUCCESS; +} + +#endif // SRSLTE_RA_HELPER_H diff --git a/lib/src/phy/phch/ra_nbiot.c b/lib/src/phy/phch/ra_nbiot.c index 8a6dd12de..5ccad883f 100644 --- a/lib/src/phy/phch/ra_nbiot.c +++ b/lib/src/phy/phch/ra_nbiot.c @@ -151,7 +151,7 @@ static int nbiot_dl_dci_to_grant_mcs(srslte_ra_nbiot_dl_dci_t* dci, srslte_ra_nb } if (tbs <= 0) { - INFO("Unsupported resource allocation specified: i_tbs=%d [0,12], i_sf=%d [0,7]\n", i_tbs, i_sf); + INFO("Unsupported resource allocation specified: i_tbs=%d [0,12], i_sf=%d [0,7]", i_tbs, i_sf); return SRSLTE_ERROR; } else { grant->mcs[0].tbs = (uint32_t)tbs; @@ -480,7 +480,7 @@ int srslte_ra_nbiot_ul_dci_to_grant(srslte_ra_nbiot_ul_dci_t* dci, } else if (grant->nof_sc == 12) { grant->nof_slots = 2; } else { - DEBUG("Unsupported value for N_sc_RU=%d\n", grant->nof_sc); + DEBUG("Unsupported value for N_sc_RU=%d", grant->nof_sc); } break; case SRSLTE_NPUSCH_FORMAT2: diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 3a9af3a6c..01c6e9364 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -22,6 +22,7 @@ #include "srslte/phy/phch/ra_nr.h" #include "srslte/phy/phch/pdsch_nr.h" #include "srslte/phy/phch/ra_dl_nr.h" +#include "srslte/phy/phch/ra_ul_nr.h" #include "srslte/phy/utils/debug.h" typedef struct { @@ -148,7 +149,7 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srslte_mcs_table_t // - the UE is configured with MCS-C-RNTI, and // - the PUSCH is scheduled by a PDCCH with // - CRC scrambled by MCS-C-RNTI, - if (mcs_c_rnti && dci_format != srslte_dci_format_nr_rar && rnti_type == srslte_rnti_type_mcs_crnti) { + if (mcs_c_rnti && dci_format != srslte_dci_format_nr_rar && rnti_type == srslte_rnti_type_mcs_c) { return ra_nr_table_3; } @@ -224,7 +225,6 @@ static ra_nr_table_t ra_nr_select_table(srslte_mcs_table_t mcs_table, srslte_search_space_type_t search_space_type, srslte_rnti_type_t rnti_type) { - // Check if it is a PUSCH transmission if (dci_format == srslte_dci_format_nr_0_0 || dci_format == srslte_dci_format_nr_0_1 || dci_format == srslte_dci_format_nr_rar || dci_format == srslte_dci_format_nr_cg) { @@ -250,7 +250,7 @@ double srslte_ra_nr_R_from_mcs(srslte_mcs_table_t mcs_table, case ra_nr_table_3: return srslte_ra_nr_R_from_mcs_table3(mcs_idx) / 1024.0; default: - ERROR("Invalid table %d\n", table); + ERROR("Invalid table %d", table); } return NAN; @@ -272,7 +272,7 @@ srslte_mod_t srslte_ra_nr_mod_from_mcs(srslte_mcs_table_t mcs_table, case ra_nr_table_3: return srslte_ra_nr_modulation_from_mcs_table3(mcs_idx); default: - ERROR("Invalid table %d\n", table); + ERROR("Invalid table %d", table); } return SRSLTE_MOD_NITEMS; @@ -284,9 +284,9 @@ int srslte_ra_dl_nr_slot_nof_re(const srslte_sch_cfg_nr_t* pdsch_cfg, const srsl int n_sh_symb = grant->L; // the number of REs for DM-RS per PRB in the scheduled duration - int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(pdsch_cfg, grant); + int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(&pdsch_cfg->dmrs, grant); if (n_prb_dmrs < SRSLTE_SUCCESS) { - ERROR("Invalid number of DMRS RE\n"); + ERROR("Invalid number of DMRS RE"); return SRSLTE_ERROR; } @@ -382,7 +382,7 @@ uint32_t srslte_ra_nr_tbs(uint32_t N_re, double S, double R, uint32_t Qm, uint32 } if (nof_layers == 0) { - ERROR("Incorrect number of layers (%d). Setting to 1.\n", nof_layers); + ERROR("Incorrect number of layers (%d). Setting to 1.", nof_layers); nof_layers = 1; } @@ -443,7 +443,7 @@ int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg, // 1) The UE shall first determine the number of REs (N RE ) within the slot. int N_re = srslte_ra_dl_nr_slot_nof_re(pdsch_cfg, grant); if (N_re <= SRSLTE_SUCCESS) { - ERROR("Invalid number of RE\n"); + ERROR("Invalid number of RE"); return SRSLTE_ERROR; } @@ -464,42 +464,185 @@ int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg, return SRSLTE_SUCCESS; } -int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, - const srslte_sch_cfg_nr_t* pdsch_cfg, - const srslte_dci_dl_nr_t* dci_dl, - srslte_sch_grant_nr_t* pdsch_grant) +static int ra_dl_dmrs(const srslte_sch_hl_cfg_nr_t* pdsch_hl_cfg, + srslte_sch_grant_nr_t* pdsch_grant, + srslte_dmrs_sch_cfg_t* dmrs_cfg) { - // Time domain resource allocation - if (srslte_ra_dl_nr_time( - pdsch_cfg, dci_dl->rnti_type, dci_dl->search_space.type, dci_dl->time_domain_assigment, pdsch_grant) < - SRSLTE_SUCCESS) { - ERROR("Error computing time domain resource allocation\n"); + const bool dedicated_dmrs_present = (pdsch_grant->mapping == srslte_sch_mapping_type_A) + ? pdsch_hl_cfg->dmrs_typeA.present + : pdsch_hl_cfg->dmrs_typeB.present; + + if (pdsch_grant->dci_format == srslte_dci_format_nr_1_0 || !dedicated_dmrs_present) { + if (pdsch_grant->mapping == srslte_sch_mapping_type_A) { + // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig + dmrs_cfg->additional_pos = srslte_dmrs_sch_add_pos_2; + dmrs_cfg->type = srslte_dmrs_sch_type_1; + dmrs_cfg->length = srslte_dmrs_sch_len_1; + dmrs_cfg->scrambling_id0_present = false; + dmrs_cfg->scrambling_id1_present = false; + + if (pdsch_grant->dci_format == srslte_dci_format_nr_1_0) { + if (srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(dmrs_cfg, pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading number of DMRS CDM groups"); + return SRSLTE_ERROR; + } + } else { + ERROR("Invalid case"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; + } + + ERROR("Unsupported configuration"); return SRSLTE_ERROR; } - // Frequency domain resource allocation - if (srslte_ra_dl_nr_freq(carrier, pdsch_cfg, dci_dl, pdsch_grant) < SRSLTE_SUCCESS) { - ERROR("Error computing time domain resource allocation\n"); + return SRSLTE_ERROR; +} + +int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* pdsch_hl_cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_sch_cfg_nr_t* pdsch_cfg, + srslte_sch_grant_nr_t* pdsch_grant) +{ + // 5.2.1.1 Resource allocation in time domain + if (srslte_ra_dl_nr_time(pdsch_hl_cfg, + dci_dl->rnti_type, + dci_dl->search_space, + dci_dl->coreset_id, + dci_dl->time_domain_assigment, + pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error computing time domain resource allocation"); return SRSLTE_ERROR; } - //??? - if (srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(pdsch_cfg, pdsch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups\n"); + // 5.1.2.2 Resource allocation in frequency domain + if (srslte_ra_dl_nr_freq(carrier, pdsch_hl_cfg, dci_dl, pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error computing frequency domain resource allocation"); return SRSLTE_ERROR; } + // 5.1.2.3 Physical resource block (PRB) bundling + // ... + pdsch_grant->nof_layers = 1; pdsch_grant->dci_format = dci_dl->format; pdsch_grant->rnti = dci_dl->rnti; + pdsch_grant->rnti_type = dci_dl->rnti_type; + pdsch_grant->tb[0].rv = dci_dl->rv; - for (uint32_t i = 0; i < carrier->nof_prb; i++) { - pdsch_grant->prb_idx[i] = true; + // 5.1.6.2 DM-RS reception procedure + if (ra_dl_dmrs(pdsch_hl_cfg, pdsch_grant, &pdsch_cfg->dmrs) < SRSLTE_SUCCESS) { + ERROR("Error selecting DMRS configuration"); + return SRSLTE_ERROR; } - // Compute TB size + // 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination if (srslte_ra_nr_fill_tb(pdsch_cfg, pdsch_grant, dci_dl->mcs, &pdsch_grant->tb[0]) < SRSLTE_SUCCESS) { - ERROR("Error filing tb\n"); + ERROR("Error filing tb"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +static int +ra_ul_dmrs(const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg, srslte_sch_grant_nr_t* pusch_grant, srslte_sch_cfg_nr_t* cfg) +{ + const bool dedicated_dmrs_present = (pusch_grant->mapping == srslte_sch_mapping_type_A) + ? pusch_hl_cfg->dmrs_typeA.present + : pusch_hl_cfg->dmrs_typeB.present; + + if (pusch_grant->dci_format == srslte_dci_format_nr_0_0 || !dedicated_dmrs_present) { + if (pusch_grant->mapping == srslte_sch_mapping_type_A) { + // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig + cfg->dmrs.additional_pos = srslte_dmrs_sch_add_pos_2; + cfg->dmrs.type = srslte_dmrs_sch_type_1; + cfg->dmrs.length = srslte_dmrs_sch_len_1; + cfg->dmrs.scrambling_id0_present = false; + cfg->dmrs.scrambling_id1_present = false; + } else { + ERROR("Unsupported configuration"); + return SRSLTE_ERROR; + } + } else { + if (pusch_grant->mapping == srslte_sch_mapping_type_A) { + cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeA.additional_pos; + cfg->dmrs.type = pusch_hl_cfg->dmrs_typeA.type; + cfg->dmrs.length = pusch_hl_cfg->dmrs_typeA.length; + cfg->dmrs.scrambling_id0_present = false; + cfg->dmrs.scrambling_id1_present = false; + } else { + cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeB.additional_pos; + cfg->dmrs.type = pusch_hl_cfg->dmrs_typeB.type; + cfg->dmrs.length = pusch_hl_cfg->dmrs_typeB.length; + cfg->dmrs.scrambling_id0_present = false; + cfg->dmrs.scrambling_id1_present = false; + } + } + + // Set number of DMRS CDM groups without data + if (pusch_grant->dci_format == srslte_dci_format_nr_0_0) { + if (srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(cfg, pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading number of DMRS CDM groups"); + return SRSLTE_ERROR; + } + } else { + ERROR("Invalid case"); + return SRSLTE_ERROR; + } + + // Set DMRS power offset Table 6.2.2-1: The ratio of PUSCH EPRE to DM-RS EPRE + if (srslte_ra_ul_nr_dmrs_power_offset(pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error setting DMRS power offset"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg, + const srslte_dci_ul_nr_t* dci_ul, + srslte_sch_cfg_nr_t* pusch_cfg, + srslte_sch_grant_nr_t* pusch_grant) +{ + // 5.2.1.1 Resource allocation in time domain + if (srslte_ra_ul_nr_time(pusch_hl_cfg, + dci_ul->rnti_type, + dci_ul->search_space, + dci_ul->coreset_id, + dci_ul->time_domain_assigment, + pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error computing time domain resource allocation"); + return SRSLTE_ERROR; + } + + // 5.1.2.2 Resource allocation in frequency domain + if (srslte_ra_ul_nr_freq(carrier, pusch_hl_cfg, dci_ul, pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error computing frequency domain resource allocation"); + return SRSLTE_ERROR; + } + + // 5.1.2.3 Physical resource block (PRB) bundling + // ... + + pusch_grant->nof_layers = 1; + pusch_grant->dci_format = dci_ul->format; + pusch_grant->rnti = dci_ul->rnti; + pusch_grant->rnti_type = dci_ul->rnti_type; + + // 5.1.6.2 DM-RS reception procedure + if (ra_ul_dmrs(pusch_hl_cfg, pusch_grant, pusch_cfg) < SRSLTE_SUCCESS) { + ERROR("Error selecting DMRS configuration"); + return SRSLTE_ERROR; + } + + // 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination + if (srslte_ra_nr_fill_tb(pusch_cfg, pusch_grant, dci_ul->mcs, &pusch_grant->tb[0]) < SRSLTE_SUCCESS) { + ERROR("Error filing tb"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/ra_ul.c b/lib/src/phy/phch/ra_ul.c index 07e1592b1..50b7a0046 100644 --- a/lib/src/phy/phch/ra_ul.c +++ b/lib/src/phy/phch/ra_ul.c @@ -80,14 +80,12 @@ static void compute_freq_hopping(srslte_ra_ul_pusch_hopping_t* q, srslte_pusch_hopping_cfg_t* hopping_cfg, srslte_pusch_grant_t* grant) { - if (q->cell.frame_type == SRSLTE_TDD) { - ERROR("Error frequency hopping for TDD not implemented (c_init for each subframe, see end of 5.3.4 36.211)\n"); + ERROR("Error frequency hopping for TDD not implemented (c_init for each subframe, see end of 5.3.4 36.211)"); } for (uint32_t slot = 0; slot < 2; slot++) { - - INFO("PUSCH Freq hopping: %d\n", grant->freq_hopping); + INFO("PUSCH Freq hopping: %d", grant->freq_hopping); uint32_t n_prb_tilde = grant->n_prb[slot]; if (grant->freq_hopping == 1) { @@ -117,7 +115,7 @@ static void compute_freq_hopping(srslte_ra_ul_pusch_hopping_t* q, 2 * (n_vrb_tilde % n_rb_sb) * f_m(q, hopping_cfg, i, hopping_cfg->current_tx_nb)) % (n_rb_sb * hopping_cfg->n_sb); - INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n", + INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d", n_prb_tilde, n_vrb_tilde, n_rb_sb, @@ -155,7 +153,7 @@ static int ra_ul_grant_to_grant_prb_allocation(srslte_dci_ul_t* dci, } else { grant->freq_hopping = 2; } - INFO("prb1: %d, prb2: %d, L: %d\n", grant->n_prb[0], grant->n_prb[1], grant->L_prb); + INFO("prb1: %d, prb2: %d, L: %d", grant->n_prb[0], grant->n_prb[1], grant->L_prb); } else { /* Type1 frequency hopping as defined in 8.4.1 of 36.213 * frequency offset between 1st and 2nd slot is fixed. @@ -165,7 +163,7 @@ static int ra_ul_grant_to_grant_prb_allocation(srslte_dci_ul_t* dci, // starting prb idx for slot 0 is as given by resource dci grant->n_prb[0] = n_prb_1; if (n_prb_1 < n_rb_ho / 2) { - INFO("Invalid Frequency Hopping parameters. Offset: %d, n_prb_1: %d\n", n_rb_ho, n_prb_1); + INFO("Invalid Frequency Hopping parameters. Offset: %d, n_prb_1: %d", n_rb_ho, n_prb_1); return SRSLTE_ERROR; } uint32_t n_prb_1_tilde = n_prb_1; @@ -188,7 +186,7 @@ static int ra_ul_grant_to_grant_prb_allocation(srslte_dci_ul_t* dci, default: break; } - INFO("n_rb_pusch: %d, prb1: %d, prb2: %d, L: %d\n", n_rb_pusch, grant->n_prb[0], grant->n_prb[1], grant->L_prb); + INFO("n_rb_pusch: %d, prb1: %d, prb2: %d, L: %d", n_rb_pusch, grant->n_prb[0], grant->n_prb[1], grant->L_prb); grant->freq_hopping = 1; } @@ -214,7 +212,7 @@ static void ul_fill_ra_mcs(srslte_ra_tb_t* tb, srslte_ra_tb_t* last_tb, uint32_t tb->mod = SRSLTE_MOD_64QAM; tb->tbs = srslte_ra_tbs_from_idx(tb->mcs_idx - 2, L_prb); } else { - ERROR("Invalid MCS index %d\n", tb->mcs_idx); + ERROR("Invalid MCS index %d", tb->mcs_idx); } } else if (tb->mcs_idx == 29 && cqi_request && L_prb <= 4) { // 8.6.1 and 8.6.2 36.213 second paragraph @@ -253,7 +251,7 @@ int srslte_ra_ul_pusch_hopping_init(srslte_ra_ul_pusch_hopping_t* q, srslte_cell q->initialized = true; /* Precompute sequence for type2 frequency hopping */ if (srslte_sequence_LTE_pr(&q->seq_type2_fo, 210, q->cell.id)) { - ERROR("Error initiating type2 frequency hopping sequence\n"); + ERROR("Error initiating type2 frequency hopping sequence"); return SRSLTE_ERROR; } ret = SRSLTE_SUCCESS; @@ -288,10 +286,8 @@ int srslte_ra_ul_dci_to_grant(srslte_cell_t* cell, srslte_dci_ul_t* dci, srslte_pusch_grant_t* grant) { - // Compute PRB allocation if (!ra_ul_grant_to_grant_prb_allocation(dci, grant, hopping_cfg->n_rb_ho, cell->nof_prb)) { - // copy default values from DCI. RV can be updated by ul_fill_ra_mcs() in case of Adaptive retx (mcs>28) grant->tb.mcs_idx = dci->tb.mcs_idx; grant->tb.rv = dci->tb.rv; @@ -299,18 +295,18 @@ int srslte_ra_ul_dci_to_grant(srslte_cell_t* cell, // Compute MCS ul_fill_ra_mcs(&grant->tb, &grant->last_tb, grant->L_prb, dci->cqi_request); - /* Compute RE assuming shortened is false*/ srslte_ra_ul_compute_nof_re(grant, cell->cp, 0); - // TODO: Need to compute hopping here before determining if there is collision with SRS, but only MAC knows if it's a + // TODO: Need to compute hopping here before determining if there is collision with SRS, but only MAC knows if it's + // a // new tx or a retx. Need to split MAC interface in 2 calls. For now, assume hopping is the same for (uint32_t i = 0; i < 2; i++) { grant->n_prb_tilde[i] = grant->n_prb[i]; } if (grant->nof_symb == 0 || grant->nof_re == 0) { - INFO("Error converting ul_dci to grant, nof_symb=%d, nof_re=%d\n", grant->nof_symb, grant->nof_re); + INFO("Error converting ul_dci to grant, nof_symb=%d, nof_re=%d", grant->nof_symb, grant->nof_re); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index dfc168954..aa3c20024 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -20,9 +20,233 @@ */ #include "srslte/phy/phch/ra_ul_nr.h" +#include "ra_helper.h" #include "srslte/phy/ch_estimation/dmrs_pucch.h" #include "srslte/phy/common/phy_common.h" #include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/vector.h" + +typedef struct { + srslte_sch_mapping_type_t mapping; + uint32_t K2; + uint32_t S; + uint32_t L; +} ue_ra_time_resource_t; + +static const ue_ra_time_resource_t ue_ul_default_A_lut[16] = {{srslte_sch_mapping_type_A, 0, 0, 14}, + {srslte_sch_mapping_type_A, 0, 0, 12}, + {srslte_sch_mapping_type_A, 0, 0, 10}, + {srslte_sch_mapping_type_B, 0, 2, 10}, + {srslte_sch_mapping_type_B, 0, 4, 10}, + {srslte_sch_mapping_type_B, 0, 4, 8}, + {srslte_sch_mapping_type_B, 0, 4, 6}, + {srslte_sch_mapping_type_A, 1, 0, 14}, + {srslte_sch_mapping_type_A, 1, 0, 12}, + {srslte_sch_mapping_type_A, 1, 0, 10}, + {srslte_sch_mapping_type_A, 2, 0, 14}, + {srslte_sch_mapping_type_A, 2, 0, 12}, + {srslte_sch_mapping_type_A, 2, 0, 10}, + {srslte_sch_mapping_type_B, 0, 8, 6}, + {srslte_sch_mapping_type_A, 3, 0, 14}, + {srslte_sch_mapping_type_A, 3, 0, 10}}; + +int srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant) +{ + uint32_t j[4] = {1, 1, 2, 3}; + + if (grant == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (scs_cfg > 4) { + ERROR("Invalid numerology (%d)", scs_cfg); + return SRSLTE_ERROR; + } + + if (m >= 16) { + ERROR("m (%d) is out-of-range", m); + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Select mapping + grant->mapping = ue_ul_default_A_lut[m].mapping; + grant->k = ue_ul_default_A_lut[m].K2 + j[scs_cfg]; + grant->S = ue_ul_default_A_lut[m].S; + grant->L = ue_ul_default_A_lut[m].L; + + return SRSLTE_SUCCESS; +} + +static void ra_ul_nr_time_hl(const srslte_sch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant) +{ + // Compute S and L from SLIV from higher layers + ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L); + + grant->k = hl_ra_cfg->k; + grant->mapping = hl_ra_cfg->mapping_type; +} + +// Validate S and L combination for TypeA time domain resource allocation +static bool check_time_ra_typeA(uint32_t* S, uint32_t* L) +{ + // Check values using Table 5.1.2.1-1 + if (*S != 0) { + ERROR("S (%d) is out-of-range {0}", *S); + return false; + } + + if (*L < 4 || *L > 14) { + ERROR("L (%d) is out-of-range {4,...,14}", *L); + return false; + } + + uint32_t sum = *S + *L; + if (sum < 4) { + ERROR("The sum of S (%d) and L (%d) is lower than 4", *S, *L); + return false; + } + + if (sum > 14) { + ERROR("The sum of S (%d) and L (%d) is greater than 14", *S, *L); + return false; + } + + return true; +} + +static bool check_time_ra_typeB(uint32_t* S, uint32_t* L) +{ + ERROR("Not implemented"); + return false; +} + +bool srslte_ra_ul_nr_time_validate(srslte_sch_grant_nr_t* grant) +{ + if (grant->mapping == srslte_sch_mapping_type_A) { + return check_time_ra_typeA(&grant->S, &grant->L); + } + + return check_time_ra_typeB(&grant->S, &grant->L); +} + +int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_rnti_type_t rnti_type, + const srslte_search_space_type_t ss_type, + const uint32_t coreset_id, + const uint8_t m, + srslte_sch_grant_nr_t* grant) +{ + if (cfg == NULL || grant == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (m >= SRSLTE_MAX_NOF_DL_ALLOCATION) { + ERROR("m (%d) is out-of-range", m); + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Determine which PUSCH Time domain RA configuration to apply (TS 38.214 Table 6.1.2.1.1-1:) + if (ss_type == srslte_search_space_type_rar) { + // Row 1 + if (cfg->nof_common_time_ra == 0) { + srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant); + } else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION && m < cfg->nof_common_time_ra) { + ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant); + } else { + ERROR("Time domain resource selection (m=%d) exceeds the maximum value (%d)", + m, + SRSLTE_MIN(cfg->nof_common_time_ra, SRSLTE_MAX_NOF_DL_ALLOCATION)); + } + } else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c || + rnti_type == srslte_rnti_type_tc || rnti_type == srslte_rnti_type_cs) && + SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id == 0) { + // Row 2 + if (cfg->nof_common_time_ra == 0) { + srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant); + } else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION) { + ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant); + } + } else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c || + rnti_type == srslte_rnti_type_tc || rnti_type == srslte_rnti_type_cs || + rnti_type == srslte_rnti_type_sp_csi) && + ((SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id != 0) || ss_type == srslte_search_space_type_ue)) { + // Row 3 + if (cfg->nof_dedicated_time_ra > 0) { + ra_ul_nr_time_hl(&cfg->dedicated_time_ra[m], grant); + } else if (cfg->nof_common_time_ra > 0) { + ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant); + } else { + srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant); + } + } else { + ERROR("Unhandled case"); + } + + // Table 6.1.2.1.1-5 defines the additional subcarrier spacing specific slot delay value for the first transmission of + // PUSCH scheduled by the RAR. When the UE transmits a PUSCH scheduled by RAR, the Δ value specific to the PUSCH + // subcarrier spacing μ PUSCH is applied in addition to the K 2 value. + if (ss_type == srslte_search_space_type_rar) { + uint32_t delta[4] = {2, 3, 4, 6}; + if (cfg->scs_cfg >= 4) { + ERROR("Invalid numerology"); + return SRSLTE_ERROR; + } + grant->k += delta[cfg->scs_cfg]; + } + + // Validate S and L parameters + if (!srslte_ra_ul_nr_time_validate(grant)) { + ERROR("Invalid Time RA S=%d; L=%d; m=%d", grant->S, grant->L, m); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg, + srslte_sch_grant_nr_t* grant) +{ + if (cfg == NULL || grant == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + /* According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure: + * For PUSCH scheduled by DCI format 0_0 or by activation DCI format 0_0 with CRC scrambled by CS-RNTI, the UE + * shall assume the number of DM-RS CDM groups without data is 1 which corresponds to CDM group 0 for the case of + * PUSCH with allocation duration of 2 or less OFDM symbols with transform precoding disabled, the UE shall assume + * that the number of DM-RS CDM groups without data is 3 which corresponds to CDM group {0,1,2} for the case of PUSCH + * scheduled by activation DCI format 0_0 and the dmrs-Type in cg-DMRS-Configuration equal to 'type2' and the PUSCH + * allocation duration being more than 2 OFDM symbols, and the UE shall assume that the number of DM-RS CDM groups + * without data is 2 which corresponds to CDM group {0,1} for all other cases. + */ + if (grant->L <= 2 && !cfg->enable_transform_precoder) { + grant->nof_dmrs_cdm_groups_without_data = 1; + // } else if (grant->L > 2 && cfg->dmrs_cg.type == srslte_dmrs_sch_type_2){ + // grant->nof_dmrs_cdm_groups_without_data = 3; + } else { + grant->nof_dmrs_cdm_groups_without_data = 2; + } + + return SRSLTE_SUCCESS; +} + +int srslte_ra_ul_nr_dmrs_power_offset(srslte_sch_grant_nr_t* grant) +{ + if (grant == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + float ratio_dB[3] = {0, -3, -4.77}; + + if (grant->nof_dmrs_cdm_groups_without_data < 1 || grant->nof_dmrs_cdm_groups_without_data > 3) { + ERROR("Invalid number of DMRS CDM groups without data (%d)", grant->nof_dmrs_cdm_groups_without_data); + return SRSLTE_ERROR; + } + + grant->beta_dmrs = srslte_convert_dB_to_amplitude(-ratio_dB[grant->nof_dmrs_cdm_groups_without_data - 1]); + + return SRSLTE_SUCCESS; +} #define RA_UL_PUCCH_CODE_RATE_N 8 #define RA_UL_PUCCH_CODE_RATE_RESERVED NAN @@ -34,7 +258,7 @@ static const double ra_ul_pucch_code_rate_table[RA_UL_PUCCH_CODE_RATE_N] = static double ra_ul_nr_pucch_code_rate_r(const srslte_pucch_nr_resource_t* resource) { if (resource->max_code_rate >= RA_UL_PUCCH_CODE_RATE_RESERVED) { - ERROR("Invalid code rate\n"); + ERROR("Invalid code rate"); return RA_UL_PUCCH_CODE_RATE_RESERVED; } @@ -51,7 +275,7 @@ static double ra_ul_nr_pucch_code_rate_r(const srslte_pucch_nr_resource_t* resou // case SRSLTE_PUCCH_NR_FORMAT_4: // return SRSLTE_PUCCH_NR_FORMAT4_NPRB; // default: -// ERROR("Invalid case\n"); +// ERROR("Invalid case"); // break; // } // return SRSLTE_ERROR; @@ -68,7 +292,7 @@ static int ra_ul_nr_pucch_nre(const srslte_pucch_nr_resource_t* resource) case SRSLTE_PUCCH_NR_FORMAT_4: return SRSLTE_NRE / resource->occ_lenth; default: - ERROR("Invalid case\n"); + ERROR("Invalid case"); break; } return SRSLTE_ERROR; @@ -93,7 +317,7 @@ static int ra_ul_nr_pucch_nsymb(const srslte_pucch_nr_resource_t* resource) return (int)resource->nof_symbols - nsymb_dmrs; } default: - ERROR("Invalid case\n"); + ERROR("Invalid case"); break; } return SRSLTE_ERROR; @@ -109,7 +333,7 @@ static int ra_ul_nr_pucch_qm(const srslte_pucch_nr_resource_t* resource) case SRSLTE_PUCCH_NR_FORMAT_4: return resource->enable_pi_bpsk ? 1 : 2; default: - ERROR("Invalid case\n"); + ERROR("Invalid case"); break; } return SRSLTE_ERROR; @@ -125,28 +349,28 @@ int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* r // Get maximum allowed code rate double r = ra_ul_nr_pucch_code_rate_r(resource); if (!isnormal(r)) { - ERROR("Invalid coderate %f\n", r); + ERROR("Invalid coderate %f", r); return SRSLTE_ERROR; } // Get number of RE/PRB int nre = ra_ul_nr_pucch_nre(resource); if (nre < SRSLTE_SUCCESS) { - ERROR("Getting nre\n"); + ERROR("Getting nre"); return SRSLTE_ERROR; } // Get number of symbols int nsymb = ra_ul_nr_pucch_nsymb(resource); if (nsymb < SRSLTE_SUCCESS) { - ERROR("Getting nsymb\n"); + ERROR("Getting nsymb"); return SRSLTE_ERROR; } // Get modulation order int qm = ra_ul_nr_pucch_qm(resource); if (qm < SRSLTE_SUCCESS) { - ERROR("Getting qm\n"); + ERROR("Getting qm"); return SRSLTE_ERROR; } @@ -164,4 +388,89 @@ int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* r // Return the minimum return (int)ceil(O_total / nof_bits_rb); -} \ No newline at end of file +} + +int srslte_ra_ul_nr_freq(const srslte_carrier_nr_t* carrier, + const srslte_sch_hl_cfg_nr_t* cfg, + const srslte_dci_ul_nr_t* dci_ul, + srslte_sch_grant_nr_t* grant) +{ + if (cfg == NULL || grant == NULL || dci_ul == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // RA scheme + if (dci_ul->format == srslte_dci_format_nr_0_0) { + // when the scheduling grant is received with DCI format 1_0 , then downlink resource allocation type 1 is used. + return ra_helper_freq_type1(carrier->nof_prb, dci_ul->freq_domain_assigment, grant); + } + + ERROR("Only DCI Format 0_0 is supported"); + return SRSLTE_ERROR; +} + +// Implements TS 38.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration +static int ra_ul_nr_pucch_resource_default(uint32_t r_pucch, srslte_pucch_nr_resource_t* resource) +{ + ERROR("Not implemented"); + return SRSLTE_ERROR; +} + +static int ra_ul_nr_pucch_resource_hl(const srslte_pucch_nr_hl_cfg_t* cfg, + uint32_t O_uci, + uint32_t pucch_resource_id, + srslte_pucch_nr_resource_t* resource) +{ + uint32_t N2 = cfg->sets[1].max_payload_size > 0 ? cfg->sets[1].max_payload_size : SRSLTE_UCI_NR_MAX_NOF_BITS; + uint32_t N3 = cfg->sets[2].max_payload_size > 0 ? cfg->sets[2].max_payload_size : SRSLTE_UCI_NR_MAX_NOF_BITS; + + // If the UE transmits O UCI UCI information bits, that include HARQ-ACK information bits, the UE determines a PUCCH + // resource set to be... + uint32_t resource_set_id = 3; + if (O_uci <= 2 && cfg->sets[0].nof_resources > 0) { + resource_set_id = 0; + } else if (O_uci <= N2 && cfg->sets[1].nof_resources > 0) { + resource_set_id = 1; + } else if (O_uci <= N3 && cfg->sets[2].nof_resources > 0) { + resource_set_id = 2; + } else if (cfg->sets[3].nof_resources == 0) { + ERROR("Invalid PUCCH resource configuration, N3=%d, O_uci=%d", N3, O_uci); + return SRSLTE_ERROR; + } else if (O_uci > SRSLTE_UCI_NR_MAX_NOF_BITS) { + ERROR("The number of UCI bits (%d), exceeds the maximum (%d)", O_uci, SRSLTE_UCI_NR_MAX_NOF_BITS); + return SRSLTE_ERROR; + } + + // Select resource from the set + if (pucch_resource_id >= SRSLTE_PUCCH_NR_MAX_NOF_RESOURCES_PER_SET || + pucch_resource_id >= cfg->sets[resource_set_id].nof_resources) { + ERROR("The PUCCH resource identifier (%d) exceeds the number of configured resources (%d) for set identifier %d", + pucch_resource_id, + cfg->sets[resource_set_id].nof_resources, + resource_set_id); + return SRSLTE_ERROR; + } + *resource = cfg->sets[resource_set_id].resources[pucch_resource_id]; + + return SRSLTE_SUCCESS; +} + +int srslte_ra_ul_nr_pucch_resource(const srslte_pucch_nr_hl_cfg_t* pucch_cfg, + const srslte_uci_cfg_nr_t* uci_cfg, + srslte_pucch_nr_resource_t* resource) +{ + if (pucch_cfg == NULL || uci_cfg == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + uint32_t O_uci = srslte_uci_nr_total_bits(uci_cfg); + + // If a UE does not have dedicated PUCCH resource configuration, provided by PUCCH-ResourceSet in PUCCH-Config, + // a PUCCH resource set is provided by pucch-ResourceCommon through an index to a row of Table 9.2.1-1 for size + // transmission of HARQ-ACK information on PUCCH in an initial UL BWP of N BWP PRBs. + if (!pucch_cfg->enabled) { + uint32_t r_pucch = (2 * uci_cfg->n_cce_0) + 2 * uci_cfg->pucch_resource_id; + return ra_ul_nr_pucch_resource_default(r_pucch, resource); + } + return ra_ul_nr_pucch_resource_hl(pucch_cfg, O_uci, uci_cfg->pucch_resource_id, resource); +} diff --git a/lib/src/phy/phch/regs.c b/lib/src/phy/phch/regs.c index 08a97433d..9af0d0f87 100644 --- a/lib/src/phy/phch/regs.c +++ b/lib/src/phy/phch/regs.c @@ -126,7 +126,7 @@ int regs_pdcch_init(srslte_regs_t* h) } } h->pdcch[cfi].nof_regs = (h->pdcch[cfi].nof_regs / 9) * 9; - INFO("Init PDCCH REG space CFI %d. %d useful REGs (%d CCEs)\n", + INFO("Init PDCCH REG space CFI %d. %d useful REGs (%d CCEs)", cfi + 1, h->pdcch[cfi].nof_regs, h->pdcch[cfi].nof_regs / 9); @@ -148,7 +148,7 @@ clean_and_exit: int srslte_regs_pdcch_nregs(srslte_regs_t* h, uint32_t cfi) { if (cfi < 1 || cfi > 3) { - ERROR("Invalid CFI=%d\n", cfi); + ERROR("Invalid CFI=%d", cfi); return SRSLTE_ERROR; } else { return (int)h->pdcch[cfi - 1].nof_regs; @@ -177,7 +177,7 @@ int srslte_regs_pdcch_put_offset(srslte_regs_t* h, uint32_t nof_regs) { if (cfi < 1 || cfi > 3) { - ERROR("Invalid CFI=%d\n", cfi); + ERROR("Invalid CFI=%d", cfi); return SRSLTE_ERROR; } if (start_reg + nof_regs <= h->pdcch[cfi - 1].nof_regs) { @@ -189,7 +189,7 @@ int srslte_regs_pdcch_put_offset(srslte_regs_t* h, } return k; } else { - ERROR("Out of range: start_reg + nof_reg must be lower than %d\n", h->pdcch[cfi - 1].nof_regs); + ERROR("Out of range: start_reg + nof_reg must be lower than %d", h->pdcch[cfi - 1].nof_regs); return SRSLTE_ERROR; } } @@ -197,7 +197,7 @@ int srslte_regs_pdcch_put_offset(srslte_regs_t* h, int srslte_regs_pdcch_put(srslte_regs_t* h, uint32_t cfi, cf_t* d, cf_t* slot_symbols) { if (cfi < 1 || cfi > 3) { - ERROR("Invalid CFI=%d\n", cfi); + ERROR("Invalid CFI=%d", cfi); return SRSLTE_ERROR; } return srslte_regs_pdcch_put_offset(h, cfi, d, slot_symbols, 0, h->pdcch[cfi - 1].nof_regs); @@ -211,7 +211,7 @@ int srslte_regs_pdcch_get_offset(srslte_regs_t* h, uint32_t nof_regs) { if (cfi < 1 || cfi > 3) { - ERROR("Invalid CFI=%d\n", cfi); + ERROR("Invalid CFI=%d", cfi); return SRSLTE_ERROR; } if (start_reg + nof_regs <= h->pdcch[cfi - 1].nof_regs) { @@ -223,7 +223,7 @@ int srslte_regs_pdcch_get_offset(srslte_regs_t* h, } return k; } else { - ERROR("Out of range: start_reg + nof_reg must be lower than %d\n", h->pdcch[cfi - 1].nof_regs); + ERROR("Out of range: start_reg + nof_reg must be lower than %d", h->pdcch[cfi - 1].nof_regs); return SRSLTE_ERROR; } } @@ -231,7 +231,7 @@ int srslte_regs_pdcch_get_offset(srslte_regs_t* h, int srslte_regs_pdcch_get(srslte_regs_t* h, uint32_t cfi, cf_t* slot_symbols, cf_t* d) { if (cfi < 1 || cfi > 3) { - ERROR("Invalid CFI=%d\n", cfi); + ERROR("Invalid CFI=%d", cfi); return SRSLTE_ERROR; } return srslte_regs_pdcch_get_offset(h, cfi, slot_symbols, d, 0, h->pdcch[cfi - 1].nof_regs); @@ -281,7 +281,7 @@ int regs_phich_init(srslte_regs_t* h, uint32_t phich_mi, bool mbsfn_or_sf1_6_tdd perror("malloc"); return -1; } - INFO("Creating %d PHICH mapping units. %s length, Ng=%.2f\n", + INFO("Creating %d PHICH mapping units. %s length, Ng=%.2f", h->ngroups_phich, h->phich_len == SRSLTE_PHICH_EXT ? "Extended" : "Normal", ng); @@ -341,7 +341,7 @@ int regs_phich_init(srslte_regs_t* h, uint32_t phich_mi, bool mbsfn_or_sf1_6_tdd } h->phich[mi].regs[i] = regs_phich[li][ni]; h->phich[mi].regs[i]->assigned = true; - DEBUG("Assigned PHICH REG#%d (%d,%d)\n", nreg, h->phich[mi].regs[i]->k0, li); + DEBUG("Assigned PHICH REG#%d (%d,%d)", nreg, h->phich[mi].regs[i]->k0, li); nreg++; } } @@ -422,7 +422,7 @@ int srslte_regs_phich_add(srslte_regs_t* h, cf_t symbols[REGS_PHICH_NSYM], uint3 { uint32_t i; if (ngroup >= h->ngroups_phich) { - ERROR("Error invalid ngroup %d\n", ngroup); + ERROR("Error invalid ngroup %d", ngroup); return SRSLTE_ERROR_INVALID_INPUTS; } if (SRSLTE_CP_ISEXT(h->cell.cp)) { @@ -467,7 +467,7 @@ int srslte_regs_phich_get(srslte_regs_t* h, cf_t* slot_symbols, cf_t symbols[REG { uint32_t i; if (ngroup >= h->ngroups_phich) { - ERROR("Error invalid ngroup %d\n", ngroup); + ERROR("Error invalid ngroup %d", ngroup); return SRSLTE_ERROR_INVALID_INPUTS; } if (SRSLTE_CP_ISEXT(h->cell.cp)) { @@ -502,22 +502,21 @@ int regs_pcfich_init(srslte_regs_t* h) } ch->nof_regs = REGS_PCFICH_NREGS; - INFO("PCFICH allocating %d regs. CellID: %d, PRB: %d\n", ch->nof_regs, h->cell.id, h->cell.nof_prb); + INFO("PCFICH allocating %d regs. CellID: %d, PRB: %d", ch->nof_regs, h->cell.id, h->cell.nof_prb); k_hat = (SRSLTE_NRE / 2) * (h->cell.id % (2 * h->cell.nof_prb)); for (i = 0; i < REGS_PCFICH_NREGS; i++) { - k = (k_hat + (i * h->cell.nof_prb / 2) * (SRSLTE_NRE / 2)) % (h->cell.nof_prb * SRSLTE_NRE); ch->regs[i] = regs_find_reg(h, k, 0); if (!ch->regs[i]) { - ERROR("Error allocating PCFICH: REG (%d,0) not found\n", k); + ERROR("Error allocating PCFICH: REG (%d,0) not found", k); return SRSLTE_ERROR; } else if (ch->regs[i]->assigned) { - ERROR("Error allocating PCFICH: REG (%d,0) already allocated\n", k); + ERROR("Error allocating PCFICH: REG (%d,0) already allocated", k); return SRSLTE_ERROR; } else { ch->regs[i]->assigned = true; - DEBUG("Assigned PCFICH REG#%d (%d,0)\n", i, k); + DEBUG("Assigned PCFICH REG#%d (%d,0)", i, k); } } return SRSLTE_SUCCESS; @@ -590,7 +589,6 @@ srslte_regs_reg_t* regs_find_reg(srslte_regs_t* h, uint32_t k, uint32_t l) */ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, srslte_cp_t cp) { - switch (symbol) { case 0: return 2; @@ -602,7 +600,7 @@ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, srslte_cp_t cp) case 4: return 2; default: - ERROR("Invalid number of ports %d\n", nof_port); + ERROR("Invalid number of ports %d", nof_port); return SRSLTE_ERROR; } break; @@ -615,7 +613,7 @@ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, srslte_cp_t cp) return 2; } default: - ERROR("Invalid symbol %d\n", symbol); + ERROR("Invalid symbol %d", symbol); return SRSLTE_ERROR; } } @@ -650,7 +648,7 @@ int regs_reg_init(srslte_regs_reg_t* reg, uint32_t symbol, uint32_t nreg, uint32 j++; } if (j != 4) { - ERROR("Something went wrong: expected 2 references\n"); + ERROR("Something went wrong: expected 2 references"); return SRSLTE_ERROR; } break; @@ -663,7 +661,7 @@ int regs_reg_init(srslte_regs_reg_t* reg, uint32_t symbol, uint32_t nreg, uint32 } break; default: - ERROR("Invalid number of REGs per PRB: %d\n", maxreg); + ERROR("Invalid number of REGs per PRB: %d", maxreg); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -718,7 +716,7 @@ int srslte_regs_init_opts(srslte_regs_t* h, srslte_cell_t cell, uint32_t phich_m } h->nof_regs += h->cell.nof_prb * n[i]; } - INFO("Indexing %d REGs. CellId: %d, %d PRB, CP: %s\n", + INFO("Indexing %d REGs. CellId: %d, %d PRB, CP: %s", h->nof_regs, h->cell.id, h->cell.nof_prb, @@ -735,10 +733,10 @@ int srslte_regs_init_opts(srslte_regs_t* h, srslte_cell_t cell, uint32_t phich_m while (k < h->nof_regs) { if (n[i] == 3 || (n[i] == 2 && jmax != 1)) { if (regs_reg_init(&h->regs[k], i, j[i], prb * SRSLTE_NRE, n[i], vo)) { - ERROR("Error initializing REGs\n"); + ERROR("Error initializing REGs"); goto clean_and_exit; } - /*DEBUG("Available REG #%3d: l=%d, prb=%d, nreg=%d (k0=%d)\n", k, i, prb, j[i], + /*DEBUG("Available REG #%3d: l=%d, prb=%d, nreg=%d (k0=%d)", k, i, prb, j[i], h->regs[k].k0); */ j[i]++; @@ -756,18 +754,18 @@ int srslte_regs_init_opts(srslte_regs_t* h, srslte_cell_t cell, uint32_t phich_m } } if (regs_pcfich_init(h)) { - ERROR("Error initializing PCFICH REGs\n"); + ERROR("Error initializing PCFICH REGs"); goto clean_and_exit; } h->phich_mi = phich_mi; if (phich_mi > 0) { if (regs_phich_init(h, phich_mi, mbsfn_or_sf1_6_tdd)) { - ERROR("Error initializing PHICH REGs\n"); + ERROR("Error initializing PHICH REGs"); goto clean_and_exit; } } if (regs_pdcch_init(h)) { - ERROR("Error initializing PDCCH REGs\n"); + ERROR("Error initializing PDCCH REGs"); goto clean_and_exit; } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index 26586c898..6e83e075f 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -48,7 +48,7 @@ static inline float get_beta_harq_offset(uint32_t idx) if (idx < 15) { ret = beta_harq_offset[idx]; } else { - ERROR("Invalid input %d (min: %d, max: %d)\n", idx, 0, 14); + ERROR("Invalid input %d (min: %d, max: %d)", idx, 0, 14); } return ret; @@ -64,7 +64,7 @@ static inline float get_beta_ri_offset(uint32_t idx) if (idx < 13) { ret = beta_ri_offset[idx]; } else { - ERROR("Invalid input %d (min: %d, max: %d)\n", idx, 0, 12); + ERROR("Invalid input %d (min: %d, max: %d)", idx, 0, 12); } return ret; @@ -80,7 +80,7 @@ static inline float get_beta_cqi_offset(uint32_t idx) if (idx > 1 && idx < 16) { ret = beta_cqi_offset[idx]; } else { - ERROR("Invalid input %d (min: %d, max: %d)\n", idx, 2, 15); + ERROR("Invalid input %d (min: %d, max: %d)", idx, 2, 15); } return ret; @@ -144,20 +144,20 @@ int srslte_sch_init(srslte_sch_t* q) bzero(q, sizeof(srslte_sch_t)); if (srslte_crc_init(&q->crc_tb, SRSLTE_LTE_CRC24A, 24)) { - ERROR("Error initiating CRC\n"); + ERROR("Error initiating CRC"); goto clean; } if (srslte_crc_init(&q->crc_cb, SRSLTE_LTE_CRC24B, 24)) { - ERROR("Error initiating CRC\n"); + ERROR("Error initiating CRC"); goto clean; } if (srslte_tcod_init(&q->encoder, SRSLTE_TCOD_MAX_LEN_CB)) { - ERROR("Error initiating Turbo Coder\n"); + ERROR("Error initiating Turbo Coder"); goto clean; } if (srslte_tdec_init(&q->decoder, SRSLTE_TCOD_MAX_LEN_CB)) { - ERROR("Error initiating Turbo Decoder\n"); + ERROR("Error initiating Turbo Decoder"); goto clean; } @@ -251,14 +251,13 @@ static int encode_tb_off(srslte_sch_t* q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && e_bits != NULL && cb_segm != NULL && softbuffer != NULL) { - if (cb_segm->F) { - ERROR("Error filler bits are not supported. Use standard TBS\n"); + ERROR("Error filler bits are not supported. Use standard TBS"); return SRSLTE_ERROR; } if (cb_segm->C > softbuffer->max_cb) { - ERROR("Error number of CB to encode (%d) exceeds soft buffer size (%d CBs)\n", cb_segm->C, softbuffer->max_cb); + ERROR("Error number of CB to encode (%d) exceeds soft buffer size (%d CBs)", cb_segm->C, softbuffer->max_cb); return -1; } @@ -275,7 +274,6 @@ static int encode_tb_off(srslte_sch_t* q, wp = 0; rp = 0; for (i = 0; i < cb_segm->C; i++) { - uint32_t cblen_idx; /* Get read lengths */ if (i < cb_segm->C2) { @@ -296,7 +294,7 @@ static int encode_tb_off(srslte_sch_t* q, n_e = Qm * ((uint32_t)ceilf((float)Gp / cb_segm->C)); } - INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, E: %d\n", i, cb_len, rlen, wp, rp, n_e); + INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, E: %d", i, cb_len, rlen, wp, rp, n_e); if (data) { bool last_cb = false; @@ -306,7 +304,7 @@ static int encode_tb_off(srslte_sch_t* q, // Copy data memcpy(q->cb_in, &data[rp / 8], rlen * sizeof(uint8_t) / 8); } else { - INFO("Last CB, appending parity: %d from %d and 24 to %d\n", rlen - 24, rp, rlen - 24); + INFO("Last CB, appending parity: %d from %d and 24 to %d", rlen - 24, rp, rlen - 24); /* Append Transport Block parity bits to the last CB */ memcpy(q->cb_in, &data[rp / 8], (rlen - 24) * sizeof(uint8_t) / 8); @@ -324,7 +322,7 @@ static int encode_tb_off(srslte_sch_t* q, cblen_idx, last_cb); } - DEBUG("RM cblen_idx=%d, n_e=%d, wp=%d, nof_e_bits=%d\n", cblen_idx, n_e, wp, nof_e_bits); + DEBUG("RM cblen_idx=%d, n_e=%d, wp=%d, nof_e_bits=%d", cblen_idx, n_e, wp, nof_e_bits); /* Rate matching */ if (srslte_rm_turbo_tx_lut(softbuffer->buffer_b[i], @@ -335,7 +333,7 @@ static int encode_tb_off(srslte_sch_t* q, n_e, (wp + w_offset) % 8, rv)) { - ERROR("Error in rate matching\n"); + ERROR("Error in rate matching"); return SRSLTE_ERROR; } @@ -344,10 +342,10 @@ static int encode_tb_off(srslte_sch_t* q, wp += n_e; } - INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp); + INFO("END CB#%d: wp: %d, rp: %d", i, wp, rp); ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters: e_bits=%d, cb_segm=%d, softbuffer=%d\n", e_bits != 0, cb_segm != 0, softbuffer != 0); + ERROR("Invalid parameters: e_bits=%d, cb_segm=%d, softbuffer=%d", e_bits != 0, cb_segm != 0, softbuffer != 0); } return ret; } @@ -373,12 +371,11 @@ bool decode_tb_cb(srslte_sch_t* q, void* e_bits, uint8_t* data) { - int8_t* e_bits_b = e_bits; int16_t* e_bits_s = e_bits; if (cb_segm->C > SRSLTE_MAX_CODEBLOCKS) { - ERROR("Error SRSLTE_MAX_CODEBLOCKS=%d\n", SRSLTE_MAX_CODEBLOCKS); + ERROR("Error SRSLTE_MAX_CODEBLOCKS=%d", SRSLTE_MAX_CODEBLOCKS); return false; } @@ -387,7 +384,6 @@ bool decode_tb_cb(srslte_sch_t* q, for (int cb_idx = 0; cb_idx < cb_segm->C; cb_idx++) { /* Do not process blocks with CRC Ok */ if (softbuffer->cb_crc[cb_idx] == false) { - uint32_t cb_len = cb_idx < cb_segm->C1 ? cb_segm->K1 : cb_segm->K2; uint32_t cb_len_idx = cb_idx < cb_segm->C1 ? cb_segm->K1_idx : cb_segm->K2_idx; @@ -406,12 +402,12 @@ bool decode_tb_cb(srslte_sch_t* q, if (q->llr_is_8bit) { if (srslte_rm_turbo_rx_lut_8bit(&e_bits_b[rp], (int8_t*)softbuffer->buffer_f[cb_idx], n_e2, cb_len_idx, rv)) { - ERROR("Error in rate matching\n"); + ERROR("Error in rate matching"); return SRSLTE_ERROR; } } else { if (srslte_rm_turbo_rx_lut(&e_bits_s[rp], softbuffer->buffer_f[cb_idx], n_e2, cb_len_idx, rv)) { - ERROR("Error in rate matching\n"); + ERROR("Error in rate matching"); return SRSLTE_ERROR; } } @@ -443,7 +439,6 @@ bool decode_tb_cb(srslte_sch_t* q, // CRC is OK if (!srslte_crc_checksum_byte(crc_ptr, &data[cb_idx * rlen / 8], len_crc)) { - softbuffer->cb_crc[cb_idx] = true; early_stop = true; @@ -453,7 +448,7 @@ bool decode_tb_cb(srslte_sch_t* q, } while (cb_noi < q->max_iterations && !early_stop); - INFO("CB %d: rp=%d, n_e=%d, cb_len=%d, CRC=%s, rlen=%d, iterations=%d/%d\n", + INFO("CB %d: rp=%d, n_e=%d, cb_len=%d, CRC=%s, rlen=%d, iterations=%d/%d", cb_idx, rp, n_e2, @@ -513,9 +508,7 @@ static int decode_tb(srslte_sch_t* q, int16_t* e_bits, uint8_t* data) { - if (q != NULL && data != NULL && softbuffer != NULL && e_bits != NULL && cb_segm != NULL) { - if (cb_segm->tbs == 0 || cb_segm->C == 0) { return SRSLTE_SUCCESS; } @@ -543,7 +536,6 @@ static int decode_tb(srslte_sch_t* q, crc_ok = decode_tb_cb(q, softbuffer, cb_segm, Qm, rv, nof_e_bits, e_bits, data); if (crc_ok) { - uint32_t par_rx = 0, par_tx = 0; // Compute transport block CRC @@ -554,17 +546,17 @@ static int decode_tb(srslte_sch_t* q, ((uint32_t)data[cb_segm->tbs / 8 + 2]); if (par_rx == par_tx && par_rx) { - INFO("TB decoded OK\n"); + INFO("TB decoded OK"); return SRSLTE_SUCCESS; } else { - INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x\n", par_tx, par_rx); + INFO("Error in TB parity: par_tx=0x%x, par_rx=0x%x", par_tx, par_rx); return SRSLTE_ERROR; } } else { return SRSLTE_ERROR; } } else { - ERROR("Missing inputs: data=%d, softbuffer=%d, e_bits=%d, cb_segm=%d\n", + ERROR("Missing inputs: data=%d, softbuffer=%d, e_bits=%d, cb_segm=%d", data != 0, softbuffer != 0, e_bits != 0, @@ -593,7 +585,7 @@ int srslte_dlsch_decode2(srslte_sch_t* q, // Prepare cbsegm srslte_cbsegm_t cb_segm; if (srslte_cbsegm(&cb_segm, (uint32_t)cfg->grant.tb[tb_idx].tbs)) { - ERROR("Error computing Codeword (%d) segmentation for TBS=%d\n", tb_idx, cfg->grant.tb[tb_idx].tbs); + ERROR("Error computing Codeword (%d) segmentation for TBS=%d", tb_idx, cfg->grant.tb[tb_idx].tbs); return SRSLTE_ERROR; } @@ -640,7 +632,7 @@ int srslte_dlsch_encode2(srslte_sch_t* q, // Prepare cbsegm srslte_cbsegm_t cb_segm; if (srslte_cbsegm(&cb_segm, (uint32_t)cfg->grant.tb[tb_idx].tbs)) { - ERROR("Error computing Codeword (%d) segmentation for TBS=%d\n", tb_idx, cfg->grant.tb[tb_idx].tbs); + ERROR("Error computing Codeword (%d) segmentation for TBS=%d", tb_idx, cfg->grant.tb[tb_idx].tbs); return SRSLTE_ERROR; } @@ -746,7 +738,6 @@ static void ulsch_interleave_qm4(uint8_t* g_bits, /* First bits are aligned to byte */ if (0 == (bit_read_idx & 0x3)) { for (; i < (cols - 3); i += 4) { - uint8_t w1 = *(_g_bits++); uint8_t w2 = *(_g_bits++); @@ -942,7 +933,7 @@ static void ulsch_interleave(uint8_t* g_bits, uint8_t* ri_present) { if (N_pusch_symbs == 0 || Qm == 0 || H_prime_total == 0 || H_prime_total < N_pusch_symbs) { - ERROR("Invalid input: N_pusch_symbs=%d, Qm=%d, H_prime_total=%d, N_pusch_symbs=%d\n", + ERROR("Invalid input: N_pusch_symbs=%d, Qm=%d, H_prime_total=%d, N_pusch_symbs=%d", N_pusch_symbs, Qm, H_prime_total, @@ -981,7 +972,7 @@ static void ulsch_interleave(uint8_t* g_bits, break; default: /* This line should never be reached */ - ERROR("Wrong Qm (%d)\n", Qm); + ERROR("Wrong Qm (%d)", Qm); } // Reset temp_buffer because will be reused next time @@ -1119,7 +1110,7 @@ int srslte_ulsch_decode(srslte_sch_t* q, // Prepare cbsegm srslte_cbsegm_t cb_segm; if (srslte_cbsegm(&cb_segm, (uint32_t)cfg->grant.tb.tbs)) { - ERROR("Error computing segmentation for TBS=%d\n", cfg->grant.tb.tbs); + ERROR("Error computing segmentation for TBS=%d", cfg->grant.tb.tbs); return SRSLTE_ERROR; } @@ -1130,7 +1121,7 @@ int srslte_ulsch_decode(srslte_sch_t* q, // Decode RI/HARQ values if ((ret = uci_decode_ri_ack(q, cfg, q_bits, c_seq, uci_data)) < 0) { - ERROR("Error decoding RI/HARQ bits\n"); + ERROR("Error decoding RI/HARQ bits"); return SRSLTE_ERROR; } @@ -1201,19 +1192,19 @@ int srslte_ulsch_encode(srslte_sch_t* q, uint32_t Qm = srslte_mod_bits_x_symbol(cfg->grant.tb.mod); if (Qm == 0) { - ERROR("Invalid input\n"); + ERROR("Invalid input"); return SRSLTE_ERROR_INVALID_INPUTS; } if (cfg->grant.nof_symb == 0) { - ERROR("Invalid input\n"); + ERROR("Invalid input"); return SRSLTE_ERROR_INVALID_INPUTS; } // Prepare cbsegm srslte_cbsegm_t cb_segm; if (srslte_cbsegm(&cb_segm, (uint32_t)cfg->grant.tb.tbs)) { - ERROR("Error computing segmentation for TBS=%d\n", cfg->grant.tb.tbs); + ERROR("Error computing segmentation for TBS=%d", cfg->grant.tb.tbs); return SRSLTE_ERROR; } @@ -1226,7 +1217,7 @@ int srslte_ulsch_encode(srslte_sch_t* q, if (cfg->uci_cfg.cqi.data_enable) { uci_cqi_len = (uint32_t)srslte_cqi_value_pack(&cfg->uci_cfg.cqi, &uci_data->cqi, cqi_buff); if (uci_cqi_len < 0) { - ERROR("Error encoding CQI bits\n"); + ERROR("Error encoding CQI bits"); return SRSLTE_ERROR; } } @@ -1324,11 +1315,11 @@ int srslte_ulsch_encode(srslte_sch_t* q, q_bits[p / 8] &= ~(1U << (7 - p % 8)); } } else { - ERROR("Invalid RI/ACK bit %d/%d, position %d. Max bits=%d, Qm=%d\n", i, nof_ri_ack_bits, p, nb_q, Qm); + ERROR("Invalid RI/ACK bit %d/%d, position %d. Max bits=%d, Qm=%d", i, nof_ri_ack_bits, p, nb_q, Qm); } } - INFO("Q_prime_ack=%d, Q_prime_cqi=%d, Q_prime_ri=%d\n", Q_prime_ack, Q_prime_cqi, Q_prime_ri); + INFO("Q_prime_ack=%d, Q_prime_cqi=%d, Q_prime_ri=%d", Q_prime_ack, Q_prime_cqi, Q_prime_ri); return nof_ri_ack_bits; } diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index a5f2884da..a26f9d973 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -79,7 +79,6 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, const srslte_sch_tb_t* tb, srslte_sch_nr_common_cfg_t* cfg) { - if (!sch_cfg || !tb || !cfg) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -91,18 +90,18 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, srslte_cbsegm_t cbsegm = {}; if (bg == BG1) { if (srslte_cbsegm_ldpc_bg1(&cbsegm, tb->tbs) != SRSLTE_SUCCESS) { - ERROR("Error: calculating LDPC BG1 code block segmentation for tbs=%d\n", tb->tbs); + ERROR("Error: calculating LDPC BG1 code block segmentation for tbs=%d", tb->tbs); return SRSLTE_ERROR; } } else { if (srslte_cbsegm_ldpc_bg2(&cbsegm, tb->tbs) != SRSLTE_SUCCESS) { - ERROR("Error: calculating LDPC BG1 code block segmentation for tbs=%d\n", tb->tbs); + ERROR("Error: calculating LDPC BG1 code block segmentation for tbs=%d", tb->tbs); return SRSLTE_ERROR; } } if (cbsegm.Z > MAX_LIFTSIZE) { - ERROR("Error: lifting size Z=%d is out-of-range maximum is %d\n", cbsegm.Z, MAX_LIFTSIZE); + ERROR("Error: lifting size Z=%d is out-of-range maximum is %d", cbsegm.Z, MAX_LIFTSIZE); return SRSLTE_ERROR; } @@ -156,7 +155,7 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, static inline uint32_t sch_nr_get_E(const srslte_sch_nr_common_cfg_t* cfg, uint32_t j) { if (cfg->Nl == 0 || cfg->Qm == 0 || cfg->Cp == 0) { - ERROR("Invalid Nl (%d), Qm (%d) or Cp (%d)\n", cfg->Nl, cfg->Qm, cfg->Cp); + ERROR("Invalid Nl (%d), Qm (%d) or Cp (%d)", cfg->Nl, cfg->Qm, cfg->Cp); return 0; } @@ -202,11 +201,18 @@ int srslte_sch_nr_init_tx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args) } srslte_ldpc_encoder_type_t encoder_type = SRSLTE_LDPC_ENCODER_C; + +#ifdef LV_HAVE_AVX512 + if (!args->disable_simd) { + encoder_type = SRSLTE_LDPC_ENCODER_AVX512; + } +#else // LV_HAVE_AVX512 #ifdef LV_HAVE_AVX2 if (!args->disable_simd) { encoder_type = SRSLTE_LDPC_ENCODER_AVX2; } #endif // LV_HAVE_AVX2 +#endif // LV_HAVE_AVX612 // Iterate over all possible lifting sizes for (uint16_t ls = 0; ls <= MAX_LIFTSIZE; ls++) { @@ -221,12 +227,12 @@ int srslte_sch_nr_init_tx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args) q->encoder_bg1[ls] = calloc(1, sizeof(srslte_ldpc_encoder_t)); if (!q->encoder_bg1[ls]) { - ERROR("Error: calloc\n"); + ERROR("Error: calloc"); return SRSLTE_ERROR; } if (srslte_ldpc_encoder_init(q->encoder_bg1[ls], encoder_type, BG1, ls) < SRSLTE_SUCCESS) { - ERROR("Error: initialising BG1 LDPC encoder for ls=%d\n", ls); + ERROR("Error: initialising BG1 LDPC encoder for ls=%d", ls); return SRSLTE_ERROR; } @@ -236,13 +242,13 @@ int srslte_sch_nr_init_tx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args) } if (srslte_ldpc_encoder_init(q->encoder_bg2[ls], encoder_type, BG2, ls) < SRSLTE_SUCCESS) { - ERROR("Error: initialising BG2 LDPC encoder for ls=%d\n", ls); + ERROR("Error: initialising BG2 LDPC encoder for ls=%d", ls); return SRSLTE_ERROR; } } if (srslte_ldpc_rm_tx_init(&q->tx_rm) < SRSLTE_SUCCESS) { - ERROR("Error: initialising Tx LDPC Rate matching\n"); + ERROR("Error: initialising Tx LDPC Rate matching"); return SRSLTE_ERROR; } @@ -256,24 +262,20 @@ int srslte_sch_nr_init_rx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args) return ret; } - srslte_ldpc_decoder_type_t decoder_type = SRSLTE_LDPC_DECODER_C; - if (args->decoder_use_flooded) { -#ifdef LV_HAVE_AVX2 - if (args->disable_simd) { - decoder_type = SRSLTE_LDPC_DECODER_C_FLOOD; - } else { - decoder_type = SRSLTE_LDPC_DECODER_C_AVX2_FLOOD; - } -#else // LV_HAVE_AVX2 - decoder_type = SRSLTE_LDPC_DECODER_C_FLOOD; -#endif // LV_HAVE_AVX2 - } else { -#ifdef LV_HAVE_AVX2 - if (!args->disable_simd) { - decoder_type = SRSLTE_LDPC_DECODER_C_AVX2; - } -#endif // LV_HAVE_AVX2 + srslte_ldpc_decoder_type_t decoder_type = + args->decoder_use_flooded ? SRSLTE_LDPC_DECODER_C_FLOOD : SRSLTE_LDPC_DECODER_C; + +#ifdef LV_HAVE_AVX512 + if (!args->disable_simd) { + decoder_type = args->decoder_use_flooded ? SRSLTE_LDPC_DECODER_C_AVX512_FLOOD : SRSLTE_LDPC_DECODER_C_AVX512; } +#else // LV_HAVE_AVX512 +#ifdef LV_HAVE_AVX2 + if (!args->disable_simd) { + decoder_type = args->decoder_use_flooded ? SRSLTE_LDPC_DECODER_C_AVX2_FLOOD : SRSLTE_LDPC_DECODER_C_AVX2; + } +#endif // LV_HAVE_AVX2 +#endif // LV_HAVE_AVX512 // If the scaling factor is not provided use a default value that allows decoding all possible combinations of nPRB // and MCS indexes for all possible MCS tables @@ -292,29 +294,29 @@ int srslte_sch_nr_init_rx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args) q->decoder_bg1[ls] = calloc(1, sizeof(srslte_ldpc_decoder_t)); if (!q->decoder_bg1[ls]) { - ERROR("Error: calloc\n"); + ERROR("Error: calloc"); return SRSLTE_ERROR; } if (srslte_ldpc_decoder_init(q->decoder_bg1[ls], decoder_type, BG1, ls, scaling_factor) < SRSLTE_SUCCESS) { - ERROR("Error: initialising BG1 LDPC decoder for ls=%d\n", ls); + ERROR("Error: initialising BG1 LDPC decoder for ls=%d", ls); return SRSLTE_ERROR; } q->decoder_bg2[ls] = calloc(1, sizeof(srslte_ldpc_decoder_t)); if (!q->decoder_bg2[ls]) { - ERROR("Error: calloc\n"); + ERROR("Error: calloc"); return SRSLTE_ERROR; } if (srslte_ldpc_decoder_init(q->decoder_bg2[ls], decoder_type, BG2, ls, scaling_factor) < SRSLTE_SUCCESS) { - ERROR("Error: initialising BG2 LDPC decoder for ls=%d\n", ls); + ERROR("Error: initialising BG2 LDPC decoder for ls=%d", ls); return SRSLTE_ERROR; } } if (srslte_ldpc_rm_rx_init_c(&q->rx_rm) < SRSLTE_SUCCESS) { - ERROR("Error: initialising Rx LDPC Rate matching\n"); + ERROR("Error: initialising Rx LDPC Rate matching"); return SRSLTE_ERROR; } @@ -378,7 +380,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, } if (!tb->softbuffer.tx) { - ERROR("Error: Missing Tx softbuffer\n"); + ERROR("Error: Missing Tx softbuffer"); return SRSLTE_ERROR; } @@ -392,19 +394,19 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, // Check encoder if (cfg.encoder == NULL) { - ERROR("Error: encoder for lifting size Z=%d not found\n", cfg.Z); + ERROR("Error: encoder for lifting size Z=%d not found (tbs=%d)", cfg.Z, tb->tbs); return SRSLTE_ERROR; } // Check CRC for TB if (cfg.crc_tb == NULL) { - ERROR("Error: CRC for TB not found\n"); + ERROR("Error: CRC for TB not found"); return SRSLTE_ERROR; } // Soft-buffer number of code-block protection if (tb->softbuffer.tx->max_cb < cfg.C) { - ERROR("Soft-buffer does not have enough code-blocks (max_cb=%d) for a TBS=%d, C=%d.\n", + ERROR("Soft-buffer does not have enough code-blocks (max_cb=%d) for a TBS=%d, C=%d.", tb->softbuffer.tx->max_cb, tb->tbs, cfg.C); @@ -412,7 +414,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, } if (tb->softbuffer.tx->max_cb_size < (cfg.encoder->liftN - 2 * cfg.Z)) { - ERROR("Soft-buffer code-block maximum size insufficient (max_cb_size=%d) for a TBS=%d, requires %d.\n", + ERROR("Soft-buffer code-block maximum size insufficient (max_cb_size=%d) for a TBS=%d, requires %d.", tb->softbuffer.tx->max_cb_size, tb->tbs, (cfg.encoder->liftN - 2 * cfg.Z)); @@ -432,7 +434,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, // Select rate matching circular buffer uint8_t* rm_buffer = tb->softbuffer.tx->buffer_b[r]; if (rm_buffer == NULL) { - ERROR("Error: soft-buffer provided NULL buffer for cb_idx=%d\n", r); + ERROR("Error: soft-buffer provided NULL buffer for cb_idx=%d", r); return SRSLTE_ERROR; } @@ -450,7 +452,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, // Append TB CRC uint8_t* ptr = &q->temp_cb[cb_len]; srslte_bit_unpack(checksum_tb, &ptr, cfg.L_tb); - SCH_INFO_TX("CB %d: appending TB CRC=%06x\n", r, checksum_tb); + SCH_INFO_TX("CB %d: appending TB CRC=%06x", r, checksum_tb); } else { // Copy payload srslte_bit_unpack_vector(input_ptr, q->temp_cb, (int)cb_len); @@ -466,7 +468,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, // Attach code block CRC if required if (cfg.L_cb) { srslte_crc_attach(&q->crc_cb, q->temp_cb, (int)(cfg.Kp - cfg.L_cb)); - SCH_INFO_TX("CB %d: CRC=%06x\n", r, (uint32_t)srslte_crc_checksum_get(&q->crc_cb)); + SCH_INFO_TX("CB %d: CRC=%06x", r, (uint32_t)srslte_crc_checksum_get(&q->crc_cb)); } // Insert filler bits @@ -493,7 +495,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q, j++; // LDPC Rate matching - SCH_INFO_TX("RM CB %d: E=%d; F=%d; BG=%d; Z=%d; RV=%d; Qm=%d; Nref=%d;\n", + SCH_INFO_TX("RM CB %d: E=%d; F=%d; BG=%d; Z=%d; RV=%d; Qm=%d; Nref=%d;", r, E, cfg.F, @@ -530,13 +532,13 @@ int sch_nr_decode(srslte_sch_nr_t* q, // Check decoder if (cfg.decoder == NULL) { - ERROR("Error: decoder for lifting size Z=%d not found\n", cfg.Z); + ERROR("Error: decoder for lifting size Z=%d not found", cfg.Z); return SRSLTE_ERROR; } // Check CRC for TB if (cfg.crc_tb == NULL) { - ERROR("Error: CRC for TB not found\n"); + ERROR("Error: CRC for TB not found"); return SRSLTE_ERROR; } @@ -554,7 +556,7 @@ int sch_nr_decode(srslte_sch_nr_t* q, bool decoded = tb->softbuffer.rx->cb_crc[r]; int8_t* rm_buffer = (int8_t*)tb->softbuffer.tx->buffer_b[r]; if (!rm_buffer) { - ERROR("Error: soft-buffer provided NULL buffer for cb_idx=%d\n", r); + ERROR("Error: soft-buffer provided NULL buffer for cb_idx=%d", r); return SRSLTE_ERROR; } @@ -563,7 +565,7 @@ int sch_nr_decode(srslte_sch_nr_t* q, if (decoded) { cb_ok++; } - SCH_INFO_RX("RM CB %d: Disabled, CRC %s ... Skipping\n", r, decoded ? "OK" : "KO"); + SCH_INFO_RX("RM CB %d: Disabled, CRC %s ... Skipping", r, decoded ? "OK" : "KO"); continue; } @@ -573,13 +575,13 @@ int sch_nr_decode(srslte_sch_nr_t* q, // Skip CB if it has a matched CRC if (decoded) { - SCH_INFO_RX("RM CB %d: CRC OK ... Skipping\n", r); + SCH_INFO_RX("RM CB %d: CRC OK ... Skipping", r); cb_ok++; continue; } // LDPC Rate matching - SCH_INFO_RX("RM CB %d: E=%d; F=%d; BG=%d; Z=%d; RV=%d; Qm=%d; Nref=%d;\n", + SCH_INFO_RX("RM CB %d: E=%d; F=%d; BG=%d; Z=%d; RV=%d; Qm=%d; Nref=%d;", r, E, cfg.F, @@ -601,7 +603,7 @@ int sch_nr_decode(srslte_sch_nr_t* q, uint32_t checksum2 = srslte_bit_pack(&ptr, cfg.L_cb); tb->softbuffer.rx->cb_crc[r] = (checksum1 == checksum2); - SCH_INFO_RX("CB %d/%d: CRC={%06x, %06x} ... %s\n", + SCH_INFO_RX("CB %d/%d: CRC={%06x, %06x} ... %s", r, cfg.C, checksum1, @@ -648,11 +650,17 @@ int sch_nr_decode(srslte_sch_nr_t* q, } } + // Check if TB is all zeros + bool all_zeros = true; + for (uint32_t i = 0; i < tb->tbs && all_zeros; i++) { + all_zeros = (data[i] == 0); + } + // Calculate TB CRC from packed data uint32_t checksum1 = srslte_crc_checksum_byte(cfg.crc_tb, data, tb->tbs); - *crc_ok = (checksum1 == checksum2); + *crc_ok = (checksum1 == checksum2 && !all_zeros); - SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}\n", tb->tbs, checksum1, checksum2); + SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2); if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { DEBUG("Decode: "); srslte_vec_fprint_byte(stdout, data, tb->tbs / 8); @@ -710,10 +718,10 @@ int srslte_sch_nr_tb_info(const srslte_sch_tb_t* tb, char* str, uint32_t str_len len += srslte_print_check(str, str_len, len, - "tb={mod=%s,Nl=%d,TBS=%d,R=%.3f,rv=%d,Nre=%d,Nbit=%d,cw=%d}", + "tb={mod=%s,Nl=%d,tbs=%d,R=%.3f,rv=%d,Nre=%d,Nbit=%d,cw=%d}", srslte_mod_string(tb->mod), tb->N_L, - tb->tbs, + tb->tbs / 8, tb->R, tb->rv, tb->nof_re, diff --git a/lib/src/phy/phch/sci.c b/lib/src/phy/phch/sci.c index f3def576a..a849fe31b 100644 --- a/lib/src/phy/phch/sci.c +++ b/lib/src/phy/phch/sci.c @@ -176,7 +176,7 @@ void srslte_sci_info(const srslte_sci_t* q, char* str, uint32_t len) n = srslte_print_check(str, SRSLTE_SCI_MSG_MAX_LEN, n, - ", trp_idx=%i, t_adv=%i, n_sa_id=%i, freqhoppflg=%s\n", + ", trp_idx=%i, t_adv=%i, n_sa_id=%i, freqhoppflg=%s", q->trp_idx, q->timing_advance, q->N_sa_id, @@ -185,7 +185,7 @@ void srslte_sci_info(const srslte_sci_t* q, char* str, uint32_t len) n = srslte_print_check(str, SRSLTE_SCI_MSG_MAX_LEN, n, - ", priority=%i, res_rsrv=%i, t_gap=%i, rtx=%i, txformat=%d\n", + ", priority=%i, res_rsrv=%i, t_gap=%i, rtx=%i, txformat=%d", q->priority, q->resource_reserv, q->time_gap, diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 5ee3d47be..43f7d3715 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "lib;phy;phch") + ######################################################################## # PBCH TEST ######################################################################## @@ -25,12 +27,12 @@ add_executable(pbch_test pbch_test.c) target_link_libraries(pbch_test srslte_phy) -add_test(pbch_test_6 pbch_test -p 1 -n 6 -c 100) -add_test(pbch_test_62 pbch_test -p 2 -n 6 -c 100) -add_test(pbch_test_64 pbch_test -p 4 -n 6 -c 100) -add_test(pbch_test_50 pbch_test -p 1 -n 50 -c 50) -add_test(pbch_test_502 pbch_test -p 2 -n 50 -c 50) -add_test(pbch_test_504 pbch_test -p 4 -n 50 -c 50) +add_lte_test(pbch_test_6 pbch_test -p 1 -n 6 -c 100) +add_lte_test(pbch_test_62 pbch_test -p 2 -n 6 -c 100) +add_lte_test(pbch_test_64 pbch_test -p 4 -n 6 -c 100) +add_lte_test(pbch_test_50 pbch_test -p 1 -n 50 -c 50) +add_lte_test(pbch_test_502 pbch_test -p 2 -n 50 -c 50) +add_lte_test(pbch_test_504 pbch_test -p 4 -n 50 -c 50) ######################################################################## # PSBCH TEST @@ -40,30 +42,30 @@ add_executable(psbch_test psbch_test.c) target_link_libraries(psbch_test srslte_phy) # TM2 self tests -add_test(psbch_test_self_test_tm2_p6_c168_self psbch_test -p 6 -c 168 -t 2) -add_test(psbch_test_self_test_tm2_p50_c168_self psbch_test -p 50 -c 252 -t 2) -add_test(psbch_test_self_test_tm2_p100_c168_self psbch_test -p 100 -c 335 -t 2) -add_test(psbch_test_self_test_tm2_p25_c168_ext_self psbch_test -p 25 -c 168 -e) -add_test(psbch_test_self_test_tm2_p100_c335_ext_self psbch_test -p 100 -c 335 -e) +add_lte_test(psbch_test_self_test_tm2_p6_c168_self psbch_test -p 6 -c 168 -t 2) +add_lte_test(psbch_test_self_test_tm2_p50_c168_self psbch_test -p 50 -c 252 -t 2) +add_lte_test(psbch_test_self_test_tm2_p100_c168_self psbch_test -p 100 -c 335 -t 2) +add_lte_test(psbch_test_self_test_tm2_p25_c168_ext_self psbch_test -p 25 -c 168 -e) +add_lte_test(psbch_test_self_test_tm2_p100_c335_ext_self psbch_test -p 100 -c 335 -e) # TM4 self tests -add_test(psbch_test_self_test_tm4_p6_c168_self psbch_test -p 6 -c 168 -t 4) -add_test(psbch_test_self_test_tm4_p50_c168_self psbch_test -p 50 -c 252 -t 4) -add_test(psbch_test_self_test_tm4_p100_c168_self psbch_test -p 100 -c 335 -t 4) +add_lte_test(psbch_test_self_test_tm4_p6_c168_self psbch_test -p 6 -c 168 -t 4) +add_lte_test(psbch_test_self_test_tm4_p50_c168_self psbch_test -p 50 -c 252 -t 4) +add_lte_test(psbch_test_self_test_tm4_p100_c168_self psbch_test -p 100 -c 335 -t 4) add_executable(psbch_file_test psbch_file_test.c) target_link_libraries(psbch_file_test srslte_phy) # TM2 file tests -add_test(psbch_file_test_ideal_tm2_p6_c0 psbch_file_test -p 6 -c 0 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) -add_test(psbch_file_test_ideal_tm2_p15_c84 psbch_file_test -p 15 -c 84 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) -add_test(psbch_file_test_ideal_tm2_p25_c168 psbch_file_test -p 25 -c 168 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) -add_test(psbch_file_test_ideal_tm2_p50_c252 psbch_file_test -p 50 -c 252 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) -add_test(psbch_file_test_ideal_tm2_p100_c335 psbch_file_test -p 100 -c 335 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) -add_test(psbch_file_test_ideal_tm2_p50_c252_ext psbch_file_test -p 50 -c 252 -e -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat) +add_lte_test(psbch_file_test_ideal_tm2_p6_c0 psbch_file_test -p 6 -c 0 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p15_c84 psbch_file_test -p 15 -c 84 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p25_c168 psbch_file_test -p 25 -c 168 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p50_c252 psbch_file_test -p 50 -c 252 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p100_c335 psbch_file_test -p 100 -c 335 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p50_c252_ext psbch_file_test -p 50 -c 252 -e -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat) # TM4 file tests -add_test(psbch_file_test_cmw_tm4_p50_c169 psbch_file_test -p 50 -c 169 -t 4 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_slss_id169.dat) +add_lte_test(psbch_file_test_cmw_tm4_p50_c169 psbch_file_test -p 50 -c 169 -t 4 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_slss_id169.dat) ######################################################################## # PSCCH TEST @@ -73,20 +75,20 @@ add_executable(pscch_test pscch_test.c) target_link_libraries(pscch_test srslte_phy) # TM2 self tests -add_test(pscch_test_tm2_p6 pscch_test -p 6) -add_test(pscch_test_tm2_p15 pscch_test -p 15) -add_test(pscch_test_tm2_p25 pscch_test -p 25) -add_test(pscch_test_tm2_p50 pscch_test -p 50) -add_test(pscch_test_tm2_p75 pscch_test -p 75) -add_test(pscch_test_tm2_p100 pscch_test -p 100) +add_lte_test(pscch_test_tm2_p6 pscch_test -p 6) +add_lte_test(pscch_test_tm2_p15 pscch_test -p 15) +add_lte_test(pscch_test_tm2_p25 pscch_test -p 25) +add_lte_test(pscch_test_tm2_p50 pscch_test -p 50) +add_lte_test(pscch_test_tm2_p75 pscch_test -p 75) +add_lte_test(pscch_test_tm2_p100 pscch_test -p 100) # TM4 self tests -add_test(pscch_test_tm4_p6 pscch_test -p 6 -t 4) -add_test(pscch_test_tm4_p15 pscch_test -p 15 -t 4) -add_test(pscch_test_tm4_p25 pscch_test -p 25 -t 4) -add_test(pscch_test_tm4_p50 pscch_test -p 50 -t 4) -add_test(pscch_test_tm4_p75 pscch_test -p 75 -t 4) -add_test(pscch_test_tm4_p100 pscch_test -p 100 -t 4) +add_lte_test(pscch_test_tm4_p6 pscch_test -p 6 -t 4) +add_lte_test(pscch_test_tm4_p15 pscch_test -p 15 -t 4) +add_lte_test(pscch_test_tm4_p25 pscch_test -p 25 -t 4) +add_lte_test(pscch_test_tm4_p50 pscch_test -p 50 -t 4) +add_lte_test(pscch_test_tm4_p75 pscch_test -p 75 -t 4) +add_lte_test(pscch_test_tm4_p100 pscch_test -p 100 -t 4) ######################################################################## # PSSCH TEST @@ -96,22 +98,22 @@ add_executable(pssch_test pssch_test.c) target_link_libraries(pssch_test srslte_phy) # TM2 self tests -add_test(pssch_test_tm2_p6 pssch_test -p 6 -m 2) -add_test(pssch_test_tm2_p15 pssch_test -p 15 -m 6) -add_test(pssch_test_tm2_p25 pssch_test -p 25 -m 7) -add_test(pssch_test_tm2_p50 pssch_test -p 50 -m 9) -add_test(pssch_test_tm2_p50_ext pssch_test -p 50 -m 9 -e) -add_test(pssch_test_tm2_p75 pssch_test -p 75 -m 17) -add_test(pssch_test_tm2_p100 pssch_test -p 100 -m 21) -add_test(pssch_test_tm2_p100_ext pssch_test -p 100 -m 21 -e) +add_lte_test(pssch_test_tm2_p6 pssch_test -p 6 -m 2) +add_lte_test(pssch_test_tm2_p15 pssch_test -p 15 -m 6) +add_lte_test(pssch_test_tm2_p25 pssch_test -p 25 -m 7) +add_lte_test(pssch_test_tm2_p50 pssch_test -p 50 -m 9) +add_lte_test(pssch_test_tm2_p50_ext pssch_test -p 50 -m 9 -e) +add_lte_test(pssch_test_tm2_p75 pssch_test -p 75 -m 17) +add_lte_test(pssch_test_tm2_p100 pssch_test -p 100 -m 21) +add_lte_test(pssch_test_tm2_p100_ext pssch_test -p 100 -m 21 -e) # TM4 self tests -add_test(pssch_test_tm4_p6 pssch_test -p 6 -t 4 -m 2) -add_test(pssch_test_tm4_p15 pssch_test -p 15 -t 4 -m 6) -add_test(pssch_test_tm4_p25 pssch_test -p 25 -t 4 -m 7) -add_test(pssch_test_tm4_p50 pssch_test -p 50 -t 4 -m 9) -add_test(pssch_test_tm4_p75 pssch_test -p 75 -t 4 -m 17) -add_test(pssch_test_tm4_p100 pssch_test -p 100 -t 4 -m 21) +add_lte_test(pssch_test_tm4_p6 pssch_test -p 6 -t 4 -m 2) +add_lte_test(pssch_test_tm4_p15 pssch_test -p 15 -t 4 -m 6) +add_lte_test(pssch_test_tm4_p25 pssch_test -p 25 -t 4 -m 7) +add_lte_test(pssch_test_tm4_p50 pssch_test -p 50 -t 4 -m 9) +add_lte_test(pssch_test_tm4_p75 pssch_test -p 75 -t 4 -m 17) +add_lte_test(pssch_test_tm4_p100 pssch_test -p 100 -t 4 -m 21) ######################################################################## # PSCCH AND PSSCH FILE TEST @@ -121,38 +123,38 @@ add_executable(pssch_pscch_file_test pssch_pscch_file_test.c) target_link_libraries(pssch_pscch_file_test srslte_phy) # TM2 file tests -add_test(pssch_pscch_file_test_ideal_tm2_p100 pssch_pscch_file_test -p 100 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_lte_test(pssch_pscch_file_test_ideal_tm2_p100 pssch_pscch_file_test -p 100 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) set_property(TEST pssch_pscch_file_test_ideal_tm2_p100 PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=2 num_decoded_tb=1") # TM4 file tests (first SF is sf_idx = 6 such that the PSSCH sf_idx=0) -add_test(pssch_pscch_file_test_ideal_tm4_p100 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -d -m 6 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p100_c335_size10_num10_cshift0_s30.72e6.dat) +add_lte_test(pssch_pscch_file_test_ideal_tm4_p100 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -d -m 6 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p100_c335_size10_num10_cshift0_s30.72e6.dat) set_property(TEST pssch_pscch_file_test_ideal_tm4_p100 PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=1") -add_test(pssch_pscch_test_tm4_p50_qc pssch_pscch_file_test -p 50 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_qc9150_f5.92e9_s15.36e6_50prb_20offset.dat) +add_lte_test(pssch_pscch_test_tm4_p50_qc pssch_pscch_file_test -p 50 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_qc9150_f5.92e9_s15.36e6_50prb_20offset.dat) set_property(TEST pssch_pscch_test_tm4_p50_qc PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=1 num_decoded_tb=1") # Capture has a SFO offset of ~64 samples, but offsetting by 20 is enough to decode it -add_test(pssch_pscch_test_tm4_p50_cmw pssch_pscch_file_test -p 50 -t 4 -o 20 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_0offset_1ms.dat) +add_lte_test(pssch_pscch_test_tm4_p50_cmw pssch_pscch_file_test -p 50 -t 4 -o 20 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_0offset_1ms.dat) set_property(TEST pssch_pscch_test_tm4_p50_cmw PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=1 num_decoded_tb=1") # With PHY retransmission (3 TTI offset) first SF at sf_idx=5 -add_test(pssch_pscch_test_tm4_p50_huawei pssch_pscch_file_test -p 50 -t 4 -m 5 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_huawei_s11.52e6_50prb_10prb_offset_with_retx.dat) +add_lte_test(pssch_pscch_test_tm4_p50_huawei pssch_pscch_file_test -p 50 -t 4 -m 5 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_huawei_s11.52e6_50prb_10prb_offset_with_retx.dat) set_property(TEST pssch_pscch_test_tm4_p50_huawei PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=2 num_decoded_tb=2") # With PHY ReTx (0 TTI offset?) -add_test(pssch_pscch_test_tm4_p50_uxm1 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs12.dat) +add_lte_test(pssch_pscch_test_tm4_p50_uxm1 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs12.dat) set_property(TEST pssch_pscch_test_tm4_p50_uxm1 PROPERTY PASS_REGULAR_EXPRESSION "mcs=12.*num_decoded_sci=2 num_decoded_tb=2") # 100 PRB startOffset 1 MCS12 MAC padding, first SF is index 0 -add_test(pssch_pscch_test_tm4_p100_uxm2 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s23.04e6_100prb_1prb_offset_mcs12_padding.dat) +add_lte_test(pssch_pscch_test_tm4_p100_uxm2 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s23.04e6_100prb_1prb_offset_mcs12_padding.dat) set_property(TEST pssch_pscch_test_tm4_p100_uxm2 PROPERTY PASS_REGULAR_EXPRESSION "mcs=12.*num_decoded_sci=4") # 100 PRB LTE sampling rate, startOffset1 MCS12 ITS data, first SF is index 6 -add_test(pssch_pscch_test_tm4_p100_uxm3 pssch_pscch_file_test -p 100 -d -t 4 -s 10 -n 10 -m 6 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s30.72e6_100prb_1prb_offset_mcs12_its.dat) +add_lte_test(pssch_pscch_test_tm4_p100_uxm3 pssch_pscch_file_test -p 100 -d -t 4 -s 10 -n 10 -m 6 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s30.72e6_100prb_1prb_offset_mcs12_its.dat) set_property(TEST pssch_pscch_test_tm4_p100_uxm3 PROPERTY PASS_REGULAR_EXPRESSION "mcs=12.*num_decoded_sci=1") # 50 PRB LTE sampling rate, startOffset0 MCS28 MAC padding, first SF is index 1 -add_test(pssch_pscch_test_tm4_p50_uxm4 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -m 1 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs28_padding_5ms.dat) +add_lte_test(pssch_pscch_test_tm4_p50_uxm4 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -m 1 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs28_padding_5ms.dat) set_property(TEST pssch_pscch_test_tm4_p50_uxm4 PROPERTY PASS_REGULAR_EXPRESSION "mcs=28.*num_decoded_sci=5") ######################################################################## @@ -161,12 +163,12 @@ set_property(TEST pssch_pscch_test_tm4_p50_uxm4 PROPERTY PASS_REGULAR_EXPRESSION add_executable(npbch_test npbch_test.c) target_link_libraries(npbch_test srslte_phy) -add_test(npbch_test npbch_test) +add_lte_test(npbch_test npbch_test) -add_test(npbch_file_test_r13 npbch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_amari_nid0_sfn514_sib2.bin) -add_test(npbch_file_test_r14 npbch_file_test -l 256 -R -r 0 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_nid256_r14_sf0.bin) -add_test(npbch_file_test_nid257_r13 npbch_file_test -l 257 -r 4 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_nid257_r13_sf0.bin) -add_test(npbch_file_test_nid257_r14 npbch_file_test -l 257 -R -r 7 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_nid257_r14_sf0.bin) +add_lte_test(npbch_file_test_r13 npbch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_amari_nid0_sfn514_sib2.bin) +add_lte_test(npbch_file_test_r14 npbch_file_test -l 256 -R -r 0 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_nid256_r14_sf0.bin) +add_lte_test(npbch_file_test_nid257_r13 npbch_file_test -l 257 -r 4 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_nid257_r13_sf0.bin) +add_lte_test(npbch_file_test_nid257_r14 npbch_file_test -l 257 -R -r 7 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_nid257_r14_sf0.bin) ######################################################################## # PCFICH TEST @@ -175,12 +177,12 @@ add_test(npbch_file_test_nid257_r14 npbch_file_test -l 257 -R -r 7 -i ${CMAKE_CU add_executable(pcfich_test pcfich_test.c) target_link_libraries(pcfich_test srslte_phy) -add_test(pcfich_test_6 pcfich_test -p 1 -n 6) -add_test(pcfich_test_62 pcfich_test -p 2 -n 6) -add_test(pcfich_test_64 pcfich_test -p 4 -n 6) -add_test(pcfich_test_10 pcfich_test -p 1 -n 10) -add_test(pcfich_test_102 pcfich_test -p 2 -n 10) -add_test(pcfich_test_104 pcfich_test -p 4 -n 10) +add_lte_test(pcfich_test_6 pcfich_test -p 1 -n 6) +add_lte_test(pcfich_test_62 pcfich_test -p 2 -n 6) +add_lte_test(pcfich_test_64 pcfich_test -p 4 -n 6) +add_lte_test(pcfich_test_10 pcfich_test -p 1 -n 10) +add_lte_test(pcfich_test_102 pcfich_test -p 2 -n 10) +add_lte_test(pcfich_test_104 pcfich_test -p 4 -n 10) ######################################################################## # PHICH TEST @@ -189,17 +191,17 @@ add_test(pcfich_test_104 pcfich_test -p 4 -n 10) add_executable(phich_test phich_test.c) target_link_libraries(phich_test srslte_phy) -add_test(phich_test_6 phich_test -p 1 -n 6) -add_test(phich_test_62 phich_test -p 2 -n 6) -add_test(phich_test_64 phich_test -p 4 -n 6 -g 1/6) +add_lte_test(phich_test_6 phich_test -p 1 -n 6) +add_lte_test(phich_test_62 phich_test -p 2 -n 6) +add_lte_test(phich_test_64 phich_test -p 4 -n 6 -g 1/6) -add_test(phich_test_6e phich_test -p 1 -n 6 -e) -add_test(phich_test_62e phich_test -p 2 -n 6 -e -l) -add_test(phich_test_64e phich_test -p 4 -n 6 -e -l -g 2) +add_lte_test(phich_test_6e phich_test -p 1 -n 6 -e) +add_lte_test(phich_test_62e phich_test -p 2 -n 6 -e -l) +add_lte_test(phich_test_64e phich_test -p 4 -n 6 -e -l -g 2) -add_test(phich_test_10 phich_test -p 1 -n 10 -e) -add_test(phich_test_102 phich_test -p 2 -n 10 -g 2) -add_test(phich_test_104 phich_test -p 4 -n 10 -e -l -g 1/2) +add_lte_test(phich_test_10 phich_test -p 1 -n 10 -e) +add_lte_test(phich_test_102 phich_test -p 2 -n 10 -g 2) +add_lte_test(phich_test_104 phich_test -p 4 -n 10 -e -l -g 1/2) ######################################################################## # PDCCH TEST @@ -208,19 +210,19 @@ add_test(phich_test_104 phich_test -p 4 -n 10 -e -l -g 1/2) add_executable(pdcch_test pdcch_test.c) target_link_libraries(pdcch_test srslte_phy) -add_test(pdcch_test_6 pdcch_test -n 6) -add_test(pdcch_test_15 pdcch_test -n 15) -add_test(pdcch_test_25 pdcch_test -n 25) -add_test(pdcch_test_50 pdcch_test -n 50) -add_test(pdcch_test_75 pdcch_test -n 75) -add_test(pdcch_test_100 pdcch_test -n 100) -add_test(pdcch_test_6_mimo pdcch_test -n 6 -p 2) -add_test(pdcch_test_15_mimo pdcch_test -n 15 -p 2) -add_test(pdcch_test_25_mimo pdcch_test -n 25 -p 2) -add_test(pdcch_test_50_mimo pdcch_test -n 50 -p 2) -add_test(pdcch_test_75_mimo pdcch_test -n 75 -p 2) -add_test(pdcch_test_100_mimo pdcch_test -n 100 -p 2) -#add_test(pdcch_test_crosscarrier pdcch_test -x) +add_lte_test(pdcch_test_6 pdcch_test -n 6) +add_lte_test(pdcch_test_15 pdcch_test -n 15) +add_lte_test(pdcch_test_25 pdcch_test -n 25) +add_lte_test(pdcch_test_50 pdcch_test -n 50) +add_lte_test(pdcch_test_75 pdcch_test -n 75) +add_lte_test(pdcch_test_100 pdcch_test -n 100) +add_lte_test(pdcch_test_6_mimo pdcch_test -n 6 -p 2) +add_lte_test(pdcch_test_15_mimo pdcch_test -n 15 -p 2) +add_lte_test(pdcch_test_25_mimo pdcch_test -n 25 -p 2) +add_lte_test(pdcch_test_50_mimo pdcch_test -n 50 -p 2) +add_lte_test(pdcch_test_75_mimo pdcch_test -n 75 -p 2) +add_lte_test(pdcch_test_100_mimo pdcch_test -n 100 -p 2) +#add_lte_test(pdcch_test_crosscarrier pdcch_test -x) ######################################################################## # PDSCH TEST @@ -229,106 +231,106 @@ add_test(pdcch_test_100_mimo pdcch_test -n 100 -p 2) add_executable(pdsch_test pdsch_test.c) target_link_libraries(pdsch_test srslte_phy) -add_test(pdsch_test_qpsk pdsch_test -m 10 -n 50 -r 1) -add_test(pdsch_test_qam16 pdsch_test -m 20 -n 100) -add_test(pdsch_test_qam16 pdsch_test -m 20 -n 100 -r 2) -add_test(pdsch_test_qam64 pdsch_test -n 100) +add_lte_test(pdsch_test_qpsk pdsch_test -m 10 -n 50 -r 1) +add_lte_test(pdsch_test_qam16 pdsch_test -m 20 -n 100) +add_lte_test(pdsch_test_qam16 pdsch_test -m 20 -n 100 -r 2) +add_lte_test(pdsch_test_qam64 pdsch_test -n 100) # PDSCH test for 1 transmision mode and 2 Rx antennas -add_test(pdsch_test_sin_6 pdsch_test -x 1 -a 2 -n 6) -add_test(pdsch_test_sin_12 pdsch_test -x 1 -a 2 -n 12) -add_test(pdsch_test_sin_25 pdsch_test -x 1 -a 2 -n 25) -add_test(pdsch_test_sin_50 pdsch_test -x 1 -a 2 -n 50) -add_test(pdsch_test_sin_75 pdsch_test -x 1 -a 2 -n 75) -add_test(pdsch_test_sin_100 pdsch_test -x 1 -a 2 -n 100) +add_lte_test(pdsch_test_sin_6 pdsch_test -x 1 -a 2 -n 6) +add_lte_test(pdsch_test_sin_12 pdsch_test -x 1 -a 2 -n 12) +add_lte_test(pdsch_test_sin_25 pdsch_test -x 1 -a 2 -n 25) +add_lte_test(pdsch_test_sin_50 pdsch_test -x 1 -a 2 -n 50) +add_lte_test(pdsch_test_sin_75 pdsch_test -x 1 -a 2 -n 75) +add_lte_test(pdsch_test_sin_100 pdsch_test -x 1 -a 2 -n 100) # PDSCH test for transmit 2 transmision mode (1 codeword) -add_test(pdsch_test_div_6 pdsch_test -x 2 -a 2 -n 6) -add_test(pdsch_test_div_12 pdsch_test -x 2 -a 2 -n 12) -add_test(pdsch_test_div_25 pdsch_test -x 2 -a 2 -n 25) -add_test(pdsch_test_div_50 pdsch_test -x 2 -a 2 -n 50) -add_test(pdsch_test_div_75 pdsch_test -x 2 -a 2 -n 75) -add_test(pdsch_test_div_100 pdsch_test -x 2 -a 2 -n 100) +add_lte_test(pdsch_test_div_6 pdsch_test -x 2 -a 2 -n 6) +add_lte_test(pdsch_test_div_12 pdsch_test -x 2 -a 2 -n 12) +add_lte_test(pdsch_test_div_25 pdsch_test -x 2 -a 2 -n 25) +add_lte_test(pdsch_test_div_50 pdsch_test -x 2 -a 2 -n 50) +add_lte_test(pdsch_test_div_75 pdsch_test -x 2 -a 2 -n 75) +add_lte_test(pdsch_test_div_100 pdsch_test -x 2 -a 2 -n 100) # PDSCH test for CDD transmision mode (2 codeword) -add_test(pdsch_test_cdd_6 pdsch_test -x 3 -a 2 -t 0 -n 6) -add_test(pdsch_test_cdd_12 pdsch_test -x 3 -a 2 -t 0 -n 12) -add_test(pdsch_test_cdd_25 pdsch_test -x 3 -a 2 -t 0 -n 25) -add_test(pdsch_test_cdd_50 pdsch_test -x 3 -a 2 -t 0 -n 50) -add_test(pdsch_test_cdd_75 pdsch_test -x 3 -a 2 -t 0 -n 75) -add_test(pdsch_test_cdd_100 pdsch_test -x 3 -a 2 -t 0 -n 100) +add_lte_test(pdsch_test_cdd_6 pdsch_test -x 3 -a 2 -t 0 -n 6) +add_lte_test(pdsch_test_cdd_12 pdsch_test -x 3 -a 2 -t 0 -n 12) +add_lte_test(pdsch_test_cdd_25 pdsch_test -x 3 -a 2 -t 0 -n 25) +add_lte_test(pdsch_test_cdd_50 pdsch_test -x 3 -a 2 -t 0 -n 50) +add_lte_test(pdsch_test_cdd_75 pdsch_test -x 3 -a 2 -t 0 -n 75) +add_lte_test(pdsch_test_cdd_100 pdsch_test -x 3 -a 2 -t 0 -n 100) # PDSCH test for CDD transmision mode (2 codeword) and 256QAM -add_test(pdsch_test_cdd_6 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 6 -q) -add_test(pdsch_test_cdd_12 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 12 -q) -add_test(pdsch_test_cdd_25 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 25 -q) -add_test(pdsch_test_cdd_50 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 50 -q) -add_test(pdsch_test_cdd_75 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 75 -q) -add_test(pdsch_test_cdd_100 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 100 -q) +add_lte_test(pdsch_test_cdd_6 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 6 -q) +add_lte_test(pdsch_test_cdd_12 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 12 -q) +add_lte_test(pdsch_test_cdd_25 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 25 -q) +add_lte_test(pdsch_test_cdd_50 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 50 -q) +add_lte_test(pdsch_test_cdd_75 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 75 -q) +add_lte_test(pdsch_test_cdd_100 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 100 -q) # PDSCH test for Spatial Multiplex transmision mode with PMI = 0 (1 codeword) -add_test(pdsch_test_multiplex1cw_p0_6 pdsch_test -x 4 -a 2 -p 0 -n 6) -add_test(pdsch_test_multiplex1cw_p0_12 pdsch_test -x 4 -a 2 -p 0 -n 12) -add_test(pdsch_test_multiplex1cw_p0_25 pdsch_test -x 4 -a 2 -p 0 -n 25) -add_test(pdsch_test_multiplex1cw_p0_50 pdsch_test -x 4 -a 2 -p 0 -n 50) -add_test(pdsch_test_multiplex1cw_p0_75 pdsch_test -x 4 -a 2 -p 0 -n 75) -add_test(pdsch_test_multiplex1cw_p0_100 pdsch_test -x 4 -a 2 -p 0 -n 100) +add_lte_test(pdsch_test_multiplex1cw_p0_6 pdsch_test -x 4 -a 2 -p 0 -n 6) +add_lte_test(pdsch_test_multiplex1cw_p0_12 pdsch_test -x 4 -a 2 -p 0 -n 12) +add_lte_test(pdsch_test_multiplex1cw_p0_25 pdsch_test -x 4 -a 2 -p 0 -n 25) +add_lte_test(pdsch_test_multiplex1cw_p0_50 pdsch_test -x 4 -a 2 -p 0 -n 50) +add_lte_test(pdsch_test_multiplex1cw_p0_75 pdsch_test -x 4 -a 2 -p 0 -n 75) +add_lte_test(pdsch_test_multiplex1cw_p0_100 pdsch_test -x 4 -a 2 -p 0 -n 100) # PDSCH test for Spatial Multiplex transmision mode with PMI = 0 (1 codeword, swapped) -add_test(pdsch_test_multiplex1cw_p0_swap_6 pdsch_test -x 4 -a 2 -p 0 -w -n 6) -add_test(pdsch_test_multiplex1cw_p0_swap_12 pdsch_test -x 4 -a 2 -p 0 -w -n 12) -add_test(pdsch_test_multiplex1cw_p0_swap_25 pdsch_test -x 4 -a 2 -p 0 -w -n 25) -add_test(pdsch_test_multiplex1cw_p0_swap_50 pdsch_test -x 4 -a 2 -p 0 -w -n 50) -add_test(pdsch_test_multiplex1cw_p0_swap_75 pdsch_test -x 4 -a 2 -p 0 -w -n 75) -add_test(pdsch_test_multiplex1cw_p0_swap_100 pdsch_test -x 4 -a 2 -p 0 -w -n 100) +add_lte_test(pdsch_test_multiplex1cw_p0_swap_6 pdsch_test -x 4 -a 2 -p 0 -w -n 6) +add_lte_test(pdsch_test_multiplex1cw_p0_swap_12 pdsch_test -x 4 -a 2 -p 0 -w -n 12) +add_lte_test(pdsch_test_multiplex1cw_p0_swap_25 pdsch_test -x 4 -a 2 -p 0 -w -n 25) +add_lte_test(pdsch_test_multiplex1cw_p0_swap_50 pdsch_test -x 4 -a 2 -p 0 -w -n 50) +add_lte_test(pdsch_test_multiplex1cw_p0_swap_75 pdsch_test -x 4 -a 2 -p 0 -w -n 75) +add_lte_test(pdsch_test_multiplex1cw_p0_swap_100 pdsch_test -x 4 -a 2 -p 0 -w -n 100) # PDSCH test for Spatial Multiplex transmision mode with PMI = 1 (1 codeword) -add_test(pdsch_test_multiplex1cw_p1_6 pdsch_test -x 4 -a 2 -p 1 -n 6) -add_test(pdsch_test_multiplex1cw_p1_12 pdsch_test -x 4 -a 2 -p 1 -n 12) -add_test(pdsch_test_multiplex1cw_p1_25 pdsch_test -x 4 -a 2 -p 1 -n 25) -add_test(pdsch_test_multiplex1cw_p1_50 pdsch_test -x 4 -a 2 -p 1 -n 50) -add_test(pdsch_test_multiplex1cw_p1_75 pdsch_test -x 4 -a 2 -p 1 -n 75) -add_test(pdsch_test_multiplex1cw_p1_100 pdsch_test -x 4 -a 2 -p 1 -n 100) +add_lte_test(pdsch_test_multiplex1cw_p1_6 pdsch_test -x 4 -a 2 -p 1 -n 6) +add_lte_test(pdsch_test_multiplex1cw_p1_12 pdsch_test -x 4 -a 2 -p 1 -n 12) +add_lte_test(pdsch_test_multiplex1cw_p1_25 pdsch_test -x 4 -a 2 -p 1 -n 25) +add_lte_test(pdsch_test_multiplex1cw_p1_50 pdsch_test -x 4 -a 2 -p 1 -n 50) +add_lte_test(pdsch_test_multiplex1cw_p1_75 pdsch_test -x 4 -a 2 -p 1 -n 75) +add_lte_test(pdsch_test_multiplex1cw_p1_100 pdsch_test -x 4 -a 2 -p 1 -n 100) # PDSCH test for Spatial Multiplex transmision mode with PMI = 2 (1 codeword) -add_test(pdsch_test_multiplex1cw_p2_6 pdsch_test -x 4 -a 2 -p 2 -n 6) -add_test(pdsch_test_multiplex1cw_p2_12 pdsch_test -x 4 -a 2 -p 2 -n 12) -add_test(pdsch_test_multiplex1cw_p2_25 pdsch_test -x 4 -a 2 -p 2 -n 25) -add_test(pdsch_test_multiplex1cw_p2_50 pdsch_test -x 4 -a 2 -p 2 -n 50) -add_test(pdsch_test_multiplex1cw_p2_75 pdsch_test -x 4 -a 2 -p 2 -n 75) -add_test(pdsch_test_multiplex1cw_p2_100 pdsch_test -x 4 -a 2 -p 2 -n 100) +add_lte_test(pdsch_test_multiplex1cw_p2_6 pdsch_test -x 4 -a 2 -p 2 -n 6) +add_lte_test(pdsch_test_multiplex1cw_p2_12 pdsch_test -x 4 -a 2 -p 2 -n 12) +add_lte_test(pdsch_test_multiplex1cw_p2_25 pdsch_test -x 4 -a 2 -p 2 -n 25) +add_lte_test(pdsch_test_multiplex1cw_p2_50 pdsch_test -x 4 -a 2 -p 2 -n 50) +add_lte_test(pdsch_test_multiplex1cw_p2_75 pdsch_test -x 4 -a 2 -p 2 -n 75) +add_lte_test(pdsch_test_multiplex1cw_p2_100 pdsch_test -x 4 -a 2 -p 2 -n 100) # PDSCH test for Spatial Multiplex transmision mode with PMI = 3 (1 codeword) -add_test(pdsch_test_multiplex1cw_p3_6 pdsch_test -x 4 -a 2 -p 3 -n 6) -add_test(pdsch_test_multiplex1cw_p3_12 pdsch_test -x 4 -a 2 -p 3 -n 12) -add_test(pdsch_test_multiplex1cw_p3_25 pdsch_test -x 4 -a 2 -p 3 -n 25) -add_test(pdsch_test_multiplex1cw_p3_50 pdsch_test -x 4 -a 2 -p 3 -n 50) -add_test(pdsch_test_multiplex1cw_p3_75 pdsch_test -x 4 -a 2 -p 3 -n 75) -add_test(pdsch_test_multiplex1cw_p3_100 pdsch_test -x 4 -a 2 -p 3 -n 100) +add_lte_test(pdsch_test_multiplex1cw_p3_6 pdsch_test -x 4 -a 2 -p 3 -n 6) +add_lte_test(pdsch_test_multiplex1cw_p3_12 pdsch_test -x 4 -a 2 -p 3 -n 12) +add_lte_test(pdsch_test_multiplex1cw_p3_25 pdsch_test -x 4 -a 2 -p 3 -n 25) +add_lte_test(pdsch_test_multiplex1cw_p3_50 pdsch_test -x 4 -a 2 -p 3 -n 50) +add_lte_test(pdsch_test_multiplex1cw_p3_75 pdsch_test -x 4 -a 2 -p 3 -n 75) +add_lte_test(pdsch_test_multiplex1cw_p3_100 pdsch_test -x 4 -a 2 -p 3 -n 100) # PDSCH test for Spatial Multiplex transmision mode with PMI = 0 (2 codeword) -add_test(pdsch_test_multiplex2cw_p0_6 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 6) -add_test(pdsch_test_multiplex2cw_p0_12 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 12) -add_test(pdsch_test_multiplex2cw_p0_25 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 25) -add_test(pdsch_test_multiplex2cw_p0_50 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 50) -add_test(pdsch_test_multiplex2cw_p0_75 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 75) -add_test(pdsch_test_multiplex2cw_p0_100 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 100) +add_lte_test(pdsch_test_multiplex2cw_p0_6 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 6) +add_lte_test(pdsch_test_multiplex2cw_p0_12 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 12) +add_lte_test(pdsch_test_multiplex2cw_p0_25 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 25) +add_lte_test(pdsch_test_multiplex2cw_p0_50 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 50) +add_lte_test(pdsch_test_multiplex2cw_p0_75 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 75) +add_lte_test(pdsch_test_multiplex2cw_p0_100 pdsch_test -x 4 -a 2 -t 0 -p 0 -n 100) # PDSCH test for Spatial Multiplex transmision mode with PMI = 0 (2 codeword, swapped) -add_test(pdsch_test_multiplex2cw_p0_6_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -M 28 -n 6 -w -F 1) -add_test(pdsch_test_multiplex2cw_p0_12_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -m 28 -n 12 -w) -add_test(pdsch_test_multiplex2cw_p0_25_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -M 28 -n 25 -w) -add_test(pdsch_test_multiplex2cw_p0_50_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -m 28 -n 50 -w) -add_test(pdsch_test_multiplex2cw_p0_75_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -M 28 -n 75 -w) -add_test(pdsch_test_multiplex2cw_p0_100_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -m 28 -n 100 -w) +add_lte_test(pdsch_test_multiplex2cw_p0_6_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -M 28 -n 6 -w -F 1) +add_lte_test(pdsch_test_multiplex2cw_p0_12_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -m 28 -n 12 -w) +add_lte_test(pdsch_test_multiplex2cw_p0_25_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -M 28 -n 25 -w) +add_lte_test(pdsch_test_multiplex2cw_p0_50_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -m 28 -n 50 -w) +add_lte_test(pdsch_test_multiplex2cw_p0_75_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -M 28 -n 75 -w) +add_lte_test(pdsch_test_multiplex2cw_p0_100_swap pdsch_test -x 4 -a 2 -t 0 -p 0 -m 28 -n 100 -w) # PDSCH test for Spatial Multiplex transmision mode with PMI = 1 (2 codeword) -add_test(pdsch_test_multiplex2cw_p1_6 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 6) -add_test(pdsch_test_multiplex2cw_p1_12 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 12) -add_test(pdsch_test_multiplex2cw_p1_25 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 25) -add_test(pdsch_test_multiplex2cw_p1_50 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 50) -add_test(pdsch_test_multiplex2cw_p1_75 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 75) -add_test(pdsch_test_multiplex2cw_p1_100 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 100) +add_lte_test(pdsch_test_multiplex2cw_p1_6 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 6) +add_lte_test(pdsch_test_multiplex2cw_p1_12 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 12) +add_lte_test(pdsch_test_multiplex2cw_p1_25 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 25) +add_lte_test(pdsch_test_multiplex2cw_p1_50 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 50) +add_lte_test(pdsch_test_multiplex2cw_p1_75 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 75) +add_lte_test(pdsch_test_multiplex2cw_p1_100 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 100) ######################################################################## # PMCH TEST @@ -337,9 +339,9 @@ add_test(pdsch_test_multiplex2cw_p1_100 pdsch_test -x 4 -a 2 -t 0 -p 1 -n 100) add_executable(pmch_test pmch_test.c) target_link_libraries(pmch_test srslte_phy) -add_test(pmch_test_qpsk pmch_test -m 6 -n 50) -add_test(pmch_test_qam16 pmch_test -m 15 -n 100) -add_test(pmch_test_qam64 pmch_test -m 25 -n 100) +add_lte_test(pmch_test_qpsk pmch_test -m 6 -n 50) +add_lte_test(pmch_test_qam16 pmch_test -m 15 -n 100) +add_lte_test(pmch_test_qam64 pmch_test -m 25 -n 100) ######################################################################## @@ -349,51 +351,51 @@ add_test(pmch_test_qam64 pmch_test -m 25 -n 100) add_executable(npdsch_test npdsch_test.c) target_link_libraries(npdsch_test srslte_phy) -add_test(npdsch_test_tbs208 npdsch_test -m 12) -add_test(npdsch_test_tbs104 npdsch_test -m 7) -add_test(npdsch_test_tbs40 npdsch_test -m 3) -add_test(npdsch_test_tbs16 npdsch_test -m 0) +add_lte_test(npdsch_test_tbs208 npdsch_test -m 12) +add_lte_test(npdsch_test_tbs104 npdsch_test -m 7) +add_lte_test(npdsch_test_tbs40 npdsch_test -m 3) +add_lte_test(npdsch_test_tbs16 npdsch_test -m 0) # Resource element extraction for different operation modes and cell configuration # Standalone mode with one Tx port gives maximum number of NPDSCH symbols -add_test(npdsch_test_cellid0_standalone_1port npdsch_test -l 0 -M 3 -x 160) -add_test(npdsch_test_cellid1_standalone_1port npdsch_test -l 1 -M 3 -x 160) -add_test(npdsch_test_cellid2_standalone_1port npdsch_test -l 2 -M 3 -x 160) -add_test(npdsch_test_cellid3_standalone_1port npdsch_test -l 3 -M 3 -x 160) -add_test(npdsch_test_cellid4_standalone_1port npdsch_test -l 4 -M 3 -x 160) -add_test(npdsch_test_cellid5_standalone_1port npdsch_test -l 5 -M 3 -x 160) +add_lte_test(npdsch_test_cellid0_standalone_1port npdsch_test -l 0 -M 3 -x 160) +add_lte_test(npdsch_test_cellid1_standalone_1port npdsch_test -l 1 -M 3 -x 160) +add_lte_test(npdsch_test_cellid2_standalone_1port npdsch_test -l 2 -M 3 -x 160) +add_lte_test(npdsch_test_cellid3_standalone_1port npdsch_test -l 3 -M 3 -x 160) +add_lte_test(npdsch_test_cellid4_standalone_1port npdsch_test -l 4 -M 3 -x 160) +add_lte_test(npdsch_test_cellid5_standalone_1port npdsch_test -l 5 -M 3 -x 160) # Standalone mode with two Tx ports -add_test(npdsch_test_cellid0_standalone_2port npdsch_test -l 0 -M 3 -P 2 -x 152) -add_test(npdsch_test_cellid1_standalone_2port npdsch_test -l 1 -M 3 -P 2 -x 152) -add_test(npdsch_test_cellid2_standalone_2port npdsch_test -l 2 -M 3 -P 2 -x 152) -add_test(npdsch_test_cellid3_standalone_2port npdsch_test -l 3 -M 3 -P 2 -x 152) -add_test(npdsch_test_cellid4_standalone_2port npdsch_test -l 4 -M 3 -P 2 -x 152) -add_test(npdsch_test_cellid5_standalone_2port npdsch_test -l 5 -M 3 -P 2 -x 152) +add_lte_test(npdsch_test_cellid0_standalone_2port npdsch_test -l 0 -M 3 -P 2 -x 152) +add_lte_test(npdsch_test_cellid1_standalone_2port npdsch_test -l 1 -M 3 -P 2 -x 152) +add_lte_test(npdsch_test_cellid2_standalone_2port npdsch_test -l 2 -M 3 -P 2 -x 152) +add_lte_test(npdsch_test_cellid3_standalone_2port npdsch_test -l 3 -M 3 -P 2 -x 152) +add_lte_test(npdsch_test_cellid4_standalone_2port npdsch_test -l 4 -M 3 -P 2 -x 152) +add_lte_test(npdsch_test_cellid5_standalone_2port npdsch_test -l 5 -M 3 -P 2 -x 152) # Inband same PCI with 1 LTE antenna port and two NB-IoT ports -add_test(npdsch_test_cellid0_inband_1port_2port npdsch_test -l 0 -M 0 -p 1 -P 2 -x 144) -add_test(npdsch_test_cellid1_inband_1port_2port npdsch_test -l 1 -M 0 -p 1 -P 2 -x 144) -add_test(npdsch_test_cellid2_inband_1port_2port npdsch_test -l 2 -M 0 -p 1 -P 2 -x 144) -add_test(npdsch_test_cellid3_inband_1port_2port npdsch_test -l 3 -M 0 -p 1 -P 2 -x 144) -add_test(npdsch_test_cellid4_inband_1port_2port npdsch_test -l 4 -M 0 -p 1 -P 2 -x 144) -add_test(npdsch_test_cellid5_inband_1port_2port npdsch_test -l 5 -M 0 -p 1 -P 2 -x 144) +add_lte_test(npdsch_test_cellid0_inband_1port_2port npdsch_test -l 0 -M 0 -p 1 -P 2 -x 144) +add_lte_test(npdsch_test_cellid1_inband_1port_2port npdsch_test -l 1 -M 0 -p 1 -P 2 -x 144) +add_lte_test(npdsch_test_cellid2_inband_1port_2port npdsch_test -l 2 -M 0 -p 1 -P 2 -x 144) +add_lte_test(npdsch_test_cellid3_inband_1port_2port npdsch_test -l 3 -M 0 -p 1 -P 2 -x 144) +add_lte_test(npdsch_test_cellid4_inband_1port_2port npdsch_test -l 4 -M 0 -p 1 -P 2 -x 144) +add_lte_test(npdsch_test_cellid5_inband_1port_2port npdsch_test -l 5 -M 0 -p 1 -P 2 -x 144) # Inband same PCI with 2 antenna ports each -add_test(npdsch_test_cellid0_inband_2port_2port npdsch_test -l 0 -M 0 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid1_inband_2port_2port npdsch_test -l 1 -M 0 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid2_inband_2port_2port npdsch_test -l 2 -M 0 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid3_inband_2port_2port npdsch_test -l 3 -M 0 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid4_inband_2port_2port npdsch_test -l 4 -M 0 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid5_inband_2port_2port npdsch_test -l 5 -M 0 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid0_inband_2port_2port npdsch_test -l 0 -M 0 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid1_inband_2port_2port npdsch_test -l 1 -M 0 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid2_inband_2port_2port npdsch_test -l 2 -M 0 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid3_inband_2port_2port npdsch_test -l 3 -M 0 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid4_inband_2port_2port npdsch_test -l 4 -M 0 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid5_inband_2port_2port npdsch_test -l 5 -M 0 -p 2 -P 2 -x 136) # Inband different PCI with 2 antenna ports each -add_test(npdsch_test_cellid0_inband_diffpci_2port_2port npdsch_test -l 0 -M 1 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid1_inband_diffpci_2port_2port npdsch_test -l 1 -M 1 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid2_inband_diffpci_2port_2port npdsch_test -l 2 -M 1 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid3_inband_diffpci_2port_2port npdsch_test -l 3 -M 1 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid4_inband_diffpci_2port_2port npdsch_test -l 4 -M 1 -p 2 -P 2 -x 136) -add_test(npdsch_test_cellid5_inband_diffpci_2port_2port npdsch_test -l 5 -M 1 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid0_inband_diffpci_2port_2port npdsch_test -l 0 -M 1 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid1_inband_diffpci_2port_2port npdsch_test -l 1 -M 1 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid2_inband_diffpci_2port_2port npdsch_test -l 2 -M 1 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid3_inband_diffpci_2port_2port npdsch_test -l 3 -M 1 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid4_inband_diffpci_2port_2port npdsch_test -l 4 -M 1 -p 2 -P 2 -x 136) +add_lte_test(npdsch_test_cellid5_inband_diffpci_2port_2port npdsch_test -l 5 -M 1 -p 2 -P 2 -x 136) ######################################################################## # NB-IoT DCI TEST @@ -401,7 +403,7 @@ add_test(npdsch_test_cellid5_inband_diffpci_2port_2port npdsch_test -l 5 -M 1 -p add_executable(dci_nbiot_test dci_nbiot_test.c) target_link_libraries(dci_nbiot_test srslte_phy) -add_test(dci_nbiot_test dci_nbiot_test) +add_lte_test(dci_nbiot_test dci_nbiot_test) ######################################################################## # FILE TEST @@ -428,17 +430,17 @@ target_link_libraries(npbch_file_test srslte_phy) add_executable(npdsch_npdcch_file_test npdsch_npdcch_file_test.c) target_link_libraries(npdsch_npdcch_file_test srslte_phy) -add_test(pbch_file_test pbch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.dat) +add_lte_test(pbch_file_test pbch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.dat) add_executable(pmch_file_test pmch_file_test.c) target_link_libraries(pmch_file_test srslte_phy) -add_test(pbch_file_test pbch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.dat) -add_test(pcfich_file_test pcfich_file_test -c 150 -n 50 -p 2 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.10M.dat) -add_test(phich_file_test phich_file_test -c 150 -n 50 -p 2 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.10M.dat) -add_test(pdcch_file_test pdcch_file_test -c 1 -f 3 -n 6 -p 1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.amar.dat) -add_test(pdsch_pdcch_file_test pdsch_pdcch_file_test -c 1 -f 3 -n 6 -p 1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.amar.dat) -add_test(pmch_file_test pmch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/pmch_100prbs_MCS2_SR0.bin) +add_lte_test(pbch_file_test pbch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.dat) +add_lte_test(pcfich_file_test pcfich_file_test -c 150 -n 50 -p 2 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.10M.dat) +add_lte_test(phich_file_test phich_file_test -c 150 -n 50 -p 2 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.10M.dat) +add_lte_test(pdcch_file_test pdcch_file_test -c 1 -f 3 -n 6 -p 1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.amar.dat) +add_lte_test(pdsch_pdcch_file_test pdsch_pdcch_file_test -c 1 -f 3 -n 6 -p 1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal.1.92M.amar.dat) +add_lte_test(pmch_file_test pmch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/pmch_100prbs_MCS2_SR0.bin) ######################################################################## # NPDCCH TEST @@ -446,15 +448,15 @@ add_test(pmch_file_test pmch_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/pmch_100p add_executable(npdcch_test npdcch_test.c) target_link_libraries(npdcch_test srslte_phy) -add_test(npdcch_formatN1_test npdcch_test -o FormatN1) +add_lte_test(npdcch_formatN1_test npdcch_test -o FormatN1) add_executable(npdcch_file_test npdcch_file_test.c) target_link_libraries(npdcch_file_test srslte_phy) -add_test(npdcch_formatN0_file_test npdcch_file_test -c 0 -t 8624 -r 258 -L 1 -l 0 -v -o FormatN0 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN0_L_1_nid0_tti_8624_rnti_0x102.bin) -add_test(npdcch_formatN1_file_test npdcch_file_test -c 0 -t 5461 -r 137 -L 2 -l 0 -v -o FormatN1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN1_nid0_tti_5461_rnti_0x89.bin) +add_lte_test(npdcch_formatN0_file_test npdcch_file_test -c 0 -t 8624 -r 258 -L 1 -l 0 -v -o FormatN0 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN0_L_1_nid0_tti_8624_rnti_0x102.bin) +add_lte_test(npdcch_formatN1_file_test npdcch_file_test -c 0 -t 5461 -r 137 -L 2 -l 0 -v -o FormatN1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN1_nid0_tti_5461_rnti_0x89.bin) -add_test(npdsch_npdcch_dci_formatN0_test npdsch_npdcch_file_test -c 0 -s 4 -w 862 -r 0x102 -v -o FormatN0 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN0_L_1_nid0_tti_8624_rnti_0x102.bin) -add_test(npdsch_npdcch_dci_formatN1_test npdsch_npdcch_file_test -c 0 -s 1 -w 546 -r 0x89 -v -o FormatN1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN1_nid0_tti_5461_rnti_0x89.bin) +add_lte_test(npdsch_npdcch_dci_formatN0_test npdsch_npdcch_file_test -c 0 -s 4 -w 862 -r 0x102 -v -o FormatN0 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN0_L_1_nid0_tti_8624_rnti_0x102.bin) +add_lte_test(npdsch_npdcch_dci_formatN1_test npdsch_npdcch_file_test -c 0 -s 1 -w 546 -r 0x89 -v -o FormatN1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_nbiot_dci_formatN1_nid0_tti_5461_rnti_0x89.bin) ######################################################################## # PUSCH TEST @@ -531,7 +533,7 @@ foreach (cell_n_prb 6 15 25 50 75 100) string(REGEX REPLACE "\ " "" test_name_args ${pusch_test_args}) - add_test(pusch_test${test_name_args} pusch_test ${pusch_test_args}) + add_lte_test(pusch_test${test_name_args} pusch_test ${pusch_test_args}) endforeach (cqi) endforeach (ack) endforeach (mcs) @@ -545,8 +547,8 @@ endforeach (cell_n_prb) add_executable(pucch_test pucch_test.c) target_link_libraries(pucch_test srslte_phy) -add_test(pucch_test pucch_test) -add_test(pucch_test_uci_cqi_decoder pucch_test -q) +add_lte_test(pucch_test pucch_test) +add_lte_test(pucch_test_uci_cqi_decoder pucch_test -q) ######################################################################## # PRACH TEST @@ -555,67 +557,67 @@ add_test(pucch_test_uci_cqi_decoder pucch_test -q) add_executable(prach_test prach_test.c) target_link_libraries(prach_test srslte_phy) -add_test(prach prach_test) +add_lte_test(prach prach_test) -add_test(prach_256 prach_test -n 15) -add_test(prach_512 prach_test -n 25) -add_test(prach_1024 prach_test -n 50) -add_test(prach_1536 prach_test -n 75) -add_test(prach_2048 prach_test -n 100) +add_lte_test(prach_256 prach_test -n 15) +add_lte_test(prach_512 prach_test -n 25) +add_lte_test(prach_1024 prach_test -n 50) +add_lte_test(prach_1536 prach_test -n 75) +add_lte_test(prach_2048 prach_test -n 100) -add_test(prach_f0 prach_test -f 0) -add_test(prach_f1 prach_test -f 1) -add_test(prach_f2 prach_test -f 2) -add_test(prach_f3 prach_test -f 3) +add_lte_test(prach_f0 prach_test -f 0) +add_lte_test(prach_f1 prach_test -f 1) +add_lte_test(prach_f2 prach_test -f 2) +add_lte_test(prach_f3 prach_test -f 3) -add_test(prach_rs1 prach_test -r 1) -add_test(prach_rs2 prach_test -r 2) -add_test(prach_rs3 prach_test -r 3) +add_lte_test(prach_rs1 prach_test -r 1) +add_lte_test(prach_rs2 prach_test -r 2) +add_lte_test(prach_rs3 prach_test -r 3) -add_test(prach_zc0 prach_test -z 0) -add_test(prach_zc2 prach_test -z 2) -add_test(prach_zc3 prach_test -z 3) +add_lte_test(prach_zc0 prach_test -z 0) +add_lte_test(prach_zc2 prach_test -z 2) +add_lte_test(prach_zc3 prach_test -z 3) add_executable(prach_test_multi prach_test_multi.c) target_link_libraries(prach_test_multi srslte_phy) -add_test(prach_test_multi prach_test_multi) +add_lte_test(prach_test_multi prach_test_multi) -add_test(prach_test_multi_n32 prach_test_multi -n 32) -add_test(prach_test_multi_n16 prach_test_multi -n 16) -add_test(prach_test_multi_n8 prach_test_multi -n 8) -add_test(prach_test_multi_n4 prach_test_multi -n 4) +add_lte_test(prach_test_multi_n32 prach_test_multi -n 32) +add_lte_test(prach_test_multi_n16 prach_test_multi -n 16) +add_lte_test(prach_test_multi_n8 prach_test_multi -n 8) +add_lte_test(prach_test_multi_n4 prach_test_multi -n 4) -add_test(prach_test_multi_stagger_power prach_test_multi -s -S) -add_test(prach_test_multi_stagger_power prach_test_multi -s -S -N 50) +add_lte_test(prach_test_multi_stagger_power prach_test_multi -s -S) +add_lte_test(prach_test_multi_stagger_power prach_test_multi -s -S -N 50) -add_test(prach_test_multi_offset_test prach_test_multi -O) -add_test(prach_test_multi_offset_test_50 prach_test_multi -O -N 50) +add_lte_test(prach_test_multi_offset_test prach_test_multi -O) +add_lte_test(prach_test_multi_offset_test_50 prach_test_multi -O -N 50) -add_test(prach_test_multi_freq_offset_test_n1_o100_prb6 prach_test_multi -n 1 -F -z 0 -o 100) -add_test(prach_test_multi_freq_offset_test_n1_o500_prb6 prach_test_multi -n 1 -F -z 0 -o 500) -add_test(prach_test_multi_freq_offset_test_n1_o800_prb6 prach_test_multi -n 1 -F -z 0 -o 800) +add_lte_test(prach_test_multi_freq_offset_test_n1_o100_prb6 prach_test_multi -n 1 -F -z 0 -o 100) +add_lte_test(prach_test_multi_freq_offset_test_n1_o500_prb6 prach_test_multi -n 1 -F -z 0 -o 500) +add_lte_test(prach_test_multi_freq_offset_test_n1_o800_prb6 prach_test_multi -n 1 -F -z 0 -o 800) -add_test(prach_test_multi_freq_offset_test_n1_o100_prb50 prach_test_multi -n 1 -F -z 0 -o 100 -N 50) -add_test(prach_test_multi_freq_offset_test_n1_o500_prb50 prach_test_multi -n 1 -F -z 0 -o 500 -N 50) -add_test(prach_test_multi_freq_offset_test_n1_o800_prb50 prach_test_multi -n 1 -F -z 0 -o 800 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n1_o100_prb50 prach_test_multi -n 1 -F -z 0 -o 100 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n1_o500_prb50 prach_test_multi -n 1 -F -z 0 -o 500 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n1_o800_prb50 prach_test_multi -n 1 -F -z 0 -o 800 -N 50) -add_test(prach_test_multi_freq_offset_test_n2_o100_prb6 prach_test_multi -n 2 -F -z 0 -o 100) -add_test(prach_test_multi_freq_offset_test_n2_o500_prb6 prach_test_multi -n 2 -F -z 0 -o 500) -add_test(prach_test_multi_freq_offset_test_n2_o800_prb6 prach_test_multi -n 2 -F -z 0 -o 800) +add_lte_test(prach_test_multi_freq_offset_test_n2_o100_prb6 prach_test_multi -n 2 -F -z 0 -o 100) +add_lte_test(prach_test_multi_freq_offset_test_n2_o500_prb6 prach_test_multi -n 2 -F -z 0 -o 500) +add_lte_test(prach_test_multi_freq_offset_test_n2_o800_prb6 prach_test_multi -n 2 -F -z 0 -o 800) -add_test(prach_test_multi_freq_offset_test_n2_o100_prb50 prach_test_multi -n 2 -F -z 0 -o 100 -N 50) -add_test(prach_test_multi_freq_offset_test_n2_o500_prb50 prach_test_multi -n 2 -F -z 0 -o 500 -N 50) -add_test(prach_test_multi_freq_offset_test_n2_o800_prb50 prach_test_multi -n 2 -F -z 0 -o 800 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n2_o100_prb50 prach_test_multi -n 2 -F -z 0 -o 100 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n2_o500_prb50 prach_test_multi -n 2 -F -z 0 -o 500 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n2_o800_prb50 prach_test_multi -n 2 -F -z 0 -o 800 -N 50) -add_test(prach_test_multi_freq_offset_test_n4_o100_prb6 prach_test_multi -n 4 -F -z 0 -o 100) -add_test(prach_test_multi_freq_offset_test_n4_o500_prb6 prach_test_multi -n 4 -F -z 0 -o 500) -add_test(prach_test_multi_freq_offset_test_n4_o800_prb6 prach_test_multi -n 4 -F -z 0 -o 800) +add_lte_test(prach_test_multi_freq_offset_test_n4_o100_prb6 prach_test_multi -n 4 -F -z 0 -o 100) +add_lte_test(prach_test_multi_freq_offset_test_n4_o500_prb6 prach_test_multi -n 4 -F -z 0 -o 500) +add_lte_test(prach_test_multi_freq_offset_test_n4_o800_prb6 prach_test_multi -n 4 -F -z 0 -o 800) -add_test(prach_test_multi_freq_offset_test_n4_o100_prb50 prach_test_multi -n 4 -F -z 0 -o 100 -N 50) -add_test(prach_test_multi_freq_offset_test_n4_o500_prb50 prach_test_multi -n 4 -F -z 0 -o 500 -N 50) -add_test(prach_test_multi_freq_offset_test_n4_o800_prb50 prach_test_multi -n 4 -F -z 0 -o 800 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n4_o100_prb50 prach_test_multi -n 4 -F -z 0 -o 100 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n4_o500_prb50 prach_test_multi -n 4 -F -z 0 -o 500 -N 50) +add_lte_test(prach_test_multi_freq_offset_test_n4_o800_prb50 prach_test_multi -n 4 -F -z 0 -o 800 -N 50) if(RF_FOUND) add_executable(prach_test_usrp prach_test_usrp.c) @@ -628,20 +630,20 @@ endif(RF_FOUND) add_executable(pucch_nr_test pucch_nr_test.c) target_link_libraries(pucch_nr_test srslte_phy) -add_test(pucch_nr_test pucch_nr_test) +add_nr_test(pucch_nr_test pucch_nr_test) add_executable(sch_nr_test sch_nr_test.c) target_link_libraries(sch_nr_test srslte_phy) -add_test(sch_nr_test sch_nr_test -m 0 -p 1) +add_nr_test(sch_nr_test sch_nr_test -m 0 -p 1) add_executable(pdsch_nr_test pdsch_nr_test.c) target_link_libraries(pdsch_nr_test srslte_phy) -add_test(pdsch_nr_test pdsch_nr_test -p 6 -m 20) +add_nr_test(pdsch_nr_test pdsch_nr_test -p 6 -m 20) add_executable(pusch_nr_test pusch_nr_test.c) target_link_libraries(pusch_nr_test srslte_phy) -add_test(pusch_nr_test pusch_nr_test -p 6 -m 20) +add_nr_test(pusch_nr_test pusch_nr_test -p 6 -m 20) add_executable(pdcch_nr_test pdcch_nr_test.c) target_link_libraries(pdcch_nr_test srslte_phy) -add_test(pdcch_nr_test pdcch_nr_test) +add_nr_test(pdcch_nr_test pdcch_nr_test) diff --git a/lib/src/phy/phch/test/npbch_file_test.c b/lib/src/phy/phch/test/npbch_file_test.c index a2a9e83df..8ca311caf 100644 --- a/lib/src/phy/phch/test/npbch_file_test.c +++ b/lib/src/phy/phch/test/npbch_file_test.c @@ -174,7 +174,7 @@ int base_init() return -1; } - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } @@ -225,7 +225,7 @@ int main(int argc, char** argv) if (nread == SFLEN) { // do IFFT and channel estimation only on subframes that are known to contain NRS if (sf_idx == 0 || sf_idx == 4) { - INFO("%d.%d: Estimating channel.\n", frame_cnt, sf_idx); + INFO("%d.%d: Estimating channel.", frame_cnt, sf_idx); srslte_ofdm_rx_sf(&fft); // srslte_ofdm_set_normalize(&fft, true); @@ -238,10 +238,10 @@ int main(int argc, char** argv) if (sf_idx == 0) { float noise_est = (do_chest) ? srslte_chest_dl_nbiot_get_noise_estimate(&chest) : 0.0; if (frame_cnt % 8 == 0) { - DEBUG("Reseting NPBCH decoder.\n"); + DEBUG("Reseting NPBCH decoder."); srslte_npbch_decode_reset(&npbch); } - INFO("%d.0: Calling NPBCH decoder (noise_est=%.2f)\n", frame_cnt, noise_est); + INFO("%d.0: Calling NPBCH decoder (noise_est=%.2f)", frame_cnt, noise_est); ret = srslte_npbch_decode_nf(&npbch, fft_buffer, ce, noise_est, bch_payload, &nof_tx_ports, NULL, nf); if (ret == SRSLTE_SUCCESS) { @@ -255,10 +255,10 @@ int main(int argc, char** argv) if (SRSLTE_VERBOSE_ISDEBUG()) { if (do_chest) { - DEBUG("SAVED FILE npbch_rx_chest_on.bin: NPBCH with chest\n"); + DEBUG("SAVED FILE npbch_rx_chest_on.bin: NPBCH with chest"); srslte_vec_save_file("npbch_rx_chest_on.bin", npbch.d, npbch.nof_symbols * sizeof(cf_t)); } else { - DEBUG("SAVED FILE npbch_rx_chest_off.bin: NPBCH without chest\n"); + DEBUG("SAVED FILE npbch_rx_chest_off.bin: NPBCH without chest"); srslte_vec_save_file("npbch_rx_chest_off.bin", npbch.d, npbch.nof_symbols * sizeof(cf_t)); } } diff --git a/lib/src/phy/phch/test/npdcch_file_test.c b/lib/src/phy/phch/test/npdcch_file_test.c index 3486ee1f6..d518d1f3d 100644 --- a/lib/src/phy/phch/test/npdcch_file_test.c +++ b/lib/src/phy/phch/test/npdcch_file_test.c @@ -84,7 +84,7 @@ void parse_args(int argc, char** argv) case 'o': dci_format = srslte_dci_format_from_string(argv[optind]); if (dci_format == SRSLTE_DCI_NOF_FORMATS) { - ERROR("Error unsupported format %s\n", argv[optind]); + ERROR("Error unsupported format %s", argv[optind]); exit(-1); } break; @@ -186,7 +186,7 @@ int main(int argc, char** argv) // Run FFT and estimate channel srslte_ofdm_rx_sf(&fft); - INFO("%d.%d: Estimating channel.\n", frame_cnt, tti % 10); + INFO("%d.%d: Estimating channel.", frame_cnt, tti % 10); srslte_chest_dl_nbiot_estimate(&chest, fft_buffer, ce, tti % 10); // Extract LLR diff --git a/lib/src/phy/phch/test/npdcch_test.c b/lib/src/phy/phch/test/npdcch_test.c index 725e01a83..e02ca4872 100644 --- a/lib/src/phy/phch/test/npdcch_test.c +++ b/lib/src/phy/phch/test/npdcch_test.c @@ -69,7 +69,7 @@ void parse_args(int argc, char** argv) case 'o': dci_format = srslte_dci_format_from_string(argv[optind]); if (dci_format == SRSLTE_DCI_NOF_FORMATS) { - ERROR("Error unsupported format %s\n", argv[optind]); + ERROR("Error unsupported format %s", argv[optind]); exit(-1); } break; diff --git a/lib/src/phy/phch/test/npdsch_npdcch_file_test.c b/lib/src/phy/phch/test/npdsch_npdcch_file_test.c index 7607c01f9..f40a5c213 100644 --- a/lib/src/phy/phch/test/npdsch_npdcch_file_test.c +++ b/lib/src/phy/phch/test/npdsch_npdcch_file_test.c @@ -168,7 +168,7 @@ int base_init() srslte_nbiot_ue_dl_set_rnti(&ue_dl, rnti); // srslte_mib_nb_printf(stdout, 0, &mib); - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } @@ -218,7 +218,7 @@ int main(int argc, char** argv) do { nread = srslte_filesource_read(&fsrc, buff_ptrs[0], flen); if (nread > 0) { - DEBUG("%d.%d: Reading %d samples.\n", sfn, sf_idx, nread); + DEBUG("%d.%d: Reading %d samples.", sfn, sf_idx, nread); // add some noise to the signal if (snr != -1.0) { @@ -233,7 +233,7 @@ int main(int argc, char** argv) // attempt to decode NPDSCH n = srslte_nbiot_ue_dl_decode_npdsch(&ue_dl, buff_ptrs[0], data, sfn, sf_idx, rnti); if (n == SRSLTE_SUCCESS) { - INFO("NPDSCH decoded ok.\n"); + INFO("NPDSCH decoded ok."); if (decode_sib1) { srslte_nbiot_ue_dl_decode_sib1(&ue_dl, sfn); @@ -247,7 +247,7 @@ int main(int argc, char** argv) srslte_dci_msg_t dci_msg; n = srslte_nbiot_ue_dl_decode_npdcch(&ue_dl, buff_ptrs[0], sfn, sf_idx, rnti, &dci_msg); if (n == SRSLTE_NBIOT_UE_DL_FOUND_DCI) { - INFO("Found %s DCI for RNTI=0x%x\n", srslte_dci_format_string(dci_msg.format), rnti); + INFO("Found %s DCI for RNTI=0x%x", srslte_dci_format_string(dci_msg.format), rnti); last_dci_format = dci_msg.format; if (dci_msg.format == SRSLTE_DCI_FORMATN0) { diff --git a/lib/src/phy/phch/test/npdsch_test.c b/lib/src/phy/phch/test/npdsch_test.c index 9add50f31..6f23bc8ba 100644 --- a/lib/src/phy/phch/test/npdsch_test.c +++ b/lib/src/phy/phch/test/npdsch_test.c @@ -129,17 +129,17 @@ int get_ref_res(srslte_nbiot_cell_t cell, int32_t* re_with_refs) // add all RE that contain NRS for (int p = 0; p < cell.nof_ports; p++) { - DEBUG("Adding NRS for port=%d n_id_ncell=%d\n", p, cell.n_id_ncell); + DEBUG("Adding NRS for port=%d n_id_ncell=%d", p, cell.n_id_ncell); uint32_t nof_syms = srslte_refsignal_dl_nbiot_nof_symbols(p); for (int l = 0; l < nof_syms; l++) { uint32_t nsymbol = srslte_refsignal_nrs_nsymbol(l); - DEBUG(" - adding NRS for symbol=%d\n", nsymbol); + DEBUG(" - adding NRS for symbol=%d", nsymbol); // two references per symbol for (int m = 0; m < SRSLTE_NBIOT_NUM_NRS_X_SYM_X_PORT; m++) { uint32_t fidx = srslte_refsignal_dl_nbiot_fidx(cell, l, p, m); uint32_t re_idx = SRSLTE_RE_IDX(cell.base.nof_prb, nsymbol, fidx); - DEBUG(" - adding NRS at re_idx=%d with fidx=%d\n", re_idx, fidx); + DEBUG(" - adding NRS at re_idx=%d with fidx=%d", re_idx, fidx); re_with_refs[num_ref] = re_idx; num_ref++; } @@ -148,17 +148,17 @@ int get_ref_res(srslte_nbiot_cell_t cell, int32_t* re_with_refs) // add all RE that contain CRS for (int p = 0; p < cell.base.nof_ports; p++) { - DEBUG("Adding CRS for port=%d cell_id=%d\n", p, cell.base.id); + DEBUG("Adding CRS for port=%d cell_id=%d", p, cell.base.id); uint32_t nof_syms = srslte_refsignal_cs_nof_symbols(NULL, NULL, p); for (int l = 0; l < nof_syms; l++) { uint32_t nsymbol = srslte_refsignal_cs_nsymbol(l, cell.base.cp, p); - DEBUG(" - adding CRS for symbol=%d\n", nsymbol); + DEBUG(" - adding CRS for symbol=%d", nsymbol); // two references per symbol for (int m = 0; m < 2; m++) { uint32_t fidx = ((srslte_refsignal_cs_v(p, l) + (cell.base.id % 6)) % 6) + m * 6; uint32_t re_idx = SRSLTE_RE_IDX(cell.base.nof_prb, nsymbol, fidx); - DEBUG(" - adding CRS at re_idx=%d with fidx=%d\n", re_idx, fidx); + DEBUG(" - adding CRS at re_idx=%d with fidx=%d", re_idx, fidx); re_with_refs[num_ref] = re_idx; num_ref++; } @@ -263,8 +263,8 @@ int coding_test(int argc, char** argv) srslte_ra_nbiot_dl_grant_t grant; srslte_npdsch_cfg_t npdsch_cfg; srslte_npdsch_t npdsch; - uint8_t* data = NULL; - uint8_t* rx_data = NULL; + uint8_t* data = NULL; + uint8_t* rx_data = NULL; cf_t* ce[SRSLTE_MAX_PORTS] = {NULL}; cf_t* sf_symbols = NULL; cf_t* slot_symbols[SRSLTE_MAX_PORTS] = {NULL}; @@ -274,12 +274,12 @@ int coding_test(int argc, char** argv) // setup cell config for this test srslte_nbiot_cell_t cell = {}; - cell.base.nof_prb = 1; - cell.base.cp = SRSLTE_CP_NORM; - cell.base.nof_ports = 1; - cell.nof_ports = 1; - cell.mode = SRSLTE_NBIOT_MODE_STANDALONE; - cell.n_id_ncell = n_id_ncell; + cell.base.nof_prb = 1; + cell.base.cp = SRSLTE_CP_NORM; + cell.base.nof_ports = 1; + cell.nof_ports = 1; + cell.mode = SRSLTE_NBIOT_MODE_STANDALONE; + cell.n_id_ncell = n_id_ncell; if (!srslte_nbiot_cell_isvalid(&cell)) { printf("Cell is not properly configured\n"); @@ -406,7 +406,7 @@ int coding_test(int argc, char** argv) #endif if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("SAVED FILE npdsch_tx_sf.bin: transmitted subframe symbols\n"); + DEBUG("SAVED FILE npdsch_tx_sf.bin: transmitted subframe symbols"); srslte_vec_save_file("npdsch_tx_sf.bin", sf_symbols, SRSLTE_NBIOT_SFLEN * sizeof(cf_t)); } diff --git a/lib/src/phy/phch/test/pbch_file_test.c b/lib/src/phy/phch/test/pbch_file_test.c index f046c5589..a40cc4c42 100644 --- a/lib/src/phy/phch/test/pbch_file_test.c +++ b/lib/src/phy/phch/test/pbch_file_test.c @@ -101,9 +101,8 @@ void parse_args(int argc, char** argv) int base_init() { - if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } @@ -120,38 +119,38 @@ int base_init() } if (!srslte_cell_isvalid(&cell)) { - ERROR("Invalid cell properties\n"); + ERROR("Invalid cell properties"); return -1; } if (srslte_chest_dl_init(&chest, cell.nof_prb, 1)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_res_init(&chest_res, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_set_cell(&chest, cell)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_ofdm_rx_init(&fft, cell.cp, input_buffer, fft_buffer[0], cell.nof_prb)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); return -1; } if (srslte_pbch_init(&pbch)) { - ERROR("Error initiating PBCH\n"); + ERROR("Error initiating PBCH"); return -1; } if (srslte_pbch_set_cell(&pbch, cell)) { - ERROR("Error initiating PBCH\n"); + ERROR("Error initiating PBCH"); return -1; } - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } @@ -185,7 +184,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (base_init()) { - ERROR("Error initializing receiver\n"); + ERROR("Error initializing receiver"); exit(-1); } @@ -205,7 +204,7 @@ int main(int argc, char** argv) /* Get channel estimates for each port */ srslte_chest_dl_estimate(&chest, &dl_sf, fft_buffer, &chest_res); - INFO("Decoding PBCH\n"); + INFO("Decoding PBCH"); srslte_pbch_decode_reset(&pbch); n = srslte_pbch_decode(&pbch, &chest_res, fft_buffer, bch_payload, &nof_tx_ports, &sfn_offset); @@ -213,12 +212,12 @@ int main(int argc, char** argv) if (n == 1) { nof_decoded_mibs++; } else if (n < 0) { - ERROR("Error decoding PBCH\n"); + ERROR("Error decoding PBCH"); exit(-1); } frame_cnt++; } else if (nread < 0) { - ERROR("Error reading from file\n"); + ERROR("Error reading from file"); exit(-1); } } while (nread > 0 && frame_cnt < nof_frames); diff --git a/lib/src/phy/phch/test/pbch_test.c b/lib/src/phy/phch/test/pbch_test.c index 152134249..3d623ecdf 100644 --- a/lib/src/phy/phch/test/pbch_test.c +++ b/lib/src/phy/phch/test/pbch_test.c @@ -101,11 +101,11 @@ int main(int argc, char** argv) } } if (srslte_pbch_init(&pbch)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } if (srslte_pbch_set_cell(&pbch, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } diff --git a/lib/src/phy/phch/test/pcfich_file_test.c b/lib/src/phy/phch/test/pcfich_file_test.c index 1c81cb860..378dde2d2 100644 --- a/lib/src/phy/phch/test/pcfich_file_test.c +++ b/lib/src/phy/phch/test/pcfich_file_test.c @@ -107,7 +107,7 @@ int base_init() srslte_use_standard_symbol_size(use_standard_lte_rates); if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } @@ -136,44 +136,43 @@ int base_init() } if (srslte_chest_dl_init(&chest, cell.nof_prb, 1)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_res_init(&chest_res, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_set_cell(&chest, cell)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_ofdm_rx_init(&fft, cell.cp, input_buffer, fft_buffer[0], cell.nof_prb)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); return -1; } if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating REGs\n"); + ERROR("Error initiating REGs"); return -1; } if (srslte_pcfich_init(&pcfich, 1)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); return -1; } if (srslte_pcfich_set_cell(&pcfich, ®s, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); return -1; } - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } void base_free() { - srslte_filesource_free(&fsrc); if (fmatlab) { fclose(fmatlab); @@ -205,7 +204,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (base_init()) { - ERROR("Error initializing receiver\n"); + ERROR("Error initializing receiver"); exit(-1); } @@ -231,7 +230,7 @@ int main(int argc, char** argv) /* Get channel estimates for each port */ srslte_chest_dl_estimate(&chest, &dl_sf, fft_buffer, &chest_res); - INFO("Decoding PCFICH\n"); + INFO("Decoding PCFICH"); n = srslte_pcfich_decode(&pcfich, &dl_sf, &chest_res, fft_buffer, &cfi_corr); printf("cfi: %d, distance: %f\n", dl_sf.cfi, cfi_corr); @@ -244,7 +243,7 @@ int main(int argc, char** argv) base_free(); if (n < 0) { - ERROR("Error decoding PCFICH\n"); + ERROR("Error decoding PCFICH"); exit(-1); } else if (n == 0) { printf("Could not decode PCFICH\n"); diff --git a/lib/src/phy/phch/test/pcfich_test.c b/lib/src/phy/phch/test/pcfich_test.c index 778053fb2..6fd0d5afe 100644 --- a/lib/src/phy/phch/test/pcfich_test.c +++ b/lib/src/phy/phch/test/pcfich_test.c @@ -117,16 +117,16 @@ int main(int argc, char** argv) printf("Testing CellID=%d...\n", cid); if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating regs\n"); + ERROR("Error initiating regs"); exit(-1); } if (srslte_pcfich_init(&pcfich, 1)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } if (srslte_pcfich_set_cell(&pcfich, ®s, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } @@ -146,7 +146,7 @@ int main(int argc, char** argv) if (srslte_pcfich_decode(&pcfich, &dl_sf, &chest_res, slot_symbols, &corr_res) < 0) { exit(-1); } - INFO("cfi_tx: %d, cfi_rx: %d, ns: %d, distance: %f\n", cfi, dl_sf.cfi, nsf, corr_res); + INFO("cfi_tx: %d, cfi_rx: %d, ns: %d, distance: %f", cfi, dl_sf.cfi, nsf, corr_res); } } srslte_pcfich_free(&pcfich); diff --git a/lib/src/phy/phch/test/pdcch_file_test.c b/lib/src/phy/phch/test/pdcch_file_test.c index 912e1db3c..8290c1586 100644 --- a/lib/src/phy/phch/test/pdcch_file_test.c +++ b/lib/src/phy/phch/test/pdcch_file_test.c @@ -97,7 +97,7 @@ void parse_args(int argc, char** argv) case 'o': dci_format = srslte_dci_format_from_string(argv[optind]); if (dci_format == SRSLTE_DCI_NOF_FORMATS) { - ERROR("Error unsupported format %s\n", argv[optind]); + ERROR("Error unsupported format %s", argv[optind]); exit(-1); } break; @@ -120,9 +120,8 @@ void parse_args(int argc, char** argv) int base_init() { - if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } @@ -141,44 +140,43 @@ int base_init() } if (srslte_chest_dl_init(&chest, cell.nof_prb, 1)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_res_init(&chest_res, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_set_cell(&chest, cell)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_ofdm_rx_init(&fft, cell.cp, input_buffer, fft_buffer[0], cell.nof_prb)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); return -1; } if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating regs\n"); + ERROR("Error initiating regs"); return -1; } if (srslte_pdcch_init_ue(&pdcch, cell.nof_prb, 1)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch, ®s, cell)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); exit(-1); } - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } void base_free() { - srslte_filesource_free(&fsrc); free(input_buffer); @@ -211,7 +209,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (base_init()) { - ERROR("Error initializing memory\n"); + ERROR("Error initializing memory"); exit(-1); } @@ -220,7 +218,7 @@ int main(int argc, char** argv) do { srslte_filesource_read(&fsrc, input_buffer, flen); - INFO("Reading %d samples sub-frame %d\n", flen, frame_cnt); + INFO("Reading %d samples sub-frame %d", flen, frame_cnt); srslte_ofdm_rx_sf(&fft); @@ -233,14 +231,14 @@ int main(int argc, char** argv) srslte_chest_dl_estimate(&chest, &dl_sf, fft_buffer, &chest_res); if (srslte_pdcch_extract_llr(&pdcch, &dl_sf, &chest_res, fft_buffer)) { - ERROR("Error extracting LLRs\n"); + ERROR("Error extracting LLRs"); return -1; } if (rnti == SRSLTE_SIRNTI) { - INFO("Initializing common search space for SI-RNTI\n"); + INFO("Initializing common search space for SI-RNTI"); nof_locations = srslte_pdcch_common_locations(&pdcch, locations, SRSLTE_MAX_CANDIDATES, cfi); } else { - INFO("Initializing user-specific search space for RNTI: 0x%x\n", rnti); + INFO("Initializing user-specific search space for RNTI: 0x%x", rnti); nof_locations = srslte_pdcch_ue_locations(&pdcch, &dl_sf, locations, SRSLTE_MAX_CANDIDATES, rnti); } @@ -253,17 +251,16 @@ int main(int argc, char** argv) dci_msg.location = locations[i]; dci_msg.format = dci_format; if (srslte_pdcch_decode_msg(&pdcch, &dl_sf, &dci_cfg, &dci_msg)) { - ERROR("Error decoding DCI msg\n"); + ERROR("Error decoding DCI msg"); return -1; } } if (dci_msg.rnti == rnti) { - srslte_dci_dl_t dci; bzero(&dci, sizeof(srslte_dci_dl_t)); if (srslte_dci_msg_unpack_pdsch(&cell, &dl_sf, &dci_cfg, &dci_msg, &dci)) { - ERROR("Can't unpack DCI message\n"); + ERROR("Can't unpack DCI message"); } else { if (dci.alloc_type == SRSLTE_RA_ALLOC_TYPE2 && dci.type2_alloc.mode == SRSLTE_RA_TYPE2_LOC && dci.type2_alloc.riv == 11 && dci.tb[0].rv == 0 && dci.pid == 0 && dci.tb[0].mcs_idx == 2) { diff --git a/lib/src/phy/phch/test/pdcch_nr_test.c b/lib/src/phy/phch/test/pdcch_nr_test.c index 4c985e309..da5c42e7d 100644 --- a/lib/src/phy/phch/test/pdcch_nr_test.c +++ b/lib/src/phy/phch/test/pdcch_nr_test.c @@ -125,19 +125,19 @@ int main(int argc, char** argv) srslte_dmrs_pdcch_ce_t* ce = SRSLTE_MEM_ALLOC(srslte_dmrs_pdcch_ce_t, 1); cf_t* buffer = srslte_vec_cf_malloc(grid_sz); if (rand_gen == NULL || ce == NULL || buffer == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } SRSLTE_MEM_ZERO(ce, srslte_dmrs_pdcch_ce_t, 1); if (srslte_pdcch_nr_init_tx(&pdcch_tx, &args) < SRSLTE_SUCCESS) { - ERROR("Error init\n"); + ERROR("Error init"); goto clean_exit; } if (srslte_pdcch_nr_init_rx(&pdcch_rx, &args) < SRSLTE_SUCCESS) { - ERROR("Error init\n"); + ERROR("Error init"); goto clean_exit; } @@ -151,17 +151,16 @@ int main(int argc, char** argv) } for (coreset.duration = SRSLTE_CORESET_DURATION_MIN; coreset.duration <= SRSLTE_CORESET_DURATION_MAX; coreset.duration++) { - srslte_search_space_t search_space = {}; search_space.type = srslte_search_space_type_ue; if (srslte_pdcch_nr_set_carrier(&pdcch_tx, &carrier, &coreset) < SRSLTE_SUCCESS) { - ERROR("Error setting carrier\n"); + ERROR("Error setting carrier"); goto clean_exit; } if (srslte_pdcch_nr_set_carrier(&pdcch_rx, &carrier, &coreset) < SRSLTE_SUCCESS) { - ERROR("Error setting carrier\n"); + ERROR("Error setting carrier"); goto clean_exit; } @@ -183,7 +182,7 @@ int main(int argc, char** argv) int n = srslte_pdcch_nr_locations_coreset( &coreset, &search_space, rnti, aggregation_level, slot_idx, dci_locations); if (n < SRSLTE_SUCCESS) { - ERROR("Error calculating locations in CORESET\n"); + ERROR("Error calculating locations in CORESET"); goto clean_exit; } @@ -193,9 +192,9 @@ int main(int argc, char** argv) } for (uint32_t ncce_idx = 0; ncce_idx < n; ncce_idx++) { - // Init MSG srslte_dci_msg_nr_t dci_msg = {}; + dci_msg.format = srslte_dci_format_nr_1_0; dci_msg.rnti_type = srslte_rnti_type_c; dci_msg.location.L = aggregation_level; dci_msg.location.ncce = dci_locations[ncce_idx]; @@ -214,7 +213,7 @@ int main(int argc, char** argv) ce->noise_var = 0.0f; if (test(&pdcch_tx, &pdcch_rx, buffer, ce, &dci_msg) < SRSLTE_SUCCESS) { - ERROR("test failed\n"); + ERROR("test failed"); goto clean_exit; } } @@ -230,7 +229,7 @@ int main(int argc, char** argv) printf("+--------+--------+--------+--------+\n"); for (uint32_t i = 0; i < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; i++) { if (enc_time[i].count > 0 && dec_time[i].count) { - printf("| %6d | %6ld | %6.1f | %6.1f |\n", + printf("| %6" PRIu32 "| %6" PRIu64 " | %6.1f | %6.1f |\n", i, enc_time[i].count, (double)enc_time[i].time_us / (double)enc_time[i].count, diff --git a/lib/src/phy/phch/test/pdcch_test.c b/lib/src/phy/phch/test/pdcch_test.c index 87e8f9ef7..d1e421ca5 100644 --- a/lib/src/phy/phch/test/pdcch_test.c +++ b/lib/src/phy/phch/test/pdcch_test.c @@ -119,7 +119,7 @@ int test_dci_payload_size() for (j = 0; j < 5; j++) { x[j] = srslte_dci_format_sizeof(&cell_test, &dl_sf, &dci_cfg, formats[j]); if (x[j] != dci_sz[i][j]) { - ERROR("Invalid DCI payload size for %s and %d PRB. Is %d and should be %d\n", + ERROR("Invalid DCI payload size for %s and %d PRB. Is %d and should be %d", srslte_dci_format_string(formats[j]), n, x[j], @@ -163,7 +163,6 @@ typedef struct { int main(int argc, char** argv) { - srslte_chest_dl_res_t chest_dl_res; srslte_pdcch_t pdcch_tx, pdcch_rx; testcase_dci_t testcases[10]; @@ -200,25 +199,25 @@ int main(int argc, char** argv) } if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating regs\n"); + ERROR("Error initiating regs"); exit(-1); } if (srslte_pdcch_init_enb(&pdcch_tx, cell.nof_prb)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch_tx, ®s, cell)) { - ERROR("Error setting cell in PDCCH object\n"); + ERROR("Error setting cell in PDCCH object"); exit(-1); } if (srslte_pdcch_init_ue(&pdcch_rx, cell.nof_prb, nof_rx_ant)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch_rx, ®s, cell)) { - ERROR("Error setting cell in PDCCH object\n"); + ERROR("Error setting cell in PDCCH object"); exit(-1); } @@ -311,14 +310,14 @@ int main(int argc, char** argv) } if (srslte_pdcch_encode(&pdcch_tx, &dl_sf, &testcases[i].dci_tx, slot_symbols)) { - ERROR("Error encoding DCI message\n"); + ERROR("Error encoding DCI message"); goto quit; } } /* Execute 'Rx' */ if (srslte_pdcch_extract_llr(&pdcch_rx, &dl_sf, &chest_dl_res, slot_symbols)) { - ERROR("Error extracting LLRs\n"); + ERROR("Error extracting LLRs"); goto quit; } @@ -327,11 +326,11 @@ int main(int argc, char** argv) testcases[i].dci_rx.format = testcases[i].dci_format; testcases[i].dci_rx.location = testcases[i].dci_location; if (srslte_pdcch_decode_msg(&pdcch_rx, &dl_sf, &dci_cfg, &testcases[i].dci_rx)) { - ERROR("Error decoding DCI message\n"); + ERROR("Error decoding DCI message"); goto quit; } if (srslte_dci_msg_unpack_pdsch(&cell, &dl_sf, &dci_cfg, &testcases[i].dci_rx, &testcases[i].ra_dl_rx)) { - ERROR("Error unpacking DCI message\n"); + ERROR("Error unpacking DCI message"); goto quit; } if (testcases[i].dci_rx.rnti >= 1234 && testcases[i].dci_rx.rnti < 1234 + nof_dcis) { diff --git a/lib/src/phy/phch/test/pdsch_nr_test.c b/lib/src/phy/phch/test/pdsch_nr_test.c index 52df69dfe..464eb5066 100644 --- a/lib/src/phy/phch/test/pdsch_nr_test.c +++ b/lib/src/phy/phch/test/pdsch_nr_test.c @@ -108,29 +108,29 @@ int main(int argc, char** argv) pdsch_args.measure_evm = true; if (srslte_pdsch_nr_init_enb(&pdsch_tx, &pdsch_args) < SRSLTE_SUCCESS) { - ERROR("Error initiating PDSCH for Tx\n"); + ERROR("Error initiating PDSCH for Tx"); goto clean_exit; } if (srslte_pdsch_nr_init_ue(&pdsch_rx, &pdsch_args) < SRSLTE_SUCCESS) { - ERROR("Error initiating SCH NR for Rx\n"); + ERROR("Error initiating SCH NR for Rx"); goto clean_exit; } if (srslte_pdsch_nr_set_carrier(&pdsch_tx, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } if (srslte_pdsch_nr_set_carrier(&pdsch_rx, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } for (uint32_t i = 0; i < carrier.max_mimo_layers; i++) { sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(carrier.nof_prb)); if (sf_symbols[i] == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } } @@ -139,7 +139,7 @@ int main(int argc, char** argv) data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); if (data_tx[i] == NULL || data_rx[i] == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } @@ -151,25 +151,25 @@ int main(int argc, char** argv) if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } // Use grant default A time resources with m=0 - if (srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading default grant\n"); + if (srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading default grant"); goto clean_exit; } // Load number of DMRS CDM groups without data - if (srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&pdsch_cfg, &pdsch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups without data\n"); + if (srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&pdsch_cfg.dmrs, &pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading number of DMRS CDM groups without data"); goto clean_exit; } @@ -192,19 +192,18 @@ int main(int argc, char** argv) } if (srslte_chest_dl_res_init(&chest, carrier.nof_prb) < SRSLTE_SUCCESS) { - ERROR("Initiating chest\n"); + ERROR("Initiating chest"); goto clean_exit; } for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { for (mcs = mcs_start; mcs < mcs_end; mcs++) { - for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { pdsch_grant.prb_idx[n] = (n < n_prb); } if (srslte_ra_nr_fill_tb(&pdsch_cfg, &pdsch_grant, mcs, &pdsch_grant.tb[0]) < SRSLTE_SUCCESS) { - ERROR("Error filing tb\n"); + ERROR("Error filing tb"); goto clean_exit; } @@ -221,7 +220,7 @@ int main(int argc, char** argv) } if (srslte_pdsch_nr_encode(&pdsch_tx, &pdsch_cfg, &pdsch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { - ERROR("Error encoding\n"); + ERROR("Error encoding"); goto clean_exit; } @@ -236,12 +235,12 @@ int main(int argc, char** argv) chest.nof_re = pdsch_grant.tb->nof_re; if (srslte_pdsch_nr_decode(&pdsch_rx, &pdsch_cfg, &pdsch_grant, &chest, sf_symbols, pdsch_res) < SRSLTE_SUCCESS) { - ERROR("Error encoding\n"); + ERROR("Error encoding"); goto clean_exit; } if (pdsch_res->evm > 0.001f) { - ERROR("Error PDSCH EVM is too high %f\n", pdsch_res->evm); + ERROR("Error PDSCH EVM is too high %f", pdsch_res->evm); goto clean_exit; } @@ -256,7 +255,7 @@ int main(int argc, char** argv) mse = mse / (nof_re * pdsch_grant.nof_layers); } if (mse > 0.001) { - ERROR("MSE error (%f) is too high\n", mse); + ERROR("MSE error (%f) is too high", mse); for (uint32_t i = 0; i < pdsch_grant.nof_layers; i++) { printf("d_tx[%d]=", i); srslte_vec_fprint_c(stdout, pdsch_tx.d[i], nof_re); @@ -267,12 +266,12 @@ int main(int argc, char** argv) } if (!pdsch_res[0].crc) { - ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pdsch_grant.tb[0].tbs); + ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_grant.tb[0].tbs); goto clean_exit; } if (memcmp(data_tx[0], data_rx[0], pdsch_grant.tb[0].tbs / 8) != 0) { - ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pdsch_grant.tb[0].tbs); + ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_grant.tb[0].tbs); printf("Tx data: "); srslte_vec_fprint_byte(stdout, data_tx[0], pdsch_grant.tb[0].tbs / 8); printf("Rx data: "); diff --git a/lib/src/phy/phch/test/pdsch_pdcch_file_test.c b/lib/src/phy/phch/test/pdsch_pdcch_file_test.c index f138aca91..313fd2854 100644 --- a/lib/src/phy/phch/test/pdsch_pdcch_file_test.c +++ b/lib/src/phy/phch/test/pdsch_pdcch_file_test.c @@ -100,7 +100,7 @@ void parse_args(int argc, char** argv) case 'o': dci_format = srslte_dci_format_from_string(argv[optind]); if (dci_format == SRSLTE_DCI_NOF_FORMATS) { - ERROR("Error unsupported format %s\n", argv[optind]); + ERROR("Error unsupported format %s", argv[optind]); exit(-1); } break; @@ -123,9 +123,8 @@ void parse_args(int argc, char** argv) int base_init() { - if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } @@ -138,17 +137,17 @@ int base_init() } if (srslte_ue_dl_init(&ue_dl, input_buffer, cell.nof_prb, 1)) { - ERROR("Error initializing UE DL\n"); + ERROR("Error initializing UE DL"); return -1; } if (srslte_ue_dl_set_cell(&ue_dl, cell)) { - ERROR("Error initializing UE DL\n"); + ERROR("Error initializing UE DL"); return -1; } srslte_ue_dl_set_rnti(&ue_dl, rnti); - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } @@ -173,7 +172,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (base_init()) { - ERROR("Error initializing memory\n"); + ERROR("Error initializing memory"); exit(-1); } @@ -201,7 +200,7 @@ int main(int argc, char** argv) nof_frames = 0; do { srslte_filesource_read(&fsrc, input_buffer[0], flen); - INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); + INFO("Reading %d samples sub-frame %d", flen, sf_idx); dl_sf.tti = sf_idx; ret = srslte_ue_dl_find_and_decode(&ue_dl, &dl_sf, &ue_dl_cfg, &pdsch_cfg, data, acks); diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index 34318ddcf..7f59618f3 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -158,7 +158,6 @@ static int check_softbits(srslte_pdsch_t* pdsch_enb, int ret = SRSLTE_SUCCESS; if (!pdsch_ue->llr_is_8bit && !tb_cw_swap) { - // Generate sequence srslte_sequence_pdsch(&pdsch_ue->tmp_seq, rnti, @@ -280,7 +279,7 @@ int main(int argc, char** argv) /* Generate dci from DCI */ if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, tm, enable_256qam, &dci, &pdsch_cfg.grant)) { - ERROR("Error computing resource allocation\n"); + ERROR("Error computing resource allocation"); return ret; } @@ -327,11 +326,11 @@ int main(int argc, char** argv) } if (srslte_pdsch_init_ue(&pdsch_rx, cell.nof_prb, nof_rx_antennas)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); goto quit; } if (srslte_pdsch_set_cell(&pdsch_rx, cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); goto quit; } @@ -343,12 +342,12 @@ int main(int argc, char** argv) for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers_rx[i] = calloc(sizeof(srslte_softbuffer_rx_t), 1); if (!softbuffers_rx[i]) { - ERROR("Error allocating RX soft buffer\n"); + ERROR("Error allocating RX soft buffer"); goto quit; } if (srslte_softbuffer_rx_init(softbuffers_rx[i], cell.nof_prb)) { - ERROR("Error initiating RX soft buffer\n"); + ERROR("Error initiating RX soft buffer"); goto quit; } @@ -358,12 +357,12 @@ int main(int argc, char** argv) if (input_file) { srslte_filesource_t fsrc; if (srslte_filesource_init(&fsrc, input_file, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file); + ERROR("Error opening file %s", input_file); goto quit; } if (srslte_chest_dl_init(&chest, cell.nof_prb, 1)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); exit(-1); } if (srslte_chest_dl_set_cell(&chest, cell)) { @@ -376,13 +375,12 @@ int main(int argc, char** argv) srslte_filesource_free(&fsrc); } else { - if (srslte_pdsch_init_enb(&pdsch_tx, cell.nof_prb)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); goto quit; } if (srslte_pdsch_set_cell(&pdsch_tx, cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); goto quit; } @@ -391,11 +389,11 @@ int main(int argc, char** argv) for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers_tx[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffers_tx[i]) { - ERROR("Error allocating TX soft buffer\n"); + ERROR("Error allocating TX soft buffer"); } if (srslte_softbuffer_tx_init(softbuffers_tx[i], cell.nof_prb)) { - ERROR("Error initiating TX soft buffer\n"); + ERROR("Error initiating TX soft buffer"); goto quit; } } @@ -421,7 +419,7 @@ int main(int argc, char** argv) } /* Do 1st transmission for rv_idx!=0 */ if (srslte_pdsch_encode(&pdsch_tx, &dl_sf, &pdsch_cfg, data_tx, tx_slot_symbols)) { - ERROR("Error encoding PDSCH\n"); + ERROR("Error encoding PDSCH"); goto quit; } } @@ -453,25 +451,25 @@ int main(int argc, char** argv) } } - INFO(" Global:\n"); - INFO(" nof_prb=%d\n", cell.nof_prb); - INFO(" nof_ports=%d\n", cell.nof_ports); - INFO(" id=%d\n", cell.id); - INFO(" cp=%s\n", srslte_cp_string(cell.cp)); - INFO(" phich_length=%d\n", (int)cell.phich_length); - INFO(" phich_resources=%d\n", (int)cell.phich_resources); - INFO(" nof_prb=%d\n", pdsch_cfg.grant.nof_prb); - INFO(" sf_idx=%d\n", dl_sf.tti); - INFO(" nof_tb=%d\n", pdsch_cfg.grant.nof_tb); + INFO(" Global:"); + INFO(" nof_prb=%d", cell.nof_prb); + INFO(" nof_ports=%d", cell.nof_ports); + INFO(" id=%d", cell.id); + INFO(" cp=%s", srslte_cp_string(cell.cp)); + INFO(" phich_length=%d", (int)cell.phich_length); + INFO(" phich_resources=%d", (int)cell.phich_resources); + INFO(" nof_prb=%d", pdsch_cfg.grant.nof_prb); + INFO(" sf_idx=%d", dl_sf.tti); + INFO(" nof_tb=%d", pdsch_cfg.grant.nof_tb); for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { - INFO(" Tranport block index %d:\n", i); - INFO(" enabled=%d\n", pdsch_cfg.grant.tb[i].enabled); - INFO(" mcs.idx=%d\n", pdsch_cfg.grant.tb[i].mcs_idx); - INFO(" mcs.tbs=%d\n", pdsch_cfg.grant.tb[i].tbs); - INFO(" mcs.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.tb[i].mod)); - INFO(" rv=%d\n", pdsch_cfg.grant.tb[i].rv); - INFO(" nof_bits=%d\n", pdsch_cfg.grant.tb[i].nof_bits); - INFO(" nof_re=%d\n", pdsch_cfg.grant.nof_re); + INFO(" Tranport block index %d:", i); + INFO(" enabled=%d", pdsch_cfg.grant.tb[i].enabled); + INFO(" mcs.idx=%d", pdsch_cfg.grant.tb[i].mcs_idx); + INFO(" mcs.tbs=%d", pdsch_cfg.grant.tb[i].tbs); + INFO(" mcs.mod=%s", srslte_mod_string(pdsch_cfg.grant.tb[i].mod)); + INFO(" rv=%d", pdsch_cfg.grant.tb[i].rv); + INFO(" nof_bits=%d", pdsch_cfg.grant.tb[i].nof_bits); + INFO(" nof_re=%d", pdsch_cfg.grant.nof_re); } int r = 0; diff --git a/lib/src/phy/phch/test/phich_file_test.c b/lib/src/phy/phch/test/phich_file_test.c index 6f400503c..ce4787545 100644 --- a/lib/src/phy/phch/test/phich_file_test.c +++ b/lib/src/phy/phch/test/phich_file_test.c @@ -96,7 +96,7 @@ void parse_args(int argc, char** argv) } else if (!strcmp(argv[optind], "2")) { cell.phich_resources = SRSLTE_PHICH_R_2; } else { - ERROR("Invalid phich ng factor %s. Setting to default.\n", argv[optind]); + ERROR("Invalid phich ng factor %s. Setting to default.", argv[optind]); } break; case 'e': @@ -127,9 +127,8 @@ void parse_args(int argc, char** argv) int base_init() { - if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } @@ -158,44 +157,43 @@ int base_init() } if (srslte_chest_dl_init(&chest, cell.nof_prb, 1)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_res_init(&chest_res, cell.nof_prb)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_chest_dl_set_cell(&chest, cell)) { - ERROR("Error initializing equalizer\n"); + ERROR("Error initializing equalizer"); return -1; } if (srslte_ofdm_rx_init(&fft, cell.cp, input_buffer, fft_buffer[0], cell.nof_prb)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); return -1; } if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating regs\n"); + ERROR("Error initiating regs"); return -1; } if (srslte_phich_init(&phich, 1)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); return -1; } if (srslte_phich_set_cell(&phich, ®s, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); return -1; } - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } void base_free() { - srslte_filesource_free(&fsrc); if (fmatlab) { fclose(fmatlab); @@ -229,7 +227,7 @@ int main(int argc, char** argv) max_nseq = SRSLTE_CP_ISNORM(cell.cp) ? SRSLTE_PHICH_NORM_NSEQUENCES : SRSLTE_PHICH_EXT_NSEQUENCES; if (base_init()) { - ERROR("Error initializing memory\n"); + ERROR("Error initializing memory"); exit(-1); } @@ -254,12 +252,11 @@ int main(int argc, char** argv) /* Get channel estimates for each port */ srslte_chest_dl_estimate(&chest, &dl_sf, fft_buffer, &chest_res); - INFO("Decoding PHICH\n"); + INFO("Decoding PHICH"); /* Receive all PHICH groups and sequence numbers */ for (ngroup = 0; ngroup < srslte_phich_ngroups(&phich); ngroup++) { for (nseq = 0; nseq < max_nseq; nseq++) { - srslte_phich_resource_t resource; resource.ngroup = ngroup; resource.nseq = nseq; @@ -271,14 +268,14 @@ int main(int argc, char** argv) exit(-1); } - INFO("%d/%d, ack_rx: %d, ns: %d, distance: %f\n", ngroup, nseq, res.ack_value, numsubframe, res.distance); + INFO("%d/%d, ack_rx: %d, ns: %d, distance: %f", ngroup, nseq, res.ack_value, numsubframe, res.distance); } } base_free(); if (n < 0) { - ERROR("Error decoding phich\n"); + ERROR("Error decoding phich"); exit(-1); } else if (n == 0) { printf("Could not decode phich\n"); diff --git a/lib/src/phy/phch/test/phich_test.c b/lib/src/phy/phch/test/phich_test.c index 0e333fef6..e44b65a99 100644 --- a/lib/src/phy/phch/test/phich_test.c +++ b/lib/src/phy/phch/test/phich_test.c @@ -77,7 +77,7 @@ void parse_args(int argc, char** argv) } else if (!strcmp(argv[optind], "2")) { phich_res = SRSLTE_PHICH_R_2; } else { - ERROR("Invalid phich ng factor %s. Setting to default.\n", argv[optind]); + ERROR("Invalid phich ng factor %s. Setting to default.", argv[optind]); } break; case 'e': @@ -136,7 +136,7 @@ int main(int argc, char** argv) max_cid = cell.id; } if (srslte_phich_init(&phich, 1)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } while (cid <= max_cid) { @@ -145,12 +145,12 @@ int main(int argc, char** argv) printf("Testing CellID=%d...\n", cid); if (srslte_regs_init(®s, cell)) { - ERROR("Error initiating regs\n"); + ERROR("Error initiating regs"); exit(-1); } if (srslte_phich_set_cell(&phich, ®s, cell)) { - ERROR("Error creating PBCH object\n"); + ERROR("Error creating PBCH object"); exit(-1); } @@ -158,7 +158,6 @@ int main(int argc, char** argv) ZERO_OBJECT(dl_sf); for (nsf = 0; nsf < 10; nsf++) { - dl_sf.tti = nsf; srslte_phich_reset(&phich, slot_symbols); @@ -168,7 +167,6 @@ int main(int argc, char** argv) /* Transmit all PHICH groups and sequence numbers */ for (ngroup = 0; ngroup < srslte_phich_ngroups(&phich); ngroup++) { for (nseq = 0; nseq < max_nseq; nseq++) { - resource.ngroup = ngroup; resource.nseq = nseq; @@ -187,7 +185,6 @@ int main(int argc, char** argv) /* Receive all PHICH groups and sequence numbers */ for (ngroup = 0; ngroup < srslte_phich_ngroups(&phich); ngroup++) { for (nseq = 0; nseq < max_nseq; nseq++) { - resource.ngroup = ngroup; resource.nseq = nseq; @@ -197,7 +194,7 @@ int main(int argc, char** argv) printf("Error decoding ACK\n"); exit(-1); } - INFO("%d/%d, ack_tx: %d, ack_rx: %d, ns: %d, distance: %f\n", + INFO("%d/%d, ack_tx: %d, ack_rx: %d, ns: %d, distance: %f", ngroup, nseq, ack[ngroup][nseq], diff --git a/lib/src/phy/phch/test/pmch_file_test.c b/lib/src/phy/phch/test/pmch_file_test.c index 071417304..f390d925c 100644 --- a/lib/src/phy/phch/test/pmch_file_test.c +++ b/lib/src/phy/phch/test/pmch_file_test.c @@ -113,9 +113,8 @@ void parse_args(int argc, char** argv) int base_init() { - if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } @@ -128,12 +127,12 @@ int base_init() } if (srslte_ue_dl_init(&ue_dl, input_buffer, cell.nof_prb, 1)) { - ERROR("Error initializing UE DL\n"); + ERROR("Error initializing UE DL"); return -1; } if (srslte_ue_dl_set_cell(&ue_dl, cell)) { - ERROR("Error initializing UE DL\n"); + ERROR("Error initializing UE DL"); return -1; } @@ -143,7 +142,7 @@ int base_init() srslte_softbuffer_rx_init(&softbuffer_rx, cell.nof_prb); srslte_softbuffer_rx_reset(&softbuffer_rx); - DEBUG("Memory init OK\n"); + DEBUG("Memory init OK"); return 0; } @@ -166,7 +165,7 @@ int main(int argc, char** argv) parse_args(argc, argv); srslte_use_standard_symbol_size(false); if (base_init()) { - ERROR("Error initializing memory\n"); + ERROR("Error initializing memory"); exit(-1); } @@ -179,7 +178,7 @@ int main(int argc, char** argv) ret = -1; srslte_filesource_read(&fsrc, input_buffer[0], flen); - INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); + INFO("Reading %d samples sub-frame %d", flen, sf_idx); srslte_dl_sf_cfg_t dl_sf; ZERO_OBJECT(dl_sf); @@ -193,10 +192,10 @@ int main(int argc, char** argv) ue_dl_cfg.chest_cfg.mbsfn_area_id = mbsfn_area_id; // Special configuration for MBSFN channel estimation - ue_dl_cfg.chest_cfg.filter_type = SRSLTE_CHEST_FILTER_TRIANGLE; - ue_dl_cfg.chest_cfg.filter_coef[0] = 0.1; - ue_dl_cfg.chest_cfg.estimator_alg = SRSLTE_ESTIMATOR_ALG_INTERPOLATE; - ue_dl_cfg.chest_cfg.noise_alg = SRSLTE_NOISE_ALG_PSS; + ue_dl_cfg.chest_cfg.filter_type = SRSLTE_CHEST_FILTER_TRIANGLE; + ue_dl_cfg.chest_cfg.filter_coef[0] = 0.1; + ue_dl_cfg.chest_cfg.estimator_alg = SRSLTE_ESTIMATOR_ALG_INTERPOLATE; + ue_dl_cfg.chest_cfg.noise_alg = SRSLTE_NOISE_ALG_PSS; if ((ret = srslte_ue_dl_decode_fft_estimate(&ue_dl, &dl_sf, &ue_dl_cfg)) < 0) { return ret; diff --git a/lib/src/phy/phch/test/pmch_test.c b/lib/src/phy/phch/test/pmch_test.c index 0d0f9b19b..2365f6670 100644 --- a/lib/src/phy/phch/test/pmch_test.c +++ b/lib/src/phy/phch/test/pmch_test.c @@ -169,11 +169,11 @@ int main(int argc, char** argv) for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers_tx[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffers_tx[i]) { - ERROR("Error allocating TX soft buffer\n"); + ERROR("Error allocating TX soft buffer"); } if (srslte_softbuffer_tx_init(softbuffers_tx[i], cell.nof_prb)) { - ERROR("Error initiating TX soft buffer\n"); + ERROR("Error initiating TX soft buffer"); goto quit; } } @@ -189,12 +189,12 @@ int main(int argc, char** argv) for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers_rx[i] = calloc(sizeof(srslte_softbuffer_rx_t), 1); if (!softbuffers_rx[i]) { - ERROR("Error allocating RX soft buffer\n"); + ERROR("Error allocating RX soft buffer"); goto quit; } if (srslte_softbuffer_rx_init(softbuffers_rx[i], cell.nof_prb)) { - ERROR("Error initiating RX soft buffer\n"); + ERROR("Error initiating RX soft buffer"); goto quit; } } @@ -205,7 +205,7 @@ int main(int argc, char** argv) tx_sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_PRB(cell.nof_prb)); srslte_vec_cf_zero(tx_sf_symbols[i], SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn[i], SRSLTE_CP_EXT, tx_slot_symbols[i], tx_sf_symbols[i], cell.nof_prb)) { - ERROR("Error creating iFFT object\n"); + ERROR("Error creating iFFT object"); exit(-1); } @@ -217,7 +217,7 @@ int main(int argc, char** argv) rx_sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_PRB(cell.nof_prb)); srslte_vec_cf_zero(rx_sf_symbols[i], SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (srslte_ofdm_rx_init_mbsfn(&fft_mbsfn[i], SRSLTE_CP_EXT, rx_sf_symbols[i], rx_slot_symbols[i], cell.nof_prb)) { - ERROR("Error creating iFFT object\n"); + ERROR("Error creating iFFT object"); exit(-1); } @@ -268,26 +268,26 @@ int main(int argc, char** argv) } } - INFO(" Global:\n"); - INFO(" nof_prb=%d\n", cell.nof_prb); - INFO(" nof_ports=%d\n", cell.nof_ports); - INFO(" id=%d\n", cell.id); - INFO(" cp=%s\n", srslte_cp_string(cell.cp)); - INFO(" phich_length=%d\n", (int)cell.phich_length); - INFO(" phich_resources=%d\n", (int)cell.phich_resources); - INFO(" nof_prb=%d\n", pmch_cfg.pdsch_cfg.grant.nof_prb); - INFO(" sf_idx=%d\n", subframe); - INFO(" nof_tb=%d\n", pmch_cfg.pdsch_cfg.grant.nof_tb); + INFO(" Global:"); + INFO(" nof_prb=%d", cell.nof_prb); + INFO(" nof_ports=%d", cell.nof_ports); + INFO(" id=%d", cell.id); + INFO(" cp=%s", srslte_cp_string(cell.cp)); + INFO(" phich_length=%d", (int)cell.phich_length); + INFO(" phich_resources=%d", (int)cell.phich_resources); + INFO(" nof_prb=%d", pmch_cfg.pdsch_cfg.grant.nof_prb); + INFO(" sf_idx=%d", subframe); + INFO(" nof_tb=%d", pmch_cfg.pdsch_cfg.grant.nof_tb); - INFO(" mcs.idx=0x%X\n", pmch_cfg.pdsch_cfg.grant.tb[0].mcs_idx); - INFO(" mcs.tbs=%d\n", pmch_cfg.pdsch_cfg.grant.tb[0].tbs); - INFO(" mcs.mod=%s\n", srslte_mod_string(pmch_cfg.pdsch_cfg.grant.tb[0].mod)); - INFO(" rv=%d\n", pmch_cfg.pdsch_cfg.grant.tb[0].rv); - INFO(" nof_bits=%d\n", pmch_cfg.pdsch_cfg.grant.tb[0].nof_bits); - INFO(" nof_re=%d\n", pmch_cfg.pdsch_cfg.grant.nof_re); + INFO(" mcs.idx=0x%X", pmch_cfg.pdsch_cfg.grant.tb[0].mcs_idx); + INFO(" mcs.tbs=%d", pmch_cfg.pdsch_cfg.grant.tb[0].tbs); + INFO(" mcs.mod=%s", srslte_mod_string(pmch_cfg.pdsch_cfg.grant.tb[0].mod)); + INFO(" rv=%d", pmch_cfg.pdsch_cfg.grant.tb[0].rv); + INFO(" nof_bits=%d", pmch_cfg.pdsch_cfg.grant.tb[0].nof_bits); + INFO(" nof_re=%d", pmch_cfg.pdsch_cfg.grant.nof_re); if (srslte_pmch_init(&pmch, cell.nof_prb, 1)) { - ERROR("Error creating PMCH object\n"); + ERROR("Error creating PMCH object"); } srslte_pmch_set_area_id(&pmch, mbsfn_area_id); @@ -300,7 +300,7 @@ int main(int argc, char** argv) } if (srslte_pmch_encode(&pmch, &dl_sf, &pmch_cfg, data_tx[0], tx_slot_symbols)) { - ERROR("Error encoding PDSCH\n"); + ERROR("Error encoding PDSCH"); exit(-1); } gettimeofday(&t[2], NULL); @@ -438,6 +438,5 @@ quit: printf("Ok\n"); } - exit(ret); } diff --git a/lib/src/phy/phch/test/prach_test.c b/lib/src/phy/phch/test/prach_test.c index ff527d57f..decf30bb0 100644 --- a/lib/src/phy/phch/test/prach_test.c +++ b/lib/src/phy/phch/test/prach_test.c @@ -32,12 +32,13 @@ #define MAX_LEN 70176 -uint32_t nof_prb = 50; -uint32_t config_idx = 3; -uint32_t root_seq_idx = 0; -uint32_t zero_corr_zone = 15; -uint32_t num_ra_preambles = 0; // use default -void usage(char* prog) +static uint32_t nof_prb = 50; +static uint32_t config_idx = 3; +static uint32_t root_seq_idx = 0; +static uint32_t zero_corr_zone = 15; +static uint32_t num_ra_preambles = 0; // use default + +static void usage(char* prog) { printf("Usage: %s\n", prog); printf("\t-n Uplink number of PRB [Default %d]\n", nof_prb); @@ -46,7 +47,7 @@ void usage(char* prog) printf("\t-z Zero correlation zone config [Default 1]\n"); } -void parse_args(int argc, char** argv) +static void parse_args(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "nfrz")) != -1) { @@ -92,10 +93,16 @@ int main(int argc, char** argv) if (srslte_prach_init(&prach, srslte_symbol_sz(nof_prb))) { return -1; } + + struct timeval t[3] = {}; + gettimeofday(&t[1], NULL); if (srslte_prach_set_cfg(&prach, &prach_cfg, nof_prb)) { - ERROR("Error initiating PRACH object\n"); + ERROR("Error initiating PRACH object"); return -1; } + gettimeofday(&t[2], NULL); + get_time_interval(t); + printf("It took %ld microseconds to configure\n", t[0].tv_usec + t[0].tv_sec * 1000000UL); uint32_t seq_index = 0; uint32_t indices[64]; @@ -108,7 +115,6 @@ int main(int argc, char** argv) uint32_t prach_len = prach.N_seq; - struct timeval t[3]; gettimeofday(&t[1], NULL); srslte_prach_detect(&prach, 0, &preamble[prach.N_cp], prach_len, indices, &n_indices); gettimeofday(&t[2], NULL); diff --git a/lib/src/phy/phch/test/prach_test_multi.c b/lib/src/phy/phch/test/prach_test_multi.c index c1e360ee9..01984e19b 100644 --- a/lib/src/phy/phch/test/prach_test_multi.c +++ b/lib/src/phy/phch/test/prach_test_multi.c @@ -27,16 +27,16 @@ #include #include -#include -#include "srslte/srslte.h" -#include #include "srslte/phy/phch/prach.h" #include "srslte/phy/utils/debug.h" +#include "srslte/srslte.h" +#include +#include char* input_file_name = NULL; #define PRACH_SRATE 1048750 #define MAX_LEN 70176 -int offset = -1; +int offset = -1; uint32_t nof_prb = 6; uint32_t preamble_format = 0; uint32_t root_seq_idx = 0; @@ -49,7 +49,7 @@ bool test_successive_cancellation = false; bool test_offset_calculation = false; bool stagger_prach_power_and_phase = false; // this will work best with one or two simultaenous prach -srslte_filesource_t fsrc; +srslte_filesource_t fsrc; void usage(char* prog) { @@ -89,7 +89,7 @@ void parse_args(int argc, char** argv) input_file_name = argv[optind]; break; case 'o': - offset = (uint32_t)strtol(argv[optind], NULL, 10); + offset = (uint32_t)strtol(argv[optind], NULL, 10); break; case 's': test_successive_cancellation = true; @@ -110,8 +110,13 @@ void parse_args(int argc, char** argv) } } // this function staggers power and phase of the different PRACH signals for more realisitc testing -void stagger_prach_powers(srslte_prach_t *prach, cf_t *preamble, cf_t* preamble_sum, int freq_offset, int n_seqs, int *offsets) { - +void stagger_prach_powers(srslte_prach_t* prach, + cf_t* preamble, + cf_t* preamble_sum, + int freq_offset, + int n_seqs, + int* offsets) +{ for (int seq_index = 0; seq_index < n_seqs; seq_index++) { srslte_prach_gen(prach, seq_index, freq_offset, preamble); if (seq_index == 0) { @@ -157,12 +162,12 @@ int main(int argc, char** argv) memset(preamble_sum, 0, sizeof(cf_t) * MAX_LEN); int offsets[64]; memset(offsets, 0, sizeof(int) * 64); - float t_offsets[64]; + float t_offsets[64]; srslte_prach_cfg_t prach_cfg; ZERO_OBJECT(prach_cfg); - if(input_file_name) { + if (input_file_name) { if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } } @@ -175,14 +180,14 @@ int main(int argc, char** argv) prach_cfg.enable_successive_cancellation = test_successive_cancellation; prach_cfg.enable_freq_domain_offset_calc = freq_domain_offset_calc; - int srate = srslte_sampling_freq_hz(nof_prb); - int divisor = srate / PRACH_SRATE; + int srate = srslte_sampling_freq_hz(nof_prb); + int divisor = srate / PRACH_SRATE; if (test_offset_calculation || test_successive_cancellation || stagger_prach_power_and_phase) { if (n_seqs > 6) { n_seqs = 6; } - prach_cfg.zero_corr_zone = 0; - prach_cfg.num_ra_preambles = 8; + prach_cfg.zero_corr_zone = 0; + prach_cfg.num_ra_preambles = 8; printf("limiting number of preambles to 6\n"); if (test_offset_calculation) { for (int i = 0; i < 6; i++) { @@ -196,11 +201,11 @@ int main(int argc, char** argv) } if (srslte_prach_set_cfg(&prach, &prach_cfg, nof_prb)) { - ERROR("Error initiating PRACH object\n"); + ERROR("Error initiating PRACH object"); return -1; } - uint32_t seq_index = 0; + uint32_t seq_index = 0; uint32_t indices[64]; uint32_t n_indices = 0; @@ -221,7 +226,7 @@ int main(int argc, char** argv) } if (input_file_name) { - srslte_filesource_read(&fsrc, &preamble_sum[prach.N_cp], prach.N_seq); + srslte_filesource_read(&fsrc, &preamble_sum[prach.N_cp], prach.N_seq); } uint32_t prach_len = prach.N_seq; @@ -230,7 +235,7 @@ int main(int argc, char** argv) } struct timeval t[3]; gettimeofday(&t[1], NULL); - srslte_prach_detect_offset(&prach, 0, &preamble_sum[prach.N_cp], prach_len, indices, t_offsets , NULL, &n_indices); + srslte_prach_detect_offset(&prach, 0, &preamble_sum[prach.N_cp], prach_len, indices, t_offsets, NULL, &n_indices); gettimeofday(&t[2], NULL); get_time_interval(t); printf("texec=%ld us\n", t[0].tv_usec); @@ -241,7 +246,7 @@ int main(int argc, char** argv) } for (int i = 0; i < n_indices; i++) { if (test_offset_calculation) { - int error = (int)(t_offsets[i] * srate) - offsets[i]; + int error = (int)(t_offsets[i] * srate) - offsets[i]; if (abs(error) > divisor) { printf("preamble %d has incorrect offset calculated as %d, should be %d\n", indices[i], @@ -251,7 +256,7 @@ int main(int argc, char** argv) } } } - if (err){ + if (err) { return -1; } diff --git a/lib/src/phy/phch/test/prach_test_usrp.c b/lib/src/phy/phch/test/prach_test_usrp.c index e876c0115..3d41c6023 100644 --- a/lib/src/phy/phch/test/prach_test_usrp.c +++ b/lib/src/phy/phch/test/prach_test_usrp.c @@ -53,7 +53,7 @@ static const uint32_t tx_delay_ms = 4; // RF parameters static float uhd_rx_gain = 40, uhd_tx_gain = 60, uhd_freq = 2.4e9; -static char* uhd_args = ""; +static char* uhd_args = ""; static char* device_name = ""; // SRSLTE Verbose @@ -128,7 +128,7 @@ void parse_args(int argc, char** argv) case 'p': nof_prb = (int)strtol(argv[optind], NULL, 10); if (!srslte_nofprb_isvalid(nof_prb)) { - ERROR("Invalid number of UL RB %d\n", nof_prb); + ERROR("Invalid number of UL RB %d", nof_prb); exit(-1); } break; @@ -160,7 +160,6 @@ void parse_args(int argc, char** argv) void rf_msg_callback(void* arg, srslte_rf_error_t error) { switch (error.type) { - case SRSLTE_RF_ERROR_LATE: printf("L"); break; @@ -213,7 +212,7 @@ int main(int argc, char** argv) } if (srslte_prach_set_cfg(&prach, &prach_cfg, nof_prb)) { - ERROR("Error initiating PRACH object\n"); + ERROR("Error initiating PRACH object"); return SRSLTE_ERROR; } @@ -224,7 +223,7 @@ int main(int argc, char** argv) srslte_rf_t rf; printf("Opening RF device...\n"); if (srslte_rf_open_devname(&rf, device_name, uhd_args, 1)) { - ERROR("Error opening &uhd\n"); + ERROR("Error opening &uhd"); exit(-1); } printf("Test summary:\n"); @@ -245,7 +244,7 @@ int main(int argc, char** argv) printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); int srate_rf = (int)srslte_rf_set_rx_srate(&rf, (double)srate); if (srate_rf != srate) { - ERROR("Could not set sampling rate\n"); + ERROR("Could not set sampling rate"); exit(-1); } srslte_rf_set_tx_srate(&rf, (double)srate); @@ -280,16 +279,16 @@ int main(int argc, char** argv) // For a the number of frames for (uint32_t nframe = 0; nframe < nof_frames; nframe++) { - INFO("Rep %d. Receiving frame %d\n", rep, nframe); + INFO("Rep %d. Receiving frame %d", rep, nframe); srslte_rf_recv_with_time(&rf, &buffer[flen * nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs); srslte_timestamp_add(&tstamp, 0, tx_delay_ms * 1e-3 - timeadv * 1e-6); if (nframe == 10 - tx_delay_ms) { srslte_rf_send_timed2(&rf, preamble, flen, tstamp.full_secs, tstamp.frac_secs, false, !continous_tx); - INFO("Rep %d. Transmitting PRACH\n", rep); + INFO("Rep %d. Transmitting PRACH", rep); } else if (nframe == 10 - tx_delay_ms - 1 || continous_tx) { srslte_rf_send_timed2(&rf, zeros, flen, tstamp.full_secs, tstamp.frac_secs, is_start_of_burst, false); - INFO("Rep %d. Transmitting Zeros\n", rep); + INFO("Rep %d. Transmitting Zeros", rep); is_start_of_burst = false; } } @@ -311,9 +310,9 @@ int main(int argc, char** argv) } // Prompt detected PRACH - INFO("Rep %d. Nof detected PRACHs: %d\n", rep, nof_detected); + INFO("Rep %d. Nof detected PRACHs: %d", rep, nof_detected); for (int i = 0; i < nof_detected; i++) { - INFO("%d/%d index=%d, offset=%.2f us (%d samples)\n", + INFO("%d/%d index=%d, offset=%.2f us (%d samples)", i, nof_detected, indices[i], diff --git a/lib/src/phy/phch/test/psbch_file_test.c b/lib/src/phy/phch/test/psbch_file_test.c index 747f17127..69088e32f 100644 --- a/lib/src/phy/phch/test/psbch_file_test.c +++ b/lib/src/phy/phch/test/psbch_file_test.c @@ -135,7 +135,7 @@ int main(int argc, char** argv) // TX srslte_ofdm_t ifft; if (srslte_ofdm_tx_init(&ifft, cell.cp, sf_buffer, output_buffer, cell.nof_prb)) { - ERROR("Error creating IFFT object\n"); + ERROR("Error creating IFFT object"); return SRSLTE_ERROR; } srslte_ofdm_set_normalize(&ifft, true); @@ -153,20 +153,20 @@ int main(int argc, char** argv) // PSBCH srslte_psbch_t psbch; if (srslte_psbch_init(&psbch, cell.nof_prb, cell.N_sl_id, cell.tm, cell.cp) != SRSLTE_SUCCESS) { - ERROR("Error in psbch init\n"); + ERROR("Error in psbch init"); return SRSLTE_ERROR; } // PSCBH DMRS srslte_sl_comm_resource_pool_t sl_comm_resource_pool; if (srslte_sl_comm_resource_pool_get_default_config(&sl_comm_resource_pool, cell) != SRSLTE_SUCCESS) { - ERROR("Error initializing sl_comm_resource_pool\n"); + ERROR("Error initializing sl_comm_resource_pool"); return SRSLTE_ERROR; } - srslte_chest_sl_t psbch_chest; + srslte_chest_sl_t psbch_chest; if (srslte_chest_sl_init(&psbch_chest, SRSLTE_SIDELINK_PSBCH, cell, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error in chest PSBCH init\n"); + ERROR("Error in chest PSBCH init"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/test/psbch_test.c b/lib/src/phy/phch/test/psbch_test.c index b738ac1f7..b4f7913d4 100644 --- a/lib/src/phy/phch/test/psbch_test.c +++ b/lib/src/phy/phch/test/psbch_test.c @@ -107,7 +107,7 @@ int main(int argc, char** argv) // PSBCH srslte_psbch_t psbch; if (srslte_psbch_init(&psbch, cell.nof_prb, cell.N_sl_id, cell.tm, cell.cp) != SRSLTE_SUCCESS) { - ERROR("Error in psbch init\n"); + ERROR("Error in psbch init"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/test/pscch_test.c b/lib/src/phy/phch/test/pscch_test.c index 2ef55e38c..a8f03bac6 100644 --- a/lib/src/phy/phch/test/pscch_test.c +++ b/lib/src/phy/phch/test/pscch_test.c @@ -96,7 +96,7 @@ int main(int argc, char** argv) srslte_sl_comm_resource_pool_t sl_comm_resource_pool; if (srslte_sl_comm_resource_pool_get_default_config(&sl_comm_resource_pool, cell) != SRSLTE_SUCCESS) { - ERROR("Error initializing sl_comm_resource_pool\n"); + ERROR("Error initializing sl_comm_resource_pool"); return SRSLTE_ERROR; } @@ -113,12 +113,12 @@ int main(int argc, char** argv) // PSCCH srslte_pscch_t pscch; if (srslte_pscch_init(&pscch, SRSLTE_MAX_PRB) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH init\n"); + ERROR("Error in PSCCH init"); return SRSLTE_ERROR; } if (srslte_pscch_set_cell(&pscch, cell) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH init\n"); + ERROR("Error in PSCCH init"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/test/pssch_pscch_file_test.c b/lib/src/phy/phch/test/pssch_pscch_file_test.c index f3a4014ae..5928a539d 100644 --- a/lib/src/phy/phch/test/pssch_pscch_file_test.c +++ b/lib/src/phy/phch/test/pssch_pscch_file_test.c @@ -133,7 +133,7 @@ int base_init() sf_n_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); if (srslte_sl_comm_resource_pool_get_default_config(&sl_comm_resource_pool, cell) != SRSLTE_SUCCESS) { - ERROR("Error initializing sl_comm_resource_pool\n"); + ERROR("Error initializing sl_comm_resource_pool"); return SRSLTE_ERROR; } sl_comm_resource_pool.num_sub_channel = num_sub_channel; @@ -141,21 +141,21 @@ int base_init() sf_buffer = srslte_vec_cf_malloc(sf_n_re); if (!sf_buffer) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(sf_buffer, sf_n_re); equalized_sf_buffer = srslte_vec_cf_malloc(sf_n_re); if (!equalized_sf_buffer) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(equalized_sf_buffer, sf_n_re); input_buffer = srslte_vec_cf_malloc(sf_n_samples); if (!input_buffer) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(input_buffer, sf_n_samples); @@ -163,37 +163,37 @@ int base_init() srslte_sci_init(&sci, cell, sl_comm_resource_pool); if (srslte_pscch_init(&pscch, SRSLTE_MAX_PRB) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH init\n"); + ERROR("Error in PSCCH init"); return SRSLTE_ERROR; } if (srslte_pscch_set_cell(&pscch, cell) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH set cell\n"); + ERROR("Error in PSCCH set cell"); return SRSLTE_ERROR; } if (srslte_chest_sl_init(&pscch_chest, SRSLTE_SIDELINK_PSCCH, cell, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error in PSCCH DMRS init\n"); + ERROR("Error in PSCCH DMRS init"); return SRSLTE_ERROR; } if (srslte_pssch_init(&pssch, cell, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error initializing PSSCH\n"); + ERROR("Error initializing PSSCH"); return SRSLTE_ERROR; } if (srslte_chest_sl_init(&pssch_chest, SRSLTE_SIDELINK_PSSCH, cell, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error in chest PSSCH init\n"); + ERROR("Error in chest PSSCH init"); return SRSLTE_ERROR; } if (input_file_name) { if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - printf("Error opening file %s\n", input_file_name); + printf("Error opening file %s", input_file_name); return SRSLTE_ERROR; } } else { - ERROR("Invalid input file name\n"); + ERROR("Invalid input file name"); return SRSLTE_ERROR; } @@ -239,7 +239,7 @@ int main(int argc, char** argv) srslte_use_standard_symbol_size(use_standard_lte_rates); if (base_init()) { - ERROR("Error initializing\n"); + ERROR("Error initializing"); base_free(); return SRSLTE_ERROR; } @@ -279,15 +279,12 @@ int main(int argc, char** argv) srslte_ofdm_rx_sf(&fft); if (cell.tm == SRSLTE_SIDELINK_TM1 || cell.tm == SRSLTE_SIDELINK_TM2) { - // 3GPP TS 36.213 Section 14.2.1.2 UE procedure for determining subframes // and resource blocks for transmitting PSCCH for sidelink transmission mode 2 if (sl_comm_resource_pool.pscch_sf_bitmap[period_sf_idx] == 1) { - for (uint32_t pscch_prb_start_idx = sl_comm_resource_pool.prb_start; pscch_prb_start_idx <= sl_comm_resource_pool.prb_end; pscch_prb_start_idx++) { - // PSCCH Channel estimation pscch_chest_sl_cfg.prb_start_idx = pscch_prb_start_idx; srslte_chest_sl_set_cfg(&pscch_chest, pscch_chest_sl_cfg); @@ -295,7 +292,6 @@ int main(int argc, char** argv) if (srslte_pscch_decode(&pscch, equalized_sf_buffer, sci_rx, pscch_prb_start_idx) == SRSLTE_SUCCESS) { if (srslte_sci_format0_unpack(&sci, sci_rx) == SRSLTE_SUCCESS) { - srslte_sci_info(&sci, sci_msg, sizeof(sci_msg)); fprintf(stdout, "%s", sci_msg); @@ -315,7 +311,6 @@ int main(int argc, char** argv) if ((sl_comm_resource_pool.pssch_sf_bitmap[period_sf_idx] == 1) && (sci_decoded == true)) { if (srslte_ra_sl_pssch_allowed_sf(current_sf_idx, sci.trp_idx, SRSLTE_SL_DUPLEX_MODE_FDD, 0)) { - // Redundancy version uint32_t rv_idx = allowed_pssch_sf_idx % 4; diff --git a/lib/src/phy/phch/test/pssch_test.c b/lib/src/phy/phch/test/pssch_test.c index 8d5b3cefe..c7a562e6f 100644 --- a/lib/src/phy/phch/test/pssch_test.c +++ b/lib/src/phy/phch/test/pssch_test.c @@ -87,22 +87,22 @@ int main(int argc, char** argv) srslte_sl_comm_resource_pool_t sl_comm_resource_pool; if (srslte_sl_comm_resource_pool_get_default_config(&sl_comm_resource_pool, cell) != SRSLTE_SUCCESS) { - ERROR("Error initializing sl_comm_resource_pool\n"); + ERROR("Error initializing sl_comm_resource_pool"); return SRSLTE_ERROR; } srslte_pssch_t pssch = {}; if (srslte_pssch_init(&pssch, cell, sl_comm_resource_pool) != SRSLTE_SUCCESS) { - ERROR("Error initializing PSSCH\n"); + ERROR("Error initializing PSSCH"); return SRSLTE_ERROR; } uint32_t nof_prb_pssch = srslte_dft_precoding_get_valid_prb(cell.nof_prb); - uint32_t N_x_id = 255; - uint32_t sf_n_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); - cf_t* sf_buffer = srslte_vec_cf_malloc(sf_n_re); + uint32_t N_x_id = 255; + uint32_t sf_n_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); + cf_t* sf_buffer = srslte_vec_cf_malloc(sf_n_re); if (!sf_buffer) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return SRSLTE_ERROR; } srslte_vec_cf_zero(sf_buffer, sf_n_re); @@ -115,7 +115,7 @@ int main(int argc, char** argv) srslte_pssch_cfg_t pssch_cfg = {prb_start_idx, nof_prb_pssch, N_x_id, mcs_idx, 0, 0}; if (srslte_pssch_set_cfg(&pssch, pssch_cfg) != SRSLTE_SUCCESS) { - ERROR("Error configuring PSSCH\n"); + ERROR("Error configuring PSSCH"); goto clean_exit; } @@ -129,13 +129,13 @@ int main(int argc, char** argv) // PSSCH encoding if (srslte_pssch_encode(&pssch, tb, pssch.sl_sch_tb_len, sf_buffer) != SRSLTE_SUCCESS) { - ERROR("Error encoding PSSCH\n"); + ERROR("Error encoding PSSCH"); goto clean_exit; } // PSSCH decoding if (srslte_pssch_decode(&pssch, sf_buffer, tb_rx, pssch.sl_sch_tb_len) != SRSLTE_SUCCESS) { - ERROR("Error decoding PSSCH\n"); + ERROR("Error decoding PSSCH"); goto clean_exit; } diff --git a/lib/src/phy/phch/test/pucch_nr_test.c b/lib/src/phy/phch/test/pucch_nr_test.c index 16bc98f76..711722949 100644 --- a/lib/src/phy/phch/test/pucch_nr_test.c +++ b/lib/src/phy/phch/test/pucch_nr_test.c @@ -48,7 +48,7 @@ static srslte_channel_awgn_t awgn = {}; static int test_pucch_format0(srslte_pucch_nr_t* pucch, const srslte_pucch_nr_common_cfg_t* cfg, cf_t* slot_symbols) { - srslte_dl_slot_cfg_t slot = {}; + srslte_slot_cfg_t slot = {}; srslte_pucch_nr_resource_t resource = {}; resource.format = SRSLTE_PUCCH_NR_FORMAT_0; @@ -97,7 +97,7 @@ static int test_pucch_format1(srslte_pucch_nr_t* pucch, srslte_chest_ul_res_t* chest_res, cf_t* slot_symbols) { - srslte_dl_slot_cfg_t slot = {}; + srslte_slot_cfg_t slot = {}; srslte_pucch_nr_resource_t resource = {}; resource.format = SRSLTE_PUCCH_NR_FORMAT_1; @@ -170,21 +170,18 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, srslte_chest_ul_res_t* chest_res, cf_t* slot_symbols) { - srslte_dl_slot_cfg_t slot = {}; + srslte_slot_cfg_t slot = {}; srslte_pucch_nr_resource_t resource = {}; resource.format = SRSLTE_PUCCH_NR_FORMAT_2; for (slot.idx = 0; slot.idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot.idx++) { - for (resource.nof_symbols = SRSLTE_PUCCH_NR_FORMAT2_MIN_NSYMB; resource.nof_symbols <= SRSLTE_PUCCH_NR_FORMAT2_MAX_NSYMB; resource.nof_symbols++) { - for (resource.start_symbol_idx = 0; resource.start_symbol_idx <= SRSLTE_MIN(SRSLTE_PUCCH_NR_FORMAT2_MAX_STARTSYMB, SRSLTE_NSYMB_PER_SLOT_NR - resource.nof_symbols); resource.start_symbol_idx += starting_symbol_stride) { - srslte_uci_cfg_nr_t uci_cfg = {}; for (uci_cfg.o_ack = SRSLTE_PUCCH_NR_FORMAT2_MIN_NOF_BITS; uci_cfg.o_ack <= SRSLTE_UCI_NR_MAX_ACK_BITS; @@ -198,7 +195,6 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, } for (resource.max_code_rate = 0; resource.max_code_rate < max_code_rate_end; resource.max_code_rate++) { - // Skip case if not enough PRB are used int min_nof_prb = srslte_ra_ul_nr_pucch_format_2_3_min_prb(&resource, &uci_cfg); TESTASSERT(min_nof_prb > SRSLTE_SUCCESS); @@ -206,10 +202,8 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, for (resource.nof_prb = min_nof_prb; resource.nof_prb < SRSLTE_MIN(carrier.nof_prb, SRSLTE_PUCCH_NR_FORMAT2_MAX_NPRB); resource.nof_prb++) { - for (resource.starting_prb = 0; resource.starting_prb < (carrier.nof_prb - resource.nof_prb); resource.starting_prb += starting_prb_stride) { - // Generate ACKs for (uint32_t i = 0; i < uci_cfg.o_ack; i++) { uci_value.ack[i] = (uint8_t)srslte_random_uniform_int_dist(random_gen, 0, 1); @@ -231,7 +225,7 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch, // Estimate channel TESTASSERT(srslte_dmrs_pucch_format2_estimate( pucch, &carrier, cfg, &slot, &resource, slot_symbols, chest_res) == SRSLTE_SUCCESS); - INFO("RSRP=%+.2f; EPRE=%+.2f; SNR=%+.2f;\n", + INFO("RSRP=%+.2f; EPRE=%+.2f; SNR=%+.2f;", chest_res->rsrp_dBfs, chest_res->epre_dBfs, chest_res->snr_db); @@ -311,33 +305,33 @@ int main(int argc, char** argv) random_gen = srslte_random_init(0x1234); if (random_gen == NULL) { - ERROR("Random init\n"); + ERROR("Random init"); goto clean_exit; } if (slot_symb == NULL) { - ERROR("Alloc\n"); + ERROR("Alloc"); goto clean_exit; } srslte_pucch_nr_args_t pucch_args = {}; if (srslte_pucch_nr_init(&pucch, &pucch_args) < SRSLTE_SUCCESS) { - ERROR("PUCCH init\n"); + ERROR("PUCCH init"); goto clean_exit; } if (srslte_chest_ul_res_init(&chest_res, carrier.nof_prb)) { - ERROR("Chest UL\n"); + ERROR("Chest UL"); goto clean_exit; } if (srslte_channel_awgn_init(&awgn, 1234) < SRSLTE_SUCCESS) { - ERROR("AWGN init\n"); + ERROR("AWGN init"); goto clean_exit; } if (srslte_channel_awgn_set_n0(&awgn, -snr_db) < SRSLTE_SUCCESS) { - ERROR("AWGN set N0\n"); + ERROR("AWGN set N0"); goto clean_exit; } @@ -346,7 +340,7 @@ int main(int argc, char** argv) // Test Format 0 if (format < 0 || format == 0) { if (test_pucch_format0(&pucch, &common_cfg, slot_symb) < SRSLTE_SUCCESS) { - ERROR("Failed PUCCH format 0\n"); + ERROR("Failed PUCCH format 0"); goto clean_exit; } } @@ -354,7 +348,7 @@ int main(int argc, char** argv) // Test Format 1 if (format < 0 || format == 1) { if (test_pucch_format1(&pucch, &common_cfg, &chest_res, slot_symb) < SRSLTE_SUCCESS) { - ERROR("Failed PUCCH format 1\n"); + ERROR("Failed PUCCH format 1"); goto clean_exit; } } @@ -362,7 +356,7 @@ int main(int argc, char** argv) // Test Format 2 if (format < 0 || format == 2) { if (test_pucch_format2(&pucch, &common_cfg, &chest_res, slot_symb) < SRSLTE_SUCCESS) { - ERROR("Failed PUCCH format 2\n"); + ERROR("Failed PUCCH format 2"); goto clean_exit; } } diff --git a/lib/src/phy/phch/test/pucch_test.c b/lib/src/phy/phch/test/pucch_test.c index 5f55a1fae..f4d4147f5 100644 --- a/lib/src/phy/phch/test/pucch_test.c +++ b/lib/src/phy/phch/test/pucch_test.c @@ -140,10 +140,10 @@ int test_uci_cqi_pucch(void) int main(int argc, char** argv) { - srslte_pucch_t pucch_ue = {}; - srslte_pucch_t pucch_enb = {}; - srslte_pucch_cfg_t pucch_cfg = {}; - srslte_refsignal_ul_t dmrs; + srslte_pucch_t pucch_ue = {}; + srslte_pucch_t pucch_enb = {}; + srslte_pucch_cfg_t pucch_cfg = {}; + srslte_refsignal_ul_t dmrs = {}; cf_t* sf_symbols = NULL; cf_t pucch_dmrs[2 * SRSLTE_NRE * 3]; int ret = -1; @@ -158,55 +158,55 @@ int main(int argc, char** argv) } if (srslte_pucch_init_ue(&pucch_ue)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } if (srslte_pucch_set_cell(&pucch_ue, cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } if (srslte_pucch_set_rnti(&pucch_ue, 11)) { - ERROR("Error setting C-RNTI\n"); + ERROR("Error setting C-RNTI"); goto quit; } if (srslte_pucch_init_enb(&pucch_enb)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } if (srslte_pucch_set_cell(&pucch_enb, cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } if (srslte_pucch_set_rnti(&pucch_enb, 11)) { - ERROR("Error setting C-RNTI\n"); + ERROR("Error setting C-RNTI"); goto quit; } if (srslte_refsignal_ul_set_cell(&dmrs, cell)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); exit(-1); } if (srslte_chest_ul_init(&chest, cell.nof_prb) < SRSLTE_SUCCESS) { - ERROR("Error initiating channel estimator\n"); + ERROR("Error initiating channel estimator"); goto quit; } if (srslte_chest_ul_res_init(&chest_res, cell.nof_prb) < SRSLTE_SUCCESS) { - ERROR("Error initiating channel estimator result\n"); + ERROR("Error initiating channel estimator result"); goto quit; } if (srslte_chest_ul_set_cell(&chest, cell) < SRSLTE_SUCCESS) { - ERROR("Error setting channel estimator cell\n"); + ERROR("Error setting channel estimator cell"); goto quit; } if (srslte_channel_awgn_init(&awgn, 0x1234) < SRSLTE_SUCCESS) { - ERROR("Error initiating AWGN\n"); + ERROR("Error initiating AWGN"); goto quit; } if (srslte_channel_awgn_set_n0(&awgn, -snr_db) < SRSLTE_SUCCESS) { - ERROR("Error setting AWGN\n"); + ERROR("Error setting AWGN"); goto quit; } @@ -223,7 +223,6 @@ int main(int argc, char** argv) for (uint32_t d = 1; d <= 3; d++) { for (uint32_t ncs = 0; ncs < 8; ncs += d) { for (uint32_t n_pucch = 1; n_pucch < 130; n_pucch += 50) { - struct timeval t[3]; pucch_cfg.delta_pucch_shift = d; @@ -265,16 +264,16 @@ int main(int argc, char** argv) // Encode PUCCH signals gettimeofday(&t[1], NULL); if (srslte_pucch_encode(&pucch_ue, &ul_sf, &pucch_cfg, &uci_data.value, sf_symbols)) { - ERROR("Error encoding PUCCH\n"); + ERROR("Error encoding PUCCH"); goto quit; } if (srslte_refsignal_dmrs_pucch_gen(&dmrs, &ul_sf, &pucch_cfg, pucch_dmrs)) { - ERROR("Error encoding PUCCH\n"); + ERROR("Error encoding PUCCH"); goto quit; } if (srslte_refsignal_dmrs_pucch_put(&dmrs, &pucch_cfg, pucch_dmrs, sf_symbols)) { - ERROR("Error encoding PUCCH\n"); + ERROR("Error encoding PUCCH"); goto quit; } gettimeofday(&t[2], NULL); @@ -287,13 +286,13 @@ int main(int argc, char** argv) // Decode PUCCH signals gettimeofday(&t[1], NULL); if (srslte_chest_ul_estimate_pucch(&chest, &ul_sf, &pucch_cfg, sf_symbols, &chest_res) < SRSLTE_SUCCESS) { - ERROR("Error estimating PUCCH channel\n"); + ERROR("Error estimating PUCCH channel"); goto quit; } srslte_pucch_res_t res = {}; if (srslte_pucch_decode(&pucch_enb, &ul_sf, &pucch_cfg, &chest_res, sf_symbols, &res) < SRSLTE_SUCCESS) { - ERROR("Error decoding PUCCH\n"); + ERROR("Error decoding PUCCH"); goto quit; } gettimeofday(&t[2], NULL); @@ -303,15 +302,15 @@ int main(int argc, char** argv) // Check EPRE and RSRP are +/- 1 dB and SNR measurements are +/- 3dB if (fabsf(chest_res.epre_dBfs) > 1.0 || fabsf(chest_res.rsrp_dBfs) > 1.0 || fabsf(chest_res.snr_db - snr_db) > 3.0) { - ERROR("Invalid EPRE (%+.2f), RSRP (%+.2f) or SNR (%+.2f)\n", + ERROR("Invalid EPRE (%+.2f), RSRP (%+.2f) or SNR (%+.2f)", chest_res.epre_dBfs, chest_res.rsrp_dBfs, chest_res.snr_db); goto quit; } - INFO("format %d, n_pucch: %d, ncs: %d, d: %d, t_encode=%ld us, t_decode=%ld us, EPRE=%+.1f dBfs, RSRP=%+.1f " - "dBfs, SNR=%+.1f dBfs\n", + INFO("format %d, n_pucch: %d, ncs: %d, d: %d, t_encode=%" PRIu64 " us, t_decode=%" PRIu64 + " us, EPRE=%+.1f dBfs, RSRP=%+.1f dBfs, SNR=%+.1f dBfs\n", format, n_pucch, ncs, diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index 6da8fb445..e7e515222 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -21,7 +21,7 @@ #include "srslte/phy/phch/pusch_nr.h" #include "srslte/phy/phch/ra_nr.h" -#include "srslte/phy/ue/ue_ul_nr_data.h" +#include "srslte/phy/phch/ra_ul_nr.h" #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/random.h" #include "srslte/phy/utils/vector.h" @@ -106,30 +106,30 @@ int main(int argc, char** argv) pusch_args.sch.disable_simd = false; pusch_args.measure_evm = true; - if (srslte_pusch_nr_init_enb(&pusch_tx, &pusch_args) < SRSLTE_SUCCESS) { - ERROR("Error initiating PUSCH for Tx\n"); + if (srslte_pusch_nr_init_ue(&pusch_tx, &pusch_args) < SRSLTE_SUCCESS) { + ERROR("Error initiating PUSCH for Tx"); goto clean_exit; } - if (srslte_pusch_nr_init_ue(&pusch_rx, &pusch_args) < SRSLTE_SUCCESS) { - ERROR("Error initiating SCH NR for Rx\n"); + if (srslte_pusch_nr_init_gnb(&pusch_rx, &pusch_args) < SRSLTE_SUCCESS) { + ERROR("Error initiating SCH NR for Rx"); goto clean_exit; } if (srslte_pusch_nr_set_carrier(&pusch_tx, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } if (srslte_pusch_nr_set_carrier(&pusch_rx, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } for (uint32_t i = 0; i < carrier.max_mimo_layers; i++) { sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(carrier.nof_prb)); if (sf_symbols[i] == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } } @@ -138,7 +138,7 @@ int main(int argc, char** argv) data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); if (data_tx[i] == NULL || data_rx[i] == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } @@ -150,25 +150,25 @@ int main(int argc, char** argv) if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } // Use grant default A time resources with m=0 - if (srslte_ue_ul_nr_pdsch_time_resource_default_A(0, &pusch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading default grant\n"); + if (srslte_ra_ul_nr_pdsch_time_resource_default_A(carrier.numerology, 0, &pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading default grant"); goto clean_exit; } // Load number of DMRS CDM groups without data - if (srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups without data\n"); + if (srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading number of DMRS CDM groups without data"); goto clean_exit; } @@ -191,20 +191,19 @@ int main(int argc, char** argv) } if (srslte_chest_dl_res_init(&chest, carrier.nof_prb) < SRSLTE_SUCCESS) { - ERROR("Initiating chest\n"); + ERROR("Initiating chest"); goto clean_exit; } for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { for (mcs = mcs_start; mcs < mcs_end; mcs++) { - for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { pusch_grant.prb_idx[n] = (n < n_prb); } pusch_grant.dci_format = srslte_dci_format_nr_0_0; if (srslte_ra_nr_fill_tb(&pusch_cfg, &pusch_grant, mcs, &pusch_grant.tb[0]) < SRSLTE_SUCCESS) { - ERROR("Error filing tb\n"); + ERROR("Error filing tb"); goto clean_exit; } @@ -221,7 +220,7 @@ int main(int argc, char** argv) } if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { - ERROR("Error encoding\n"); + ERROR("Error encoding"); goto clean_exit; } @@ -236,12 +235,12 @@ int main(int argc, char** argv) chest.nof_re = pusch_grant.tb->nof_re; if (srslte_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_grant, &chest, sf_symbols, pusch_res) < SRSLTE_SUCCESS) { - ERROR("Error encoding\n"); + ERROR("Error encoding"); goto clean_exit; } if (pusch_res->evm > 0.001f) { - ERROR("Error PUSCH EVM is too high %f\n", pusch_res->evm); + ERROR("Error PUSCH EVM is too high %f", pusch_res->evm); goto clean_exit; } @@ -256,7 +255,7 @@ int main(int argc, char** argv) mse = mse / (nof_re * pusch_grant.nof_layers); } if (mse > 0.001) { - ERROR("MSE error (%f) is too high\n", mse); + ERROR("MSE error (%f) is too high", mse); for (uint32_t i = 0; i < pusch_grant.nof_layers; i++) { printf("d_tx[%d]=", i); srslte_vec_fprint_c(stdout, pusch_tx.d[i], nof_re); @@ -267,12 +266,12 @@ int main(int argc, char** argv) } if (!pusch_res[0].crc) { - ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pusch_grant.tb[0].tbs); + ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs); goto clean_exit; } if (memcmp(data_tx[0], data_rx[0], pusch_grant.tb[0].tbs / 8) != 0) { - ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pusch_grant.tb[0].tbs); + ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_grant.tb[0].tbs); printf("Tx data: "); srslte_vec_fprint_byte(stdout, data_tx[0], pusch_grant.tb[0].tbs / 8); printf("Rx data: "); diff --git a/lib/src/phy/phch/test/pusch_test.c b/lib/src/phy/phch/test/pusch_test.c index c87312d63..240da4ee5 100644 --- a/lib/src/phy/phch/test/pusch_test.c +++ b/lib/src/phy/phch/test/pusch_test.c @@ -131,7 +131,7 @@ void parse_extensive_param(char* param, char* arg) } if (ext_code) { - ERROR("Error parsing parameter '%s' and argument '%s'\n", param, arg); + ERROR("Error parsing parameter '%s' and argument '%s'", param, arg); exit(ext_code); } } @@ -218,7 +218,7 @@ int main(int argc, char** argv) srslte_pusch_hopping_cfg_t ul_hopping = {.n_sb = 1, .hopping_offset = 0, .hop_mode = 1}; if (srslte_ra_ul_dci_to_grant(&cell, &ul_sf, &ul_hopping, &dci, &cfg.grant)) { - ERROR("Error computing resource allocation\n"); + ERROR("Error computing resource allocation"); return ret; } @@ -226,19 +226,19 @@ int main(int argc, char** argv) cfg.grant.n_prb_tilde[1] = cfg.grant.n_prb[1]; if (srslte_pusch_init_ue(&pusch_tx, cell.nof_prb)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto quit; } if (srslte_pusch_set_cell(&pusch_tx, cell)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto quit; } if (srslte_pusch_init_enb(&pusch_rx, cell.nof_prb)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto quit; } if (srslte_pusch_set_cell(&pusch_rx, cell)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto quit; } @@ -268,12 +268,12 @@ int main(int argc, char** argv) } if (srslte_softbuffer_tx_init(&softbuffer_tx, 100)) { - ERROR("Error initiating soft buffer\n"); + ERROR("Error initiating soft buffer"); goto quit; } if (srslte_softbuffer_rx_init(&softbuffer_rx, 100)) { - ERROR("Error initiating soft buffer\n"); + ERROR("Error initiating soft buffer"); goto quit; } @@ -309,14 +309,13 @@ int main(int argc, char** argv) cfg.softbuffers.tx = &softbuffer_tx; if (srslte_pusch_encode(&pusch_tx, &ul_sf, &cfg, &pdata, sf_symbols)) { - ERROR("Error encoding TB\n"); + ERROR("Error encoding TB"); exit(-1); } if (rv_idx > 0) { - cfg.grant.tb.rv = rv_idx; if (srslte_pusch_encode(&pusch_tx, &ul_sf, &cfg, &pdata, sf_symbols)) { - ERROR("Error encoding TB\n"); + ERROR("Error encoding TB"); exit(-1); } } @@ -338,7 +337,7 @@ int main(int argc, char** argv) printf("Unmatched data detected\n"); ret = SRSLTE_ERROR; } else { - INFO("Rx Data is Ok\n"); + INFO("Rx Data is Ok"); } if (uci_data_tx.cfg.ack[0].nof_acks) { @@ -367,7 +366,7 @@ int main(int argc, char** argv) printf("UCI RI bit error: %d != %d\n", uci_data_tx.value.ri, pusch_res.uci.ri); ret = SRSLTE_ERROR; } else { - INFO("Rx RI is Ok\n"); + INFO("Rx RI is Ok"); } } @@ -377,7 +376,7 @@ int main(int argc, char** argv) printf("CQI Decode failed at subframe %d\n", n); ret = SRSLTE_ERROR; } else { - INFO("Rx CQI is Ok (crc=%d, wb_cqi=%d)\n", pusch_res.uci.cqi.data_crc, pusch_res.uci.cqi.wideband.wideband_cqi); + INFO("Rx CQI is Ok (crc=%d, wb_cqi=%d)", pusch_res.uci.cqi.data_crc, pusch_res.uci.cqi.wideband.wideband_cqi); } } diff --git a/lib/src/phy/phch/test/sch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c index 8a2490e16..2a2e3f824 100644 --- a/lib/src/phy/phch/test/sch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -106,22 +106,22 @@ int main(int argc, char** argv) srslte_sch_nr_args_t args = {}; args.disable_simd = false; if (srslte_sch_nr_init_tx(&sch_nr_tx, &args) < SRSLTE_SUCCESS) { - ERROR("Error initiating SCH NR for Tx\n"); + ERROR("Error initiating SCH NR for Tx"); goto clean_exit; } if (srslte_sch_nr_init_rx(&sch_nr_rx, &args) < SRSLTE_SUCCESS) { - ERROR("Error initiating SCH NR for Rx\n"); + ERROR("Error initiating SCH NR for Rx"); goto clean_exit; } if (srslte_sch_nr_set_carrier(&sch_nr_tx, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } if (srslte_sch_nr_set_carrier(&sch_nr_rx, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } @@ -130,19 +130,19 @@ int main(int argc, char** argv) if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } // Use grant default A time resources with m=0 - if (srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading default grant\n"); + if (srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading default grant"); goto clean_exit; } pdsch_grant.nof_layers = carrier.max_mimo_layers; @@ -164,14 +164,13 @@ int main(int argc, char** argv) for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { for (mcs = mcs_start; mcs < mcs_end; mcs++) { - for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { pdsch_grant.prb_idx[n] = (n < n_prb); } srslte_sch_tb_t tb = {}; if (srslte_ra_nr_fill_tb(&pdsch_cfg, &pdsch_grant, mcs, &tb) < SRSLTE_SUCCESS) { - ERROR("Error filing tb\n"); + ERROR("Error filing tb"); goto clean_exit; } @@ -182,7 +181,7 @@ int main(int argc, char** argv) tb.softbuffer.tx = &softbuffer_tx; if (srslte_dlsch_nr_encode(&sch_nr_tx, &pdsch_cfg.sch_cfg, &tb, data_tx, encoded) < SRSLTE_SUCCESS) { - ERROR("Error encoding\n"); + ERROR("Error encoding"); goto clean_exit; } @@ -195,17 +194,17 @@ int main(int argc, char** argv) bool crc = false; if (srslte_dlsch_nr_decode(&sch_nr_rx, &pdsch_cfg.sch_cfg, &tb, llr, data_rx, &crc) < SRSLTE_SUCCESS) { - ERROR("Error encoding\n"); + ERROR("Error encoding"); goto clean_exit; } if (!crc) { - ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, tb.tbs); + ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, tb.tbs); goto clean_exit; } if (memcmp(data_tx, data_rx, tb.tbs / 8) != 0) { - ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, tb.tbs); + ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, tb.tbs); printf("Tx data: "); srslte_vec_fprint_byte(stdout, data_tx, tb.tbs / 8); printf("Rx data: "); diff --git a/lib/src/phy/phch/uci.c b/lib/src/phy/phch/uci.c index 2c9eb20fb..0329ae014 100644 --- a/lib/src/phy/phch/uci.c +++ b/lib/src/phy/phch/uci.c @@ -134,7 +134,6 @@ int16_t srslte_uci_decode_cqi_pucch(srslte_uci_cqi_pucch_t* q, int32_t max_corr = INT32_MIN; uint32_t nwords = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH; for (uint32_t w = 0; w < nwords; w += 1 << (SRSLTE_UCI_MAX_CQI_LEN_PUCCH - cqi_len)) { - // Calculate correlation with pregenerated word and select maximum int32_t corr = srslte_vec_dot_prod_sss(q->cqi_table_s[w], b_bits, SRSLTE_UCI_CQI_CODED_PUCCH_B); if (corr > max_corr) { @@ -146,7 +145,7 @@ int16_t srslte_uci_decode_cqi_pucch(srslte_uci_cqi_pucch_t* q, uint8_t* ptr = cqi_data; srslte_bit_unpack(max_w, &ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH); - INFO("Decoded CQI: w=%d, corr=%d\n", max_w, max_corr); + INFO("Decoded CQI: w=%d, corr=%d", max_w, max_corr); return max_corr; } else { return SRSLTE_ERROR_INVALID_INPUTS; @@ -173,7 +172,6 @@ void srslte_uci_cqi_free(srslte_uci_cqi_pusch_t* q) static uint32_t Q_prime_cqi(srslte_pusch_cfg_t* cfg, uint32_t O, float beta, uint32_t Q_prime_ri) { - uint32_t K = cfg->K_segm; uint32_t Q_prime = 0; @@ -215,7 +213,7 @@ int decode_cqi_short(srslte_uci_cqi_pusch_t* q, int16_t* q_bits, uint32_t Q, uin { if (nof_bits <= SRSLTE_FEC_BLOCK_MAX_NOF_BITS && nof_bits > 0 && q != NULL && data != NULL && q_bits != NULL) { int32_t max_corr = srslte_block_decode_i16(q_bits, Q, data, nof_bits); - INFO("Decoded CQI: corr=%d\n", max_corr); + INFO("Decoded CQI: corr=%d", max_corr); return SRSLTE_SUCCESS; } else { return SRSLTE_ERROR_INVALID_INPUTS; @@ -262,7 +260,6 @@ int decode_cqi_long(srslte_uci_cqi_pusch_t* q, int16_t* q_bits, uint32_t Q, uint { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (nof_bits + 8 < SRSLTE_UCI_MAX_CQI_LEN_PUSCH && q != NULL && data != NULL && q_bits != NULL) { - srslte_rm_conv_rx_s(q_bits, Q, q->encoded_cqi_s, 3 * (nof_bits + 8)); DEBUG("cconv_rx="); @@ -300,7 +297,7 @@ int srslte_uci_decode_cqi_pusch(srslte_uci_cqi_pusch_t* q, bool* cqi_ack) { if (beta < 0) { - ERROR("Error beta is reserved\n"); + ERROR("Error beta is reserved"); return -1; } uint32_t Q_prime = Q_prime_cqi(cfg, cqi_len, beta, Q_prime_ri); @@ -343,7 +340,7 @@ int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t* q, uint8_t* q_bits) { if (beta < 0) { - ERROR("Error beta is reserved\n"); + ERROR("Error beta is reserved"); return -1; } @@ -370,7 +367,6 @@ static int uci_ulsch_interleave_ack_gen(uint32_t ack_q_bit_idx, uint32_t N_pusch_symbs, srslte_uci_bit_t* ack_bits) { - const uint32_t ack_column_set_norm[4] = {2, 3, 8, 9}; const uint32_t ack_column_set_ext[4] = {1, 2, 6, 7}; @@ -383,7 +379,7 @@ static int uci_ulsch_interleave_ack_gen(uint32_t ack_q_bit_idx, } return SRSLTE_SUCCESS; } else { - ERROR("Error interleaving UCI-ACK bit idx %d for H_prime_total=%d and N_pusch_symbs=%d\n", + ERROR("Error interleaving UCI-ACK bit idx %d for H_prime_total=%d and N_pusch_symbs=%d", ack_q_bit_idx, H_prime_total, N_pusch_symbs); @@ -398,7 +394,6 @@ static int uci_ulsch_interleave_ri_gen(uint32_t ri_q_bit_idx, uint32_t N_pusch_symbs, srslte_uci_bit_t* ri_bits) { - static uint32_t ri_column_set_norm[4] = {1, 4, 7, 10}; static uint32_t ri_column_set_ext[4] = {0, 3, 5, 8}; @@ -412,7 +407,7 @@ static int uci_ulsch_interleave_ri_gen(uint32_t ri_q_bit_idx, } return SRSLTE_SUCCESS; } else { - ERROR("Error interleaving UCI-RI bit idx %d for H_prime_total=%d and N_pusch_symbs=%d\n", + ERROR("Error interleaving UCI-RI bit idx %d for H_prime_total=%d and N_pusch_symbs=%d", ri_q_bit_idx, H_prime_total, N_pusch_symbs); @@ -422,9 +417,8 @@ static int uci_ulsch_interleave_ri_gen(uint32_t ri_q_bit_idx, static uint32_t Q_prime_ri_ack(srslte_pusch_cfg_t* cfg, uint32_t O, uint32_t O_cqi, float beta) { - if (beta < 0) { - ERROR("Error beta is reserved\n"); + ERROR("Error beta is reserved"); return -1; } @@ -492,7 +486,7 @@ encode_ack_long(const uint8_t* data, uint32_t O_ack, uint8_t Q_m, uint32_t Q_pri uint32_t Q_ack = Q_m * Q_prime; if (O_ack > SRSLTE_UCI_MAX_ACK_BITS) { - ERROR("Error encoding long ACK bits: O_ack can't be higher than %d\n", SRSLTE_UCI_MAX_ACK_BITS); + ERROR("Error encoding long ACK bits: O_ack can't be higher than %d", SRSLTE_UCI_MAX_ACK_BITS); return 0; } @@ -593,7 +587,7 @@ int srslte_uci_encode_ack_ri(srslte_pusch_cfg_t* cfg, srslte_uci_bit_t* bits) { if (beta < 0) { - ERROR("Error beta is reserved\n"); + ERROR("Error beta is reserved"); return -1; } uint32_t Q_prime = Q_prime_ri_ack(cfg, O_ack, O_cqi, beta); @@ -648,7 +642,7 @@ int srslte_uci_decode_ack_ri(srslte_pusch_cfg_t* cfg, bool is_ri) { if (beta < 0) { - ERROR("Error beta (%f) is reserved\n", beta); + ERROR("Error beta (%f) is reserved", beta); return SRSLTE_ERROR; } @@ -742,7 +736,6 @@ int srslte_uci_data_info(srslte_uci_cfg_t* uci_cfg, srslte_uci_value_t* uci_data if (nof_acks) { n = srslte_print_check(str, str_len, n, ", ack="); if (uci_data->ack.valid) { - for (uint32_t i = 0; i < nof_acks; i++) { n = srslte_print_check(str, str_len, n, "%d", uci_data->ack.ack_value[i]); } diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index b1bfd28a2..e76d71e5d 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -25,12 +25,11 @@ #include "srslte/phy/phch/uci_cfg.h" #include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/vector.h" +#include #define UCI_NR_INFO_TX(...) INFO("UCI-NR Tx: " __VA_ARGS__) #define UCI_NR_INFO_RX(...) INFO("UCI-NR Rx: " __VA_ARGS__) -// TS 38.212 section 5.2.1 Polar coding: The value of A is no larger than 1706. -#define UCI_NR_MAX_A 1706U #define UCI_NR_MAX_L 11U #define UCI_NR_POLAR_MAX 2048U #define UCI_NR_POLAR_RM_IBIL 0 @@ -58,63 +57,63 @@ int srslte_uci_nr_init(srslte_uci_nr_t* q, const srslte_uci_nr_args_t* args) #endif // LV_HAVE_AVX2 if (srslte_polar_code_init(&q->code)) { - ERROR("Initialising polar code\n"); + ERROR("Initialising polar code"); return SRSLTE_ERROR; } if (srslte_polar_encoder_init(&q->encoder, polar_encoder_type, NMAX_LOG) < SRSLTE_SUCCESS) { - ERROR("Initialising polar encoder\n"); + ERROR("Initialising polar encoder"); return SRSLTE_ERROR; } if (srslte_polar_decoder_init(&q->decoder, polar_decoder_type, NMAX_LOG) < SRSLTE_SUCCESS) { - ERROR("Initialising polar encoder\n"); + ERROR("Initialising polar encoder"); return SRSLTE_ERROR; } if (srslte_polar_rm_tx_init(&q->rm_tx) < SRSLTE_SUCCESS) { - ERROR("Initialising polar RM\n"); + ERROR("Initialising polar RM"); return SRSLTE_ERROR; } if (srslte_polar_rm_rx_init_c(&q->rm_rx) < SRSLTE_SUCCESS) { - ERROR("Initialising polar RM\n"); + ERROR("Initialising polar RM"); return SRSLTE_ERROR; } if (srslte_crc_init(&q->crc6, SRSLTE_LTE_CRC6, 6) < SRSLTE_SUCCESS) { - ERROR("Initialising CRC\n"); + ERROR("Initialising CRC"); return SRSLTE_ERROR; } if (srslte_crc_init(&q->crc11, SRSLTE_LTE_CRC11, 11) < SRSLTE_SUCCESS) { - ERROR("Initialising CRC\n"); + ERROR("Initialising CRC"); return SRSLTE_ERROR; } // Allocate bit sequence with space for the CRC - q->bit_sequence = srslte_vec_u8_malloc(UCI_NR_MAX_A); + q->bit_sequence = srslte_vec_u8_malloc(SRSLTE_UCI_NR_MAX_NOF_BITS); if (q->bit_sequence == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); return SRSLTE_ERROR; } // Allocate c with space for a and the CRC - q->c = srslte_vec_u8_malloc(UCI_NR_MAX_A + UCI_NR_MAX_L); + q->c = srslte_vec_u8_malloc(SRSLTE_UCI_NR_MAX_NOF_BITS + UCI_NR_MAX_L); if (q->c == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); return SRSLTE_ERROR; } q->allocated = srslte_vec_u8_malloc(UCI_NR_POLAR_MAX); if (q->allocated == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); return SRSLTE_ERROR; } q->d = srslte_vec_u8_malloc(UCI_NR_POLAR_MAX); if (q->d == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); return SRSLTE_ERROR; } @@ -204,12 +203,12 @@ static int uci_nr_A(const srslte_uci_cfg_nr_t* cfg) // 6.3.1.1.2 CSI only if (cfg->o_ack == 0 && cfg->o_sr == 0) { - ERROR("CSI only are not implemented\n"); + ERROR("CSI only are not implemented"); return SRSLTE_ERROR; } // 6.3.1.1.3 HARQ-ACK/SR and CSI - ERROR("HARQ-ACK/SR and CSI encoding are not implemented\n"); + ERROR("HARQ-ACK/SR and CSI encoding are not implemented"); return SRSLTE_ERROR; } @@ -222,12 +221,12 @@ static int uci_nr_packing(const srslte_uci_cfg_nr_t* cfg, const srslte_uci_value // 6.3.1.1.2 CSI only if (cfg->o_ack == 0 && cfg->o_sr == 0) { - ERROR("CSI only are not implemented\n"); + ERROR("CSI only are not implemented"); return SRSLTE_ERROR; } // 6.3.1.1.3 HARQ-ACK/SR and CSI - ERROR("HARQ-ACK/SR and CSI encoding are not implemented\n"); + ERROR("HARQ-ACK/SR and CSI encoding are not implemented"); return SRSLTE_ERROR; } @@ -240,12 +239,12 @@ static int uci_nr_unpacking(const srslte_uci_cfg_nr_t* cfg, const uint8_t* seque // 6.3.1.1.2 CSI only if (cfg->o_ack == 0 && cfg->o_sr == 0) { - ERROR("CSI only are not implemented\n"); + ERROR("CSI only are not implemented"); return SRSLTE_ERROR; } // 6.3.1.1.3 HARQ-ACK/SR and CSI - ERROR("HARQ-ACK/SR and CSI encoding are not implemented\n"); + ERROR("HARQ-ACK/SR and CSI encoding are not implemented"); return SRSLTE_ERROR; } @@ -300,7 +299,7 @@ static int uci_nr_encode_1bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg break; case SRSLTE_MOD_NITEMS: default: - ERROR("Invalid modulation\n"); + ERROR("Invalid modulation"); return SRSLTE_ERROR; } @@ -315,7 +314,6 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg srslte_uci_bit_type_t c2 = ((q->bit_sequence[0] ^ q->bit_sequence[1]) == 0) ? UCI_BIT_0 : UCI_BIT_1; switch (cfg->modulation) { - case SRSLTE_MOD_BPSK: case SRSLTE_MOD_QPSK: while (i < E) { @@ -393,7 +391,7 @@ static int uci_nr_encode_2bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg break; case SRSLTE_MOD_NITEMS: default: - ERROR("Invalid modulation\n"); + ERROR("Invalid modulation"); return SRSLTE_ERROR; } @@ -426,7 +424,7 @@ static int uci_nr_decode_3_11_bit(srslte_uci_nr_t* q, } if (A == 11 && E <= 16) { - ERROR("NR-UCI Impossible to decode A=%d; E=%d\n", A, E); + ERROR("NR-UCI Impossible to decode A=%d; E=%d", A, E); return SRSLTE_ERROR; } @@ -448,7 +446,7 @@ static int uci_nr_decode_3_11_bit(srslte_uci_nr_t* q, if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { UCI_NR_INFO_RX("Block decoding NR-UCI llr="); srslte_vec_fprint_bs(stdout, llr, E); - UCI_NR_INFO_RX("Block decoding NR-UCI A=%d; E=%d; pwr=%f; corr=%f; norm=%f; thr=%f; %s\n", + UCI_NR_INFO_RX("Block decoding NR-UCI A=%d; E=%d; pwr=%f; corr=%f; norm=%f; thr=%f; %s", A, E, pwr, @@ -508,7 +506,7 @@ uci_nr_encode_11_1706_bit(srslte_uci_nr_t* q, const srslte_uci_cfg_nr_t* cfg, ui // Attach CRC srslte_crc_attach(crc, q->c, A_prime / C); - UCI_NR_INFO_TX("Attaching %d/%d CRC%d=%02lx\n", r, C, L, srslte_crc_checksum_get(crc)); + UCI_NR_INFO_TX("Attaching %d/%d CRC%d=%" PRIx64, r, C, L, srslte_crc_checksum_get(crc)); if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { UCI_NR_INFO_TX("Polar cb %d/%d c=", r, C); @@ -615,7 +613,7 @@ static int uci_nr_decode_11_1706_bit(srslte_uci_nr_t* q, uint32_t checksum1 = srslte_crc_checksum(crc, q->c, A_prime / C); uint32_t checksum2 = srslte_bit_pack(&ptr, L); (*decoded_ok) = ((*decoded_ok) && (checksum1 == checksum2)); - UCI_NR_INFO_RX("Checking %d/%d CRC%d={%02x,%02x}\n", r, C, L, checksum1, checksum2); + UCI_NR_INFO_RX("Checking %d/%d CRC%d={%02x,%02x}", r, C, L, checksum1, checksum2); // Prefix (A_prime - A) zeros for the first CB only if (r == 0) { @@ -666,7 +664,7 @@ static int uci_nr_encode(srslte_uci_nr_t* q, } // Encoding of other sizes up to 1906 - if (A < UCI_NR_MAX_A) { + if (A < SRSLTE_UCI_NR_MAX_NOF_BITS) { return uci_nr_encode_11_1706_bit(q, uci_cfg, A, o, E_uci); } @@ -686,25 +684,25 @@ static int uci_nr_decode(srslte_uci_nr_t* q, // 6.3.1.1 UCI bit sequence generation int A = uci_nr_A(uci_cfg); if (A < SRSLTE_SUCCESS) { - ERROR("Error getting number of bits\n"); + ERROR("Error getting number of bits"); return SRSLTE_ERROR; } // Decode LLR if (A == 1) { - ERROR("Not implemented\n"); + ERROR("Not implemented"); } else if (A == 2) { - ERROR("Not implemented\n"); + ERROR("Not implemented"); } else if (A <= 11) { if (uci_nr_decode_3_11_bit(q, uci_cfg, A, llr, E_uci, &uci_value->valid) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } - } else if (A < UCI_NR_MAX_A) { + } else if (A < SRSLTE_UCI_NR_MAX_NOF_BITS) { if (uci_nr_decode_11_1706_bit(q, uci_cfg, A, llr, E_uci, &uci_value->valid) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } } else { - ERROR("Invalid number of bits (A=%d)\n", A); + ERROR("Invalid number of bits (A=%d)", A); } // Unpack bits @@ -731,7 +729,7 @@ int srslte_uci_nr_pucch_format_2_3_4_E(const srslte_pucch_nr_resource_t* resourc return (int)(12 * resource->nof_symbols * resource->nof_prb); case SRSLTE_PUCCH_NR_FORMAT_4: if (resource->occ_lenth != 1 && resource->occ_lenth != 2) { - ERROR("Invalid spreading factor (%d)\n", resource->occ_lenth); + ERROR("Invalid spreading factor (%d)", resource->occ_lenth); return SRSLTE_ERROR; } if (!resource->enable_pi_bpsk) { @@ -739,7 +737,7 @@ int srslte_uci_nr_pucch_format_2_3_4_E(const srslte_pucch_nr_resource_t* resourc } return (int)(12 * resource->nof_symbols / resource->occ_lenth); default: - ERROR("Invalid case\n"); + ERROR("Invalid case"); } return SRSLTE_ERROR; } @@ -749,7 +747,7 @@ static int uci_nr_pucch_E_uci(const srslte_pucch_nr_resource_t* pucch_cfg, const srslte_uci_cfg_nr_t* uci_cfg, uint32_t E_tot) { if (uci_cfg->o_csi1 != 0 && uci_cfg->o_csi2) { - ERROR("Simultaneous CSI part 1 and CSI part 2 is not implemented\n"); + ERROR("Simultaneous CSI part 1 and CSI part 2 is not implemented"); return SRSLTE_ERROR; } @@ -764,13 +762,13 @@ int srslte_uci_nr_encode_pucch(srslte_uci_nr_t* q, { int E_tot = srslte_uci_nr_pucch_format_2_3_4_E(pucch_resource_cfg); if (E_tot < SRSLTE_SUCCESS) { - ERROR("Error calculating number of bits\n"); + ERROR("Error calculating number of bits"); return SRSLTE_ERROR; } int E_uci = uci_nr_pucch_E_uci(pucch_resource_cfg, uci_cfg, E_tot); if (E_uci < SRSLTE_SUCCESS) { - ERROR("Error calculating number of bits\n"); + ERROR("Error calculating number of bits"); return SRSLTE_ERROR; } @@ -795,3 +793,45 @@ int srslte_uci_nr_decode_pucch(srslte_uci_nr_t* q, return uci_nr_decode(q, uci_cfg, llr, E_uci, value); } + +uint32_t srslte_uci_nr_total_bits(const srslte_uci_cfg_nr_t* uci_cfg) +{ + if (uci_cfg == NULL) { + return 0; + } + + return uci_cfg->o_ack + uci_cfg->o_csi1 + uci_cfg->o_csi2 + uci_cfg->o_sr; +} + +uint32_t srslte_uci_nr_info(const srslte_uci_data_nr_t* uci_data, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + len = srslte_print_check(str, str_len, len, "rnti=0x%x", uci_data->cfg.rnti); + + if (uci_data->cfg.o_ack > 0) { + char str2[10]; + srslte_vec_sprint_bin(str2, 10, uci_data->value.ack, uci_data->cfg.o_ack); + len = srslte_print_check(str, str_len, len, ", ack=%s", str2); + } + + if (uci_data->cfg.o_csi1 > 0) { + char str2[10]; + srslte_vec_sprint_bin(str2, 10, uci_data->value.csi1, uci_data->cfg.o_csi1); + len = srslte_print_check(str, str_len, len, ", csi1=%s", str2); + } + + if (uci_data->cfg.o_csi2 > 0) { + char str2[10]; + srslte_vec_sprint_bin(str2, 10, uci_data->value.csi2, uci_data->cfg.o_csi2); + len = srslte_print_check(str, str_len, len, ", csi2=%s", str2); + } + + if (uci_data->cfg.o_sr > 0) { + char str2[10]; + srslte_vec_sprint_bin(str2, 10, uci_data->value.sr, uci_data->cfg.o_sr); + len = srslte_print_check(str, str_len, len, ", sr=%s", str2); + } + + return len; +} diff --git a/lib/src/phy/resampling/interp.c b/lib/src/phy/resampling/interp.c index d0b73b836..f95f1d3fc 100644 --- a/lib/src/phy/resampling/interp.c +++ b/lib/src/phy/resampling/interp.c @@ -120,7 +120,7 @@ int srslte_interp_linear_vector_resize(srslte_interp_linsrslte_vec_t* q, uint32_ q->vector_len = vector_len; return SRSLTE_SUCCESS; } else { - ERROR("Error resizing interp_linear: vector_len must be lower or equal than initialized\n"); + ERROR("Error resizing interp_linear: vector_len must be lower or equal than initialized"); return SRSLTE_ERROR; } } @@ -242,7 +242,6 @@ void srslte_interp_linear_free(srslte_interp_lin_t* q) int srslte_interp_linear_resize(srslte_interp_lin_t* q, uint32_t vector_len, uint32_t M) { if (vector_len <= q->max_vector_len && M <= q->max_M) { - for (int i = 0; i < M; i++) { q->ramp[i] = (float)i; } @@ -251,7 +250,7 @@ int srslte_interp_linear_resize(srslte_interp_lin_t* q, uint32_t vector_len, uin q->M = M; return SRSLTE_SUCCESS; } else { - ERROR("Error resizing interp_linear: vector_len and M must be lower or equal than initialized\n"); + ERROR("Error resizing interp_linear: vector_len and M must be lower or equal than initialized"); return SRSLTE_ERROR; } } diff --git a/lib/src/phy/resampling/resampler.c b/lib/src/phy/resampling/resampler.c index 4735a0921..56ec1d02c 100644 --- a/lib/src/phy/resampling/resampler.c +++ b/lib/src/phy/resampling/resampler.c @@ -99,14 +99,14 @@ int srslte_resampler_fft_init(srslte_resampler_fft_t* q, srslte_resampler_mode_t int err = srslte_dft_plan_guru_c(&q->fft, input_fft_size, SRSLTE_DFT_FORWARD, q->in_buffer, q->out_buffer, 1, 1, 1, 1, 1); if (err != SRSLTE_SUCCESS) { - ERROR("Initialising DFT\n"); + ERROR("Initialising DFT"); return err; } err = srslte_dft_plan_guru_c( &q->ifft, output_fft_size, SRSLTE_DFT_BACKWARD, q->in_buffer, q->out_buffer, 1, 1, 1, 1, 1); if (err != SRSLTE_SUCCESS) { - ERROR("Initialising DFT\n"); + ERROR("Initialising DFT"); return err; } diff --git a/lib/src/phy/rf/rf_blade_imp.c b/lib/src/phy/rf/rf_blade_imp.c index 9536238ed..9de6c5362 100644 --- a/lib/src/phy/rf/rf_blade_imp.c +++ b/lib/src/phy/rf/rf_blade_imp.c @@ -78,12 +78,12 @@ int rf_blade_start_tx_stream(void* h) num_transfers, timeout_ms); if (status != 0) { - ERROR("Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); + ERROR("Failed to configure TX sync interface: %s", bladerf_strerror(status)); return status; } status = bladerf_enable_module(handler->dev, BLADERF_TX_X1, true); if (status != 0) { - ERROR("Failed to enable TX module: %s\n", bladerf_strerror(status)); + ERROR("Failed to enable TX module: %s", bladerf_strerror(status)); return status; } handler->tx_stream_enabled = true; @@ -107,7 +107,7 @@ int rf_blade_start_rx_stream(void* h, UNUSED bool now) num_transfers, timeout_ms); if (status != 0) { - ERROR("Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); + ERROR("Failed to configure RX sync interface: %s", bladerf_strerror(status)); return status; } status = bladerf_sync_config(handler->dev, @@ -118,17 +118,17 @@ int rf_blade_start_rx_stream(void* h, UNUSED bool now) num_transfers, timeout_ms); if (status != 0) { - ERROR("Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); + ERROR("Failed to configure TX sync interface: %s", bladerf_strerror(status)); return status; } status = bladerf_enable_module(handler->dev, BLADERF_RX_X1, true); if (status != 0) { - ERROR("Failed to enable RX module: %s\n", bladerf_strerror(status)); + ERROR("Failed to enable RX module: %s", bladerf_strerror(status)); return status; } status = bladerf_enable_module(handler->dev, BLADERF_TX_X1, true); if (status != 0) { - ERROR("Failed to enable TX module: %s\n", bladerf_strerror(status)); + ERROR("Failed to enable TX module: %s", bladerf_strerror(status)); return status; } handler->rx_stream_enabled = true; @@ -140,12 +140,12 @@ int rf_blade_stop_rx_stream(void* h) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; int status = bladerf_enable_module(handler->dev, BLADERF_RX_X1, false); if (status != 0) { - ERROR("Failed to enable RX module: %s\n", bladerf_strerror(status)); + ERROR("Failed to enable RX module: %s", bladerf_strerror(status)); return status; } status = bladerf_enable_module(handler->dev, BLADERF_TX_X1, false); if (status != 0) { - ERROR("Failed to enable TX module: %s\n", bladerf_strerror(status)); + ERROR("Failed to enable TX module: %s", bladerf_strerror(status)); return status; } handler->rx_stream_enabled = false; @@ -186,13 +186,13 @@ int rf_blade_open(char* args, void** h) printf("Opening bladeRF...\n"); int status = bladerf_open(&handler->dev, args); if (status) { - ERROR("Unable to open device: %s\n", bladerf_strerror(status)); + ERROR("Unable to open device: %s", bladerf_strerror(status)); goto clean_exit; } status = bladerf_set_gain_mode(handler->dev, BLADERF_RX_X1, BLADERF_GAIN_MGC); if (status) { - ERROR("Unable to open device: %s\n", bladerf_strerror(status)); + ERROR("Unable to open device: %s", bladerf_strerror(status)); goto clean_exit; } @@ -201,19 +201,19 @@ int rf_blade_open(char* args, void** h) /* Get Gain ranges and set Rx to maximum */ status = bladerf_get_gain_range(handler->dev, BLADERF_RX_X1, &range_rx); if ((status != 0) || (range_rx == NULL)) { - ERROR("Failed to get RX gain range: %s\n", bladerf_strerror(status)); + ERROR("Failed to get RX gain range: %s", bladerf_strerror(status)); goto clean_exit; } status = bladerf_get_gain_range(handler->dev, BLADERF_TX_X1, &range_tx); if ((status != 0) || (range_tx == NULL)) { - ERROR("Failed to get TX gain range: %s\n", bladerf_strerror(status)); + ERROR("Failed to get TX gain range: %s", bladerf_strerror(status)); goto clean_exit; } status = bladerf_set_gain(handler->dev, BLADERF_RX_X1, (bladerf_gain)range_rx->max); if (status != 0) { - ERROR("Failed to set RX LNA gain: %s\n", bladerf_strerror(status)); + ERROR("Failed to set RX LNA gain: %s", bladerf_strerror(status)); goto clean_exit; } handler->rx_stream_enabled = false; @@ -249,19 +249,19 @@ double rf_blade_set_rx_srate(void* h, double freq) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; int status = bladerf_set_sample_rate(handler->dev, BLADERF_RX_X1, (uint32_t)freq, &handler->rx_rate); if (status != 0) { - ERROR("Failed to set samplerate = %u: %s\n", (uint32_t)freq, bladerf_strerror(status)); + ERROR("Failed to set samplerate = %u: %s", (uint32_t)freq, bladerf_strerror(status)); return -1; } if (handler->rx_rate < 2000000) { status = bladerf_set_bandwidth(handler->dev, BLADERF_RX_X1, handler->rx_rate, &bw); if (status != 0) { - ERROR("Failed to set bandwidth = %u: %s\n", handler->rx_rate, bladerf_strerror(status)); + ERROR("Failed to set bandwidth = %u: %s", handler->rx_rate, bladerf_strerror(status)); return -1; } } else { status = bladerf_set_bandwidth(handler->dev, BLADERF_RX_X1, (bladerf_bandwidth)(handler->rx_rate * 0.8), &bw); if (status != 0) { - ERROR("Failed to set bandwidth = %u: %s\n", handler->rx_rate, bladerf_strerror(status)); + ERROR("Failed to set bandwidth = %u: %s", handler->rx_rate, bladerf_strerror(status)); return -1; } } @@ -275,12 +275,12 @@ double rf_blade_set_tx_srate(void* h, double freq) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; int status = bladerf_set_sample_rate(handler->dev, BLADERF_TX_X1, (uint32_t)freq, &handler->tx_rate); if (status != 0) { - ERROR("Failed to set samplerate = %u: %s\n", (uint32_t)freq, bladerf_strerror(status)); + ERROR("Failed to set samplerate = %u: %s", (uint32_t)freq, bladerf_strerror(status)); return -1; } status = bladerf_set_bandwidth(handler->dev, BLADERF_TX_X1, handler->tx_rate, &bw); if (status != 0) { - ERROR("Failed to set bandwidth = %u: %s\n", handler->tx_rate, bladerf_strerror(status)); + ERROR("Failed to set bandwidth = %u: %s", handler->tx_rate, bladerf_strerror(status)); return -1; } return (double)handler->tx_rate; @@ -292,7 +292,7 @@ int rf_blade_set_rx_gain(void* h, double gain) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; status = bladerf_set_gain(handler->dev, BLADERF_RX_X1, (bladerf_gain)gain); if (status != 0) { - ERROR("Failed to set RX gain: %s\n", bladerf_strerror(status)); + ERROR("Failed to set RX gain: %s", bladerf_strerror(status)); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -309,7 +309,7 @@ int rf_blade_set_tx_gain(void* h, double gain) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; status = bladerf_set_gain(handler->dev, BLADERF_TX_X1, (bladerf_gain)gain); if (status != 0) { - ERROR("Failed to set TX gain: %s\n", bladerf_strerror(status)); + ERROR("Failed to set TX gain: %s", bladerf_strerror(status)); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -327,7 +327,7 @@ double rf_blade_get_rx_gain(void* h) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; status = bladerf_get_gain(handler->dev, BLADERF_RX_X1, &gain); if (status != 0) { - ERROR("Failed to get RX gain: %s\n", bladerf_strerror(status)); + ERROR("Failed to get RX gain: %s", bladerf_strerror(status)); return -1; } return gain; @@ -340,7 +340,7 @@ double rf_blade_get_tx_gain(void* h) rf_blade_handler_t* handler = (rf_blade_handler_t*)h; status = bladerf_get_gain(handler->dev, BLADERF_TX_X1, &gain); if (status != 0) { - ERROR("Failed to get TX gain: %s\n", bladerf_strerror(status)); + ERROR("Failed to get TX gain: %s", bladerf_strerror(status)); return -1; } return gain; @@ -348,7 +348,6 @@ double rf_blade_get_tx_gain(void* h) srslte_rf_info_t* rf_blade_get_info(void* h) { - srslte_rf_info_t* info = NULL; if (h) { @@ -365,7 +364,7 @@ double rf_blade_set_rx_freq(void* h, UNUSED uint32_t ch, double freq) bladerf_frequency f_int = (uint32_t)round(freq); int status = bladerf_set_frequency(handler->dev, BLADERF_RX_X1, f_int); if (status != 0) { - ERROR("Failed to set samplerate = %u: %s\n", (uint32_t)freq, bladerf_strerror(status)); + ERROR("Failed to set samplerate = %u: %s", (uint32_t)freq, bladerf_strerror(status)); return -1; } f_int = 0; @@ -381,7 +380,7 @@ double rf_blade_set_tx_freq(void* h, UNUSED uint32_t ch, double freq) bladerf_frequency f_int = (uint32_t)round(freq); int status = bladerf_set_frequency(handler->dev, BLADERF_TX_X1, f_int); if (status != 0) { - ERROR("Failed to set samplerate = %u: %s\n", (uint32_t)freq, bladerf_strerror(status)); + ERROR("Failed to set samplerate = %u: %s", (uint32_t)freq, bladerf_strerror(status)); return -1; } @@ -410,7 +409,7 @@ void rf_blade_get_time(void* h, time_t* secs, double* frac_secs) int status = bladerf_get_timestamp(handler->dev, BLADERF_RX, &meta.timestamp); if (status != 0) { - ERROR("Failed to get current RX timestamp: %s\n", bladerf_strerror(status)); + ERROR("Failed to get current RX timestamp: %s", bladerf_strerror(status)); } timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs); } @@ -440,12 +439,12 @@ int rf_blade_recv_with_time(void* h, meta.flags = BLADERF_META_FLAG_RX_NOW; if (2 * nsamples > CONVERT_BUFFER_SIZE) { - ERROR("RX failed: nsamples exceeds buffer size (%d>%d)\n", nsamples, CONVERT_BUFFER_SIZE); + ERROR("RX failed: nsamples exceeds buffer size (%d>%d)", nsamples, CONVERT_BUFFER_SIZE); return -1; } status = bladerf_sync_rx(handler->dev, handler->rx_buffer, nsamples, &meta, 2000); if (status) { - ERROR("RX failed: %s; nsamples=%d;\n", bladerf_strerror(status), nsamples); + ERROR("RX failed: %s; nsamples=%d;", bladerf_strerror(status), nsamples); return -1; } else if (meta.status & BLADERF_META_STATUS_OVERRUN) { if (blade_error_handler) { @@ -455,7 +454,7 @@ int rf_blade_recv_with_time(void* h, blade_error_handler(blade_error_handler_arg, error); } else { /*ERROR("Overrun detected in scheduled RX. " - "%u valid samples were read.\n\n", meta.actual_count);*/ + "%u valid samples were read.", meta.actual_count);*/ } } @@ -498,7 +497,7 @@ int rf_blade_send_timed(void* h, } if (2 * nsamples > CONVERT_BUFFER_SIZE) { - ERROR("TX failed: nsamples exceeds buffer size (%d>%d)\n", nsamples, CONVERT_BUFFER_SIZE); + ERROR("TX failed: nsamples exceeds buffer size (%d>%d)", nsamples, CONVERT_BUFFER_SIZE); return -1; } @@ -527,17 +526,17 @@ int rf_blade_send_timed(void* h, error.type = SRSLTE_RF_ERROR_LATE; blade_error_handler(blade_error_handler_arg, error); } else { - ERROR("TX failed: %s\n", bladerf_strerror(status)); + ERROR("TX failed: %s", bladerf_strerror(status)); } } else if (status) { - ERROR("TX failed: %s\n", bladerf_strerror(status)); + ERROR("TX failed: %s", bladerf_strerror(status)); return status; } else if (meta.status == BLADERF_META_STATUS_UNDERRUN) { if (blade_error_handler) { error.type = SRSLTE_RF_ERROR_UNDERFLOW; blade_error_handler(blade_error_handler_arg, error); } else { - ERROR("TX warning: underflow detected.\n"); + ERROR("TX warning: underflow detected."); } } diff --git a/lib/src/phy/rf/rf_helper.h b/lib/src/phy/rf/rf_helper.h index c71252f47..4a16ba25a 100644 --- a/lib/src/phy/rf/rf_helper.h +++ b/lib/src/phy/rf/rf_helper.h @@ -127,4 +127,17 @@ static inline int parse_uint32(char* args, const char* config_arg_base, int chan return ret; } +static inline int parse_int32(char* args, const char* config_arg_base, int channel_index, int32_t* value) +{ + char tmp_value[RF_PARAM_LEN] = {0}; + int ret = parse_string(args, config_arg_base, channel_index, tmp_value); + + // Copy parsed value only if was found, otherwise it keeps the default + if (ret == SRSLTE_SUCCESS) { + *value = (int32_t)strtof(tmp_value, NULL); + } + + return ret; +} + #endif /* SRSLTE_RF_HELPER_H_ */ diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index 4244b8c1e..3e4a5b214 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -126,7 +126,7 @@ int srslte_rf_open_devname(srslte_rf_t* rf, const char* devname, char* args, uin } i++; } - ERROR("No compatible RF frontend found\n"); + ERROR("No compatible RF frontend found"); return -1; } @@ -309,7 +309,6 @@ int srslte_rf_send_timed3(srslte_rf_t* rf, bool is_start_of_burst, bool is_end_of_burst) { - return ((rf_dev_t*)rf->dev) ->srslte_rf_send_timed( rf->handler, data, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst); @@ -324,7 +323,6 @@ int srslte_rf_send_timed_multi(srslte_rf_t* rf, bool is_start_of_burst, bool is_end_of_burst) { - return ((rf_dev_t*)rf->dev) ->srslte_rf_send_timed_multi( rf->handler, data, nsamples, secs, frac_secs, true, blocking, is_start_of_burst, is_end_of_burst); @@ -337,7 +335,6 @@ int srslte_rf_send_multi(srslte_rf_t* rf, bool is_start_of_burst, bool is_end_of_burst) { - return ((rf_dev_t*)rf->dev) ->srslte_rf_send_timed_multi( rf->handler, data, nsamples, 0, 0, false, blocking, is_start_of_burst, is_end_of_burst); diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 341ce0e23..400a302e9 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -136,10 +136,10 @@ static void* async_thread(void* h) // this is a timeout of the readStreamStatus call, ignoring it .. } else if (ret == SOAPY_SDR_NOT_SUPPORTED) { // stopping async thread - ERROR("Receiving async metadata not supported by device. Exiting thread.\n"); + ERROR("Receiving async metadata not supported by device. Exiting thread."); handler->async_thread_running = false; } else { - ERROR("Error while receiving aync metadata: %s (%d), flags=%d, channel=%zu, timeNs=%lld\n", + ERROR("Error while receiving aync metadata: %s (%d), flags=%d, channel=%zu, timeNs=%lld", SoapySDR_errToStr(ret), ret, flags, @@ -285,7 +285,7 @@ float rf_soapy_get_rssi(void* h) int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels) { - size_t length; + size_t length; // Let Soapy pick the device if no arguments are passed SoapySDRKwargs* soapy_args = @@ -326,7 +326,7 @@ int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels) copy_subdev_string(dev_str, dev_ptr + strnlen(dev_arg, 64)); dev_id = strtol(dev_str, NULL, 0); if (dev_id < 0 || dev_id > 10) { - ERROR("Failed to set device. Using 0 as default.\n"); + ERROR("Failed to set device. Using 0 as default."); dev_id = 0; } remove_substring(args, dev_arg); @@ -469,7 +469,7 @@ int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels) for (int i = 0; i < handler->num_rx_channels; i++) { printf("Setting Rx channel %d antenna to %s\n", i, rx_ant_str); if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_RX, i, rx_ant_str) != 0) { - ERROR("Failed to set Rx antenna for channel %d.\n", i); + ERROR("Failed to set Rx antenna for channel %d.", i); } } remove_substring(args, rx_ant_arg); @@ -485,7 +485,7 @@ int rf_soapy_open_multi(char* args, void** h, uint32_t num_requested_channels) for (int i = 0; i < handler->num_rx_channels; i++) { printf("Setting Tx channel %d antenna to %s\n", i, tx_ant_str); if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_TX, i, tx_ant_str) != 0) { - ERROR("Failed to set Tx antenna for channel %d.\n", i); + ERROR("Failed to set Tx antenna for channel %d.", i); } } remove_substring(args, tx_ant_arg); @@ -983,7 +983,7 @@ int rf_soapy_send_timed_multi(void* h, printf("U"); break; default: - ERROR("Error during writeStream\n"); + ERROR("Error during writeStream"); exit(-1); return SRSLTE_ERROR; } @@ -992,7 +992,7 @@ int rf_soapy_send_timed_multi(void* h, } while (n < nsamples && trials < 100); if (n != nsamples) { - ERROR("Couldn't write all samples after %d trials.\n", trials); + ERROR("Couldn't write all samples after %d trials.", trials); } return n; diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index ea684f1a9..28c3f4c25 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -179,7 +179,7 @@ static cf_t zero_mem[64 * 1024] = {}; #define print_usrp_error(h) \ do { \ - ERROR("USRP reported the following error: %s\n", h->uhd->last_error.c_str()); \ + ERROR("USRP reported the following error: %s", h->uhd->last_error.c_str()); \ } while (false) static void log_overflow(rf_uhd_handler_t* h) @@ -230,7 +230,7 @@ static void log_underflow(rf_uhd_handler_t* h) static void log_rx_error(rf_uhd_handler_t* h) { if (h->uhd_error_handler) { - ERROR("USRP reported the following error: %s\n", h->uhd->last_error.c_str()); + ERROR("USRP reported the following error: %s", h->uhd->last_error.c_str()); srslte_rf_error_t error; bzero(&error, sizeof(srslte_rf_error_t)); @@ -274,7 +274,7 @@ static void* async_thread(void* h) handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST; } } else { - ERROR("UHD unhandled event code %d\n", event_code); + ERROR("UHD unhandled event code %d", event_code); } } else { std::this_thread::sleep_for(RF_UHD_IMP_ASYNCH_MSG_SLEEP_MS); @@ -366,7 +366,7 @@ static int set_time_to_gps_time(rf_uhd_handler_t* handler) // No sensor found if (not found) { - ERROR("Sensor '%s` not found.\n", sensor_name.c_str()); + ERROR("Sensor '%s` not found.", sensor_name.c_str()); return UHD_ERROR_NONE; } @@ -427,7 +427,7 @@ static int wait_sensor_locked(rf_uhd_handler_t* handler, // No sensor found if (not found) { - ERROR("Sensor '%s` not found.\n", sensor_name.c_str()); + ERROR("Sensor '%s` not found.", sensor_name.c_str()); return UHD_ERROR_NONE; } @@ -471,7 +471,7 @@ bool rf_uhd_rx_wait_lo_locked(void* h) int error = wait_sensor_locked(handler, sensor_name, false, 300, is_locked); if (not is_locked and error == SRSLTE_SUCCESS) { - ERROR("Could not lock reference clock source. Sensor: %s=%s\n", sensor_name.c_str(), is_locked ? "true" : "false"); + ERROR("Could not lock reference clock source. Sensor: %s=%s", sensor_name.c_str(), is_locked ? "true" : "false"); } return is_locked; @@ -577,7 +577,7 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels) } if (nof_channels > SRSLTE_MAX_CHANNELS) { - ERROR("Error opening UHD: maximum number of channels exceeded (%d>%d)\n", nof_channels, SRSLTE_MAX_CHANNELS); + ERROR("Error opening UHD: maximum number of channels exceeded (%d>%d)", nof_channels, SRSLTE_MAX_CHANNELS); return SRSLTE_ERROR; } @@ -1221,7 +1221,7 @@ int rf_uhd_recv_with_time_multi(void* h, } else if (error_code == uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND) { log_late(handler, true); } else if (error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) { - ERROR("Error timed out while receiving samples from UHD.\n"); + ERROR("Error timed out while receiving samples from UHD."); if (RF_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) { // Stop Rx stream @@ -1230,8 +1230,8 @@ int rf_uhd_recv_with_time_multi(void* h, return -1; } else if (error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { - ERROR("Error %s was returned during streaming. Aborting.\n", md.to_pp_string(true).c_str()); - INFO("Error %s was returned during streaming. Aborting.\n", md.to_pp_string(true).c_str()); + ERROR("Error %s was returned during streaming. Aborting.", md.to_pp_string(true).c_str()); + INFO("Error %s was returned during streaming. Aborting.", md.to_pp_string(true).c_str()); } } diff --git a/lib/src/phy/rf/rf_utils.c b/lib/src/phy/rf/rf_utils.c index d947a82ae..8c27979d7 100644 --- a/lib/src/phy/rf/rf_utils.c +++ b/lib/src/phy/rf/rf_utils.c @@ -81,7 +81,7 @@ free_and_exit: int srslte_rf_recv_wrapper_cs(void* h, cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ----", nsamples); void* ptr[SRSLTE_MAX_CHANNELS] = {}; for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { ptr[i] = data[i]; @@ -113,15 +113,15 @@ int rf_mib_decoder(srslte_rf_t* rf, } if (srslte_ue_mib_sync_set_cell(&ue_mib, *cell)) { - ERROR("Error initiating srslte_ue_mib_sync\n"); + ERROR("Error initiating srslte_ue_mib_sync"); goto clean_exit; } int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB); - INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float)srate / 1000000); + INFO("Setting sampling frequency %.2f MHz for PSS search", (float)srate / 1000000); srslte_rf_set_rx_srate(rf, (float)srate); - INFO("Starting receiver...\n"); + INFO("Starting receiver..."); srslte_rf_start_rx_stream(rf, false); // Copy CFO estimate if provided and disable CP estimation during find @@ -135,7 +135,7 @@ int rf_mib_decoder(srslte_rf_t* rf, /* Find and decode MIB */ ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pbch, bch_payload, &cell->nof_ports, NULL); if (ret < 0) { - ERROR("Error decoding MIB\n"); + ERROR("Error decoding MIB"); goto clean_exit; } if (ret == 1) { @@ -179,10 +179,10 @@ int rf_cell_search(srslte_rf_t* rf, srslte_ue_cellsearch_set_nof_valid_frames(&cs, config->nof_valid_pss_frames); } - INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ / 1000000); + INFO("Setting sampling frequency %.2f MHz for PSS search", SRSLTE_CS_SAMP_FREQ / 1000000); srslte_rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ); - INFO("Starting receiver...\n"); + INFO("Starting receiver..."); srslte_rf_start_rx_stream(rf, false); if (config->force_tdd) { @@ -201,10 +201,10 @@ int rf_cell_search(srslte_rf_t* rf, srslte_rf_stop_rx_stream(rf); if (ret < 0) { - ERROR("Error searching cell\n"); + ERROR("Error searching cell"); return SRSLTE_ERROR; } else if (ret == 0) { - ERROR("Could not find any cell in this frequency\n"); + ERROR("Could not find any cell in this frequency"); return SRSLTE_SUCCESS; } @@ -260,7 +260,7 @@ int rf_search_and_decode_mib(srslte_rf_t* rf, printf("Decoding PBCH for cell %d (N_id_2=%d)\n", cell->id, cell->id % 3); ret = rf_mib_decoder(rf, nof_rx_channels, config, cell, cfo); if (ret < 0) { - ERROR("Could not decode PBCH from CELL ID %d\n", cell->id); + ERROR("Could not decode PBCH from CELL ID %d", cell->id); return SRSLTE_ERROR; } } @@ -285,10 +285,10 @@ int rf_cell_search_nbiot(srslte_rf_t* rf, cell_search_cfg_t* config, srslte_nbio srslte_ue_sync_nbiot_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_wrapper, config->init_agc); } - DEBUG("Setting sampling frequency %.2f MHz for NPSS search\n", SRSLTE_CS_SAMP_FREQ / 1000000); + DEBUG("Setting sampling frequency %.2f MHz for NPSS search", SRSLTE_CS_SAMP_FREQ / 1000000); srslte_rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ); - INFO("Starting receiver...\n"); + INFO("Starting receiver..."); srslte_rf_start_rx_stream(rf, false); ret = srslte_ue_cellsearch_nbiot_scan(&cs); @@ -297,11 +297,11 @@ int rf_cell_search_nbiot(srslte_rf_t* rf, cell_search_cfg_t* config, srslte_nbio goto clean_exit; } - INFO("Stopping receiver...\n"); + INFO("Stopping receiver..."); srslte_rf_stop_rx_stream(rf); // Find a cell - INFO("Running N_id_ncell detection\n"); + INFO("Running N_id_ncell detection"); uint32_t max_peak_cell = 0; ret = srslte_ue_cellsearch_nbiot_detect(&cs, found_cells); diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index 3697f936d..80fd3a9a3 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -295,10 +295,8 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) } for (int i = 0; i < handler->nof_channels; i++) { - char rx_port[RF_PARAM_LEN] = {}; - char tx_port[RF_PARAM_LEN] = {}; - // rx_port + char rx_port[RF_PARAM_LEN] = {}; parse_string(args, "rx_port", i, rx_port); // rx_freq @@ -306,7 +304,11 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) parse_double(args, "rx_freq", i, &rx_freq); rx_opts.frequency_mhz = (uint32_t)(rx_freq / 1e6); + // rx_offset + parse_int32(args, "rx_offset", i, &rx_opts.sample_offset); + // tx_port + char tx_port[RF_PARAM_LEN] = {}; parse_string(args, "tx_port", i, tx_port); // tx_freq @@ -314,6 +316,9 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) parse_double(args, "tx_freq", i, &tx_freq); tx_opts.frequency_mhz = (uint32_t)(tx_freq / 1e6); + // tx_offset + parse_int32(args, "tx_offset", i, &tx_opts.sample_offset); + // fail_on_disconnect char tmp[RF_PARAM_LEN] = {}; parse_string(args, "fail_on_disconnect", i, tmp); @@ -321,6 +326,17 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) rx_opts.fail_on_disconnect = true; } + // trx_timeout_ms + rx_opts.trx_timeout_ms = ZMQ_TIMEOUT_MS; + parse_uint32(args, "trx_timeout_ms", i, &rx_opts.trx_timeout_ms); + + // log_trx_timeout + char tmp2[RF_PARAM_LEN] = {}; + parse_string(args, "log_trx_timeout", i, tmp); + if (strncmp(tmp2, "true", RF_PARAM_LEN) == 0 || strncmp(tmp2, "yes", RF_PARAM_LEN) == 0) { + rx_opts.log_trx_timeout = true; + } + // initialize transmitter if (strlen(tx_port) != 0) { if (rf_zmq_tx_open(&handler->transmitter[i], tx_opts, handler->context, tx_port) != SRSLTE_SUCCESS) { @@ -667,7 +683,7 @@ int rf_zmq_recv_with_time_multi(void* h, rf_zmq_info(handler->id, " - next tx time: %d + %.3f\n", ts_tx.full_secs, ts_tx.frac_secs); // Leave time for the Tx to transmit - usleep((1000000 * nsamples) / handler->base_srate); + usleep((1000000 * nsamples_baserate) / handler->base_srate); // check for tx gap if we're also transmitting on this radio for (int i = 0; i < handler->nof_channels; i++) { @@ -711,6 +727,9 @@ int rf_zmq_recv_with_time_multi(void* h, // No error count[i] += n; } else if (n == SRSLTE_ERROR_TIMEOUT) { + if (handler->receiver[i].log_trx_timeout) { + fprintf(stderr, "Error: timeout receiving samples after %dms\n", handler->receiver[i].trx_timeout_ms); + } // Other end disconnected, either keep going, or fail if (handler->receiver[i].fail_on_disconnect) { goto clean_exit; diff --git a/lib/src/phy/rf/rf_zmq_imp_rx.c b/lib/src/phy/rf/rf_zmq_imp_rx.c index 33708aa72..b7ca298b9 100644 --- a/lib/src/phy/rf/rf_zmq_imp_rx.c +++ b/lib/src/phy/rf/rf_zmq_imp_rx.c @@ -78,7 +78,10 @@ static void* rf_zmq_async_rx_thread(void* h) // Try to write in ring buffer while (n < 0 && q->running) { - n = srslte_ringbuffer_write_timed(&q->ringbuffer, q->temp_buffer, nbytes, ZMQ_TIMEOUT_MS); + n = srslte_ringbuffer_write_timed(&q->ringbuffer, q->temp_buffer, nbytes, q->trx_timeout_ms); + if (n == SRSLTE_ERROR_TIMEOUT && q->log_trx_timeout) { + fprintf(stderr, "Error: timeout writing samples to ringbuffer after %dms\n", q->trx_timeout_ms); + } } // Check write @@ -117,6 +120,9 @@ int rf_zmq_rx_open(rf_zmq_rx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock q->sample_format = opts.sample_format; q->frequency_mhz = opts.frequency_mhz; q->fail_on_disconnect = opts.fail_on_disconnect; + q->sample_offset = opts.sample_offset; + q->trx_timeout_ms = opts.trx_timeout_ms; + q->log_trx_timeout = opts.log_trx_timeout; if (opts.socket_type == ZMQ_SUB) { zmq_setsockopt(q->sock, ZMQ_SUBSCRIBE, "", 0); @@ -147,24 +153,24 @@ int rf_zmq_rx_open(rf_zmq_rx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock goto clean_exit; } -#if ZMQ_TIMEOUT_MS - int timeout = ZMQ_TIMEOUT_MS; - if (zmq_setsockopt(q->sock, ZMQ_RCVTIMEO, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting receive timeout on rx socket\n"); - goto clean_exit; - } + if (opts.trx_timeout_ms) { + int timeout = opts.trx_timeout_ms; + if (zmq_setsockopt(q->sock, ZMQ_RCVTIMEO, &timeout, sizeof(timeout)) == -1) { + fprintf(stderr, "Error: setting receive timeout on rx socket\n"); + goto clean_exit; + } - if (zmq_setsockopt(q->sock, ZMQ_SNDTIMEO, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting receive timeout on rx socket\n"); - goto clean_exit; - } + if (zmq_setsockopt(q->sock, ZMQ_SNDTIMEO, &timeout, sizeof(timeout)) == -1) { + fprintf(stderr, "Error: setting receive timeout on rx socket\n"); + goto clean_exit; + } - timeout = 0; - if (zmq_setsockopt(q->sock, ZMQ_LINGER, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting linger timeout on rx socket\n"); - goto clean_exit; + timeout = 0; + if (zmq_setsockopt(q->sock, ZMQ_LINGER, &timeout, sizeof(timeout)) == -1) { + fprintf(stderr, "Error: setting linger timeout on rx socket\n"); + goto clean_exit; + } } -#endif if (srslte_ringbuffer_init(&q->ringbuffer, ZMQ_MAX_BUFFER_SIZE)) { fprintf(stderr, "Error: initiating ringbuffer\n"); @@ -210,7 +216,29 @@ int rf_zmq_rx_baseband(rf_zmq_rx_t* q, cf_t* buffer, uint32_t nsamples) sample_sz = 2 * sizeof(short); } - int n = srslte_ringbuffer_read_timed(&q->ringbuffer, dst_buffer, sample_sz * nsamples, ZMQ_TIMEOUT_MS); + // If the read needs to be delayed + while (q->sample_offset > 0) { + uint32_t n_offset = SRSLTE_MIN(q->sample_offset, NBYTES2NSAMPLES(ZMQ_MAX_BUFFER_SIZE)); + srslte_vec_zero(q->temp_buffer, n_offset); + int n = srslte_ringbuffer_write(&q->ringbuffer, q->temp_buffer, (int)(n_offset * sample_sz)); + if (n < SRSLTE_SUCCESS) { + return n; + } + q->sample_offset -= n_offset; + } + + // If the read needs to be advanced + while (q->sample_offset < 0) { + uint32_t n_offset = SRSLTE_MIN(-q->sample_offset, NBYTES2NSAMPLES(ZMQ_MAX_BUFFER_SIZE)); + int n = + srslte_ringbuffer_read_timed(&q->ringbuffer, q->temp_buffer, (int)(n_offset * sample_sz), q->trx_timeout_ms); + if (n < SRSLTE_SUCCESS) { + return n; + } + q->sample_offset += n_offset; + } + + int n = srslte_ringbuffer_read_timed(&q->ringbuffer, dst_buffer, sample_sz * nsamples, q->trx_timeout_ms); if (n < 0) { return n; } diff --git a/lib/src/phy/rf/rf_zmq_imp_trx.h b/lib/src/phy/rf/rf_zmq_imp_trx.h index a3f44d72f..f616b74ac 100644 --- a/lib/src/phy/rf/rf_zmq_imp_trx.h +++ b/lib/src/phy/rf/rf_zmq_imp_trx.h @@ -51,6 +51,7 @@ typedef struct { cf_t* zeros; void* temp_buffer_convert; uint32_t frequency_mhz; + int32_t sample_offset; } rf_zmq_tx_t; typedef struct { @@ -71,6 +72,9 @@ typedef struct { void* temp_buffer_convert; uint32_t frequency_mhz; bool fail_on_disconnect; + uint32_t trx_timeout_ms; + bool log_trx_timeout; + int32_t sample_offset; } rf_zmq_rx_t; typedef struct { @@ -79,6 +83,9 @@ typedef struct { rf_zmq_format_t sample_format; uint32_t frequency_mhz; bool fail_on_disconnect; + uint32_t trx_timeout_ms; + bool log_trx_timeout; + int32_t sample_offset; ///< offset in samples } rf_zmq_opts_t; /* diff --git a/lib/src/phy/rf/rf_zmq_imp_tx.c b/lib/src/phy/rf/rf_zmq_imp_tx.c index b72100ec8..73e7c6342 100644 --- a/lib/src/phy/rf/rf_zmq_imp_tx.c +++ b/lib/src/phy/rf/rf_zmq_imp_tx.c @@ -48,6 +48,7 @@ int rf_zmq_tx_open(rf_zmq_tx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock q->socket_type = opts.socket_type; q->sample_format = opts.sample_format; q->frequency_mhz = opts.frequency_mhz; + q->sample_offset = opts.sample_offset; rf_zmq_info(q->id, "Binding transmitter: %s\n", sock_args); @@ -57,24 +58,24 @@ int rf_zmq_tx_open(rf_zmq_tx_t* q, rf_zmq_opts_t opts, void* zmq_ctx, char* sock goto clean_exit; } -#if ZMQ_TIMEOUT_MS - int timeout = ZMQ_TIMEOUT_MS; - if (zmq_setsockopt(q->sock, ZMQ_RCVTIMEO, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting receive timeout on tx socket\n"); - goto clean_exit; - } + if (opts.trx_timeout_ms) { + int timeout = opts.trx_timeout_ms; + if (zmq_setsockopt(q->sock, ZMQ_RCVTIMEO, &timeout, sizeof(timeout)) == -1) { + fprintf(stderr, "Error: setting receive timeout on tx socket\n"); + goto clean_exit; + } - if (zmq_setsockopt(q->sock, ZMQ_SNDTIMEO, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting receive timeout on tx socket\n"); - goto clean_exit; - } + if (zmq_setsockopt(q->sock, ZMQ_SNDTIMEO, &timeout, sizeof(timeout)) == -1) { + fprintf(stderr, "Error: setting receive timeout on tx socket\n"); + goto clean_exit; + } - timeout = 0; - if (zmq_setsockopt(q->sock, ZMQ_LINGER, &timeout, sizeof(timeout)) == -1) { - fprintf(stderr, "Error: setting linger timeout on tx socket\n"); - goto clean_exit; + timeout = 0; + if (zmq_setsockopt(q->sock, ZMQ_LINGER, &timeout, sizeof(timeout)) == -1) { + fprintf(stderr, "Error: setting linger timeout on tx socket\n"); + goto clean_exit; + } } -#endif if (pthread_mutex_init(&q->mutex, NULL)) { fprintf(stderr, "Error: creating mutex\n"); @@ -188,6 +189,19 @@ int rf_zmq_tx_baseband(rf_zmq_tx_t* q, cf_t* buffer, uint32_t nsamples) pthread_mutex_lock(&q->mutex); + if (q->sample_offset > 0) { + _rf_zmq_tx_baseband(q, q->zeros, (uint32_t)q->sample_offset); + q->sample_offset = 0; + } else if (q->sample_offset < 0) { + n = SRSLTE_MIN(-q->sample_offset, nsamples); + buffer += n; + nsamples -= n; + q->sample_offset += n; + if (nsamples == 0) { + return n; + } + } + n = _rf_zmq_tx_baseband(q, buffer, nsamples); pthread_mutex_unlock(&q->mutex); diff --git a/lib/src/phy/rf/rf_zmq_test.c b/lib/src/phy/rf/rf_zmq_test.c index 09b6a08ed..b78cfe36f 100644 --- a/lib/src/phy/rf/rf_zmq_test.c +++ b/lib/src/phy/rf/rf_zmq_test.c @@ -238,7 +238,8 @@ int main() } // two trx radios with continous tx (no timed tx) using TCP transport for both directions - if (run_test("tx_port=tcp://*:5554,rx_port=tcp://localhost:5555,id=ue,base_srate=1.92e6", + if (run_test("tx_port=tcp://*:5554,rx_port=tcp://" + "localhost:5555,id=ue,base_srate=1.92e6,log_trx_timeout=true,trx_timeout_ms=1000", "rx_port=tcp://localhost:5554,tx_port=tcp://*:5555,id=enb,base_srate=1.92e6", false) != SRSLTE_SUCCESS) { fprintf(stderr, "Two TRx radio test failed!\n"); diff --git a/lib/src/phy/scrambling/test/scrambling_test.c b/lib/src/phy/scrambling/test/scrambling_test.c index ed0e030f9..ee0342fd3 100644 --- a/lib/src/phy/scrambling/test/scrambling_test.c +++ b/lib/src/phy/scrambling/test/scrambling_test.c @@ -88,7 +88,7 @@ int init_sequence(srslte_sequence_t* seq, char* name) bzero(seq, sizeof(srslte_sequence_t)); return srslte_sequence_pdsch(seq, 1234, 0, 0, cell_id, nof_bits); } else { - ERROR("Unsupported sequence name %s\n", name); + ERROR("Unsupported sequence name %s", name); return -1; } } @@ -104,7 +104,7 @@ int main(int argc, char** argv) parse_args(argc, argv); if (init_sequence(&seq, srslte_sequence_name) == -1) { - ERROR("Error initiating sequence %s\n", srslte_sequence_name); + ERROR("Error initiating sequence %s", srslte_sequence_name); exit(-1); } diff --git a/lib/src/phy/sync/cfo.c b/lib/src/phy/sync/cfo.c index 1bd5e2f36..48d784242 100644 --- a/lib/src/phy/sync/cfo.c +++ b/lib/src/phy/sync/cfo.c @@ -86,7 +86,7 @@ int srslte_cfo_resize(srslte_cfo_t* h, uint32_t samples) srslte_cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, samples); h->nsamples = samples; } else { - ERROR("Error in cfo_resize(): nof_samples must be lower than initialized\n"); + ERROR("Error in cfo_resize(): nof_samples must be lower than initialized"); return SRSLTE_ERROR; } #endif /* SRSLTE_CFO_USE_EXP_TABLE */ @@ -99,7 +99,7 @@ void srslte_cfo_correct(srslte_cfo_t* h, const cf_t* input, cf_t* output, float if (fabs(h->last_freq - freq) > h->tol) { h->last_freq = freq; srslte_cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, h->nsamples); - DEBUG("CFO generating new table for frequency %.4fe-6\n", freq * 1e6); + DEBUG("CFO generating new table for frequency %.4fe-6", freq * 1e6); } srslte_vec_prod_ccc(h->cur_cexp, input, output, h->nsamples); #else /* SRSLTE_CFO_USE_EXP_TABLE */ @@ -122,7 +122,7 @@ void srslte_cfo_correct_offset(srslte_cfo_t* h, if (fabs(h->last_freq - freq) > h->tol) { h->last_freq = freq; srslte_cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, h->nsamples); - DEBUG("CFO generating new table for frequency %.4fe-6\n", freq * 1e6); + DEBUG("CFO generating new table for frequency %.4fe-6", freq * 1e6); } srslte_vec_prod_ccc(&h->cur_cexp[cexp_offset], input, output, nsamples); } @@ -146,4 +146,4 @@ float srslte_cfo_est_corr_cp(cf_t* input_buffer, uint32_t nof_prb) float cfo = (float)(-1 * carg(cfo_estimated) / (float)(2 * M_PI * tFFT)); srslte_vec_apply_cfo(input_buffer, (float)(1 / (nFFT * 15e3)) * ((-15e3 / 2.0) - cfo), input_buffer, sf_n_samples); return cfo; -} \ No newline at end of file +} diff --git a/lib/src/phy/sync/cp.c b/lib/src/phy/sync/cp.c index 5b195fbbb..d29da9a2c 100644 --- a/lib/src/phy/sync/cp.c +++ b/lib/src/phy/sync/cp.c @@ -49,7 +49,7 @@ void srslte_cp_synch_free(srslte_cp_synch_t* q) int srslte_cp_synch_resize(srslte_cp_synch_t* q, uint32_t symbol_sz) { if (symbol_sz > q->max_symbol_sz) { - ERROR("Error in cp_synch_resize(): symbol_sz must be lower than initialized\n"); + ERROR("Error in cp_synch_resize(): symbol_sz must be lower than initialized"); return SRSLTE_ERROR; } q->symbol_sz = symbol_sz; diff --git a/lib/src/phy/sync/npss.c b/lib/src/phy/sync/npss.c index 5ddb79cce..215a7e250 100644 --- a/lib/src/phy/sync/npss.c +++ b/lib/src/phy/sync/npss.c @@ -330,7 +330,7 @@ int srslte_npss_sync_find(srslte_npss_synch_t* q, cf_t* input, float* corr_peak_ *corr_peak_value = q->conv_output_avg[corr_peak_pos] / side_lobe_value; if (*corr_peak_value < 10) { - DEBUG("peak_pos=%2d, pl_ub=%2d, pl_lb=%2d, sl_right: %2d, sl_left: %2d, PSR: %.2f/%.2f=%.2f\n", + DEBUG("peak_pos=%2d, pl_ub=%2d, pl_lb=%2d, sl_right: %2d, sl_left: %2d, PSR: %.2f/%.2f=%.2f", corr_peak_pos, pl_ub, pl_lb, diff --git a/lib/src/phy/sync/nsss.c b/lib/src/phy/sync/nsss.c index bf770fd40..7bc83024c 100644 --- a/lib/src/phy/sync/nsss.c +++ b/lib/src/phy/sync/nsss.c @@ -47,7 +47,7 @@ int srslte_nsss_synch_init(srslte_nsss_synch_t* q, uint32_t input_size, uint32_t q->corr_peak_threshold = 2.0; uint32_t buffer_size = SRSLTE_NSSS_CORR_FILTER_LEN + q->input_size + 1; - DEBUG("NSSS buffer size is %d samples.\n", buffer_size); + DEBUG("NSSS buffer size is %d samples.", buffer_size); q->tmp_input = srslte_vec_cf_malloc(buffer_size); if (!q->tmp_input) { fprintf(stderr, "Error allocating memory\n"); @@ -144,7 +144,7 @@ int srslte_nsss_synch_resize(srslte_nsss_synch_t* q, uint32_t fft_size) int srslte_nsss_corr_init(srslte_nsss_synch_t* q) { srslte_dft_plan_t plan; - float complex nsss_signal_pad[q->fft_size]; + float complex nsss_signal_pad[q->fft_size]; // construct dft plan if (srslte_dft_plan(&plan, q->fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { @@ -170,7 +170,7 @@ int srslte_nsss_corr_init(srslte_nsss_synch_t* q) #endif // generate correlation sequences - DEBUG("Generating NSSS sequences\n"); + DEBUG("Generating NSSS sequences"); for (int i = 0; i < SRSLTE_NUM_PCI; i++) { float complex nsss_signal[SRSLTE_NSSS_TOT_LEN] = {}; srslte_nsss_generate(nsss_signal, i); @@ -243,7 +243,7 @@ int srslte_nsss_sync_find(srslte_nsss_synch_t* q, memcpy(q->tmp_input, input, q->input_size * sizeof(cf_t)); if (*cell_id == SRSLTE_CELL_ID_UNKNOWN) { - DEBUG("N_id_ncell is not set. Perform exhaustive search on input.\n"); + DEBUG("N_id_ncell is not set. Perform exhaustive search on input."); // brute-force: correlate with all possible sequences until cell is found for (int i = 0; i < SRSLTE_NUM_PCI; i++) { @@ -260,7 +260,7 @@ int srslte_nsss_sync_find(srslte_nsss_synch_t* q, peak_value = q->peak_values[max_id]; } else { - DEBUG("Current N_id_ncell is %d.\n", *cell_id); + DEBUG("Current N_id_ncell is %d.", *cell_id); // run correlation only for given id srslte_nsss_sync_find_pci(q, q->tmp_input, *cell_id); @@ -328,7 +328,7 @@ void srslte_nsss_sync_find_pci(srslte_nsss_synch_t* q, cf_t* input, uint32_t cel int sl_left = srslte_vec_max_fi(q->conv_output_abs, sl_distance_left); float side_lobe_value = SRSLTE_MAX(q->conv_output_abs[sl_right], q->conv_output_abs[sl_left]); q->peak_values[cell_id] = q->conv_output_abs[corr_peak_pos] / side_lobe_value; - DEBUG("NSSS n_id_ncell=%d at peak_pos=%2d, pl_ub=%2d, pl_lb=%2d, sl_right: %2d, sl_left: %2d, PSR: %.2f/%.2f=%.2f\n", + DEBUG("NSSS n_id_ncell=%d at peak_pos=%2d, pl_ub=%2d, pl_lb=%2d, sl_right: %2d, sl_left: %2d, PSR: %.2f/%.2f=%.2f", cell_id, corr_peak_pos, pl_ub, @@ -341,7 +341,7 @@ void srslte_nsss_sync_find_pci(srslte_nsss_synch_t* q, cf_t* input, uint32_t cel #else // save max. absolute value q->peak_values[cell_id] = q->conv_output_abs[corr_peak_pos]; - DEBUG("NSSS n_id_ncell=%d with peak=%f found at: %d\n", cell_id, q->peak_values[cell_id], corr_peak_pos); + DEBUG("NSSS n_id_ncell=%d with peak=%f found at: %d", cell_id, q->peak_values[cell_id], corr_peak_pos); #endif } @@ -360,7 +360,7 @@ void srslte_nsss_generate(cf_t* signal, uint32_t cell_id) int n_prime = n % 131; int m = n % 128; - float arg = (float)sign * 2.0 * M_PI * ((float)theta_f) * ((float)n); + float arg = (float)sign * 2.0 * M_PI * ((float)theta_f) * ((float)n); float complex tmp1; __real__ tmp1 = cosf(arg); __imag__ tmp1 = sinf(arg); @@ -374,7 +374,7 @@ void srslte_nsss_generate(cf_t* signal, uint32_t cell_id) } } } else { - DEBUG("Invalid n_id_ncell %d\n", cell_id); + DEBUG("Invalid n_id_ncell %d", cell_id); } } @@ -390,7 +390,7 @@ void srslte_nsss_put_subframe(srslte_nsss_synch_t* q, // skip first 3 OFDM symbols over all PRBs completely int k = 3 * nof_prb * SRSLTE_NRE + nbiot_prb_offset * SRSLTE_NRE; - DEBUG("%d.9: Putting NSSS with theta_f=%d\n", nf, theta_f); + DEBUG("%d.9: Putting NSSS with theta_f=%d", nf, theta_f); for (int l = 0; l < SRSLTE_CP_NORM_SF_NSYMB - 3; l++) { memcpy(&subframe[k + SRSLTE_NSSS_NSC * l], &nsss[(theta_f * SRSLTE_NSSS_LEN) + (l * SRSLTE_NSSS_NSC)], diff --git a/lib/src/phy/sync/pss.c b/lib/src/phy/sync/pss.c index 6242508dd..76952b899 100644 --- a/lib/src/phy/sync/pss.c +++ b/lib/src/phy/sync/pss.c @@ -35,7 +35,6 @@ int srslte_pss_init_N_id_2(cf_t* pss_signal_freq, cf_t* pss_signal_time, uint32_ int ret = SRSLTE_ERROR_INVALID_INPUTS; if (srslte_N_id_2_isvalid(N_id_2) && fft_size <= 2048) { - srslte_pss_generate(pss_signal_freq, N_id_2); srslte_vec_cf_zero(pss_signal_pad, fft_size); @@ -90,10 +89,8 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, int offset, int decimate) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - ret = SRSLTE_ERROR; uint32_t N_id_2; @@ -127,7 +124,7 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, } if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error creating DFT plan \n"); + ERROR("Error creating DFT plan "); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->dftp_input, true); @@ -135,7 +132,7 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, srslte_dft_plan_set_norm(&q->dftp_input, false); if (srslte_dft_plan(&q->idftp_input, fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error creating DFT plan \n"); + ERROR("Error creating DFT plan "); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->idftp_input, true); @@ -146,7 +143,7 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, q->tmp_input = srslte_vec_cf_malloc(buffer_size + frame_size * (q->decimate - 1)); if (!q->tmp_input) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); goto clean_and_exit; } @@ -154,20 +151,20 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, q->conv_output = srslte_vec_cf_malloc(buffer_size); if (!q->conv_output) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); goto clean_and_exit; } srslte_vec_cf_zero(q->conv_output, buffer_size); q->conv_output_avg = srslte_vec_f_malloc(buffer_size); if (!q->conv_output_avg) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); goto clean_and_exit; } srslte_vec_f_zero(q->conv_output_avg, buffer_size); #ifdef SRSLTE_PSS_ACCUMULATE_ABS q->conv_output_abs = srslte_vec_f_malloc(buffer_size); if (!q->conv_output_abs) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); goto clean_and_exit; } srslte_vec_f_zero(q->conv_output_abs, buffer_size); @@ -176,12 +173,12 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, for (N_id_2 = 0; N_id_2 < 3; N_id_2++) { q->pss_signal_time[N_id_2] = srslte_vec_cf_malloc(buffer_size); if (!q->pss_signal_time[N_id_2]) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); goto clean_and_exit; } /* The PSS is translated into the time domain for each N_id_2 */ if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { - ERROR("Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); + ERROR("Error initiating PSS detector for N_id_2=%d fft_size=%d", N_id_2, fft_size); goto clean_and_exit; } srslte_vec_cf_zero(&q->pss_signal_time[N_id_2][q->fft_size], q->frame_size); @@ -189,7 +186,7 @@ int srslte_pss_init_fft_offset_decim(srslte_pss_t* q, #ifdef CONVOLUTION_FFT if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { - ERROR("Error initiating convolution FFT\n"); + ERROR("Error initiating convolution FFT"); goto clean_and_exit; } for (N_id_2 = 0; N_id_2 < 3; N_id_2++) { @@ -218,14 +215,12 @@ clean_and_exit: */ int srslte_pss_resize(srslte_pss_t* q, uint32_t frame_size, uint32_t fft_size, int offset) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - ret = SRSLTE_ERROR; if (fft_size > q->max_fft_size || frame_size > q->max_frame_size) { - ERROR("Error in pss_config(): fft_size and frame_size must be lower than initialized\n"); + ERROR("Error in pss_config(): fft_size and frame_size must be lower than initialized"); return SRSLTE_ERROR; } @@ -244,12 +239,12 @@ int srslte_pss_resize(srslte_pss_t* q, uint32_t frame_size, uint32_t fft_size, i buffer_size = fft_size + frame_size + 1; if (srslte_dft_replan(&q->dftp_input, fft_size)) { - ERROR("Error creating DFT plan \n"); + ERROR("Error creating DFT plan "); return SRSLTE_ERROR; } if (srslte_dft_replan(&q->idftp_input, fft_size)) { - ERROR("Error creating DFT plan \n"); + ERROR("Error creating DFT plan "); return SRSLTE_ERROR; } @@ -266,7 +261,7 @@ int srslte_pss_resize(srslte_pss_t* q, uint32_t frame_size, uint32_t fft_size, i // Generate PSS sequences for this FFT size for (N_id_2 = 0; N_id_2 < 3; N_id_2++) { if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { - ERROR("Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); + ERROR("Error initiating PSS detector for N_id_2=%d fft_size=%d", N_id_2, fft_size); return SRSLTE_ERROR; } srslte_vec_cf_zero(&q->pss_signal_time[N_id_2][q->fft_size], q->frame_size); @@ -274,7 +269,7 @@ int srslte_pss_resize(srslte_pss_t* q, uint32_t frame_size, uint32_t fft_size, i #ifdef CONVOLUTION_FFT if (srslte_conv_fft_cc_replan(&q->conv_fft, frame_size, fft_size)) { - ERROR("Error initiating convolution FFT\n"); + ERROR("Error initiating convolution FFT"); return SRSLTE_ERROR; } for (int i = 0; i < 3; i++) { @@ -353,7 +348,7 @@ int srslte_pss_generate(cf_t* signal, uint32_t N_id_2) int sign = -1; if (N_id_2 > 2) { - ERROR("Invalid N_id_2 %d\n", N_id_2); + ERROR("Invalid N_id_2 %d", N_id_2); return -1; } @@ -395,7 +390,7 @@ void srslte_pss_get_slot(cf_t* slot, cf_t* pss_signal, uint32_t nof_prb, srslte_ int srslte_pss_set_N_id_2(srslte_pss_t* q, uint32_t N_id_2) { if (!srslte_N_id_2_isvalid((N_id_2))) { - ERROR("Invalid N_id_2 %d\n", N_id_2); + ERROR("Invalid N_id_2 %d", N_id_2); return -1; } else { q->N_id_2 = N_id_2; @@ -453,12 +448,11 @@ int srslte_pss_find_pss(srslte_pss_t* q, const cf_t* input, float* corr_peak_val int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && input != NULL) { - uint32_t corr_peak_pos; uint32_t conv_output_len; if (!srslte_N_id_2_isvalid(q->N_id_2)) { - ERROR("Error finding PSS peak, Must set N_id_2 first\n"); + ERROR("Error finding PSS peak, Must set N_id_2 first"); return SRSLTE_ERROR; } @@ -548,9 +542,8 @@ int srslte_pss_chest(srslte_pss_t* q, const cf_t* input, cf_t ce[SRSLTE_PSS_LEN] int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && input != NULL) { - if (!srslte_N_id_2_isvalid(q->N_id_2)) { - ERROR("Error finding PSS peak, Must set N_id_2 first\n"); + ERROR("Error finding PSS peak, Must set N_id_2 first"); return SRSLTE_ERROR; } @@ -572,7 +565,6 @@ int srslte_pss_chest(srslte_pss_t* q, const cf_t* input, cf_t ce[SRSLTE_PSS_LEN] void srslte_pss_sic(srslte_pss_t* q, cf_t* input) { if (q->chest_on_filter) { - srslte_vec_cf_zero(q->tmp_fft, q->fft_size); // Pass transmitted PSS sequence through the channel @@ -587,7 +579,7 @@ void srslte_pss_sic(srslte_pss_t* q, cf_t* input) srslte_vec_sub_ccc(input, q->tmp_fft2, input, q->fft_size); } else { - ERROR("Error calling srslte_pss_sic(): need to enable channel estimation on filtering\n"); + ERROR("Error calling srslte_pss_sic(): need to enable channel estimation on filtering"); } } diff --git a/lib/src/phy/sync/psss.c b/lib/src/phy/sync/psss.c index 1b5b32411..cb0cedb3f 100644 --- a/lib/src/phy/sync/psss.c +++ b/lib/src/phy/sync/psss.c @@ -37,11 +37,10 @@ int srslte_psss_init(srslte_psss_t* q, uint32_t nof_prb, srslte_cp_t cp) int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - // Generate the 2 PSSS sequences for (uint32_t i = 0; i < 2; i++) { if (srslte_psss_generate(q->psss_signal[i], i) != SRSLTE_SUCCESS) { - ERROR("Error srslte_psss_generate\n"); + ERROR("Error srslte_psss_generate"); return SRSLTE_ERROR; } } @@ -151,7 +150,7 @@ int srslte_psss_generate(cf_t* psss_signal, uint32_t N_id_2) const float root_value[] = {26.0, 37.0}; if (N_id_2 > 1) { - ERROR("Invalid N_id_2 %d\n", N_id_2); + ERROR("Invalid N_id_2 %d", N_id_2); return SRSLTE_ERROR; } @@ -225,7 +224,7 @@ int srslte_psss_find(srslte_psss_t* q, cf_t* input, uint32_t nof_prb, srslte_cp_ // Experimental Validation uint32_t symbol_sz = (uint32_t)srslte_symbol_sz(nof_prb); - int cp_len = SRSLTE_CP_SZ(symbol_sz, cp); + int cp_len = SRSLTE_CP_SZ(symbol_sz, cp); // Correlation output peaks: // diff --git a/lib/src/phy/sync/refsignal_dl_sync.c b/lib/src/phy/sync/refsignal_dl_sync.c index 2bc7a281a..bcb2c3cdc 100644 --- a/lib/src/phy/sync/refsignal_dl_sync.c +++ b/lib/src/phy/sync/refsignal_dl_sync.c @@ -352,7 +352,7 @@ int srslte_refsignal_dl_sync_find_peak(srslte_refsignal_dl_sync_t* q, cf_t* buff } } - INFO("pci=%03d; sf_len=%d; imax=%d; peak=%.3f; rms=%.3f; peak/rms=%.3f\n", + INFO("pci=%03d; sf_len=%d; imax=%d; peak=%.3f; rms=%.3f; peak/rms=%.3f", q->refsignal.cell.id, sf_len, peak_idx, @@ -475,7 +475,7 @@ void srslte_refsignal_dl_sync_run(srslte_refsignal_dl_sync_t* q, cf_t* buffer, u } INFO("-- pci=%03d; rsrp_dB=(%+.1f|%+.1f|%+.1f); rsrp_max-min=%.1f; rsrp_false_ratio=%.1f; " - "cfo=(%.1f|%.1f|%.1f); cfo_max-min=%.1f; sss_ratio=%f; false_count=%d;\n", + "cfo=(%.1f|%.1f|%.1f); cfo_max-min=%.1f; sss_ratio=%f; false_count=%d;", q->refsignal.cell.id, rsrp_dB_min, rsrp_dB, @@ -490,7 +490,6 @@ void srslte_refsignal_dl_sync_run(srslte_refsignal_dl_sync_t* q, cf_t* buffer, u false_count); if (!false_alarm) { - // Calculate in dBm q->rsrp_dBfs = rsrp_dB; @@ -564,7 +563,6 @@ void srslte_refsignal_dl_sync_measure_sf(srslte_refsignal_dl_sync_t* q, } if (cfo) { - // Distances between symbols float distance_1 = (cp_len1 + symbol_sz) * 4.0f; // Number of samples between first and second symbol float distance_2 = diff --git a/lib/src/phy/sync/sss.c b/lib/src/phy/sync/sss.c index 25f9299da..3021f99f7 100644 --- a/lib/src/phy/sync/sss.c +++ b/lib/src/phy/sync/sss.c @@ -37,7 +37,6 @@ void generate_N_id_1_table(uint32_t table[30][30]); int srslte_sss_init(srslte_sss_t* q, uint32_t fft_size) { - if (q != NULL && fft_size <= 2048) { uint32_t N_id_2; srslte_sss_tables_t sss_tables; @@ -70,7 +69,7 @@ int srslte_sss_resize(srslte_sss_t* q, uint32_t fft_size) { if (q != NULL && fft_size <= 2048) { if (fft_size > q->max_fft_size) { - ERROR("Error in sss_synch_resize(): fft_size must be lower than initialized\n"); + ERROR("Error in sss_synch_resize(): fft_size must be lower than initialized"); return SRSLTE_ERROR; } if (srslte_dft_replan(&q->dftp_input, fft_size)) { @@ -93,7 +92,7 @@ void srslte_sss_free(srslte_sss_t* q) int srslte_sss_set_N_id_2(srslte_sss_t* q, uint32_t N_id_2) { if (!srslte_N_id_2_isvalid(N_id_2)) { - ERROR("Invalid N_id_2 %d\n", N_id_2); + ERROR("Invalid N_id_2 %d", N_id_2); return SRSLTE_ERROR; } else { q->N_id_2 = N_id_2; diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index 1c29623eb..7adf3f346 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -82,12 +82,12 @@ int srslte_sync_init_decim(srslte_sync_t* q, uint32_t frame_size, uint32_t max_o srslte_sync_cfo_reset(q, 0.0f); if (srslte_cfo_init(&q->cfo_corr_frame, q->frame_size)) { - ERROR("Error initiating CFO\n"); + ERROR("Error initiating CFO"); goto clean_exit; } if (srslte_cfo_init(&q->cfo_corr_symbol, q->fft_size)) { - ERROR("Error initiating CFO\n"); + ERROR("Error initiating CFO"); goto clean_exit; } @@ -115,7 +115,7 @@ int srslte_sync_init_decim(srslte_sync_t* q, uint32_t frame_size, uint32_t max_o } if (srslte_dft_plan(&q->idftp_sss, fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error creating DFT plan \n"); + ERROR("Error creating DFT plan "); goto clean_exit; } srslte_dft_plan_set_mirror(&q->idftp_sss, true); @@ -123,24 +123,24 @@ int srslte_sync_init_decim(srslte_sync_t* q, uint32_t frame_size, uint32_t max_o srslte_dft_plan_set_norm(&q->idftp_sss, false); if (srslte_pss_init_fft_offset_decim(&q->pss, max_offset, fft_size, 0, decimate)) { - ERROR("Error initializing PSS object\n"); + ERROR("Error initializing PSS object"); goto clean_exit; } if (srslte_sss_init(&q->sss, fft_size)) { - ERROR("Error initializing SSS object\n"); + ERROR("Error initializing SSS object"); goto clean_exit; } if (srslte_cp_synch_init(&q->cp_synch, fft_size)) { - ERROR("Error initiating CFO\n"); + ERROR("Error initiating CFO"); goto clean_exit; } - DEBUG("SYNC init with frame_size=%d, max_offset=%d and fft_size=%d\n", frame_size, max_offset, fft_size); + DEBUG("SYNC init with frame_size=%d, max_offset=%d and fft_size=%d", frame_size, max_offset, fft_size); ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters frame_size: %d, fft_size: %d\n", frame_size, fft_size); + ERROR("Invalid parameters frame_size: %d, fft_size: %d", frame_size, fft_size); } clean_exit: @@ -176,12 +176,11 @@ void srslte_sync_free(srslte_sync_t* q) int srslte_sync_resize(srslte_sync_t* q, uint32_t frame_size, uint32_t max_offset, uint32_t fft_size) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && fft_size_isvalid(fft_size)) { if (frame_size > q->max_frame_size) { - ERROR("Error in sync_resize(): frame_size must be lower than initialized\n"); + ERROR("Error in sync_resize(): frame_size must be lower than initialized"); return SRSLTE_ERROR; } @@ -190,31 +189,31 @@ int srslte_sync_resize(srslte_sync_t* q, uint32_t frame_size, uint32_t max_offse q->max_offset = max_offset; if (srslte_pss_resize(&q->pss, q->max_offset, q->fft_size, 0)) { - ERROR("Error resizing PSS object\n"); + ERROR("Error resizing PSS object"); return SRSLTE_ERROR; } if (srslte_sss_resize(&q->sss, q->fft_size)) { - ERROR("Error resizing SSS object\n"); + ERROR("Error resizing SSS object"); return SRSLTE_ERROR; } if (srslte_dft_replan(&q->idftp_sss, fft_size)) { - ERROR("Error resizing DFT plan \n"); + ERROR("Error resizing DFT plan "); return SRSLTE_ERROR; } if (srslte_cp_synch_resize(&q->cp_synch, q->fft_size)) { - ERROR("Error resizing CFO\n"); + ERROR("Error resizing CFO"); return SRSLTE_ERROR; } if (srslte_cfo_resize(&q->cfo_corr_frame, q->frame_size)) { - ERROR("Error resizing CFO\n"); + ERROR("Error resizing CFO"); return SRSLTE_ERROR; } if (srslte_cfo_resize(&q->cfo_corr_symbol, q->fft_size)) { - ERROR("Error resizing CFO\n"); + ERROR("Error resizing CFO"); return SRSLTE_ERROR; } @@ -222,7 +221,7 @@ int srslte_sync_resize(srslte_sync_t* q, uint32_t frame_size, uint32_t max_offse for (int i = 0; i < 2; i++) { int offset = (i == 0) ? -1 : 1; if (srslte_pss_resize(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { - ERROR("Error initializing PSS object\n"); + ERROR("Error initializing PSS object"); } for (int t = 0; t < q->frame_size; t++) { q->cfo_i_corr[i][t] = cexpf(-2 * _Complex_I * M_PI * offset * (float)t / q->fft_size); @@ -233,11 +232,11 @@ int srslte_sync_resize(srslte_sync_t* q, uint32_t frame_size, uint32_t max_offse // Update CFO tolerance srslte_sync_set_cfo_tol(q, q->current_cfo_tol); - DEBUG("SYNC init with frame_size=%d, max_offset=%d and fft_size=%d\n", frame_size, max_offset, fft_size); + DEBUG("SYNC init with frame_size=%d, max_offset=%d and fft_size=%d", frame_size, max_offset, fft_size); ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters frame_size: %d, fft_size: %d\n", frame_size, fft_size); + ERROR("Invalid parameters frame_size: %d, fft_size: %d", frame_size, fft_size); } return ret; @@ -296,7 +295,7 @@ int srslte_sync_set_N_id_2(srslte_sync_t* q, uint32_t N_id_2) q->N_id_2 = N_id_2; return SRSLTE_SUCCESS; } else { - ERROR("Invalid N_id_2=%d\n", N_id_2); + ERROR("Invalid N_id_2=%d", N_id_2); return SRSLTE_ERROR_INVALID_INPUTS; } } @@ -322,7 +321,7 @@ static void generate_freq_sss(srslte_sync_t* q, uint32_t N_id_1) srslte_dft_run_c(&q->idftp_sss, symbol, q->sss_signal[n]); } q->sss_generated = true; - DEBUG("Generated SSS for N_id_1=%d, cell_id=%d\n", N_id_1, cell_id); + DEBUG("Generated SSS for N_id_1=%d, cell_id=%d", N_id_1, cell_id); } int srslte_sync_set_N_id_1(srslte_sync_t* q, uint32_t N_id_1) @@ -331,7 +330,7 @@ int srslte_sync_set_N_id_1(srslte_sync_t* q, uint32_t N_id_1) generate_freq_sss(q, N_id_1); return SRSLTE_SUCCESS; } else { - ERROR("Invalid N_id_2=%d\n", N_id_1); + ERROR("Invalid N_id_2=%d", N_id_1); return SRSLTE_ERROR_INVALID_INPUTS; } } @@ -370,7 +369,7 @@ void srslte_sync_set_cfo_i_enable(srslte_sync_t* q, bool enable) for (int i = 0; i < 2; i++) { int offset = (i == 0) ? -1 : 1; if (srslte_pss_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { - ERROR("Error initializing PSS object\n"); + ERROR("Error initializing PSS object"); } for (int t = 0; t < q->frame_size; t++) { q->cfo_i_corr[i][t] = cexpf(-2 * _Complex_I * M_PI * offset * (float)t / q->fft_size); @@ -464,7 +463,6 @@ srslte_cp_t srslte_sync_detect_cp(srslte_sync_t* q, const cf_t* input, uint32_t } if (nof_symbols > 0) { - const cf_t* input_cp_norm = &input[peak_pos - nof_symbols * (q->fft_size + cp_norm_len)]; const cf_t* input_cp_ext = &input[peak_pos - nof_symbols * (q->fft_size + cp_ext_len)]; @@ -535,7 +533,7 @@ static bool sync_sss_symbol(srslte_sync_t* q, const cf_t* input, uint32_t* sf_id } *N_id_1 = q->N_id_1; *corr = ratio; - DEBUG("SSS correlation with N_id_1=%d, sf0=%.2f, sf5=%.2f, sf_idx=%d, ratio=%.1f\n", + DEBUG("SSS correlation with N_id_1=%d, sf0=%.2f, sf5=%.2f, sf_idx=%d, ratio=%.1f", q->N_id_1, res[0], res[1], @@ -564,7 +562,7 @@ static bool sync_sss_symbol(srslte_sync_t* q, const cf_t* input, uint32_t* sf_id ret = srslte_sss_N_id_1(&q->sss, q->m0, q->m1, *corr); if (ret >= 0) { *N_id_1 = (uint32_t)ret; - INFO("SSS detected N_id_1=%d (corr=%7.1f), sf_idx=%d, %s CP\n", + INFO("SSS detected N_id_1=%d (corr=%7.1f), sf_idx=%d, %s CP", *N_id_1, *corr, *sf_idx, @@ -639,7 +637,6 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint } if (input != NULL && srslte_N_id_2_isvalid(q->N_id_2) && fft_size_isvalid(q->fft_size)) { - q->sss_detected = false; if (peak_position) { @@ -654,13 +651,13 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint */ if (q->cfo_i_enable) { if (cfo_i_estimate(q, input_ptr, find_offset, &peak_pos, &q->cfo_i_value) < 0) { - ERROR("Error calling finding PSS sequence at : %d \n", peak_pos); + ERROR("Error calling finding PSS sequence at : %d ", peak_pos); return SRSLTE_ERROR; } // Correct it using precomputed signal and store in buffer (don't modify input signal) if (q->cfo_i_value != 0) { srslte_vec_prod_ccc((cf_t*)input_ptr, q->cfo_i_corr[q->cfo_i_value < 0 ? 0 : 1], q->temp, q->frame_size); - INFO("Compensating cfo_i=%d\n", q->cfo_i_value); + INFO("Compensating cfo_i=%d", q->cfo_i_value); input_ptr = q->temp; } } @@ -679,7 +676,7 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint q->cfo_cp_mean = SRSLTE_VEC_EMA(cfo_cp, q->cfo_cp_mean, q->cfo_ema_alpha); } - DEBUG("CP-CFO: estimated=%f, mean=%f\n", cfo_cp, q->cfo_cp_mean); + DEBUG("CP-CFO: estimated=%f, mean=%f", cfo_cp, q->cfo_cp_mean); /* Correct CFO with the averaged CFO estimation */ srslte_cfo_correct(&q->cfo_corr_frame, input_ptr, q->temp, -q->cfo_cp_mean / q->fft_size); @@ -692,12 +689,12 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint srslte_pss_set_N_id_2(&q->pss, q->N_id_2); peak_pos = srslte_pss_find_pss(&q->pss, &input_ptr[find_offset], q->threshold > 0 ? &q->peak_value : NULL); if (peak_pos < 0) { - ERROR("Error calling finding PSS sequence at : %d \n", peak_pos); + ERROR("Error calling finding PSS sequence at : %d ", peak_pos); return SRSLTE_ERROR; } } - DEBUG("PSS: id=%d, peak_pos=%d, peak_value=%f\n", q->N_id_2, peak_pos, q->peak_value); + DEBUG("PSS: id=%d, peak_pos=%d, peak_value=%f", q->N_id_2, peak_pos, q->peak_value); // Save peak position if (peak_position) { @@ -711,9 +708,7 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint /* If peak is over threshold, compute CFO and SSS */ if (q->peak_value >= q->threshold || q->threshold == 0) { - if (q->cfo_pss_enable && peak_pos >= q->fft_size) { - // Filter central bands before PSS-based CFO estimation const cf_t* pss_ptr = &input_ptr[find_offset + peak_pos - q->fft_size]; if (q->pss_filtering_enabled) { @@ -730,7 +725,7 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint q->cfo_pss_mean = SRSLTE_VEC_EMA(q->cfo_pss, q->cfo_pss_mean, q->cfo_ema_alpha); } - DEBUG("PSS-CFO: filter=%s, estimated=%f, mean=%f\n", + DEBUG("PSS-CFO: filter=%s, estimated=%f, mean=%f", q->pss_filtering_enabled ? "yes" : "no", q->cfo_pss, q->cfo_pss_mean); @@ -738,10 +733,8 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint // If there is enough space for CP and SSS estimation if (peak_pos + find_offset >= 2 * (q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { - // If SSS search is enabled, correlate SSS sequence if (q->sss_en) { - int sss_idx; uint32_t nof_frame_type_trials; srslte_frame_type_t frame_type_trials[2]; @@ -804,7 +797,7 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint q->N_id_1 = N_id_1[1]; q->sss_corr = sss_corr[1]; } - DEBUG("SYNC: Detected SSS %s, corr=%.2f/%.2f\n", + DEBUG("SYNC: Detected SSS %s, corr=%.2f/%.2f", q->frame_type == SRSLTE_FDD ? "FDD" : "TDD", sss_corr[0], sss_corr[1]); @@ -832,7 +825,7 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint ret = SRSLTE_SYNC_NOFOUND; } - DEBUG("SYNC ret=%d N_id_2=%d find_offset=%d frame_len=%d, pos=%d peak=%.2f threshold=%.2f CFO=%.3f kHz\n", + DEBUG("SYNC ret=%d N_id_2=%d find_offset=%d frame_len=%d, pos=%d peak=%.2f threshold=%.2f CFO=%.3f kHz", ret, q->N_id_2, find_offset, @@ -843,7 +836,7 @@ srslte_sync_find(srslte_sync_t* q, const cf_t* input, uint32_t find_offset, uint 15 * (srslte_sync_get_cfo(q))); } else if (!srslte_N_id_2_isvalid(q->N_id_2)) { - ERROR("Must call srslte_sync_set_N_id_2() first!\n"); + ERROR("Must call srslte_sync_set_N_id_2() first!"); } return ret; diff --git a/lib/src/phy/sync/sync_nbiot.c b/lib/src/phy/sync/sync_nbiot.c index 68652907d..7d1c820df 100644 --- a/lib/src/phy/sync/sync_nbiot.c +++ b/lib/src/phy/sync/sync_nbiot.c @@ -170,7 +170,7 @@ int srslte_sync_nbiot_resize(srslte_sync_nbiot_t* q, uint32_t frame_size, uint32 // Update CFO tolerance srslte_sync_nbiot_set_cfo_tol(q, q->current_cfo_tol); - DEBUG("NBIOT SYNC init with frame_size=%d, max_offset=%d and fft_size=%d\n", frame_size, max_offset, fft_size); + DEBUG("NBIOT SYNC init with frame_size=%d, max_offset=%d and fft_size=%d", frame_size, max_offset, fft_size); ret = SRSLTE_SUCCESS; } else { @@ -235,13 +235,13 @@ srslte_sync_nbiot_find(srslte_sync_nbiot_t* q, cf_t* input, uint32_t find_offset // compute exponential moving average CFO q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha); - DEBUG("CFO=%.4f, mean=%.4f (%.2f Hz), ema=%.2f\n", cfo, q->mean_cfo, q->mean_cfo * 15000, q->cfo_ema_alpha); + DEBUG("CFO=%.4f, mean=%.4f (%.2f Hz), ema=%.2f", cfo, q->mean_cfo, q->mean_cfo * 15000, q->cfo_ema_alpha); } else { - DEBUG("Not enough samples for CFO estimation. Skipping.\n"); + DEBUG("Not enough samples for CFO estimation. Skipping."); } } - DEBUG("sync_nbiot ret=%d find_offset=%d frame_len=%d, pos=%d peak=%.2f threshold=%.2f, CFO=%.3f kHz\n", + DEBUG("sync_nbiot ret=%d find_offset=%d frame_len=%d, pos=%d peak=%.2f threshold=%.2f, CFO=%.3f kHz", ret, find_offset, q->frame_size, diff --git a/lib/src/phy/sync/test/cfo_test.c b/lib/src/phy/sync/test/cfo_test.c index 2f6619003..aad7dd40c 100644 --- a/lib/src/phy/sync/test/cfo_test.c +++ b/lib/src/phy/sync/test/cfo_test.c @@ -89,7 +89,7 @@ int main(int argc, char** argv) } if (srslte_cfo_init(&cfocorr, num_samples)) { - ERROR("Error initiating CFO\n"); + ERROR("Error initiating CFO"); return -1; } diff --git a/lib/src/phy/sync/test/pss_file.c b/lib/src/phy/sync/test/pss_file.c index 2c550cc5a..855d3440b 100644 --- a/lib/src/phy/sync/test/pss_file.c +++ b/lib/src/phy/sync/test/pss_file.c @@ -149,12 +149,12 @@ int main(int argc, char** argv) } if (srslte_pss_init_fft(&pss, flen, fft_size)) { - ERROR("Error initiating PSS\n"); + ERROR("Error initiating PSS"); exit(-1); } if (srslte_pss_set_N_id_2(&pss, N_id_2_sync)) { - ERROR("Error setting N_id_2=%d\n", N_id_2_sync); + ERROR("Error setting N_id_2=%d", N_id_2_sync); exit(-1); } @@ -162,7 +162,7 @@ int main(int argc, char** argv) srslte_cfo_init(&cfocorr64, flen); if (srslte_sss_init(&sss, fft_size)) { - ERROR("Error initializing SSS object\n"); + ERROR("Error initializing SSS object"); return SRSLTE_ERROR; } @@ -170,7 +170,7 @@ int main(int argc, char** argv) printf("Opening file...\n"); if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", input_file_name); + ERROR("Error opening file %s", input_file_name); exit(-1); } printf("N_id_2: %d\n", N_id_2); @@ -198,7 +198,7 @@ int main(int argc, char** argv) while (frame_cnt < nof_frames || nof_frames == -1) { n = srslte_filesource_read(&fsrc, buffer, flen - peak_offset); if (n < 0) { - ERROR("Error reading samples\n"); + ERROR("Error reading samples"); exit(-1); } if (n < flen - peak_offset) { @@ -208,7 +208,7 @@ int main(int argc, char** argv) peak_idx = srslte_pss_find_pss(&pss, buffer, &peak_value); if (peak_idx < 0) { - ERROR("Error finding PSS peak\n"); + ERROR("Error finding PSS peak"); exit(-1); } @@ -218,7 +218,6 @@ int main(int argc, char** argv) nof_det++; if (peak_idx >= fft_size) { - // Estimate CFO cfo = srslte_pss_cfo_compute(&pss, &buffer[peak_idx - fft_size]); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); @@ -228,7 +227,7 @@ int main(int argc, char** argv) // Estimate channel if (srslte_pss_chest(&pss, &buffer[peak_idx - fft_size], ce)) { - ERROR("Error computing channel estimation\n"); + ERROR("Error computing channel estimation"); exit(-1); } @@ -241,18 +240,18 @@ int main(int argc, char** argv) if (srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value) != N_id_1) { sss_error2++; } - INFO("sf_idx = %d\n", srslte_sss_subframe(m0, m1)); - INFO("Partial N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); + INFO("sf_idx = %d", srslte_sss_subframe(m0, m1)); + INFO("Partial N_id_1: %d", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); srslte_sss_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value); if (srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value) != N_id_1) { sss_error3++; } - INFO("Diff N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); + INFO("Diff N_id_1: %d", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); if (srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value) != N_id_1) { sss_error1++; } - INFO("Full N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); + INFO("Full N_id_1: %d", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); } // Estimate CP @@ -264,7 +263,7 @@ int main(int argc, char** argv) } } else { - INFO("No space for CFO computation. Frame starts at \n"); + INFO("No space for CFO computation. Frame starts at "); } if (srslte_sss_subframe(m0, m1) == 0) { diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index a3c5960f0..5519c7c0b 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -156,7 +156,7 @@ int main(int argc, char** argv) printf("Opening RF device...\n"); if (srslte_rf_open(&rf, rf_args)) { - ERROR("Error opening rf\n"); + ERROR("Error opening rf"); exit(-1); } srslte_rf_set_rx_gain(&rf, rf_gain); @@ -171,12 +171,12 @@ int main(int argc, char** argv) } if (srslte_pss_init_fft(&pss, flen, fft_size)) { - ERROR("Error initiating PSS\n"); + ERROR("Error initiating PSS"); exit(-1); } if (srslte_pss_set_N_id_2(&pss, N_id_2_sync)) { - ERROR("Error setting N_id_2=%d\n", N_id_2_sync); + ERROR("Error setting N_id_2=%d", N_id_2_sync); exit(-1); } @@ -184,7 +184,7 @@ int main(int argc, char** argv) srslte_cfo_init(&cfocorr64, flen); if (srslte_sss_init(&sss, fft_size)) { - ERROR("Error initializing SSS object\n"); + ERROR("Error initializing SSS object"); exit(-1); } @@ -222,13 +222,13 @@ int main(int argc, char** argv) while (frame_cnt < nof_frames || nof_frames == -1) { n = srslte_rf_recv(&rf, buffer, flen - peak_offset, 1); if (n < 0) { - ERROR("Error receiving samples\n"); + ERROR("Error receiving samples"); exit(-1); } peak_idx = srslte_pss_find_pss(&pss, buffer, &peak_value); if (peak_idx < 0) { - ERROR("Error finding PSS peak\n"); + ERROR("Error finding PSS peak"); exit(-1); } @@ -238,7 +238,6 @@ int main(int argc, char** argv) nof_det++; if (peak_idx >= fft_size) { - // Estimate CFO cfo = srslte_pss_cfo_compute(&pss, &buffer[peak_idx - fft_size]); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); @@ -248,7 +247,7 @@ int main(int argc, char** argv) // Estimate channel if (srslte_pss_chest(&pss, &buffer[peak_idx - fft_size], ce)) { - ERROR("Error computing channel estimation\n"); + ERROR("Error computing channel estimation"); exit(-1); } @@ -264,21 +263,20 @@ int main(int argc, char** argv) : SRSLTE_CP_LEN(fft_size, SRSLTE_CP_EXT_LEN)); } if (sss_idx >= 0 && sss_idx < flen - fft_size) { - // Filter SSS srslte_pss_filter(&pss, &buffer[sss_idx], &buffer[sss_idx]); - INFO("Full N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); + INFO("Full N_id_1: %d", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, ce, &m0, &m0_value, &m1, &m1_value); if (srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value) != N_id_1) { sss_error2++; } - INFO("Partial N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); + INFO("Partial N_id_1: %d", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); srslte_sss_m0m1_diff_coh(&sss, &buffer[sss_idx], ce, &m0, &m0_value, &m1, &m1_value); if (srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value) != N_id_1) { sss_error3++; } - INFO("Diff N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); + INFO("Diff N_id_1: %d", srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value)); } srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); if (srslte_sss_N_id_1(&sss, m0, m1, m1_value + m0_value) != N_id_1) { @@ -294,7 +292,7 @@ int main(int argc, char** argv) } } else { - INFO("No space for CFO computation. Frame starts at \n"); + INFO("No space for CFO computation. Frame starts at "); } if (srslte_sss_subframe(m0, m1) == 0) { diff --git a/lib/src/phy/sync/test/sync_sl_test.c b/lib/src/phy/sync/test/sync_sl_test.c index 3cf7407e8..ccb9fb3f0 100644 --- a/lib/src/phy/sync/test/sync_sl_test.c +++ b/lib/src/phy/sync/test/sync_sl_test.c @@ -121,7 +121,6 @@ void parse_args(int argc, char** argv) int main(int argc, char** argv) { - parse_args(argc, argv); srslte_use_standard_symbol_size(use_standard_lte_rates); @@ -142,7 +141,7 @@ int main(int argc, char** argv) srslte_ofdm_t ifft; if (srslte_ofdm_tx_init(&ifft, cp, sf_buffer, output_buffer, nof_prb)) { - ERROR("Error creating IFFT object\n"); + ERROR("Error creating IFFT object"); return SRSLTE_ERROR; } srslte_ofdm_set_normalize(&ifft, true); @@ -201,7 +200,6 @@ int main(int argc, char** argv) bool sync = false; while (sync == false) { - samples_to_read = sf_n_samples - offset_pos; if (offset < samples_to_read) { @@ -239,7 +237,6 @@ int main(int argc, char** argv) // Find sync signals if (srslte_psss_find(&psss, input_buffer, nof_prb, cp) == SRSLTE_SUCCESS) { - printf("PSSS correlation peak pos: %d value: %f N_id_2: %d\n", psss.corr_peak_pos, psss.corr_peak_value, @@ -248,7 +245,6 @@ int main(int argc, char** argv) if (psss.corr_peak_pos - sf_n_samples == 0) { // Find SSSS if (srslte_ssss_find(&ssss, input_buffer, nof_prb, psss.N_id_2, cp) == SRSLTE_SUCCESS) { - printf("SSSS correlation peak pos: %d value: %f N_sl_id: %d \n", ssss.corr_peak_pos, ssss.corr_peak_value, diff --git a/lib/src/phy/sync/test/sync_test.c b/lib/src/phy/sync/test/sync_test.c index b5f819aea..24c3e7030 100644 --- a/lib/src/phy/sync/test/sync_test.c +++ b/lib/src/phy/sync/test/sync_test.c @@ -91,7 +91,7 @@ int main(int argc, char** argv) fft_size = srslte_symbol_sz(nof_prb); if (fft_size < 0) { - ERROR("Invalid nof_prb=%d\n", nof_prb); + ERROR("Invalid nof_prb=%d", nof_prb); exit(-1); } @@ -108,12 +108,12 @@ int main(int argc, char** argv) } if (srslte_ofdm_tx_init(&ifft, cp, buffer, fft_buffer, nof_prb)) { - ERROR("Error creating iFFT object\n"); + ERROR("Error creating iFFT object"); exit(-1); } if (srslte_sync_init(&syncobj, FLEN, FLEN, fft_size)) { - ERROR("Error initiating PSS/SSS\n"); + ERROR("Error initiating PSS/SSS"); return -1; } @@ -156,7 +156,7 @@ int main(int argc, char** argv) srslte_vec_cf_zero(fft_buffer, offset); if (srslte_sync_find(&syncobj, fft_buffer, 0, &find_idx) < 0) { - ERROR("Error running srslte_sync_find\n"); + ERROR("Error running srslte_sync_find"); exit(-1); } find_sf = srslte_sync_get_sf_idx(&syncobj); diff --git a/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c b/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c index db29aa929..196ebe889 100644 --- a/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c +++ b/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c @@ -110,7 +110,7 @@ void sig_int_handler(int signo) int srslte_rf_recv_wrapper(void* h, cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ---- ", nsamples); void* ptr[SRSLTE_MAX_PORTS]; for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { ptr[i] = data[i]; diff --git a/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c b/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c index 3a670047d..190bff82e 100644 --- a/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c +++ b/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c @@ -129,7 +129,7 @@ void sig_int_handler(int signo) int srslte_rf_recv_wrapper_cs(void* h, void* data, uint32_t nsamples, srslte_timestamp_t* t) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); + DEBUG(" ---- Receive %d samples ---- ", nsamples); return srslte_rf_recv(h, data, nsamples, 1); } diff --git a/lib/src/phy/ue/ue_cell_search.c b/lib/src/phy/ue/ue_cell_search.c index 120d17ddb..46fc71ee3 100644 --- a/lib/src/phy/ue/ue_cell_search.c +++ b/lib/src/phy/ue/ue_cell_search.c @@ -51,12 +51,12 @@ int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t* q, cell.nof_prb = SRSLTE_CS_NOF_PRB; if (srslte_ue_sync_init(&q->ue_sync, cell.nof_prb, true, recv_callback, stream_handler)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); goto clean_exit; } if (srslte_ue_sync_set_cell(&q->ue_sync, cell)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); goto clean_exit; } @@ -119,7 +119,7 @@ int srslte_ue_cellsearch_init_multi( goto clean_exit; } if (srslte_ue_sync_set_cell(&q->ue_sync, cell)) { - ERROR("Error setting cell in ue_sync\n"); + ERROR("Error setting cell in ue_sync"); goto clean_exit; } @@ -266,10 +266,10 @@ int srslte_ue_cellsearch_scan(srslte_ue_cellsearch_t* q, uint32_t nof_detected_cells = 0; for (uint32_t N_id_2 = 0; N_id_2 < 3; N_id_2++) { - INFO("CELL SEARCH: Starting scan for N_id_2=%d\n", N_id_2); + INFO("CELL SEARCH: Starting scan for N_id_2=%d", N_id_2); ret = srslte_ue_cellsearch_scan_N_id_2(q, N_id_2, &found_cells[N_id_2]); if (ret < 0) { - ERROR("Error searching cell\n"); + ERROR("Error searching cell"); return ret; } nof_detected_cells += ret; @@ -309,7 +309,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t* q, do { ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer, CELL_SEARCH_BUFFER_MAX_SAMPLES); if (ret < 0) { - ERROR("Error calling srslte_ue_sync_work()\n"); + ERROR("Error calling srslte_ue_sync_work()"); return -1; } else if (ret == 1) { /* This means a peak was found in find state */ @@ -322,7 +322,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t* q, q->candidates[nof_detected_frames].psr = srslte_sync_get_peak_value(&q->ue_sync.sfind); q->candidates[nof_detected_frames].cfo = 15000 * srslte_sync_get_cfo(&q->ue_sync.sfind); q->candidates[nof_detected_frames].frame_type = srslte_ue_sync_get_frame_type(&q->ue_sync); - INFO("CELL SEARCH: [%d/%d/%d]: Found peak PSR=%.3f, Cell_id: %d CP: %s, CFO=%.1f KHz\n", + INFO("CELL SEARCH: [%d/%d/%d]: Found peak PSR=%.3f, Cell_id: %d CP: %s, CFO=%.1f KHz", nof_detected_frames, nof_scanned_frames, q->nof_valid_frames, diff --git a/lib/src/phy/ue/ue_cell_search_nbiot.c b/lib/src/phy/ue/ue_cell_search_nbiot.c index 063406d29..a6cbb026b 100644 --- a/lib/src/phy/ue/ue_cell_search_nbiot.c +++ b/lib/src/phy/ue/ue_cell_search_nbiot.c @@ -32,7 +32,7 @@ int srslte_ue_cellsearch_nbiot_init(srslte_ue_cellsearch_nbiot_t* q, uint32_t max_frames_total, - int(recv_callback)(void*, cf_t * [SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + int(recv_callback)(void*, cf_t* [SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), void* stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -123,13 +123,13 @@ int srslte_ue_cellsearch_nbiot_scan(srslte_ue_cellsearch_nbiot_t* q) break; } else if (ret == 1) { // we are in sync, wait until we have received two full frames, store subframe 9 for both - DEBUG("In tracking state sf_idx=%d\n", srslte_ue_sync_nbiot_get_sfidx(&q->ue_sync)); + DEBUG("In tracking state sf_idx=%d", srslte_ue_sync_nbiot_get_sfidx(&q->ue_sync)); if (srslte_ue_sync_nbiot_get_sfidx(&q->ue_sync) == 9) { // accumulate NSSS subframes for cell id detection srslte_vec_cf_copy(&q->nsss_buffer[q->nsss_sf_counter * q->sf_len], q->rx_buffer[0], q->sf_len); q->nsss_sf_counter++; if (q->nsss_sf_counter == SRSLTE_NSSS_NUM_SF_DETECT) { - DEBUG("Captured %d subframes for NSSS detection.\n", q->nsss_sf_counter); + DEBUG("Captured %d subframes for NSSS detection.", q->nsss_sf_counter); return SRSLTE_SUCCESS; } } @@ -154,7 +154,7 @@ int srslte_ue_cellsearch_nbiot_detect(srslte_ue_cellsearch_nbiot_t* q, srslte_nb found_cells[0].peak = q->ue_sync.strack.npss.peak_value; found_cells[0].psr = srslte_sync_nbiot_get_peak_value(&q->ue_sync.strack); found_cells[0].cfo = srslte_ue_sync_nbiot_get_cfo(&q->ue_sync); - INFO("CELL SEARCH: Found peak PSR=%.3f, Cell_id: %d\n", found_cells[0].psr, found_cells[0].n_id_ncell); + INFO("CELL SEARCH: Found peak PSR=%.3f, Cell_id: %d", found_cells[0].psr, found_cells[0].n_id_ncell); } } return ret; diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index c1b2fbdc8..438987870 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -97,7 +97,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t* q, cf_t* in_buffer[SRSLTE_MAX_PORTS], uint ofdm_cfg.sf_type = SRSLTE_SF_NORM; if (srslte_ofdm_rx_init_cfg(&q->fft[i], &ofdm_cfg)) { - ERROR("Error initiating FFT\n"); + ERROR("Error initiating FFT"); goto clean_exit; } } @@ -106,46 +106,46 @@ int srslte_ue_dl_init(srslte_ue_dl_t* q, cf_t* in_buffer[SRSLTE_MAX_PORTS], uint ofdm_cfg.out_buffer = q->sf_symbols[0]; ofdm_cfg.sf_type = SRSLTE_SF_MBSFN; if (srslte_ofdm_rx_init_cfg(&q->fft_mbsfn, &ofdm_cfg)) { - ERROR("Error initiating FFT for MBSFN subframes \n"); + ERROR("Error initiating FFT for MBSFN subframes "); goto clean_exit; } srslte_ofdm_set_non_mbsfn_region(&q->fft_mbsfn, 2); // Set a default to init if (srslte_chest_dl_init(&q->chest, max_prb, nof_rx_antennas)) { - ERROR("Error initiating channel estimator\n"); + ERROR("Error initiating channel estimator"); goto clean_exit; } if (srslte_chest_dl_res_init(&q->chest_res, max_prb)) { - ERROR("Error initiating channel estimator\n"); + ERROR("Error initiating channel estimator"); goto clean_exit; } if (srslte_pcfich_init(&q->pcfich, nof_rx_antennas)) { - ERROR("Error creating PCFICH object\n"); + ERROR("Error creating PCFICH object"); goto clean_exit; } if (srslte_phich_init(&q->phich, nof_rx_antennas)) { - ERROR("Error creating PHICH object\n"); + ERROR("Error creating PHICH object"); goto clean_exit; } if (srslte_pdcch_init_ue(&q->pdcch, max_prb, nof_rx_antennas)) { - ERROR("Error creating PDCCH object\n"); + ERROR("Error creating PDCCH object"); goto clean_exit; } if (srslte_pdsch_init_ue(&q->pdsch, max_prb, nof_rx_antennas)) { - ERROR("Error creating PDSCH object\n"); + ERROR("Error creating PDSCH object"); goto clean_exit; } if (srslte_pmch_init(&q->pmch, max_prb, nof_rx_antennas)) { - ERROR("Error creating PMCH object\n"); + ERROR("Error creating PMCH object"); goto clean_exit; } ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters\n"); + ERROR("Invalid parameters"); } clean_exit: @@ -197,13 +197,13 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t* q, srslte_cell_t cell) q->cell = cell; for (int i = 0; i < SRSLTE_MI_NOF_REGS; i++) { if (srslte_regs_init_opts(&q->regs[i], q->cell, mi_reg_idx[i % 3], i > 2)) { - ERROR("Error resizing REGs\n"); + ERROR("Error resizing REGs"); return SRSLTE_ERROR; } } for (int port = 0; port < q->nof_rx_antennas; port++) { if (srslte_ofdm_rx_set_prb(&q->fft[port], q->cell.cp, q->cell.nof_prb)) { - ERROR("Error resizing FFT\n"); + ERROR("Error resizing FFT"); return SRSLTE_ERROR; } } @@ -217,35 +217,35 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t* q, srslte_cell_t cell) } if (srslte_ofdm_rx_set_prb(&q->fft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) { - ERROR("Error resizing MBSFN FFT\n"); + ERROR("Error resizing MBSFN FFT"); return SRSLTE_ERROR; } if (srslte_chest_dl_set_cell(&q->chest, q->cell)) { - ERROR("Error resizing channel estimator\n"); + ERROR("Error resizing channel estimator"); return SRSLTE_ERROR; } if (srslte_pcfich_set_cell(&q->pcfich, &q->regs[0], q->cell)) { - ERROR("Error resizing PCFICH object\n"); + ERROR("Error resizing PCFICH object"); return SRSLTE_ERROR; } if (srslte_phich_set_cell(&q->phich, &q->regs[phich_init_reg], q->cell)) { - ERROR("Error resizing PHICH object\n"); + ERROR("Error resizing PHICH object"); return SRSLTE_ERROR; } if (srslte_pdcch_set_cell(&q->pdcch, &q->regs[pdcch_init_reg], q->cell)) { - ERROR("Error resizing PDCCH object\n"); + ERROR("Error resizing PDCCH object"); return SRSLTE_ERROR; } if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) { - ERROR("Error resizing PDSCH object\n"); + ERROR("Error resizing PDSCH object"); return SRSLTE_ERROR; } if (srslte_pmch_set_cell(&q->pmch, q->cell)) { - ERROR("Error resizing PMCH object\n"); + ERROR("Error resizing PMCH object"); return SRSLTE_ERROR; } } @@ -254,7 +254,7 @@ int srslte_ue_dl_set_cell(srslte_ue_dl_t* q, srslte_cell_t cell) } ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid cell properties ue_dl: Id=%d, Ports=%d, PRBs=%d\n", cell.id, cell.nof_ports, cell.nof_prb); + ERROR("Invalid cell properties ue_dl: Id=%d, Ports=%d, PRBs=%d", cell.id, cell.nof_ports, cell.nof_prb); } return ret; } @@ -281,7 +281,6 @@ void srslte_ue_dl_set_mi_manual(srslte_ue_dl_t* q, uint32_t mi_idx) */ void srslte_ue_dl_set_rnti(srslte_ue_dl_t* q, uint16_t rnti) { - srslte_pdsch_set_rnti(&q->pdsch, rnti); srslte_dl_sf_cfg_t sf_cfg; @@ -293,7 +292,7 @@ void srslte_ue_dl_set_rnti(srslte_ue_dl_t* q, uint16_t rnti) for (int cfi = 1; cfi <= SRSLTE_NOF_CFI; cfi++) { sf_cfg.cfi = cfi; for (int sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) { - sf_cfg.tti = sf_idx; + sf_cfg.tti = sf_idx; q->current_ss_ue[i][SRSLTE_CFI_IDX(cfi)][sf_idx].nof_locations = srslte_pdcch_ue_locations( &q->pdcch, &sf_cfg, q->current_ss_ue[i][SRSLTE_CFI_IDX(cfi)][sf_idx].loc, SRSLTE_MAX_CANDIDATES_UE, rnti); } @@ -313,11 +312,11 @@ int srslte_ue_dl_set_mbsfn_area_id(srslte_ue_dl_t* q, uint16_t mbsfn_area_id) if (q != NULL) { ret = SRSLTE_ERROR; if (srslte_chest_dl_set_mbsfn_area_id(&q->chest, mbsfn_area_id)) { - ERROR("Error setting MBSFN area ID \n"); + ERROR("Error setting MBSFN area ID "); return ret; } if (srslte_pmch_set_area_id(&q->pmch, mbsfn_area_id)) { - ERROR("Error setting MBSFN area ID \n"); + ERROR("Error setting MBSFN area ID "); return ret; } q->current_mbsfn_area_id = mbsfn_area_id; @@ -331,12 +330,12 @@ static void set_mi_value(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srslte_ue_dl uint32_t sf_idx = sf->tti % 10; // Set mi value in pdcch region if (q->mi_auto) { - INFO("Setting PHICH mi value auto. sf_idx=%d, mi=%d, idx=%d\n", sf_idx, MI_VALUE(sf_idx), MI_IDX(sf_idx)); + INFO("Setting PHICH mi value auto. sf_idx=%d, mi=%d, idx=%d", sf_idx, MI_VALUE(sf_idx), MI_IDX(sf_idx)); srslte_phich_set_regs(&q->phich, &q->regs[MI_IDX(sf_idx)]); srslte_pdcch_set_regs(&q->pdcch, &q->regs[MI_IDX(sf_idx)]); } else { // No subframe 1 or 6 so no need to consider it - INFO("Setting PHICH mi value manual. sf_idx=%d, mi=%d, idx=%d\n", + INFO("Setting PHICH mi value manual. sf_idx=%d, mi=%d, idx=%d", sf_idx, q->mi_manual_index, mi_reg_idx_inv[q->mi_manual_index]); @@ -348,7 +347,6 @@ static void set_mi_value(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srslte_ue_dl static int estimate_pdcch_pcfich(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srslte_ue_dl_cfg_t* cfg) { if (q) { - float cfi_corr = 0; set_mi_value(q, sf, cfg); @@ -358,21 +356,21 @@ static int estimate_pdcch_pcfich(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srsl /* First decode PCFICH and obtain CFI */ if (srslte_pcfich_decode(&q->pcfich, sf, &q->chest_res, q->sf_symbols, &cfi_corr) < 0) { - ERROR("Error decoding PCFICH\n"); + ERROR("Error decoding PCFICH"); return SRSLTE_ERROR; } if (q->cell.frame_type == SRSLTE_TDD && ((sf->tti % 10) == 1 || (sf->tti % 10) == 6) && sf->cfi == 3) { sf->cfi = 2; - INFO("Received CFI=3 in subframe 1 or 6 and TDD. Setting to 2\n"); + INFO("Received CFI=3 in subframe 1 or 6 and TDD. Setting to 2"); } if (srslte_pdcch_extract_llr(&q->pdcch, sf, &q->chest_res, q->sf_symbols)) { - ERROR("Extracting PDCCH LLR\n"); + ERROR("Extracting PDCCH LLR"); return false; } - INFO("Decoded CFI=%d with correlation %.2f, sf_idx=%d\n", sf->cfi, cfi_corr, sf->tti % 10); + INFO("Decoded CFI=%d with correlation %.2f, sf_idx=%d", sf->cfi, cfi_corr, sf->tti % 10); return SRSLTE_SUCCESS; } else { @@ -459,15 +457,15 @@ static int dci_blind_search(srslte_ue_dl_t* q, if (rnti) { for (int l = 0; l < search_space->nof_locations; l++) { if (nof_dci >= SRSLTE_MAX_DCI_MSG) { - ERROR("Can't store more DCIs in buffer\n"); + ERROR("Can't store more DCIs in buffer"); return nof_dci; } if (dci_location_is_allocated(q, search_space->loc[l])) { - INFO("Skipping location L=%d, ncce=%d. Already allocated\n", search_space->loc[l].L, search_space->loc[l].ncce); + INFO("Skipping location L=%d, ncce=%d. Already allocated", search_space->loc[l].L, search_space->loc[l].ncce); continue; } for (uint32_t f = 0; f < search_space->nof_formats; f++) { - INFO("Searching format %s in %d,%d (%d/%d)\n", + INFO("Searching format %s in %d,%d (%d/%d)", srslte_dci_format_string(search_space->formats[f]), search_space->loc[l].ncce, search_space->loc[l].L, @@ -479,7 +477,7 @@ static int dci_blind_search(srslte_ue_dl_t* q, dci_msg[nof_dci].format = search_space->formats[f]; dci_msg[nof_dci].rnti = 0; if (srslte_pdcch_decode_msg(&q->pdcch, sf, dci_cfg, &dci_msg[nof_dci])) { - ERROR("Error decoding DCI msg\n"); + ERROR("Error decoding DCI msg"); return SRSLTE_ERROR; } @@ -509,7 +507,7 @@ static int dci_blind_search(srslte_ue_dl_t* q, dci_msg[nof_dci].format = dci_msg[nof_dci].payload[0] ? SRSLTE_DCI_FORMAT1A : SRSLTE_DCI_FORMAT0; // Format0/1A bit indicator is the MSB - INFO("DCI msg found in location L=%d, ncce=%d, size=%d belongs to the common SS and is format %s\n", + INFO("DCI msg found in location L=%d, ncce=%d, size=%d belongs to the common SS and is format %s", dci_msg[nof_dci].location.L, dci_msg[nof_dci].location.ncce, dci_msg[nof_dci].nof_bits, @@ -538,13 +536,13 @@ static int dci_blind_search(srslte_ue_dl_t* q, nof_dci++; break; } else { - INFO("Ignoring message with size %d, already decoded\n", dci_msg[nof_dci].nof_bits); + INFO("Ignoring message with size %d, already decoded", dci_msg[nof_dci].nof_bits); } } } } } else { - ERROR("RNTI not specified\n"); + ERROR("RNTI not specified"); } return nof_dci; } @@ -566,7 +564,7 @@ static int find_dci_ss(srslte_ue_dl_t* q, srslte_dci_cfg_t dci_cfg = cfg->cfg.dci; if (!SRSLTE_CFI_ISVALID(cfi)) { - ERROR("Invalid CFI=%d\n", cfi); + ERROR("Invalid CFI=%d", cfi); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -596,7 +594,7 @@ static int find_dci_ss(srslte_ue_dl_t* q, current_ss->nof_formats = nof_formats; memcpy(current_ss->formats, formats, nof_formats * sizeof(srslte_dci_format_t)); - INFO("Searching %d formats in %d locations in %s SS, csi=%d\n", + INFO("Searching %d formats in %d locations in %s SS, csi=%d", nof_formats, current_ss->nof_locations, is_ue ? "ue" : "common", @@ -628,7 +626,7 @@ int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t* q, // Unpack DCI messages for (uint32_t i = 0; i < nof_msg; i++) { if (srslte_dci_msg_unpack_pusch(&q->cell, sf, &dl_cfg->cfg.dci, &dci_msg[i], &dci_ul[i])) { - ERROR("Unpacking UL DCI\n"); + ERROR("Unpacking UL DCI"); return SRSLTE_ERROR; } } @@ -660,7 +658,7 @@ static int find_dl_ul_dci_type_crnti(srslte_ue_dl_t* q, int ret = SRSLTE_SUCCESS; if (dl_cfg->cfg.tm > SRSLTE_TM8) { - ERROR("Searching DL CRNTI: Invalid TM=%d\n", dl_cfg->cfg.tm + 1); + ERROR("Searching DL CRNTI: Invalid TM=%d", dl_cfg->cfg.tm + 1); return SRSLTE_ERROR; } @@ -679,7 +677,6 @@ static int find_dl_ul_dci_type_crnti(srslte_ue_dl_t* q, // Search common SS if (dl_cfg->cfg.dci_common_ss) { - // Search only for SRSLTE_DCI_FORMAT1A (1st in common_formats) when looking for C-RNTI ret = 0; if ((ret = find_dci_ss(q, sf, dl_cfg, rnti, &dci_msg[nof_dci_msg], common_formats, 1, false)) < 0) { @@ -715,14 +712,14 @@ int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t* q, } if (nof_msg < 0) { - ERROR("Invalid number of DCI messages\n"); + ERROR("Invalid number of DCI messages"); return SRSLTE_ERROR; } // Unpack DCI messages for (uint32_t i = 0; i < nof_msg; i++) { if (srslte_dci_msg_unpack_pdsch(&q->cell, sf, &dl_cfg->cfg.dci, &dci_msg[i], &dci_dl[i])) { - ERROR("Unpacking DL DCI\n"); + ERROR("Unpacking DL DCI"); return SRSLTE_ERROR; } } @@ -767,7 +764,7 @@ int srslte_ue_dl_decode_phich(srslte_ue_dl_t* q, set_mi_value(q, sf, cfg); srslte_phich_calc(&q->phich, grant, &n_phich); - INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, I_phich=%d, n_group=%d, n_seq=%d, Ngroups=%d, Nsf=%d\n", + INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, I_phich=%d, n_group=%d, n_seq=%d, Ngroups=%d, Nsf=%d", sf_idx, grant->n_prb_lowest, grant->n_dmrs, @@ -778,10 +775,10 @@ int srslte_ue_dl_decode_phich(srslte_ue_dl_t* q, srslte_phich_nsf(&q->phich)); if (!srslte_phich_decode(&q->phich, sf, &q->chest_res, n_phich, q->sf_symbols, result)) { - INFO("Decoded PHICH %d with distance %f\n", result->ack_value, result->distance); + INFO("Decoded PHICH %d with distance %f", result->ack_value, result->distance); return 0; } else { - ERROR("Error decoding PHICH\n"); + ERROR("Error decoding PHICH"); return -1; } } @@ -903,7 +900,6 @@ void srslte_ue_dl_gen_cqi_periodic(srslte_ue_dl_t* q, uci_data->cfg.cqi.ri_len = 1; uci_data->value.ri = cfg->last_ri; } else if (srslte_cqi_periodic_send(&cfg->cfg.cqi_report, tti, q->cell.frame_type)) { - if (cfg->cfg.cqi_report.format_is_subband) { // TODO: Implement subband periodic reports uci_data->cfg.cqi.type = SRSLTE_CQI_TYPE_SUBBAND; @@ -1009,7 +1005,7 @@ void srslte_ue_dl_gen_cqi_aperiodic(srslte_ue_dl_t* q, break; default: - ERROR("CQI mode %d not supported\n", cfg->cfg.cqi_report.aperiodic_mode); + ERROR("CQI mode %d not supported", cfg->cfg.cqi_report.aperiodic_mode); break; } } @@ -1049,7 +1045,6 @@ ue_dl_gen_ack_fdd_pcell_skip_drx(const srslte_pdsch_ack_t* ack_info, srslte_uci_ static void ue_dl_gen_ack_fdd_all_keep_drx(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* uci_data, uint32_t nof_tb) { - for (uint32_t cc_idx = 0; cc_idx < ack_info->nof_cc; cc_idx++) { // Find ACK/NACK if (ack_info->cc[cc_idx].m[0].present) { @@ -1163,7 +1158,6 @@ static void gen_ack_fdd(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* u // For each HARQ ACK/NACK feedback mode switch (ack_info->ack_nack_feedback_mode) { - case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_NORMAL: // Get ACK from PCell only, skipping DRX ue_dl_gen_ack_fdd_pcell_skip_drx(ack_info, uci_data, nof_tb); @@ -1251,7 +1245,6 @@ static void gen_ack_tdd(bool is_tdd_mode16, const srslte_pdsch_ack_t* ack_info, uint32_t min_k = 10; if (ack_value->M > 0) { - ack_cfg->tdd_ack_M = ack_value->M; // ACK/NACK bundling or multiplexing and M=1 @@ -1331,7 +1324,6 @@ static void gen_ack_tdd(bool is_tdd_mode16, const srslte_pdsch_ack_t* ack_info, // For TDD PUSCH if (is_tdd_mode16) { - uint32_t V_dai_ul = ack_info->V_dai_ul + 1; // Table 7.3-x ack_cfg->tdd_is_multiplex = ack_info->tdd_ack_multiplex; @@ -1476,7 +1468,6 @@ int srslte_ue_dl_find_and_decode(srslte_ue_dl_t* q, // Blind search PHICH mi value ret = 0; for (uint32_t i = 0; i < mi_set_len && !ret; i++) { - if (mi_set_len == 1) { srslte_ue_dl_set_mi_auto(q); } else { @@ -1495,7 +1486,7 @@ int srslte_ue_dl_find_and_decode(srslte_ue_dl_t* q, if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO) { char str[512]; srslte_dci_dl_info(&dci_dl[0], str, 512); - INFO("PDCCH: %s, snr=%.1f dB\n", str, q->chest_res.snr_db); + INFO("PDCCH: %s, snr=%.1f dB", str, q->chest_res.snr_db); } // Force known MBSFN grant @@ -1510,7 +1501,7 @@ int srslte_ue_dl_find_and_decode(srslte_ue_dl_t* q, // Convert DCI message to DL grant if (srslte_ue_dl_dci_to_pdsch_grant(q, sf, cfg, &dci_dl[0], &pdsch_cfg->grant)) { - ERROR("Error unpacking DCI\n"); + ERROR("Error unpacking DCI"); return SRSLTE_ERROR; } @@ -1538,13 +1529,13 @@ int srslte_ue_dl_find_and_decode(srslte_ue_dl_t* q, if (decode_enable) { if (sf->sf_type == SRSLTE_SF_NORM) { if (srslte_ue_dl_decode_pdsch(q, sf, pdsch_cfg, pdsch_res)) { - ERROR("ERROR: Decoding PDSCH\n"); + ERROR("ERROR: Decoding PDSCH"); ret = -1; } } else { pmch_cfg.pdsch_cfg = *pdsch_cfg; if (srslte_ue_dl_decode_pmch(q, sf, &pmch_cfg, pdsch_res)) { - ERROR("Decoding PMCH\n"); + ERROR("Decoding PMCH"); ret = -1; } } diff --git a/lib/src/phy/ue/ue_dl_nbiot.c b/lib/src/phy/ue/ue_dl_nbiot.c index 9bc9de2f8..69d773018 100644 --- a/lib/src/phy/ue/ue_dl_nbiot.c +++ b/lib/src/phy/ue/ue_dl_nbiot.c @@ -181,13 +181,11 @@ int srslte_nbiot_ue_dl_set_cell(srslte_nbiot_ue_dl_t* q, srslte_nbiot_cell_t cel int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_nbiot_cell_isvalid(&cell)) { - q->pkt_errors = 0; q->pkts_total = 0; q->sample_offset = 0; if (q->cell.n_id_ncell != cell.n_id_ncell || q->cell.base.nof_prb == 0) { - q->cell = cell; if (srslte_chest_dl_nbiot_set_cell(&q->chest, q->cell)) { @@ -258,7 +256,6 @@ void srslte_nbiot_ue_dl_set_si_params(srslte_nbiot_ue_dl_t* q, srslte_nbiot_si_params_t params) { if (type < SRSLTE_NBIOT_SI_TYPE_NITEMS) { - if (params.n != 0) { // calculate TTIs for this SI int x = (params.n - 1) * params.si_window_length; @@ -270,7 +267,7 @@ void srslte_nbiot_ue_dl_set_si_params(srslte_nbiot_ue_dl_t* q, // SI is always transmitted in subframe 1 int si_start_tti = 10 * sfn + 1; - INFO("Start SI tx in TTI=%d\n", si_start_tti); + INFO("Start SI tx in TTI=%d", si_start_tti); do { // TBS 56 and 120 are sent over 2 sub-frames, all other over 8 @@ -347,13 +344,8 @@ void srslte_nbiot_ue_dl_get_sib1_grant(srslte_nbiot_ue_dl_t* q, uint32_t sfn, sr bzero(&ra_dl_sib1, sizeof(srslte_ra_nbiot_dl_dci_t)); ra_dl_sib1.alloc.has_sib1 = true; ra_dl_sib1.alloc.sched_info_sib1 = q->mib.sched_info_sib1; - srslte_ra_nbiot_dl_dci_to_grant(&ra_dl_sib1, - grant, - srslte_nbiot_ue_dl_get_next_sib1_start(q, sfn), - 4, - DUMMY_R_MAX, - true, - q->cell.mode); + srslte_ra_nbiot_dl_dci_to_grant( + &ra_dl_sib1, grant, srslte_nbiot_ue_dl_get_next_sib1_start(q, sfn), 4, DUMMY_R_MAX, true, q->cell.mode); grant->has_sib1 = true; } @@ -420,7 +412,7 @@ void srslte_nbiot_ue_dl_decode_sib(srslte_nbiot_ue_dl_t* q, srslte_nbiot_si_params_t params) { if (q->has_dl_grant) { - INFO("Already processing grant, skipping this.\n"); + INFO("Already processing grant, skipping this."); return; } @@ -430,12 +422,12 @@ void srslte_nbiot_ue_dl_decode_sib(srslte_nbiot_ue_dl_t* q, srslte_ra_nbiot_dl_grant_t grant; srslte_nbiot_ue_dl_get_sib_grant(q, hfn, sfn, params, &grant); srslte_nbiot_ue_dl_set_grant(q, &grant); - INFO("%d.x: Activated SIB2 reception in hfn=%d, sfn=%d\n", + INFO("%d.x: Activated SIB2 reception in hfn=%d, sfn=%d", sfn, q->npdsch_cfg.grant.start_hfn, q->npdsch_cfg.grant.start_sfn); } else { - INFO("Not handling this SI type.\n"); + INFO("Not handling this SI type."); } } @@ -502,7 +494,6 @@ int srslte_nbiot_ue_dl_decode_fft_estimate(srslte_nbiot_ue_dl_t* q, uint32_t sf_ int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && sf_idx < SRSLTE_NOF_SF_X_FRAME) { - ret = SRSLTE_ERROR; // Run FFT for all subframe data @@ -608,7 +599,7 @@ dci_blind_search(srslte_nbiot_ue_dl_t* q, dci_blind_search_t* search_space, uint ret = 0; int i = 0; while (!ret && i < search_space->nof_locations) { - DEBUG("Searching format %s in %d,%d\n", + DEBUG("Searching format %s in %d,%d", srslte_dci_format_string(search_space->format), search_space->loc[i].ncce, search_space->loc[i].L); @@ -647,8 +638,7 @@ int srslte_nbiot_ue_dl_find_dl_dci_type_siprarnti(srslte_nbiot_ue_dl_t* q, uint1 dci_blind_search_t search_space; search_space.nof_locations = srslte_npdcch_common_locations(search_space.loc, SRSLTE_MAX_CANDIDATES_COM); - DEBUG( - "Searching SI/P/RA-RNTI in %d common locations, %d formats\n", search_space.nof_locations, nb_nof_common_formats); + DEBUG("Searching SI/P/RA-RNTI in %d common locations, %d formats", search_space.nof_locations, nb_nof_common_formats); // Search for RNTI only if there is room for the common search space if (search_space.nof_locations > 0) { for (int f = 0; f < nb_nof_common_formats; f++) { @@ -672,7 +662,7 @@ int srslte_nbiot_ue_dl_find_dl_dci_type_crnti(srslte_nbiot_ue_dl_t* q, // Search UE-specific search space dci_blind_search_t search_space; search_space.nof_locations = srslte_npdcch_ue_locations(search_space.loc, SRSLTE_MAX_CANDIDATES_UE); - DEBUG("x.%d: Searching DL C-RNTI=0x%x in %d locations, %d formats\n", + DEBUG("x.%d: Searching DL C-RNTI=0x%x in %d locations, %d formats", sf_idx, rnti, search_space.nof_locations, @@ -700,12 +690,12 @@ int srslte_nbiot_ue_dl_decode_npdsch(srslte_nbiot_ue_dl_t* q, // skip subframe without grant and if it's not a valid downlink subframe if (q->has_dl_grant == false || srslte_ra_nbiot_is_valid_dl_sf(sfn * 10 + sf_idx) == false) { - DEBUG("%d.%d: Skipping NPDSCH processing.\n", sfn, sf_idx); + DEBUG("%d.%d: Skipping NPDSCH processing.", sfn, sf_idx); return SRSLTE_NBIOT_UE_DL_SKIP_SF; } // run FFT and estimate channel - DEBUG("%d.%d: Estimating channel.\n", sfn, sf_idx); + DEBUG("%d.%d: Estimating channel.", sfn, sf_idx); if ((srslte_nbiot_ue_dl_decode_fft_estimate(q, sf_idx, true)) < 0) { return ret; } @@ -714,7 +704,7 @@ int srslte_nbiot_ue_dl_decode_npdsch(srslte_nbiot_ue_dl_t* q, if (srslte_nbiot_ue_dl_is_sib1_sf(q, sfn, sf_idx) && q->has_dl_grant) { if (q->npdsch_cfg.grant.has_sib1 == false) { // skip SIB1 decoding if grant is being processed - DEBUG("%d.%d: Skipping SIB1 due to ongoing DL reception.\n", sfn, sf_idx); + DEBUG("%d.%d: Skipping SIB1 due to ongoing DL reception.", sfn, sf_idx); return SRSLTE_NBIOT_EXPECT_MORE_SF; } } @@ -733,7 +723,7 @@ int srslte_nbiot_ue_dl_decode_npdsch(srslte_nbiot_ue_dl_t* q, ret = srslte_nbiot_ue_dl_decode_npdsch_no_bcch(q, data, sfn * 10 + sf_idx, rnti); } } else { - DEBUG("%d.%d: WARNING: DL grant still active. Possibly needs to be deactivated.\n", sfn, sf_idx); + DEBUG("%d.%d: WARNING: DL grant still active. Possibly needs to be deactivated.", sfn, sf_idx); ret = SRSLTE_NBIOT_UE_DL_SKIP_SF; } @@ -748,11 +738,11 @@ int srslte_nbiot_ue_dl_decode_npdsch_no_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* d int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q->npdsch_cfg.sf_idx >= SRSLTE_NPDSCH_MAX_NOF_SF) { - ERROR("Invalid npdsch_cfg.sf_idx=%d\n", q->npdsch_cfg.sf_idx); + ERROR("Invalid npdsch_cfg.sf_idx=%d", q->npdsch_cfg.sf_idx); return ret; } - INFO("%d.%d: NPDSCH processing sf_idx=%d/%d rep=%d/%d tot=%d/%d\n", + INFO("%d.%d: NPDSCH processing sf_idx=%d/%d rep=%d/%d tot=%d/%d", tti / 10, tti % 10, q->npdsch_cfg.sf_idx + 1, @@ -809,7 +799,7 @@ int srslte_nbiot_ue_dl_decode_npdsch_no_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* d if (q->npdsch_cfg.num_sf == q->npdsch_cfg.grant.nof_sf * q->npdsch_cfg.grant.nof_rep) { // try to decode NPDSCH - INFO("%d.%d: Trying to decode NPDSCH with %d subframe(s).\n", tti / 10, tti % 10, q->npdsch_cfg.grant.nof_sf); + INFO("%d.%d: Trying to decode NPDSCH with %d subframe(s).", tti / 10, tti % 10, q->npdsch_cfg.grant.nof_sf); if (srslte_nbiot_ue_dl_decode_rnti_packet(q, &q->npdsch_cfg.grant, data, @@ -820,7 +810,7 @@ int srslte_nbiot_ue_dl_decode_npdsch_no_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* d q->ce_buffer, q->npdsch_cfg.rep_idx) != SRSLTE_SUCCESS) { // decoding failed - INFO("%d.%d: Error decoding NPDSCH with %d repetitions.\n", tti / 10, tti % 10, q->npdsch_cfg.rep_idx); + INFO("%d.%d: Error decoding NPDSCH with %d repetitions.", tti / 10, tti % 10, q->npdsch_cfg.rep_idx); q->pkt_errors++; q->has_dl_grant = false; ret = SRSLTE_ERROR; @@ -829,7 +819,7 @@ int srslte_nbiot_ue_dl_decode_npdsch_no_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* d ret = SRSLTE_SUCCESS; } } else { - DEBUG("%d.%d: Waiting for %d more subframes.\n", + DEBUG("%d.%d: Waiting for %d more subframes.", tti / 10, tti % 10, q->npdsch_cfg.grant.nof_sf * q->npdsch_cfg.grant.nof_rep - q->npdsch_cfg.num_sf); @@ -851,7 +841,7 @@ int srslte_nbiot_ue_dl_decode_npdsch_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* data // make sure we also look on odd SFNs (if n_rep=16 and n_id_ncell%2=1) uint32_t valid_si_sfn = tti / 10 + srslte_ra_nbiot_sib1_start(q->cell.n_id_ncell, &q->mib); if (valid_si_sfn % 2 == 0 && tti % 10 == 4) { - INFO("%d.%d: NPDSCH processing sf_idx=%d/%d rep=%d/%d tot=%d/%d\n", + INFO("%d.%d: NPDSCH processing sf_idx=%d/%d rep=%d/%d tot=%d/%d", tti / 10, tti % 10, q->npdsch_cfg.sf_idx + 1, @@ -872,7 +862,7 @@ int srslte_nbiot_ue_dl_decode_npdsch_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* data // check if we already have received the entire transmission if (q->npdsch_cfg.num_sf % q->npdsch_cfg.grant.nof_sf == 0) { // try to decode NPDSCH - INFO("%d.%d: Trying to decode NPDSCH with %d subframe(s).\n", tti / 10, tti % 10, q->npdsch_cfg.grant.nof_sf); + INFO("%d.%d: Trying to decode NPDSCH with %d subframe(s).", tti / 10, tti % 10, q->npdsch_cfg.grant.nof_sf); if (srslte_nbiot_ue_dl_decode_rnti_packet(q, &q->npdsch_cfg.grant, data, @@ -887,11 +877,11 @@ int srslte_nbiot_ue_dl_decode_npdsch_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* data // store soft-bits of first repetition srslte_vec_f_copy(q->llr, q->npdsch.llr, q->npdsch_cfg.grant.nof_sf * q->npdsch_cfg.nbits.nof_bits); } else { - INFO("Soft-combining NPDSCH repetition %d\n", q->npdsch_cfg.rep_idx); + INFO("Soft-combining NPDSCH repetition %d", q->npdsch_cfg.rep_idx); srslte_vec_sum_fff(q->llr, q->npdsch.llr, q->llr, q->npdsch_cfg.grant.nof_sf * q->npdsch_cfg.nbits.nof_bits); // try to decode combined soft-bits - INFO("%d.%d: Trying to decode NPDSCH with %d subframe(s) after %d repetitions.\n", + INFO("%d.%d: Trying to decode NPDSCH with %d subframe(s) after %d repetitions.", tti / 10, tti % 10, q->npdsch_cfg.grant.nof_sf, @@ -912,11 +902,10 @@ int srslte_nbiot_ue_dl_decode_npdsch_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* data q->npdsch_cfg.rep_idx++; if (q->npdsch_cfg.rep_idx < q->npdsch_cfg.grant.nof_rep) { - DEBUG("%d.%d: Couldn't decode NPDSCH, waiting for next repetition\n", tti / 10, tti % 10); + DEBUG("%d.%d: Couldn't decode NPDSCH, waiting for next repetition", tti / 10, tti % 10); ret = SRSLTE_NBIOT_EXPECT_MORE_SF; } else { - - INFO("%d.%d: Error decoding NPDSCH with %d repetitions.\n", tti / 10, tti % 10, q->npdsch_cfg.rep_idx); + INFO("%d.%d: Error decoding NPDSCH with %d repetitions.", tti / 10, tti % 10, q->npdsch_cfg.rep_idx); ret = SRSLTE_ERROR; q->pkt_errors++; // count as error after all repetitons failed q->has_dl_grant = false; @@ -927,7 +916,7 @@ int srslte_nbiot_ue_dl_decode_npdsch_bcch(srslte_nbiot_ue_dl_t* q, uint8_t* data return SRSLTE_SUCCESS; } } else { - DEBUG("%d.%d: Waiting for more subframes.\n", tti / 10, tti % 10); + DEBUG("%d.%d: Waiting for more subframes.", tti / 10, tti % 10); ret = SRSLTE_NBIOT_EXPECT_MORE_SF; } } @@ -950,12 +939,12 @@ int srslte_nbiot_ue_dl_decode_npdcch(srslte_nbiot_ue_dl_t* q, // skip subframe with grant and if it's not a valid downlink subframe if (q->has_dl_grant || srslte_ra_nbiot_is_valid_dl_sf(sfn * 10 + sf_idx) == false) { - DEBUG("%d.%d: Skipping NPDCCH processing.\n", sfn, sf_idx); + DEBUG("%d.%d: Skipping NPDCCH processing.", sfn, sf_idx); return ret; } // run FFT and estimate channel - DEBUG("%d.%d: Estimating channel.\n", sfn, sf_idx); + DEBUG("%d.%d: Estimating channel.", sfn, sf_idx); if ((srslte_nbiot_ue_dl_decode_fft_estimate(q, sf_idx, true)) < 0) { return ret; } @@ -964,7 +953,7 @@ int srslte_nbiot_ue_dl_decode_npdcch(srslte_nbiot_ue_dl_t* q, if (srslte_nbiot_ue_dl_is_si_tti(q, sfn, sf_idx) && q->has_dl_grant) { if (q->npdsch_cfg.grant.has_sib1 == false) { // skip SI decoding if grant is being processed - DEBUG("%d.%d: Skipping SI SF due to ongoing DL reception.\n", sfn, sf_idx); + DEBUG("%d.%d: Skipping SI SF due to ongoing DL reception.", sfn, sf_idx); return SRSLTE_NBIOT_EXPECT_MORE_SF; } } @@ -976,10 +965,10 @@ int srslte_nbiot_ue_dl_decode_npdcch(srslte_nbiot_ue_dl_t* q, return SRSLTE_ERROR; } - DEBUG("%d.%d: Looking for DCI for RNTI=0x%x.\n", sfn, sf_idx, rnti); + DEBUG("%d.%d: Looking for DCI for RNTI=0x%x.", sfn, sf_idx, rnti); if (srslte_nbiot_ue_dl_find_dl_dci(q, sf_idx, rnti, dci_msg) == 1) { // a DCI was found - INFO("%d.%d: Found DCI for RNTI=0x%x.\n", sfn, sf_idx, rnti); + INFO("%d.%d: Found DCI for RNTI=0x%x.", sfn, sf_idx, rnti); q->nof_detected++; ret = SRSLTE_NBIOT_UE_DL_FOUND_DCI; } @@ -995,12 +984,12 @@ int srslte_nbiot_ue_dl_decode_npdcch(srslte_nbiot_ue_dl_t* q, // i.e. srslte_nbiot_ue_dl_decode_npdcch() needs to be called before int srslte_nbiot_ue_dl_find_ul_dci(srslte_nbiot_ue_dl_t* q, uint32_t tti, uint32_t rnti, srslte_dci_msg_t* dci_msg) { - DEBUG("%d.%d: Looking for UL DCI for RNTI=0x%x.\n", tti / 10, tti % 10, rnti); + DEBUG("%d.%d: Looking for UL DCI for RNTI=0x%x.", tti / 10, tti % 10, rnti); // Search UE-specific search space dci_blind_search_t search_space; search_space.nof_locations = srslte_npdcch_ue_locations(search_space.loc, SRSLTE_MAX_CANDIDATES_UE); - DEBUG("x.%d: Searching UL C-RNTI=0x%x in %d locations, %d formats\n", + DEBUG("x.%d: Searching UL C-RNTI=0x%x in %d locations, %d formats", tti % 10, rnti, search_space.nof_locations, @@ -1023,37 +1012,37 @@ void srslte_nbiot_ue_dl_save_signal(srslte_nbiot_ue_dl_t* q, cf_t* input, uint32 // RAW samples snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_raw_samples.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: rx'ed samples\n", fname); + DEBUG("SAVED FILE %s: rx'ed samples", fname); srslte_vec_save_file(fname, input, num_symbols * sizeof(cf_t)); // NPDCCH num_symbols = q->npdcch.num_decoded_symbols; snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_npdcch_symbols.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: rx'ed downlink symbols\n", fname); + DEBUG("SAVED FILE %s: rx'ed downlink symbols", fname); srslte_vec_save_file(fname, q->npdcch.symbols[0], num_symbols * sizeof(cf_t)); snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_npdcch_symbols_eq.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: eq rx'ed downlink symbols\n", fname); + DEBUG("SAVED FILE %s: eq rx'ed downlink symbols", fname); srslte_vec_save_file(fname, q->npdcch.d, num_symbols * sizeof(cf_t)); // NPDSCH num_symbols = q->npdsch_cfg.nbits.nof_re * q->npdsch_cfg.grant.nof_sf; snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_npdsch_symbols.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: rx'ed downlink symbols\n", fname); + DEBUG("SAVED FILE %s: rx'ed downlink symbols", fname); srslte_vec_save_file(fname, q->npdsch.symbols[0], num_symbols * sizeof(cf_t)); snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_npdsch_symbols_eq.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: eq rx'ed downlink symbols\n", fname); + DEBUG("SAVED FILE %s: eq rx'ed downlink symbols", fname); srslte_vec_save_file(fname, q->npdsch.d, num_symbols * sizeof(cf_t)); // CE snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_ce0.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: downlink channel estimates port 0\n", fname); + DEBUG("SAVED FILE %s: downlink channel estimates port 0", fname); srslte_vec_save_file(fname, q->ce_buffer[0], num_symbols * sizeof(cf_t)); if (q->cell.nof_ports > 1) { snprintf(fname, MAX_FNAME_LEN, "nb_ue_dl_sfn%d_sf%d_ce1.bin", sfn, sf_idx); - DEBUG("SAVED FILE %s: downlink channel estimates port 1\n", fname); + DEBUG("SAVED FILE %s: downlink channel estimates port 1", fname); srslte_vec_save_file(fname, q->ce_buffer[1], num_symbols * sizeof(cf_t)); } } diff --git a/lib/src/phy/ue/ue_dl_nr.c b/lib/src/phy/ue/ue_dl_nr.c index 7fb02cd98..ec389d175 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -20,6 +20,7 @@ */ #include "srslte/phy/ue/ue_dl_nr.h" +#include #define UE_DL_NR_PDCCH_CORR_DEFAULT_THR 0.5f #define UE_DL_NR_PDCCH_EPRE_DEFAULT_THR -10.0f @@ -41,7 +42,7 @@ static int ue_dl_nr_alloc_prb(srslte_ue_dl_nr_t* q, uint32_t new_nof_prb) q->sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(q->max_prb)); if (q->sf_symbols[i] == NULL) { - ERROR("Malloc\n"); + ERROR("Malloc"); return SRSLTE_ERROR; } } @@ -57,12 +58,21 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co } if (args->nof_rx_antennas == 0) { - ERROR("Error invalid number of antennas (%d)\n", args->nof_rx_antennas); + ERROR("Error invalid number of antennas (%d)", args->nof_rx_antennas); return SRSLTE_ERROR; } - q->nof_rx_antennas = args->nof_rx_antennas; - q->pdcch_dmrs_corr_thr = args->pdcch_dmrs_corr_thr; + q->nof_rx_antennas = args->nof_rx_antennas; + if (isnormal(args->pdcch_dmrs_corr_thr)) { + q->pdcch_dmrs_corr_thr = args->pdcch_dmrs_corr_thr; + } else { + q->pdcch_dmrs_corr_thr = UE_DL_NR_PDCCH_CORR_DEFAULT_THR; + } + if (isnormal(args->pdcch_dmrs_epre_thr)) { + q->pdcch_dmrs_epre_thr = args->pdcch_dmrs_epre_thr; + } else { + q->pdcch_dmrs_epre_thr = UE_DL_NR_PDCCH_EPRE_DEFAULT_THR; + } if (srslte_pdsch_nr_init_ue(&q->pdsch, &args->pdsch) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; @@ -73,7 +83,7 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co } if (ue_dl_nr_alloc_prb(q, args->nof_max_prb)) { - ERROR("Error allocating\n"); + ERROR("Error allocating"); return SRSLTE_ERROR; } @@ -89,13 +99,13 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co } if (srslte_dmrs_sch_init(&q->dmrs_pdsch, true) < SRSLTE_SUCCESS) { - ERROR("Error DMRS\n"); + ERROR("Error DMRS"); return SRSLTE_ERROR; } q->pdcch_ce = SRSLTE_MEM_ALLOC(srslte_dmrs_pdcch_ce_t, 1); if (q->pdcch_ce == NULL) { - ERROR("Error alloc\n"); + ERROR("Error alloc"); return SRSLTE_ERROR; } @@ -119,14 +129,17 @@ void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q) srslte_chest_dl_res_free(&q->chest); srslte_pdsch_nr_free(&q->pdsch); srslte_dmrs_sch_free(&q->dmrs_pdsch); - srslte_dmrs_pdcch_estimator_free(&q->dmrs_pdcch); + + for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_CORESET; i++) { + srslte_dmrs_pdcch_estimator_free(&q->dmrs_pdcch[i]); + } srslte_pdcch_nr_free(&q->pdcch); if (q->pdcch_ce) { free(q->pdcch_ce); } - memset(q, 0, sizeof(srslte_ue_dl_nr_t)); + SRSLTE_MEM_ZERO(q, srslte_ue_dl_nr_t, 1); } int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* carrier) @@ -136,18 +149,23 @@ int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* } if (srslte_dmrs_sch_set_carrier(&q->dmrs_pdsch, carrier) < SRSLTE_SUCCESS) { - ERROR("Error DMRS\n"); + ERROR("Error DMRS"); return SRSLTE_ERROR; } if (ue_dl_nr_alloc_prb(q, carrier->nof_prb)) { - ERROR("Error allocating\n"); + ERROR("Error allocating"); return SRSLTE_ERROR; } if (carrier->nof_prb != q->carrier.nof_prb) { for (uint32_t i = 0; i < q->nof_rx_antennas; i++) { - srslte_ofdm_rx_set_prb(&q->fft[i], SRSLTE_CP_NORM, carrier->nof_prb); + srslte_ofdm_cfg_t cfg = {}; + cfg.nof_prb = carrier->nof_prb; + cfg.symbol_sz = srslte_min_symbol_sz_rb(carrier->nof_prb); + cfg.cp = SRSLTE_CP_NORM; + cfg.keep_dc = true; + srslte_ofdm_rx_init_cfg(&q->fft[i], &cfg); } } @@ -156,26 +174,28 @@ int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* return SRSLTE_SUCCESS; } -int srslte_ue_dl_nr_set_coreset(srslte_ue_dl_nr_t* q, const srslte_coreset_t* coreset) +int srslte_ue_dl_nr_set_pdcch_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_pdcch_cfg_t* cfg) { - if (q == NULL || coreset == NULL) { + if (q == NULL || cfg == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - q->coreset = *coreset; + // Copy new configuration + q->cfg = *cfg; - if (srslte_dmrs_pdcch_estimator_init(&q->dmrs_pdcch, &q->carrier, &q->coreset) < SRSLTE_SUCCESS) { - return SRSLTE_ERROR; - } - - if (srslte_pdcch_nr_set_carrier(&q->pdcch, &q->carrier, &q->coreset) < SRSLTE_SUCCESS) { - return SRSLTE_ERROR; + // iterate over all possible CORESET and initialise/update the present ones + for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_CORESET; i++) { + if (cfg->coreset_present[i]) { + if (srslte_dmrs_pdcch_estimator_init(&q->dmrs_pdcch[i], &q->carrier, &cfg->coreset[i]) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + } } return SRSLTE_SUCCESS; } -void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg_t* slot_cfg) +void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_slot_cfg_t* slot_cfg) { if (q == NULL || slot_cfg == NULL) { return; @@ -186,89 +206,122 @@ void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg srslte_ofdm_rx_sf(&q->fft[i]); } - // Estimate PDCCH channel - srslte_dmrs_pdcch_estimate(&q->dmrs_pdcch, slot_cfg, q->sf_symbols[0]); + // Estimate PDCCH channel for every configured CORESET + for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_CORESET; i++) { + if (q->cfg.coreset_present[i]) { + srslte_dmrs_pdcch_estimate(&q->dmrs_pdcch[i], slot_cfg, q->sf_symbols[0]); + } + } } -static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q, srslte_dci_msg_nr_t* dci_msg, srslte_pdcch_nr_res_t* pdcch_res) +static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q, + srslte_dci_msg_nr_t* dci_msg, + srslte_pdcch_nr_res_t* pdcch_res, + uint32_t coreset_id) { srslte_dmrs_pdcch_measure_t m = {}; - if (srslte_dmrs_pdcch_get_measure(&q->dmrs_pdcch, &dci_msg->location, &m) < SRSLTE_SUCCESS) { - ERROR("Error getting measure location L=%d, ncce=%d\n", dci_msg->location.L, dci_msg->location.ncce); + // Measures the PDCCH transmission DMRS + if (srslte_dmrs_pdcch_get_measure(&q->dmrs_pdcch[coreset_id], &dci_msg->location, &m) < SRSLTE_SUCCESS) { + ERROR("Error getting measure location L=%d, ncce=%d", dci_msg->location.L, dci_msg->location.ncce); return SRSLTE_ERROR; } // If measured correlation is invalid, early return if (!isnormal(m.norm_corr)) { - INFO("Discarded PDCCH candidate L=%d;ncce=%d; Invalid measurement;\n", dci_msg->location.L, dci_msg->location.ncce); + INFO("Discarded PDCCH candidate L=%d;ncce=%d; Invalid measurement;", dci_msg->location.L, dci_msg->location.ncce); return SRSLTE_SUCCESS; } // Compare EPRE with threshold - { - float thr = q->pdcch_dmrs_epre_thr; - if (!isnormal(thr)) { - thr = UE_DL_NR_PDCCH_EPRE_DEFAULT_THR; //< Load default threshold if not provided - } - if (m.epre_dBfs < thr) { - INFO("Discarded PDCCH candidate L=%d;ncce=%d; EPRE is too weak (%.1f<%.1f);\n", - dci_msg->location.L, - dci_msg->location.ncce, - m.epre_dBfs, - thr); - return SRSLTE_SUCCESS; - } + if (m.epre_dBfs < q->pdcch_dmrs_epre_thr) { + INFO("Discarded PDCCH candidate L=%d;ncce=%d; EPRE is too weak (%.1f<%.1f);", + dci_msg->location.L, + dci_msg->location.ncce, + m.epre_dBfs, + q->pdcch_dmrs_epre_thr); + return SRSLTE_SUCCESS; } // Compare DMRS correlation with threshold - { - float thr = q->pdcch_dmrs_corr_thr; - if (!isnormal(thr)) { - thr = UE_DL_NR_PDCCH_CORR_DEFAULT_THR; //< Load default threshold if not provided - } - if (m.norm_corr < thr) { - INFO("Discarded PDCCH candidate L=%d;ncce=%d; Correlation is too low (%.1f<%.1f);\n", - dci_msg->location.L, - dci_msg->location.ncce, - m.norm_corr, - thr); - return SRSLTE_SUCCESS; - } + if (m.norm_corr < q->pdcch_dmrs_corr_thr) { + INFO("Discarded PDCCH candidate L=%d;ncce=%d; Correlation is too low (%.1f<%.1f); EPRE=%+.2f; RSRP=%+.2f;", + dci_msg->location.L, + dci_msg->location.ncce, + m.norm_corr, + q->pdcch_dmrs_corr_thr, + m.epre_dBfs, + m.rsrp_dBfs); + return SRSLTE_SUCCESS; } // Extract PDCCH channel estimates - if (srslte_dmrs_pdcch_get_ce(&q->dmrs_pdcch, &dci_msg->location, q->pdcch_ce) < SRSLTE_SUCCESS) { - ERROR("Error extracting PDCCH DMRS\n"); + if (srslte_dmrs_pdcch_get_ce(&q->dmrs_pdcch[coreset_id], &dci_msg->location, q->pdcch_ce) < SRSLTE_SUCCESS) { + ERROR("Error extracting PDCCH DMRS"); return SRSLTE_ERROR; } // Decode PDCCH if (srslte_pdcch_nr_decode(&q->pdcch, q->sf_symbols[0], q->pdcch_ce, dci_msg, pdcch_res) < SRSLTE_SUCCESS) { - ERROR("Error decoding PDCCH\n"); + ERROR("Error decoding PDCCH"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } -int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, - const srslte_search_space_t* search_space, - const srslte_dl_slot_cfg_t* slot_cfg, - uint16_t rnti, - srslte_dci_dl_nr_t* dci_dl_list, - uint32_t nof_dci_msg) +static bool find_dci_msg(srslte_dci_msg_nr_t* dci_msg, uint32_t nof_dci_msg, srslte_dci_msg_nr_t* match) { + bool found = false; + uint32_t nof_bits = match->nof_bits; + + for (int k = 0; k < nof_dci_msg && !found; k++) { + if (dci_msg[k].nof_bits == nof_bits) { + if (memcmp(dci_msg[k].payload, match->payload, nof_bits) == 0) { + found = true; + } + } + } + + return found; +} + +static int ue_dl_nr_find_dl_dci_ss(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_search_space_t* search_space, + uint16_t rnti, + srslte_rnti_type_t rnti_type, + srslte_dci_msg_nr_t* dci_msg_list, + uint32_t nof_dci_msg) +{ + // Check inputs + if (q == NULL || slot_cfg == NULL || dci_msg_list == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Select CORESET + uint32_t coreset_id = search_space->coreset_id; + if (coreset_id >= SRSLTE_UE_DL_NR_MAX_NOF_CORESET || !q->cfg.coreset_present[coreset_id]) { + ERROR("CORESET %d is not present in search space %d", search_space->coreset_id, search_space->id); + return SRSLTE_ERROR; + } + srslte_coreset_t* coreset = &q->cfg.coreset[search_space->coreset_id]; + + // Set CORESET in PDCCH decoder + if (srslte_pdcch_nr_set_carrier(&q->pdcch, &q->carrier, coreset) < SRSLTE_SUCCESS) { + ERROR("Setting carrier and CORESETºn"); + return SRSLTE_ERROR; + } + uint32_t count = 0; // Hard-coded values srslte_dci_format_nr_t dci_format = srslte_dci_format_nr_1_0; - srslte_rnti_type_t rnti_type = srslte_rnti_type_c; // Calculate number of DCI bits - int dci_nof_bits = srslte_dci_nr_format_1_0_sizeof(&q->carrier, &q->coreset, rnti_type); + int dci_nof_bits = srslte_dci_nr_format_1_0_sizeof(&q->carrier, coreset, rnti_type); if (dci_nof_bits <= SRSLTE_SUCCESS) { - ERROR("Error DCI size\n"); + ERROR("Error DCI size"); return SRSLTE_ERROR; } @@ -276,50 +329,171 @@ int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR && count < nof_dci_msg; L++) { // Calculate possible PDCCH DCI candidates uint32_t candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {}; - int nof_candidates = - srslte_pdcch_nr_locations_coreset(&q->coreset, search_space, rnti, L, slot_cfg->idx, candidates); + int nof_candidates = srslte_pdcch_nr_locations_coreset(coreset, search_space, rnti, L, slot_cfg->idx, candidates); if (nof_candidates < SRSLTE_SUCCESS) { - ERROR("Error calculating DCI candidate location\n"); + ERROR("Error calculating DCI candidate location"); return SRSLTE_ERROR; } // Iterate over the candidates for (int ncce_idx = 0; ncce_idx < nof_candidates && count < nof_dci_msg; ncce_idx++) { + // Set DCI context srslte_dci_msg_nr_t dci_msg = {}; dci_msg.location.L = L; dci_msg.location.ncce = candidates[ncce_idx]; dci_msg.search_space = search_space->type; + dci_msg.coreset_id = search_space->coreset_id; dci_msg.rnti_type = rnti_type; dci_msg.rnti = rnti; dci_msg.format = dci_format; dci_msg.nof_bits = (uint32_t)dci_nof_bits; + // Find and decode PDCCH transmission in the given ncce srslte_pdcch_nr_res_t res = {}; - if (ue_dl_nr_find_dci_ncce(q, &dci_msg, &res) < SRSLTE_SUCCESS) { + if (ue_dl_nr_find_dci_ncce(q, &dci_msg, &res, coreset_id) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } - if (res.crc) { - if (srslte_dci_nr_format_1_0_unpack(&q->carrier, &q->coreset, &dci_msg, &dci_dl_list[count]) < SRSLTE_SUCCESS) { - ERROR("Error unpacking DCI\n"); - return SRSLTE_ERROR; + // If the CRC was not match, move to next candidate + if (!res.crc) { + continue; + } + + // Detect if the DCI was a format 0_0 + if (!srslte_dci_nr_format_1_0_valid(&dci_msg)) { + // Change grant format to 0_0 + dci_msg.format = srslte_dci_format_nr_0_0; + + // If the pending UL grant list is full or has the dci message, keep moving + if (q->pending_ul_dci_count >= SRSLTE_MAX_DCI_MSG_NR || + find_dci_msg(q->pending_ul_dci_msg, q->pending_ul_dci_count, &dci_msg)) { + continue; } - INFO("Found DCI in L=%d,ncce=%d\n", dci_msg.location.L, dci_msg.location.ncce); - count++; + // Save the grant in the pending UL grant list + q->pending_ul_dci_msg[q->pending_ul_dci_count] = dci_msg; + q->pending_ul_dci_count++; + + // Move to next candidate + continue; } + + // Check if the grant exists already in the message list + if (find_dci_msg(dci_msg_list, count, &dci_msg)) { + // The same DCI is in the list, keep moving + continue; + } + + INFO("Found DCI in L=%d,ncce=%d", dci_msg.location.L, dci_msg.location.ncce); + // Append DCI message into the list + dci_msg_list[count] = dci_msg; + count++; } } return (int)count; } -int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_sch_cfg_nr_t* cfg, - srslte_pdsch_res_nr_t* res) +int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + uint16_t rnti, + srslte_rnti_type_t rnti_type, + srslte_dci_dl_nr_t* dci_dl_list, + uint32_t nof_dci_msg) { + int count = 0; + srslte_dci_msg_nr_t dci_msg_list[SRSLTE_MAX_DCI_MSG_NR] = {}; + // Check inputs + if (q == NULL || slot_cfg == NULL || dci_dl_list == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Limit maximum number of DCI messages to find + nof_dci_msg = SRSLTE_MIN(nof_dci_msg, SRSLTE_MAX_DCI_MSG_NR); + + // If the UE looks for a RAR and RA search space is provided, search for it + if (q->cfg.ra_search_space_present && rnti_type == srslte_rnti_type_ra) { + // Find DCIs in the RA search space + int ret = ue_dl_nr_find_dl_dci_ss(q, slot_cfg, &q->cfg.ra_search_space, rnti, rnti_type, dci_msg_list, nof_dci_msg); + if (ret < SRSLTE_SUCCESS) { + ERROR("Error searching RAR DCI"); + return SRSLTE_ERROR; + } + + // Count the found DCIs + count += ret; + } else { + // Iterate all possible common and UE search spaces + for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE && count < nof_dci_msg; i++) { + // Skip search space if not present + if (!q->cfg.search_space_present[i]) { + continue; + } + + // Find DCIs in the selected search space + int ret = ue_dl_nr_find_dl_dci_ss( + q, slot_cfg, &q->cfg.search_space[i], rnti, rnti_type, &dci_msg_list[count], nof_dci_msg - count); + if (ret < SRSLTE_SUCCESS) { + ERROR("Error searching DCI"); + return SRSLTE_ERROR; + } + + // Count the found DCIs + count += ret; + } + } + + // Convert found DCI messages into DL grants + for (uint32_t i = 0; i < count; i++) { + const srslte_coreset_t* coreset = &q->cfg.coreset[dci_msg_list[i].coreset_id]; + srslte_dci_nr_format_1_0_unpack(&q->carrier, coreset, &dci_msg_list[i], &dci_dl_list[i]); + } + + return count; +} + +int srslte_ue_dl_nr_find_ul_dci(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + uint16_t rnti, + srslte_rnti_type_t rnti_type, + srslte_dci_ul_nr_t* dci_ul_list, + uint32_t nof_dci_msg) +{ + int count = 0; + + // Check inputs + if (q == NULL || slot_cfg == NULL || dci_ul_list == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Get DCI messages from the pending list + for (uint32_t i = 0; i < q->pending_ul_dci_count && count < nof_dci_msg; i++) { + srslte_dci_msg_nr_t* dci_msg = &q->pending_ul_dci_msg[i]; + + if (dci_msg->rnti_type != rnti_type || dci_msg->rnti != rnti) { + continue; + } + + const srslte_coreset_t* coreset = &q->cfg.coreset[dci_msg->coreset_id]; + if (srslte_dci_nr_format_0_0_unpack(&q->carrier, coreset, dci_msg, &dci_ul_list[count]) < SRSLTE_SUCCESS) { + ERROR("Unpacking DCI 0_0"); + continue; + } + count++; + } + + // Reset pending UL grant list + q->pending_ul_dci_count = 0; + + return count; +} + +int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, + const srslte_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + srslte_pdsch_res_nr_t* res) +{ if (srslte_dmrs_sch_estimate(&q->dmrs_pdsch, slot, cfg, &cfg->grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -331,7 +505,7 @@ int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) { char str[512]; srslte_ue_dl_nr_pdsch_info(q, cfg, res, str, sizeof(str)); - INFO("PDSCH: %s\n", str); + INFO("PDSCH: %s", str); } return SRSLTE_SUCCESS; @@ -345,11 +519,191 @@ int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, { int len = 0; - // Append channel estimator info - // ... - // Append PDSCH info len += srslte_pdsch_nr_rx_info(&q->pdsch, cfg, &cfg->grant, res, &str[len], str_len - len); + // Append channel estimator info + len = srslte_print_check(str, str_len, len, ",SNR=%+.1f", q->chest.snr_db); + return len; } + +// Implements TS 38.213 Table 9.1.3-1: Value of counter DAI in DCI format 1_0 and of counter DAI or total DAI DCI format +// 1_1 +static uint32_t ue_dl_nr_V_DL_DAI(uint32_t dai) +{ + return dai + 1; +} + +static int ue_dl_nr_gen_ack_type2(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, + const srslte_pdsch_ack_nr_t* ack_info, + srslte_uci_data_nr_t* uci_data) +{ + bool harq_ack_spatial_bundling = + ack_info->use_pusch ? cfg->harq_ack_spatial_bundling_pusch : cfg->harq_ack_spatial_bundling_pucch; + uint8_t* o_ack = uci_data->value.ack; + + uint32_t m = 0; // PDCCH with DCI format 1_0 or DCI format 1_1 monitoring occasion index: lower index corresponds to + // earlier PDCCH with DCI format 1_0 or DCI format 1_1 monitoring occasion + uint32_t j = 0; + uint32_t V_temp = 0; + uint32_t V_temp2 = 0; + + uint32_t N_DL_cells = ack_info->nof_cc; // number of serving cells configured by higher layers for the UE + + // The following code follows the exact pseudo-code provided in TS 38.213 9.1.3.1 Type-2 HARQ-ACK codebook ... + while (m < SRSLTE_UCI_NR_MAX_M) { + uint32_t c = 0; // serving cell index: lower indexes correspond to lower RRC indexes of corresponding cell + while (c < N_DL_cells) { + // Get ACK information of serving cell c for the PDCH monitoring occasion m + const srslte_pdsch_ack_m_nr_t* ack = &ack_info->cc[c].m[m]; + + // Get DAI counter value + uint32_t V_DL_CDAI = ue_dl_nr_V_DL_DAI(ack->resource.v_dai_dl); + uint32_t V_DL_TDAI = ack->resource.dci_format_1_1 ? ue_dl_nr_V_DL_DAI(ack->resource.v_dai_dl) : UINT32_MAX; + + // Get ACK values + uint32_t ack_tb0 = ack->value[0]; + uint32_t ack_tb1 = ack->value[1]; + + // For a PDCCH monitoring occasion with DCI format 1_0 or DCI format 1_1 in the active DL BWP of a serving cell, + // when a UE receives a PDSCH with one transport block and the value of maxNrofCodeWordsScheduledByDCI is 2, the + // HARQ-ACK information is associated with the first transport block and the UE generates a NACK for the second + // transport block if harq-ACK-SpatialBundlingPUCCH is not provided and generates HARQ-ACK information with + // value of ACK for the second transport block if harq-ACK-SpatialBundlingPUCCH is provided. + if (cfg->max_cw_sched_dci_is_2 && ack->second_tb_present) { + ack_tb1 = harq_ack_spatial_bundling ? 1 : 0; + } + + // if PDCCH monitoring occasion m is before an active DL BWP change on serving cell c or an active UL + // BWP change on the PCell and an active DL BWP change is not triggered by a DCI format 1_1 in PDCCH + // monitoring occasion m + if (ack->dl_bwp_changed || ack->ul_bwp_changed) { + c = c + 1; + } else { + if (ack->present) { + // Load ACK resource data into UCI info + uci_data->cfg.pucch_resource_id = ack_info->cc[c].m[m].resource.pucch_resource_id; + uci_data->cfg.rnti = ack_info->cc[c].m[m].resource.rnti; + + if (V_DL_CDAI <= V_temp) { + j = j + 1; + } + + V_temp = V_DL_CDAI; + + if (V_DL_TDAI == UINT32_MAX) { + V_temp2 = V_DL_CDAI; + } else { + V_temp2 = V_DL_TDAI; + } + + // if harq-ACK-SpatialBundlingPUCCH is not provided and m is a monitoring occasion for PDCCH with DCI format + // 1_0 or DCI format 1_1 and the UE is configured by maxNrofCodeWordsScheduledByDCI with reception of two + // transport blocks for at least one configured DL BWP of at least one serving cell, + if (!harq_ack_spatial_bundling && cfg->max_cw_sched_dci_is_2) { + o_ack[8 * j + 2 * (V_DL_CDAI - 1) + 0] = ack_tb0; + o_ack[8 * j + 2 * (V_DL_CDAI - 1) + 1] = ack_tb1; + } + // elseif harq-ACK-SpatialBundlingPUCCH is provided to the UE and m is a monitoring occasion for + // PDCCH with DCI format 1_1 and the UE is configured by maxNrofCodeWordsScheduledByDCI with + // reception of two transport blocks in at least one configured DL BWP of a serving cell, + else if (harq_ack_spatial_bundling && ack->resource.dci_format_1_1 && cfg->max_cw_sched_dci_is_2) { + o_ack[4 * j + (V_DL_CDAI - 1)] = ack_tb0 & ack_tb1; + } + // else + else { + o_ack[4 * j + (V_DL_CDAI - 1)] = ack_tb0; + } + } + c = c + 1; + } + } + m = m + 1; + } + if (V_temp2 < V_temp) { + j = j + 1; + } + + // if harq-ACK-SpatialBundlingPUCCH is not provided to the UE and the UE is configured by + // maxNrofCodeWordsScheduledByDCI with reception of two transport blocks for at least one configured DL BWP of a + // serving cell, + if (!harq_ack_spatial_bundling && cfg->max_cw_sched_dci_is_2) { + uci_data->cfg.o_ack = 2 * (4 * j + V_temp2); + } else { + uci_data->cfg.o_ack = 4 * j + V_temp2; + } + + // Implement here SPS PDSCH reception + // ... + + return SRSLTE_SUCCESS; +} + +int ue_dl_nr_pdsch_k1(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, const srslte_dci_dl_nr_t* dci_dl) +{ + // For DCI format 1_0, the PDSCH-to-HARQ_feedback timing indicator field values map to {1, 2, 3, 4, 5, 6, 7, 8} + if (dci_dl->format == srslte_dci_format_nr_1_0) { + return (int)dci_dl->harq_feedback + 1; + } + + // For DCI format 1_1, if present, the PDSCH-to-HARQ_feedback timing indicator field values map to values for a set of + // number of slots provided by dl-DataToUL-ACK as defined in Table 9.2.3-1. + if (dci_dl->harq_feedback >= SRSLTE_MAX_NOF_DL_DATA_TO_UL || dci_dl->harq_feedback >= cfg->nof_dl_data_to_ul_ack) { + ERROR("Out-of-range PDSCH-to-HARQ feedback index (%d, max %d)", dci_dl->harq_feedback, cfg->nof_dl_data_to_ul_ack); + return SRSLTE_ERROR; + } + + return (int)cfg->dl_data_to_ul_ack[dci_dl->harq_feedback]; +} + +int srslte_ue_dl_nr_pdsch_ack_resource(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, + const srslte_dci_dl_nr_t* dci_dl, + srslte_pdsch_ack_resource_nr_t* pdsch_ack_resource) +{ + if (cfg == NULL || dci_dl == NULL || pdsch_ack_resource == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Calculate Data to UL ACK timing k1 + int k1 = ue_dl_nr_pdsch_k1(cfg, dci_dl); + if (k1 < SRSLTE_ERROR) { + ERROR("Error calculating K1"); + return SRSLTE_ERROR; + } + + // Fill PDSCH resource + pdsch_ack_resource->dci_format_1_1 = (dci_dl->format == srslte_dci_format_nr_1_1); + pdsch_ack_resource->k1 = k1; + pdsch_ack_resource->v_dai_dl = dci_dl->dai; + pdsch_ack_resource->rnti = dci_dl->rnti; + pdsch_ack_resource->pucch_resource_id = dci_dl->pucch_resource; + + return SRSLTE_SUCCESS; +} + +int srslte_ue_dl_nr_gen_ack(const srslte_ue_dl_nr_harq_ack_cfg_t* cfg, + const srslte_pdsch_ack_nr_t* ack_info, + srslte_uci_data_nr_t* uci_data) +{ + // Check inputs + if (cfg == NULL || ack_info == NULL || uci_data == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // According TS 38.213 9.1.2 Type-1 HARQ-ACK codebook determination + if (cfg->pdsch_harq_ack_codebook == srslte_pdsch_harq_ack_codebook_semi_static) { + // This clause applies if the UE is configured with pdsch-HARQ-ACK-Codebook = semi-static. + ERROR("Type-1 HARQ-ACK codebook determination is NOT implemented"); + return SRSLTE_ERROR; + } + + // According TS 38.213 9.1.3 Type-2 HARQ-ACK codebook determination + if (cfg->pdsch_harq_ack_codebook == srslte_pdsch_harq_ack_codebook_dynamic) { + // This clause applies if the UE is configured with pdsch-HARQ-ACK-Codebook = dynamic. + return ue_dl_nr_gen_ack_type2(cfg, ack_info, uci_data); + } + + ERROR("No HARQ-ACK codebook determination is NOT implemented"); + return SRSLTE_ERROR; +} diff --git a/lib/src/phy/ue/ue_mib.c b/lib/src/phy/ue/ue_mib.c index 785b5a016..aa82f9ed0 100644 --- a/lib/src/phy/ue/ue_mib.c +++ b/lib/src/phy/ue/ue_mib.c @@ -38,12 +38,11 @@ int srslte_ue_mib_init(srslte_ue_mib_t* q, cf_t* in_buffer, uint32_t max_prb) int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_ue_mib_t)); if (srslte_pbch_init(&q->pbch)) { - ERROR("Error initiating PBCH\n"); + ERROR("Error initiating PBCH"); goto clean_exit; } @@ -54,15 +53,15 @@ int srslte_ue_mib_init(srslte_ue_mib_t* q, cf_t* in_buffer, uint32_t max_prb) } if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, in_buffer, q->sf_symbols, max_prb)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); goto clean_exit; } if (srslte_chest_dl_init(&q->chest, max_prb, 1)) { - ERROR("Error initializing reference signal\n"); + ERROR("Error initializing reference signal"); goto clean_exit; } if (srslte_chest_dl_res_init(&q->chest_res, max_prb)) { - ERROR("Error initializing reference signal\n"); + ERROR("Error initializing reference signal"); goto clean_exit; } srslte_ue_mib_reset(q); @@ -97,11 +96,11 @@ int srslte_ue_mib_set_cell(srslte_ue_mib_t* q, srslte_cell_t cell) if (q != NULL && cell.nof_ports <= SRSLTE_MAX_PORTS) { if (srslte_pbch_set_cell(&q->pbch, cell)) { - ERROR("Error initiating PBCH\n"); + ERROR("Error initiating PBCH"); return SRSLTE_ERROR; } if (srslte_ofdm_rx_set_prb(&q->fft, cell.cp, cell.nof_prb)) { - ERROR("Error initializing FFT\n"); + ERROR("Error initializing FFT"); return SRSLTE_ERROR; } @@ -110,7 +109,7 @@ int srslte_ue_mib_set_cell(srslte_ue_mib_t* q, srslte_cell_t cell) } if (srslte_chest_dl_set_cell(&q->chest, cell)) { - ERROR("Error initializing reference signal\n"); + ERROR("Error initializing reference signal"); return SRSLTE_ERROR; } srslte_ue_mib_reset(q); @@ -151,21 +150,21 @@ int srslte_ue_mib_decode(srslte_ue_mib_t* q, } /* Reset decoder if we missed a frame */ if (q->frame_cnt > 8) { - INFO("Resetting PBCH decoder after %d frames\n", q->frame_cnt); + INFO("Resetting PBCH decoder after %d frames", q->frame_cnt); srslte_ue_mib_reset(q); } /* Decode PBCH */ ret = srslte_pbch_decode(&q->pbch, &q->chest_res, sf_buffer, bch_payload, nof_tx_ports, sfn_offset); if (ret < 0) { - ERROR("Error decoding PBCH (%d)\n", ret); + ERROR("Error decoding PBCH (%d)", ret); } else if (ret == 1) { - INFO("MIB decoded: %u, snr=%.1f dB\n", q->frame_cnt, q->chest_res.snr_db); + INFO("MIB decoded: %u, snr=%.1f dB", q->frame_cnt, q->chest_res.snr_db); srslte_ue_mib_reset(q); ret = SRSLTE_UE_MIB_FOUND; } else { ret = SRSLTE_UE_MIB_NOTFOUND; - INFO("MIB not decoded: %u, snr=%.1f dB\n", q->frame_cnt, q->chest_res.snr_db); + INFO("MIB not decoded: %u, snr=%.1f dB", q->frame_cnt, q->chest_res.snr_db); q->frame_cnt++; } @@ -184,7 +183,7 @@ int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t* q, // Use 1st RF channel only to receive MIB if (srslte_ue_mib_init(&q->ue_mib, q->sf_buffer[0], SRSLTE_UE_MIB_NOF_PRB)) { - ERROR("Error initiating ue_mib\n"); + ERROR("Error initiating ue_mib"); return SRSLTE_ERROR; } // Configure ue_sync to receive all channels @@ -206,11 +205,11 @@ int srslte_ue_mib_sync_set_cell(srslte_ue_mib_sync_t* q, srslte_cell_t cell) cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; if (srslte_ue_mib_set_cell(&q->ue_mib, cell)) { - ERROR("Error initiating ue_mib\n"); + ERROR("Error initiating ue_mib"); return SRSLTE_ERROR; } if (srslte_ue_sync_set_cell(&q->ue_sync, cell)) { - ERROR("Error initiating ue_sync\n"); + ERROR("Error initiating ue_sync"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; } @@ -240,7 +239,6 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t* q, uint32_t* nof_tx_ports, int* sfn_offset) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t nof_frames = 0; int mib_ret = SRSLTE_UE_MIB_NOTFOUND; @@ -255,7 +253,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t* q, mib_ret = SRSLTE_UE_MIB_NOTFOUND; ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer, MIB_BUFFER_MAX_SAMPLES); if (ret < 0) { - ERROR("Error calling srslte_ue_sync_work()\n"); + ERROR("Error calling srslte_ue_sync_work()"); return -1; } @@ -263,7 +261,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t* q, if (ret == 1) { mib_ret = srslte_ue_mib_decode(&q->ue_mib, bch_payload, nof_tx_ports, sfn_offset); } else { - DEBUG("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); + DEBUG("Resetting PBCH decoder after %d frames", q->ue_mib.frame_cnt); srslte_ue_mib_reset(&q->ue_mib); } nof_frames++; diff --git a/lib/src/phy/ue/ue_mib_nbiot.c b/lib/src/phy/ue/ue_mib_nbiot.c index d22afd796..e2c404981 100644 --- a/lib/src/phy/ue/ue_mib_nbiot.c +++ b/lib/src/phy/ue/ue_mib_nbiot.c @@ -147,7 +147,7 @@ int srslte_ue_mib_nbiot_decode(srslte_ue_mib_nbiot_t* q, // Reset decoder if we missed a NPBCH TTI if (q->frame_cnt > SRSLTE_NPBCH_NUM_FRAMES) { - INFO("Resetting NPBCH decoder after %d frames\n", q->frame_cnt); + INFO("Resetting NPBCH decoder after %d frames", q->frame_cnt); srslte_ue_mib_nbiot_reset(q); return SRSLTE_UE_MIB_NBIOT_NOTFOUND; } @@ -161,13 +161,13 @@ int srslte_ue_mib_nbiot_decode(srslte_ue_mib_nbiot_t* q, nof_tx_ports, sfn_offset, 0)) { - DEBUG("BCH decoded ok with offset %d\n", *sfn_offset); + DEBUG("BCH decoded ok with offset %d", *sfn_offset); if (memcmp(bch_payload, q->last_bch_payload, SRSLTE_MIB_NB_LEN) == 0) { - DEBUG("BCH content equals last BCH, new counter %d\n", q->frame_cnt); + DEBUG("BCH content equals last BCH, new counter %d", q->frame_cnt); } else { // new BCH transmitted if (q->frame_cnt != 0) { - INFO("MIB-NB decoded: %u with offset %d\n", q->frame_cnt, *sfn_offset); + INFO("MIB-NB decoded: %u with offset %d", q->frame_cnt, *sfn_offset); if (*sfn_offset != 0) { INFO("New BCH was decoded at block offset %d. SFN may be corrupted.", *sfn_offset); } @@ -175,7 +175,7 @@ int srslte_ue_mib_nbiot_decode(srslte_ue_mib_nbiot_t* q, return SRSLTE_UE_MIB_NBIOT_FOUND; } else { // store new BCH - DEBUG("New BCH transmitted after %d frames\n", q->frame_cnt); + DEBUG("New BCH transmitted after %d frames", q->frame_cnt); memcpy(q->last_bch_payload, bch_payload, SRSLTE_MIB_NB_LEN); } } @@ -186,7 +186,7 @@ int srslte_ue_mib_nbiot_decode(srslte_ue_mib_nbiot_t* q, int srslte_ue_mib_sync_nbiot_init_multi( srslte_ue_mib_sync_nbiot_t* q, - int(recv_callback)(void*, cf_t * [SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + int(recv_callback)(void*, cf_t* [SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), uint32_t nof_rx_antennas, void* stream_handler) { @@ -249,7 +249,7 @@ int srslte_ue_mib_sync_nbiot_decode(srslte_ue_mib_sync_nbiot_t* q, int mib_ret = SRSLTE_UE_MIB_NBIOT_NOTFOUND; if (q == NULL) { - return ret; + return ret; } do { @@ -263,7 +263,7 @@ int srslte_ue_mib_sync_nbiot_decode(srslte_ue_mib_sync_nbiot_t* q, if (srslte_ue_sync_nbiot_get_sfidx(&q->ue_sync) == 0) { mib_ret = srslte_ue_mib_nbiot_decode(&q->ue_mib, NULL, bch_payload, nof_tx_ports, sfn_offset); if (mib_ret < 0) { - DEBUG("Resetting NPBCH decoder after %d frames\n", q->ue_mib.frame_cnt); + DEBUG("Resetting NPBCH decoder after %d frames", q->ue_mib.frame_cnt); srslte_ue_mib_nbiot_reset(&q->ue_mib); } nof_frames++; diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 6de3d9770..69d95db7b 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -82,16 +82,16 @@ int srslte_ue_sync_init_file_multi(srslte_ue_sync_t* q, q->cfo_correct_enable_track = true; if (srslte_cfo_init(&q->file_cfo_correct, 2 * q->sf_len)) { - ERROR("Error initiating CFO\n"); + ERROR("Error initiating CFO"); goto clean_exit; } if (srslte_filesource_init(&q->file_source, file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Error opening file %s\n", file_name); + ERROR("Error opening file %s", file_name); goto clean_exit; } - INFO("Offseting input file by %d samples and %.1f kHz\n", offset_time, offset_freq / 1000); + INFO("Offseting input file by %d samples and %.1f kHz", offset_time, offset_freq / 1000); if (offset_time) { cf_t* file_offset_buffer = srslte_vec_cf_malloc(offset_time * nof_rx_ant); @@ -242,12 +242,10 @@ int srslte_ue_sync_init_multi_decim_mode( q->pss_stable_timeout = DEFAULT_PSS_STABLE_TIMEOUT; if (search_cell) { - /* If the cell is unkown, we search PSS/SSS in 5 ms */ q->nof_recv_sf = 5; } else { - /* If the cell is known, we work on a 1ms basis */ q->nof_recv_sf = 1; } @@ -260,12 +258,12 @@ int srslte_ue_sync_init_multi_decim_mode( if (q->mode == SYNC_MODE_PSS) { if (srslte_sync_init_decim(&q->sfind, q->frame_len, q->frame_len, q->fft_size, q->decimate)) { - ERROR("Error initiating sync find\n"); + ERROR("Error initiating sync find"); goto clean_exit; } if (search_cell) { if (srslte_sync_init(&q->strack, q->frame_len, TRACK_FRAME_SIZE, q->fft_size)) { - ERROR("Error initiating sync track\n"); + ERROR("Error initiating sync track"); goto clean_exit; } } else { @@ -273,7 +271,7 @@ int srslte_ue_sync_init_multi_decim_mode( q->frame_len, SRSLTE_MAX(TRACK_FRAME_SIZE, SRSLTE_CP_LEN_NORM(1, q->fft_size)), q->fft_size)) { - ERROR("Error initiating sync track\n"); + ERROR("Error initiating sync track"); goto clean_exit; } } @@ -334,7 +332,7 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t* q, srslte_cell_t cell) if (q != NULL && srslte_nofprb_isvalid(cell.nof_prb)) { if (cell.nof_prb > q->max_prb) { - ERROR("Error in ue_sync_set_cell(): cell.nof_prb must be lower than initialized\n"); + ERROR("Error in ue_sync_set_cell(): cell.nof_prb must be lower than initialized"); return SRSLTE_ERROR; } @@ -343,11 +341,9 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t* q, srslte_cell_t cell) q->sf_len = SRSLTE_SF_LEN(q->fft_size); if (cell.id == 1000) { - /* If the cell is unkown, we search PSS/SSS in 5 ms */ q->nof_recv_sf = 5; } else { - /* If the cell is known, we work on a 1ms basis */ q->nof_recv_sf = 1; } @@ -361,12 +357,12 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t* q, srslte_cell_t cell) } if (srslte_sync_resize(&q->sfind, q->frame_len, q->frame_len, q->fft_size)) { - ERROR("Error setting cell sync find\n"); + ERROR("Error setting cell sync find"); return SRSLTE_ERROR; } if (cell.id == 1000) { if (srslte_sync_resize(&q->strack, q->frame_len, TRACK_FRAME_SIZE, q->fft_size)) { - ERROR("Error setting cell sync track\n"); + ERROR("Error setting cell sync track"); return SRSLTE_ERROR; } } else { @@ -374,7 +370,7 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t* q, srslte_cell_t cell) q->frame_len, SRSLTE_MAX(TRACK_FRAME_SIZE, SRSLTE_CP_LEN_NORM(1, q->fft_size)), q->fft_size)) { - ERROR("Error setting cell sync track\n"); + ERROR("Error setting cell sync track"); return SRSLTE_ERROR; } } @@ -563,15 +559,14 @@ void srslte_ue_sync_set_agc_period(srslte_ue_sync_t* q, uint32_t period) static int find_peak_ok(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_CHANNELS]) { - if (srslte_sync_sss_detected(&q->sfind)) { /* Get the subframe index (0 or 5) */ q->sf_idx = (srslte_sync_get_sf_idx(&q->sfind) + q->nof_recv_sf) % 10; } else if (srslte_sync_sss_available(&q->sfind)) { - INFO("Found peak at %d, SSS not detected\n", q->peak_idx); + INFO("Found peak at %d, SSS not detected", q->peak_idx); return 0; } else { - INFO("Found peak at %d, No space for SSS. Realigning frame, reading %d samples\n", q->peak_idx, q->peak_idx); + INFO("Found peak at %d, No space for SSS. Realigning frame, reading %d samples", q->peak_idx, q->peak_idx); if (q->recv_callback(q->stream, input_buffer, q->peak_idx, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } @@ -579,7 +574,7 @@ static int find_peak_ok(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_CHANN } q->frame_find_cnt++; - DEBUG("Found peak %d at %d, value %.3f, Cell_id: %d CP: %s\n", + DEBUG("Found peak %d at %d, value %.3f, Cell_id: %d CP: %s", q->frame_find_cnt, q->peak_idx, srslte_sync_get_peak_value(&q->sfind), @@ -589,7 +584,7 @@ static int find_peak_ok(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_CHANN if (q->frame_find_cnt >= q->nof_avg_find_frames || q->peak_idx < 2 * q->fft_size) { // Receive read_len samples until the start of the next subframe (different for FDD and TDD) uint32_t read_len = q->peak_idx + PSS_OFFSET; - INFO("Realigning frame, reading %d samples\n", read_len); + INFO("Realigning frame, reading %d samples", read_len); if (q->recv_callback(q->stream, input_buffer, read_len, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } @@ -622,7 +617,6 @@ static int find_peak_ok(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_CHANN static int track_peak_ok(srslte_ue_sync_t* q, uint32_t track_idx) { - // Get sampling time offset q->last_sample_offset = ((int)track_idx - (int)q->strack.max_offset / 2 - (int)q->strack.fft_size); @@ -638,8 +632,7 @@ static int track_peak_ok(srslte_ue_sync_t* q, uint32_t track_idx) /* Adjust current CFO estimation with PSS * Since sync track has enabled only PSS-based correlation, get_cfo() returns that value only, already filtered. */ - DEBUG( - "TRACK: cfo_current=%f, cfo_strack=%f\n", 15000 * q->cfo_current_value, 15000 * srslte_sync_get_cfo(&q->strack)); + DEBUG("TRACK: cfo_current=%f, cfo_strack=%f", 15000 * q->cfo_current_value, 15000 * srslte_sync_get_cfo(&q->strack)); if (15000 * fabsf(srslte_sync_get_cfo(&q->strack)) > q->cfo_pss_min) { q->cfo_current_value += srslte_sync_get_cfo(&q->strack) * q->cfo_loop_bw_pss; q->pss_stable_cnt = 0; @@ -659,7 +652,7 @@ static int track_peak_ok(srslte_ue_sync_t* q, uint32_t track_idx) q->next_rf_sample_offset = (int)round(q->mean_sample_offset); if (q->next_rf_sample_offset) { - INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, ema=%f, length=%d\n", + INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, ema=%f, length=%d", q->next_rf_sample_offset, q->mean_sample_offset, srslte_ue_sync_get_sfo(q), @@ -672,9 +665,9 @@ static int track_peak_ok(srslte_ue_sync_t* q, uint32_t track_idx) /* If the PSS peak is beyond the frame (we sample too slowly), discard the offseted samples to align next frame */ if (q->next_rf_sample_offset > 0 && q->next_rf_sample_offset < MAX_TIME_OFFSET) { - DEBUG("Positive time offset %d samples.\n", q->next_rf_sample_offset); + DEBUG("Positive time offset %d samples.", q->next_rf_sample_offset); if (q->recv_callback(q->stream, dummy_offset_buffer, (uint32_t)q->next_rf_sample_offset, NULL) < 0) { - ERROR("Error receiving from USRP\n"); + ERROR("Error receiving from USRP"); return SRSLTE_ERROR; } q->next_rf_sample_offset = 0; @@ -689,15 +682,14 @@ static int track_peak_ok(srslte_ue_sync_t* q, uint32_t track_idx) static int track_peak_no(srslte_ue_sync_t* q) { - /* if we missed too many PSS go back to FIND and consider this frame unsynchronized */ q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { - INFO("\n%d frames lost. Going back to FIND\n", (int)q->frame_no_cnt); + INFO("%d frames lost. Going back to FIND", (int)q->frame_no_cnt); q->state = SF_FIND; return 0; } else { - INFO("Tracking peak not found. Peak %.3f, %d lost\n", srslte_sync_get_peak_value(&q->strack), (int)q->frame_no_cnt); + INFO("Tracking peak not found. Peak %.3f, %d lost", srslte_sync_get_peak_value(&q->strack), (int)q->frame_no_cnt); return 1; } } @@ -738,11 +730,10 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && input_buffer != NULL) { - if (q->file_mode) { int n = srslte_filesource_read_multi(&q->file_source, (void**)input_buffer, q->sf_len, q->nof_rx_antennas); if (n < 0) { - ERROR("Error reading input file\n"); + ERROR("Error reading input file"); return SRSLTE_ERROR; } if (n == 0) { @@ -751,7 +742,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, q->sf_idx = 9; n = srslte_filesource_read_multi(&q->file_source, (void**)input_buffer, q->sf_len, q->nof_rx_antennas); if (n < 0) { - ERROR("Error reading input file\n"); + ERROR("Error reading input file"); return SRSLTE_ERROR; } } else { @@ -767,12 +758,11 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, if (q->sf_idx == 10) { q->sf_idx = 0; } - INFO("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); + INFO("Reading %d samples. sf_idx = %d", q->sf_len, q->sf_idx); ret = 1; } else { - if (receive_samples(q, input_buffer, max_num_samples)) { - ERROR("Error receiving samples\n"); + ERROR("Error receiving samples"); return SRSLTE_ERROR; } @@ -827,7 +817,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, } break; default: - ERROR("Unknown sync state %d\n", q->state); + ERROR("Unknown sync state %d", q->state); } } } @@ -841,14 +831,14 @@ int srslte_ue_sync_run_find_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SRS switch (n) { case SRSLTE_SYNC_ERROR: - ERROR("Error finding correlation peak (%d)\n", ret); + ERROR("Error finding correlation peak (%d)", ret); return ret; case SRSLTE_SYNC_FOUND: ret = find_peak_ok(q, input_buffer); break; case SRSLTE_SYNC_FOUND_NOSPACE: /* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */ - INFO("No space for SSS/CP detection. Realigning frame...\n"); + INFO("No space for SSS/CP detection. Realigning frame..."); q->recv_callback(q->stream, dummy_offset_buffer, q->frame_len / 2, NULL); srslte_sync_reset(&q->sfind); ret = SRSLTE_SUCCESS; @@ -859,7 +849,7 @@ int srslte_ue_sync_run_find_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SRS } INFO("SYNC FIND: sf_idx=%d, ret=%d, peak_pos=%d, peak_value=%.2f, mean_cp_cfo=%.2f, mean_pss_cfo=%.2f, " - "total_cfo_khz=%.1f\n", + "total_cfo_khz=%.1f", q->sf_idx, ret, q->peak_idx, @@ -893,7 +883,7 @@ int srslte_ue_sync_run_track_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SR int n = srslte_sync_find(&q->strack, input_buffer[0], pss_idx, &track_idx); switch (n) { case SRSLTE_SYNC_ERROR: - ERROR("Error tracking correlation peak\n"); + ERROR("Error tracking correlation peak"); return SRSLTE_ERROR; case SRSLTE_SYNC_FOUND: ret = track_peak_ok(q, track_idx); @@ -902,7 +892,7 @@ int srslte_ue_sync_run_track_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SR // It's very very unlikely that we fall here because this event should happen at FIND phase only ret = 0; q->state = SF_FIND; - INFO("Warning: No space for SSS/CP while in tracking phase\n"); + INFO("Warning: No space for SSS/CP while in tracking phase"); break; case SRSLTE_SYNC_NOFOUND: ret = track_peak_no(q); @@ -910,7 +900,7 @@ int srslte_ue_sync_run_track_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SR } if (ret == SRSLTE_ERROR) { - ERROR("Error processing tracking peak\n"); + ERROR("Error processing tracking peak"); q->state = SF_FIND; return SRSLTE_SUCCESS; } @@ -918,7 +908,7 @@ int srslte_ue_sync_run_track_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SR q->frame_total_cnt++; INFO("SYNC TRACK: sf_idx=%d, ret=%d, peak_pos=%d, peak_value=%.2f, mean_cp_cfo=%.2f, mean_pss_cfo=%.2f, " - "total_cfo_khz=%.1f\n", + "total_cfo_khz=%.1f", q->sf_idx, ret, track_idx, @@ -927,7 +917,7 @@ int srslte_ue_sync_run_track_pss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SR q->strack.cfo_pss_mean, 15 * srslte_sync_get_cfo(&q->strack)); } else { - INFO("SYNC TRACK: sf_idx=%d, ret=%d, next_state=%d\n", q->sf_idx, ret, q->state); + INFO("SYNC TRACK: sf_idx=%d, ret=%d, next_state=%d", q->sf_idx, ret, q->state); } return 1; ///< 1 means subframe in sync @@ -937,7 +927,7 @@ int srslte_ue_sync_run_find_gnss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_CHANNELS], const uint32_t max_num_samples) { - INFO("Calibration samples received start at %ld + %f\n", q->last_timestamp.full_secs, q->last_timestamp.frac_secs); + INFO("Calibration samples received start at %ld + %f", q->last_timestamp.full_secs, q->last_timestamp.frac_secs); // round to nearest second srslte_timestamp_t ts_next_rx; @@ -945,7 +935,7 @@ int srslte_ue_sync_run_find_gnss_mode(srslte_ue_sync_t* q, ts_next_rx.full_secs++; ts_next_rx.frac_secs = 0.0; - INFO("Next desired recv at %ld + %f\n", ts_next_rx.full_secs, ts_next_rx.frac_secs); + INFO("Next desired recv at %ld + %f", ts_next_rx.full_secs, ts_next_rx.frac_secs); // get difference in time between second rx and now srslte_timestamp_sub(&ts_next_rx, q->last_timestamp.full_secs, q->last_timestamp.frac_secs); @@ -953,7 +943,7 @@ int srslte_ue_sync_run_find_gnss_mode(srslte_ue_sync_t* q, uint64_t align_len = srslte_timestamp_uint64(&ts_next_rx, q->sf_len * 1000); - DEBUG("Difference between first recv is %ld + %f, realigning %" PRIu64 " samples\n", + DEBUG("Difference between first recv is %ld + %f, realigning %" PRIu64 " samples", ts_next_rx.full_secs, ts_next_rx.frac_secs, align_len); @@ -967,26 +957,26 @@ int srslte_ue_sync_run_find_gnss_mode(srslte_ue_sync_t* q, sample_count += actual_rx_len; } - DEBUG("Received %d samples during alignment\n", sample_count); + DEBUG("Received %d samples during alignment", sample_count); // do one normal receive, the first time-aligned subframe if (receive_samples(q, input_buffer, max_num_samples)) { - ERROR("Error receiving samples\n"); + ERROR("Error receiving samples"); return SRSLTE_ERROR; } - INFO("First aligned samples received start at %ld + %f\n", q->last_timestamp.full_secs, q->last_timestamp.frac_secs); + INFO("First aligned samples received start at %ld + %f", q->last_timestamp.full_secs, q->last_timestamp.frac_secs); // switch to track state, from here on, samples should be ms aligned q->state = SF_TRACK; // calculate system timing if (srslte_ue_sync_set_tti_from_timestamp(q, &q->last_timestamp)) { - ERROR("Error deriving timing from received samples\n"); + ERROR("Error deriving timing from received samples"); return SRSLTE_ERROR; } - INFO("SYNC FIND: sfn=%d, sf_idx=%d next_state=%d\n", q->frame_number, q->sf_idx, q->state); + INFO("SYNC FIND: sfn=%d, sf_idx=%d next_state=%d", q->frame_number, q->sf_idx, q->state); return 1; ///< 1 means subframe in sync } @@ -994,25 +984,25 @@ int srslte_ue_sync_run_find_gnss_mode(srslte_ue_sync_t* q, ///< The track function in GNSS mode only needs to increment the system frame number int srslte_ue_sync_run_track_gnss_mode(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_CHANNELS]) { - INFO("TRACK samples received at %ld + %.4f\n", q->last_timestamp.full_secs, q->last_timestamp.frac_secs); + INFO("TRACK samples received at %ld + %.4f", q->last_timestamp.full_secs, q->last_timestamp.frac_secs); // make sure the fractional receive time is ms-aligned uint32_t rx_full_ms = floor(q->last_timestamp.frac_secs * 1e3); double rx_frac_ms = q->last_timestamp.frac_secs - (rx_full_ms / 1e3); int32_t offset_samp = round(rx_frac_ms / (1.0 / (q->sf_len * 1000))); - INFO("rx_full_ms=%d, rx_frac_ms=%f, offset_samp=%d\n", rx_full_ms, rx_frac_ms, offset_samp); + INFO("rx_full_ms=%d, rx_frac_ms=%f, offset_samp=%d", rx_full_ms, rx_frac_ms, offset_samp); if (offset_samp != q->sf_len) { q->next_rf_sample_offset = offset_samp; } if (q->next_rf_sample_offset) { - INFO("Time offset adjustment: %d samples\n", q->next_rf_sample_offset); + INFO("Time offset adjustment: %d samples", q->next_rf_sample_offset); } // update SF index q->sf_idx = ((int)round(q->last_timestamp.frac_secs * 1e3)) % SRSLTE_NOF_SF_X_FRAME; - INFO("SYNC TRACK: sfn=%d, sf_idx=%d, next_state=%d\n", q->frame_number, q->sf_idx, q->state); + INFO("SYNC TRACK: sfn=%d, sf_idx=%d, next_state=%d", q->frame_number, q->sf_idx, q->state); return 1; ///< 1 means subframe in sync } @@ -1027,7 +1017,7 @@ int srslte_ue_sync_set_tti_from_timestamp(srslte_ue_sync_t* q, srslte_timestamp_ { // calculate time_t of Rx time time_t t_cur = rx_timestamp->full_secs; - DEBUG("t_cur=%ld\n", t_cur); + DEBUG("t_cur=%ld", t_cur); // time_t of reference UTC time on 1. Jan 1900 at 0:00 // If we put this date in https://www.epochconverter.com it returns a negative number @@ -1040,11 +1030,11 @@ int srslte_ue_sync_set_tti_from_timestamp(srslte_ue_sync_t* q, srslte_timestamp_ t_ref = mktime(&t); #endif - DEBUG("t_ref=%ld\n", t_ref); + DEBUG("t_ref=%ld", t_ref); static const uint32_t MSECS_PER_SEC = 1000; - DEBUG("diff=%f\n", difftime(t_cur, t_ref)); + DEBUG("diff=%f", difftime(t_cur, t_ref)); double time_diff_secs = difftime(t_cur, t_ref); @@ -1053,11 +1043,11 @@ int srslte_ue_sync_set_tti_from_timestamp(srslte_ue_sync_t* q, srslte_timestamp_ return SRSLTE_ERROR; } - DEBUG("time diff in s %f\n", time_diff_secs); + DEBUG("time diff in s %f", time_diff_secs); // convert to ms and add fractional part double time_diff_msecs = time_diff_secs * MSECS_PER_SEC + rx_timestamp->frac_secs; - DEBUG("time diff in ms %f\n", time_diff_msecs); + DEBUG("time diff in ms %f", time_diff_msecs); // calculate SFN and SF index according to TS 36.331 Sec. 5.10.14 q->frame_number = ((uint32_t)floor(0.1 * (time_diff_msecs - q->sfn_offset))) % 1024; diff --git a/lib/src/phy/ue/ue_sync_nbiot.c b/lib/src/phy/ue/ue_sync_nbiot.c index ad5434ab7..7bbda1d90 100644 --- a/lib/src/phy/ue/ue_sync_nbiot.c +++ b/lib/src/phy/ue/ue_sync_nbiot.c @@ -112,7 +112,7 @@ int srslte_ue_sync_nbiot_init_file_multi(srslte_nbiot_ue_sync_t* q, srslte_sync_nbiot_free(&q->sfind); #endif - INFO("Offseting input file by %d samples and %.1f kHz\n", offset_time, offset_freq / 1000); + INFO("Offseting input file by %d samples and %.1f kHz", offset_time, offset_freq / 1000); srslte_filesource_read(&q->file_source, dummy_buffer_nbiot0, offset_time); srslte_ue_sync_nbiot_reset(q); @@ -162,7 +162,7 @@ int srslte_ue_sync_nbiot_init(srslte_nbiot_ue_sync_t* q, int srslte_ue_sync_nbiot_init_multi(srslte_nbiot_ue_sync_t* q, uint32_t max_prb, - int(recv_callback)(void*, cf_t * [SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + int(recv_callback)(void*, cf_t* [SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), uint32_t nof_rx_antennas, void* stream_handler) { @@ -349,7 +349,7 @@ static int find_peak_ok(srslte_nbiot_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX // set subframe idx to NPSS position q->sf_idx = 5; q->frame_find_cnt++; - DEBUG("Found peak %d at %d, value %.3f, n_id_ncell: %d\n", + DEBUG("Found peak %d at %d, value %.3f, n_id_ncell: %d", q->frame_find_cnt, q->peak_idx, srslte_sync_nbiot_get_peak_value(&q->sfind), @@ -357,7 +357,7 @@ static int find_peak_ok(srslte_nbiot_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX if (q->frame_find_cnt >= q->nof_avg_find_frames || q->peak_idx < 2 * q->fft_size) { int num_drop = (q->peak_idx - SRSLTE_NPSS_CORR_OFFSET + q->frame_len / 2) % q->frame_len; - INFO("Realigning frame, reading %d samples\n", num_drop); + INFO("Realigning frame, reading %d samples", num_drop); /* Receive the rest of the subframe so that we are subframe aligned */ if (q->recv_callback(q->stream, input_buffer, num_drop, &q->last_timestamp) < 0) { return SRSLTE_ERROR; @@ -417,7 +417,7 @@ static int track_peak_ok(srslte_nbiot_ue_sync_t* q, uint32_t track_idx) q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema); if (q->next_rf_sample_offset) { - INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/10-sf, ema=%f, length=%d\n", + INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/10-sf, ema=%f, length=%d", q->next_rf_sample_offset, q->mean_sample_offset, srslte_ue_sync_nbiot_get_sfo(q), @@ -430,7 +430,7 @@ static int track_peak_ok(srslte_nbiot_ue_sync_t* q, uint32_t track_idx) ///< If the NPSS peak is beyond the frame we sample too slow, discard the offseted samples to align next frame if (q->next_rf_sample_offset > 0 && q->next_rf_sample_offset < MAX_TIME_OFFSET) { - DEBUG("Positive time offset %d samples.\n", q->next_rf_sample_offset); + DEBUG("Positive time offset %d samples.", q->next_rf_sample_offset); if (q->recv_callback( q->stream, &dummy_offset_buffer_nbiot[0], (uint32_t)q->next_rf_sample_offset, &q->last_timestamp) < 0) { fprintf(stderr, "Error receiving from USRP\n"); @@ -450,13 +450,13 @@ static int track_peak_no(srslte_nbiot_ue_sync_t* q) ///< if we missed too many NPSS, we go back to FIND and consider this frame unsynchronized q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { - INFO("%d frames lost. Going back to FIND\n", (int)q->frame_no_cnt); + INFO("%d frames lost. Going back to FIND", (int)q->frame_no_cnt); q->nof_recv_sf = 10; q->frame_len = q->nof_recv_sf * q->sf_len; q->state = SF_FIND; return 0; } else { - INFO("Tracking peak not found. Peak %.3f, %d lost\n", + INFO("Tracking peak not found. Peak %.3f, %d lost", srslte_sync_nbiot_get_peak_value(&q->strack), (int)q->frame_no_cnt); /* @@ -527,7 +527,7 @@ int srslte_ue_sync_nbiot_zerocopy_multi(srslte_nbiot_ue_sync_t* q, cf_t** input_ if (q->sf_idx == 10) { q->sf_idx = 0; } - DEBUG("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); + DEBUG("Reading %d samples. sf_idx = %d", q->sf_len, q->sf_idx); ret = 1; } else { if (receive_samples(q, input_buffer)) { diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index a7df0b30b..fc253e3c2 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -61,21 +61,21 @@ int srslte_ue_ul_init(srslte_ue_ul_t* q, cf_t* out_buffer, uint32_t max_prb) ofdm_cfg.freq_shift_f = 0.5f; ofdm_cfg.normalize = true; if (srslte_ofdm_tx_init_cfg(&q->fft, &ofdm_cfg)) { - ERROR("Error initiating FFT\n"); + ERROR("Error initiating FFT"); goto clean_exit; } if (srslte_cfo_init(&q->cfo, MAX_SFLEN)) { - ERROR("Error creating CFO object\n"); + ERROR("Error creating CFO object"); goto clean_exit; } if (srslte_pusch_init_ue(&q->pusch, max_prb)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto clean_exit; } if (srslte_pucch_init_ue(&q->pucch)) { - ERROR("Error creating PUSCH object\n"); + ERROR("Error creating PUSCH object"); goto clean_exit; } q->refsignal = srslte_vec_cf_malloc(2 * SRSLTE_NRE * max_prb); @@ -93,7 +93,7 @@ int srslte_ue_ul_init(srslte_ue_ul_t* q, cf_t* out_buffer, uint32_t max_prb) q->signals_pregenerated = false; ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid parameters\n"); + ERROR("Invalid parameters"); } clean_exit: @@ -140,36 +140,36 @@ int srslte_ue_ul_set_cell(srslte_ue_ul_t* q, srslte_cell_t cell) q->cell = cell; if (srslte_ofdm_tx_set_prb(&q->fft, q->cell.cp, q->cell.nof_prb)) { - ERROR("Error resizing FFT\n"); + ERROR("Error resizing FFT"); return SRSLTE_ERROR; } if (srslte_cfo_resize(&q->cfo, SRSLTE_SF_LEN_PRB(q->cell.nof_prb))) { - ERROR("Error resizing CFO object\n"); + ERROR("Error resizing CFO object"); return SRSLTE_ERROR; } if (srslte_pusch_set_cell(&q->pusch, q->cell)) { - ERROR("Error resizing PUSCH object\n"); + ERROR("Error resizing PUSCH object"); return SRSLTE_ERROR; } if (srslte_pucch_set_cell(&q->pucch, q->cell)) { - ERROR("Error resizing PUSCH object\n"); + ERROR("Error resizing PUSCH object"); return SRSLTE_ERROR; } if (srslte_refsignal_ul_set_cell(&q->signals, q->cell)) { - ERROR("Error resizing srslte_refsignal_ul\n"); + ERROR("Error resizing srslte_refsignal_ul"); return SRSLTE_ERROR; } if (srslte_ra_ul_pusch_hopping_init(&q->hopping, q->cell)) { - ERROR("Error setting hopping procedure cell\n"); + ERROR("Error setting hopping procedure cell"); return SRSLTE_ERROR; } q->signals_pregenerated = false; } ret = SRSLTE_SUCCESS; } else { - ERROR("Invalid cell properties ue_ul: Id=%d, Ports=%d, PRBs=%d\n", cell.id, cell.nof_ports, cell.nof_prb); + ERROR("Invalid cell properties ue_ul: Id=%d, Ports=%d, PRBs=%d", cell.id, cell.nof_ports, cell.nof_prb); } return ret; } @@ -230,7 +230,7 @@ void srslte_ue_ul_pusch_hopping(srslte_ue_ul_t* q, srslte_pusch_grant_t* grant) { if (cfg->ul_cfg.srs.configured && cfg->ul_cfg.hopping.hopping_enabled) { - ERROR("UL SRS and frequency hopping not currently supported\n"); + ERROR("UL SRS and frequency hopping not currently supported"); } return srslte_ra_ul_pusch_hopping(&q->hopping, sf, &cfg->ul_cfg.hopping, grant); } @@ -304,15 +304,13 @@ static void add_srs(srslte_ue_ul_t* q, srslte_ue_ul_cfg_t* cfg, uint32_t tti) static int pusch_encode(srslte_ue_ul_t* q, srslte_ul_sf_cfg_t* sf, srslte_ue_ul_cfg_t* cfg, srslte_pusch_data_t* data) { - int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - srslte_vec_cf_zero(q->sf_symbols, SRSLTE_NOF_RE(q->cell)); if (srslte_pusch_encode(&q->pusch, sf, &cfg->ul_cfg.pusch, data, q->sf_symbols)) { - ERROR("Error encoding PUSCH\n"); + ERROR("Error encoding PUSCH"); return SRSLTE_ERROR; } @@ -325,7 +323,7 @@ static int pusch_encode(srslte_ue_ul_t* q, srslte_ul_sf_cfg_t* sf, srslte_ue_ul_ sf->tti % 10, cfg->ul_cfg.pusch.grant.n_dmrs, q->refsignal)) { - ERROR("Error generating PUSCH DMRS signals\n"); + ERROR("Error generating PUSCH DMRS signals"); return ret; } srslte_refsignal_dmrs_pusch_put(&q->signals, &cfg->ul_cfg.pusch, q->refsignal, q->sf_symbols); @@ -374,7 +372,7 @@ float srslte_ue_ul_pusch_power(srslte_ue_ul_t* q, srslte_ue_ul_cfg_t* cfg, float float f = 0; float pusch_power = 10 * log10f(cfg->ul_cfg.pusch.grant.L_prb) + p0_pusch + alpha * PL + delta + f; - DEBUG("PUSCH: P=%f -- 10M=%f, p0=%f,alpha=%f,PL=%f,\n", + DEBUG("PUSCH: P=%f -- 10M=%f, p0=%f,alpha=%f,PL=%f,", pusch_power, 10 * log10f(cfg->ul_cfg.pusch.grant.L_prb), p0_pusch, @@ -421,7 +419,7 @@ float srslte_ue_ul_pucch_power(srslte_ue_ul_t* q, srslte_ue_ul_cfg_t* cfg, srslt float pucch_power = p0_pucch + PL + h + delta_f + g; - DEBUG("PUCCH: P=%f -- p0=%f, PL=%f, delta_f=%f, h=%f, g=%f\n", pucch_power, p0_pucch, PL, delta_f, h, g); + DEBUG("PUCCH: P=%f -- p0=%f, PL=%f, delta_f=%f, h=%f, g=%f", pucch_power, p0_pucch, PL, delta_f, h, g); return 0; } @@ -430,7 +428,6 @@ static int srs_encode(srslte_ue_ul_t* q, uint32_t tti, srslte_ue_ul_cfg_t* cfg) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q && cfg) { - srslte_vec_cf_zero(q->sf_symbols, SRSLTE_NOF_RE(q->cell)); add_srs(q, cfg, tti); @@ -476,7 +473,7 @@ float srs_power(srslte_ue_ul_t* q, srslte_ue_ul_cfg_t* cfg, float PL) float p_srs = p_srs_offset + 10 * log10f(M_sc) + p0_pusch + alpha * PL + f; - DEBUG("SRS: P=%f -- p_offset=%f, 10M=%f, p0_pusch=%f, alpha=%f, PL=%f, f=%f\n", + DEBUG("SRS: P=%f -- p_offset=%f, 10M=%f, p0_pusch=%f, alpha=%f, PL=%f, f=%f", p_srs, p_srs_offset, 10 * log10f(M_sc), @@ -512,7 +509,7 @@ pucch_encode(srslte_ue_ul_t* q, srslte_ul_sf_cfg_t* sf, srslte_ue_ul_cfg_t* cfg, ret = SRSLTE_ERROR; if (!srslte_pucch_cfg_isvalid(&cfg->ul_cfg.pucch, q->cell.nof_prb)) { - ERROR("Invalid PUCCH configuration\n"); + ERROR("Invalid PUCCH configuration"); return ret; } @@ -525,12 +522,12 @@ pucch_encode(srslte_ue_ul_t* q, srslte_ul_sf_cfg_t* sf, srslte_ue_ul_cfg_t* cfg, srslte_refsignal_srs_pucch_shortened(&q->signals, sf, &cfg->ul_cfg.srs, &cfg->ul_cfg.pucch); if (srslte_pucch_encode(&q->pucch, sf, &cfg->ul_cfg.pucch, &uci_value2, q->sf_symbols)) { - ERROR("Error encoding TB\n"); + ERROR("Error encoding TB"); return ret; } if (srslte_refsignal_dmrs_pucch_gen(&q->signals, sf, &cfg->ul_cfg.pucch, q->refsignal)) { - ERROR("Error generating PUSCH DMRS signals\n"); + ERROR("Error generating PUSCH DMRS signals"); return ret; } srslte_refsignal_dmrs_pucch_put(&q->signals, &cfg->ul_cfg.pucch, q->refsignal, q->sf_symbols); @@ -544,7 +541,7 @@ pucch_encode(srslte_ue_ul_t* q, srslte_ul_sf_cfg_t* sf, srslte_ue_ul_cfg_t* cfg, char txt[256]; srslte_pucch_tx_info(&cfg->ul_cfg.pucch, uci_data, txt, sizeof(txt)); - INFO("[PUCCH] Encoded %s\n", txt); + INFO("[PUCCH] Encoded %s", txt); ret = SRSLTE_SUCCESS; } diff --git a/lib/src/phy/ue/ue_ul_nr.c b/lib/src/phy/ue/ue_ul_nr.c new file mode 100644 index 000000000..0a21950f5 --- /dev/null +++ b/lib/src/phy/ue/ue_ul_nr.c @@ -0,0 +1,240 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/phy/ue/ue_ul_nr.h" +#include "srslte/phy/ch_estimation/dmrs_pucch.h" +#include "srslte/phy/utils/debug.h" +#include + +int srslte_ue_ul_nr_init(srslte_ue_ul_nr_t* q, cf_t* output, const srslte_ue_ul_nr_args_t* args) +{ + if (q == NULL || output == NULL || args == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Initialise memory + SRSLTE_MEM_ZERO(q, srslte_ue_ul_nr_t, 1); + + q->max_prb = args->nof_max_prb; + + q->sf_symbols[0] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(q->max_prb)); + if (q->sf_symbols[0] == NULL) { + ERROR("Malloc"); + return SRSLTE_ERROR; + } + + if (srslte_pusch_nr_init_ue(&q->pusch, &args->pusch) < SRSLTE_SUCCESS) { + ERROR("Initiating PUSCH"); + return SRSLTE_ERROR; + } + + srslte_ofdm_cfg_t fft_cfg = {}; + fft_cfg.nof_prb = args->nof_max_prb; + fft_cfg.symbol_sz = srslte_min_symbol_sz_rb(args->nof_max_prb); + fft_cfg.keep_dc = true; + fft_cfg.in_buffer = q->sf_symbols[0]; + fft_cfg.out_buffer = output; + if (srslte_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSLTE_SUCCESS) { + ERROR("Initiating OFDM"); + return SRSLTE_ERROR; + } + + if (srslte_dmrs_sch_init(&q->dmrs, false) < SRSLTE_SUCCESS) { + ERROR("Error DMRS"); + return SRSLTE_ERROR; + } + + if (srslte_pucch_nr_init(&q->pucch, &args->pucch) < SRSLTE_SUCCESS) { + ERROR("Error UCI\n"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* carrier) +{ + if (q == NULL || carrier == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + q->carrier = *carrier; + + srslte_ofdm_cfg_t fft_cfg = {}; + fft_cfg.nof_prb = carrier->nof_prb; + fft_cfg.symbol_sz = srslte_min_symbol_sz_rb(carrier->nof_prb); + fft_cfg.keep_dc = true; + if (srslte_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSLTE_SUCCESS) { + ERROR("Initiating OFDM"); + return SRSLTE_ERROR; + } + + if (srslte_pusch_nr_set_carrier(&q->pusch, carrier) < SRSLTE_SUCCESS) { + ERROR("Setting PUSCH carrier"); + return SRSLTE_ERROR; + } + + if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier)) { + ERROR("Setting DMRS carrier"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pusch_cfg, + uint8_t* data_) +{ + uint8_t* data[SRSLTE_MAX_TB] = {}; + data[0] = data_; + + // Check inputs + if (q == NULL || pusch_cfg == NULL || data_ == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Fill with zeros the whole resource grid + srslte_vec_cf_zero(q->sf_symbols[0], SRSLTE_SLOT_LEN_RE_NR(q->carrier.nof_prb)); + + // Encode PUSCH + if (srslte_pusch_nr_encode(&q->pusch, pusch_cfg, &pusch_cfg->grant, data, q->sf_symbols) < SRSLTE_SUCCESS) { + ERROR("Encoding PUSCH"); + return SRSLTE_ERROR; + } + + // Put DMRS + if (srslte_dmrs_sch_put_sf(&q->dmrs, slot_cfg, pusch_cfg, &pusch_cfg->grant, q->sf_symbols[0])) { + ERROR("Putting DMRS"); + return SRSLTE_ERROR; + } + + // Generate signal + srslte_ofdm_tx_sf(&q->ifft); + + return SRSLTE_SUCCESS; +} + +static int ue_ul_nr_encode_pucch_format0(srslte_ue_ul_nr_t* q, + const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data) +{ + ERROR("Not implemented"); + return SRSLTE_ERROR; +} + +static int ue_ul_nr_encode_pucch_format1(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot, + const srslte_pucch_nr_common_cfg_t* cfg, + const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data) +{ + uint8_t b[SRSLTE_PUCCH_NR_FORMAT1_MAX_NOF_BITS] = {}; + b[0] = uci_data->value.ack[0]; + uint32_t nof_bits = 1; + + if (srslte_dmrs_pucch_format1_put(&q->pucch, &q->carrier, cfg, slot, resource, q->sf_symbols[0])) { + return SRSLTE_ERROR; + } + + return srslte_pucch_nr_format1_encode(&q->pucch, &q->carrier, cfg, slot, resource, b, nof_bits, q->sf_symbols[0]); +} + +int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t* q, + const srslte_slot_cfg_t* slot_cfg, + const srslte_pucch_nr_common_cfg_t* cfg, + const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data) +{ + // Check inputs + if (q == NULL || slot_cfg == NULL || resource == NULL || uci_data == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Fill with zeros the whole resource grid + srslte_vec_cf_zero(q->sf_symbols[0], SRSLTE_SLOT_LEN_RE_NR(q->carrier.nof_prb)); + + // Actual PUCCH encoding + switch (resource->format) { + case SRSLTE_PUCCH_NR_FORMAT_0: + if (ue_ul_nr_encode_pucch_format0(q, resource, uci_data) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + break; + case SRSLTE_PUCCH_NR_FORMAT_1: + if (ue_ul_nr_encode_pucch_format1(q, slot_cfg, cfg, resource, uci_data) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + break; + case SRSLTE_PUCCH_NR_FORMAT_2: + if (srslte_dmrs_pucch_format2_put(&q->pucch, &q->carrier, cfg, slot_cfg, resource, q->sf_symbols[0])) { + return SRSLTE_ERROR; + } + if (srslte_pucch_nr_format_2_3_4_encode( + &q->pucch, &q->carrier, cfg, slot_cfg, resource, &uci_data->cfg, &uci_data->value, q->sf_symbols[0]) < + SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + break; + case SRSLTE_PUCCH_NR_FORMAT_3: + case SRSLTE_PUCCH_NR_FORMAT_4: + ERROR("PUCCH format %d NOT implemented", (int)resource->format); + break; + case SRSLTE_PUCCH_NR_FORMAT_ERROR: + default: + ERROR("Invalid case"); + break; + } + + // Generate signal + srslte_ofdm_tx_sf(&q->ifft); + + return SRSLTE_SUCCESS; +} + +void srslte_ue_ul_nr_free(srslte_ue_ul_nr_t* q) +{ + if (q == NULL) { + return; + } + srslte_ofdm_tx_free(&q->ifft); + if (q->sf_symbols[0] != NULL) { + free(q->sf_symbols[0]); + } + srslte_pusch_nr_free(&q->pusch); + srslte_dmrs_sch_free(&q->dmrs); + + SRSLTE_MEM_ZERO(q, srslte_ue_ul_nr_t, 1); +} + +int srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len) +{ + int len = 0; + + // Append PDSCH info + len += srslte_pusch_nr_tx_info(&q->pusch, cfg, &cfg->grant, &str[len], str_len - len); + + return len; +} + +int srslte_ue_ul_nr_pucch_info(const srslte_pucch_nr_resource_t* resource, + const srslte_uci_data_nr_t* uci_data, + char* str, + uint32_t str_len) +{ + int len = 0; + + // Append PDSCH info + len += srslte_pucch_nr_tx_info(resource, uci_data, &str[len], str_len - len); + + return len; +} diff --git a/lib/src/phy/ue/ue_ul_nr_data.c b/lib/src/phy/ue/ue_ul_nr_data.c deleted file mode 100644 index 0c527660e..000000000 --- a/lib/src/phy/ue/ue_ul_nr_data.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ -#include "srslte/phy/ue/ue_ul_nr_data.h" -#include "srslte/phy/utils/debug.h" - -typedef struct { - srslte_sch_mapping_type_t mapping; - uint32_t K2; - uint32_t S; - uint32_t L; -} ue_ul_time_resource_t; - -static const ue_ul_time_resource_t ue_ul_default_A_lut[16] = {{srslte_sch_mapping_type_A, 0, 0, 14}, - {srslte_sch_mapping_type_A, 0, 0, 12}, - {srslte_sch_mapping_type_A, 0, 0, 10}, - {srslte_sch_mapping_type_B, 0, 2, 10}, - {srslte_sch_mapping_type_B, 0, 4, 10}, - {srslte_sch_mapping_type_B, 0, 4, 8}, - {srslte_sch_mapping_type_B, 0, 4, 6}, - {srslte_sch_mapping_type_A, 1, 0, 14}, - {srslte_sch_mapping_type_A, 1, 0, 12}, - {srslte_sch_mapping_type_A, 1, 0, 10}, - {srslte_sch_mapping_type_A, 2, 0, 14}, - {srslte_sch_mapping_type_A, 2, 0, 12}, - {srslte_sch_mapping_type_A, 2, 0, 10}, - {srslte_sch_mapping_type_B, 0, 8, 6}, - {srslte_sch_mapping_type_A, 3, 0, 14}, - {srslte_sch_mapping_type_A, 3, 0, 10}}; - -int srslte_ue_ul_nr_pdsch_time_resource_default_A(uint32_t m, srslte_sch_grant_nr_t* grant) -{ - if (grant == NULL) { - return SRSLTE_ERROR_INVALID_INPUTS; - } - - if (m >= 16) { - ERROR("m (%d) is out-of-range\n", m); - return SRSLTE_ERROR_INVALID_INPUTS; - } - - // Select mapping - grant->mapping = ue_ul_default_A_lut[m].mapping; - grant->k2 = ue_ul_default_A_lut[m].K2; - grant->S = ue_ul_default_A_lut[m].S; - grant->L = ue_ul_default_A_lut[m].L; - - return SRSLTE_SUCCESS; -} - -int srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg, - srslte_sch_grant_nr_t* grant) -{ - if (cfg == NULL || grant == NULL) { - return SRSLTE_ERROR_INVALID_INPUTS; - } - - /* According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure: - * For PUSCH scheduled by DCI format 0_0 or by activation DCI format 0_0 with CRC scrambled by CS-RNTI, the UE - * shall assume the number of DM-RS CDM groups without data is 1 which corresponds to CDM group 0 for the case of - * PUSCH with allocation duration of 2 or less OFDM symbols with transform precoding disabled, the UE shall assume - * that the number of DM-RS CDM groups without data is 3 which corresponds to CDM group {0,1,2} for the case of PUSCH - * scheduled by activation DCI format 0_0 and the dmrs-Type in cg-DMRS-Configuration equal to 'type2' and the PUSCH - * allocation duration being more than 2 OFDM symbols, and the UE shall assume that the number of DM-RS CDM groups - * without data is 2 which corresponds to CDM group {0,1} for all other cases. - */ - if (grant->L <= 2 && !cfg->enable_transform_precoder) { - grant->nof_dmrs_cdm_groups_without_data = 1; - // } else if (grant->L > 2 && cfg->dmrs_cg.type == srslte_dmrs_sch_type_2){ - // grant->nof_dmrs_cdm_groups_without_data = 3; - } else { - grant->nof_dmrs_cdm_groups_without_data = 2; - } - - return SRSLTE_SUCCESS; -} \ No newline at end of file diff --git a/lib/src/phy/utils/convolution.c b/lib/src/phy/utils/convolution.c index 745f2d496..4acc2f880 100644 --- a/lib/src/phy/utils/convolution.c +++ b/lib/src/phy/utils/convolution.c @@ -44,15 +44,15 @@ int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t* q, uint32_t input_len, uint32_ return SRSLTE_ERROR; } if (srslte_dft_plan(&q->input_plan, q->output_len, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error initiating input plan\n"); + ERROR("Error initiating input plan"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->filter_plan, q->output_len, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error initiating filter plan\n"); + ERROR("Error initiating filter plan"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->output_plan, q->output_len, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { - ERROR("Error initiating output plan\n"); + ERROR("Error initiating output plan"); return SRSLTE_ERROR; } srslte_dft_plan_set_norm(&q->input_plan, true); @@ -65,7 +65,7 @@ int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t* q, uint32_t input_len, uint32_ int srslte_conv_fft_cc_replan(srslte_conv_fft_cc_t* q, uint32_t input_len, uint32_t filter_len) { if (input_len > q->max_input_len || filter_len > q->max_filter_len) { - ERROR("Error in conv_fft_cc_replan(): input_len and filter_len must be lower than initialized\n"); + ERROR("Error in conv_fft_cc_replan(): input_len and filter_len must be lower than initialized"); return -1; } @@ -77,15 +77,15 @@ int srslte_conv_fft_cc_replan(srslte_conv_fft_cc_t* q, uint32_t input_len, uint3 return SRSLTE_ERROR; } if (srslte_dft_replan(&q->input_plan, q->output_len)) { - ERROR("Error initiating input plan\n"); + ERROR("Error initiating input plan"); return SRSLTE_ERROR; } if (srslte_dft_replan(&q->filter_plan, q->output_len)) { - ERROR("Error initiating filter plan\n"); + ERROR("Error initiating filter plan"); return SRSLTE_ERROR; } if (srslte_dft_replan(&q->output_plan, q->output_len)) { - ERROR("Error initiating output plan\n"); + ERROR("Error initiating output plan"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -121,7 +121,6 @@ uint32_t srslte_conv_fft_cc_run_opt(srslte_conv_fft_cc_t* q, const cf_t* input, uint32_t srslte_conv_fft_cc_run(srslte_conv_fft_cc_t* q, const cf_t* input, const cf_t* filter, cf_t* output) { - srslte_dft_run_c(&q->filter_plan, filter, q->filter_fft); return srslte_conv_fft_cc_run_opt(q, input, q->filter_fft, output); diff --git a/lib/src/phy/utils/ringbuffer.c b/lib/src/phy/utils/ringbuffer.c index f66570c8d..6660ef59e 100644 --- a/lib/src/phy/utils/ringbuffer.c +++ b/lib/src/phy/utils/ringbuffer.c @@ -119,7 +119,7 @@ int srslte_ringbuffer_write_timed_block(srslte_ringbuffer_t* q, void* p, int nof struct timeval now; if (q == NULL || q->buffer == NULL) { - ERROR("Invalid inputs\n"); + ERROR("Invalid inputs"); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -139,7 +139,7 @@ int srslte_ringbuffer_write_timed_block(srslte_ringbuffer_t* q, void* p, int nof pthread_cond_wait(&q->read_cvar, &q->mutex); } else { w_bytes = q->capacity - q->count; - ERROR("Buffer overrun: lost %d bytes\n", nof_bytes - w_bytes); + ERROR("Buffer overrun: lost %d bytes", nof_bytes - w_bytes); } } if (ret == ETIMEDOUT) { diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 684bd47bd..766752124 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -365,7 +365,7 @@ void srslte_vec_sprint_hex(char* str, const uint32_t max_str_len, uint8_t* x, co nbytes = len / 8; // check that hex string fits in buffer (every byte takes 3 characters, plus brackets) if ((3 * (len / 8 + ((len % 8) ? 1 : 0))) + 2 >= max_str_len) { - ERROR("Buffer too small for printing hex string (max_str_len=%d, payload_len=%d).\n", max_str_len, len); + ERROR("Buffer too small for printing hex string (max_str_len=%d, payload_len=%d).", max_str_len, len); return; } @@ -383,6 +383,36 @@ void srslte_vec_sprint_hex(char* str, const uint32_t max_str_len, uint8_t* x, co str[max_str_len - 1] = 0; } +void srslte_vec_sprint_bin(char* str, const uint32_t max_str_len, const uint8_t* x, const uint32_t len) +{ + // Trim maximum size + uint32_t N = SRSLTE_MIN(max_str_len - 1, len); + + // If the number of bits does not fit in the string, leave space for "..." if possible + if (N < len) { + if (N >= 3) { + N -= 3; + } else { + N = 0; + } + } + + // Write 1s and 0s + for (uint32_t i = 0; i < N; i++) { + str[i] = x[i] == 0 ? '0' : '1'; + } + + // Write "..." if all 1s and 0s did not fit + if (N < len) { + for (uint32_t i = N; i < max_str_len - 1; i++) { + str[i] = '.'; + } + str[max_str_len - 1] = 0; + } else { + str[N] = 0; + } +} + void srslte_vec_save_file(char* filename, const void* buffer, const uint32_t len) { FILE* f; diff --git a/lib/src/radio/CMakeLists.txt b/lib/src/radio/CMakeLists.txt index 6a0d47078..063159558 100644 --- a/lib/src/radio/CMakeLists.txt +++ b/lib/src/radio/CMakeLists.txt @@ -19,7 +19,7 @@ # if(RF_FOUND) - add_library(srslte_radio STATIC radio.cc radio_null.cc channel_mapping.cc) + add_library(srslte_radio STATIC radio.cc channel_mapping.cc) target_link_libraries(srslte_radio srslte_rf srslte_common) INSTALL(TARGETS srslte_radio DESTINATION ${LIBRARY_DIR}) endif(RF_FOUND) diff --git a/lib/src/radio/channel_mapping.cc b/lib/src/radio/channel_mapping.cc index 83d837b0e..1c9476ca6 100644 --- a/lib/src/radio/channel_mapping.cc +++ b/lib/src/radio/channel_mapping.cc @@ -36,7 +36,7 @@ bool channel_mapping::allocate_freq(const uint32_t& logical_ch, const float& fre std::lock_guard lock(mutex); if (allocated_channels.count(logical_ch)) { - ERROR("allocate_freq: Carrier logical_ch=%d already allocated to channel=%d\n", + ERROR("allocate_freq: Carrier logical_ch=%d already allocated to channel=%d", logical_ch, allocated_channels[logical_ch].carrier_idx); return false; @@ -50,7 +50,7 @@ bool channel_mapping::allocate_freq(const uint32_t& logical_ch, const float& fre return true; } } - ERROR("allocate_freq: No channels available for frequency=%.1f %s\n", freq, to_string().c_str()); + ERROR("allocate_freq: No channels available for frequency=%.1f %s", freq, to_string().c_str()); return false; } diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 34b04011d..45c6229f4 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -28,7 +28,7 @@ namespace srslte { -radio::radio(srslte::log_filter* log_h_) : logger(nullptr), log_h(log_h_), zeros(nullptr) +radio::radio() : zeros(nullptr) { zeros = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX); srslte_vec_cf_zero(zeros, SRSLTE_SF_LEN_MAX); @@ -38,15 +38,6 @@ radio::radio(srslte::log_filter* log_h_) : logger(nullptr), log_h(log_h_), zeros } } -radio::radio(srslte::logger* logger_) : logger(logger_), log_h(nullptr), zeros(nullptr) -{ - zeros = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX); - srslte_vec_cf_zero(zeros, SRSLTE_SF_LEN_MAX); - for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) { - dummy_buffers[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX); - } -} - radio::~radio() { if (zeros) { @@ -74,24 +65,15 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) phy = phy_; // Init log - if (log_h == nullptr) { - if (logger != nullptr) { - log_local.init("RF ", logger); - log_local.set_level(args.log_level); - log_h = &log_local; - } else { - fprintf(stderr, "Must all radio constructor with either logger or log_filter\n"); - return SRSLTE_ERROR; - } - } + logger.set_level(srslog::str_to_basic_level(args.log_level)); if (args.nof_antennas > SRSLTE_MAX_PORTS) { - log_h->error("Maximum number of antennas exceeded (%d > %d)\n", args.nof_antennas, SRSLTE_MAX_PORTS); + logger.error("Maximum number of antennas exceeded (%d > %d)", args.nof_antennas, SRSLTE_MAX_PORTS); return SRSLTE_ERROR; } if (args.nof_carriers > SRSLTE_MAX_CARRIERS) { - log_h->error("Maximum number of carriers exceeded (%d > %d)\n", args.nof_carriers, SRSLTE_MAX_CARRIERS); + logger.error("Maximum number of carriers exceeded (%d > %d)", args.nof_carriers, SRSLTE_MAX_CARRIERS); return SRSLTE_ERROR; } @@ -143,7 +125,7 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) // Init and start Radios for (uint32_t device_idx = 0; device_idx < (uint32_t)device_args_list.size(); device_idx++) { if (not open_dev(device_idx, args.device_name, device_args_list[device_idx])) { - log_h->error("Error opening RF device %d\n", device_idx); + logger.error("Error opening RF device %d", device_idx); return SRSLTE_ERROR; } } @@ -188,11 +170,11 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) uint32_t rf_device_idx = phys_antenna_idx / nof_channels_x_dev; uint32_t rf_channel_idx = phys_antenna_idx % nof_channels_x_dev; - log_h->info( - "Setting individual tx_gain=%.1f on dev=%d ch=%d\n", args.tx_gain_ch[i], rf_device_idx, rf_channel_idx); + logger.info( + "Setting individual tx_gain=%.1f on dev=%d ch=%d", args.tx_gain_ch[i], rf_device_idx, rf_channel_idx); if (srslte_rf_set_tx_gain_ch(&rf_devices[rf_device_idx], rf_channel_idx, args.tx_gain_ch[i]) < 0) { - log_h->error( - "Setting channel tx_gain=%.1f on dev=%d ch=%d\n", args.tx_gain_ch[i], rf_device_idx, rf_channel_idx); + logger.error( + "Setting channel tx_gain=%.1f on dev=%d ch=%d", args.tx_gain_ch[i], rf_device_idx, rf_channel_idx); } } } @@ -208,23 +190,24 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) uint32_t rf_device_idx = phys_antenna_idx / nof_channels_x_dev; uint32_t rf_channel_idx = phys_antenna_idx % nof_channels_x_dev; - log_h->info( - "Setting individual rx_gain=%.1f on dev=%d ch=%d\n", args.rx_gain_ch[i], rf_device_idx, rf_channel_idx); + logger.info( + "Setting individual rx_gain=%.1f on dev=%d ch=%d", args.rx_gain_ch[i], rf_device_idx, rf_channel_idx); if (srslte_rf_set_rx_gain_ch(&rf_devices[rf_device_idx], rf_channel_idx, args.rx_gain_ch[i]) < 0) { - log_h->error( - "Setting channel rx_gain=%.1f on dev=%d ch=%d\n", args.rx_gain_ch[i], rf_device_idx, rf_channel_idx); + logger.error( + "Setting channel rx_gain=%.1f on dev=%d ch=%d", args.rx_gain_ch[i], rf_device_idx, rf_channel_idx); } } } } - // Set resampler buffers to 5 ms + // It is not expected that any application tries to receive more than max_resamp_buf_sz_ms if (std::isnormal(fix_srate_hz)) { + size_t resamp_buf_sz = (max_resamp_buf_sz_ms * fix_srate_hz) / 1000; for (auto& buf : rx_buffer) { - buf.resize(size_t(fix_srate_hz / 200)); + buf.resize(resamp_buf_sz); } for (auto& buf : tx_buffer) { - buf.resize(size_t(fix_srate_hz / 200)); + buf.resize(resamp_buf_sz); } } @@ -293,7 +276,7 @@ bool radio::start_agc(bool tx_gain_same_rx) } for (srslte_rf_t& rf_device : rf_devices) { if (srslte_rf_start_gain_thread(&rf_device, tx_gain_same_rx)) { - ERROR("Error starting AGC Thread RF device\n"); + ERROR("Error starting AGC Thread RF device"); return false; } } @@ -307,15 +290,31 @@ bool radio::rx_now(rf_buffer_interface& buffer, rf_timestamp_interface& rxd_time rf_buffer_t buffer_rx; uint32_t ratio = SRSLTE_MAX(1, decimators[0].ratio); + // Calculate number of samples, considering the decimation ratio + uint32_t nof_samples = buffer.get_nof_samples() * ratio; + + // Check decimation buffer protection + if (ratio > 1 && nof_samples > rx_buffer[0].size()) { + // This is a corner case that could happen during sample rate change transitions, as it does not have a negative + // impact, log it as info. + logger.info(fmt::format("Rx number of samples ({}/{}) exceeds buffer size ({})\n", + buffer.get_nof_samples(), + buffer.get_nof_samples() * ratio, + rx_buffer[0].size())); + + // Limit number of samples to receive + nof_samples = rx_buffer[0].size(); + } + + // Set new buffer size + buffer_rx.set_nof_samples(nof_samples); + // If the interpolator have been set, interpolate for (uint32_t ch = 0; ch < nof_channels; ch++) { // Use rx buffer if decimator is required buffer_rx.set(ch, ratio > 1 ? rx_buffer[ch].data() : buffer.get(ch)); } - // Set new buffer size - buffer_rx.set_nof_samples(buffer.get_nof_samples() * ratio); - if (not radio_is_streaming) { for (srslte_rf_t& rf_device : rf_devices) { srslte_rf_start_rx_stream(&rf_device, false); @@ -363,7 +362,7 @@ bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& buffer } if (not map_channels(rx_channel_mapping, device_idx, 0, buffer, radio_buffers)) { - log_h->error("Mapping logical channels to physical channels for transmission\n"); + logger.error("Mapping logical channels to physical channels for transmission"); return false; } @@ -407,19 +406,36 @@ bool radio::tx(rf_buffer_interface& buffer, const rf_timestamp_interface& tx_tim { bool ret = true; std::unique_lock lock(tx_mutex); + uint32_t ratio = interpolators[0].ratio; + + // Get number of samples at the low rate + uint32_t nof_samples = buffer.get_nof_samples(); + + // Check that number of the interpolated samples does not exceed the buffer size + if (ratio > 1 && nof_samples * ratio > tx_buffer[0].size()) { + // This is a corner case that could happen during sample rate change transitions, as it does not have a negative + // impact, log it as info. + logger.info(fmt::format("Tx number of samples ({}/{}) exceeds buffer size ({})\n", + buffer.get_nof_samples(), + buffer.get_nof_samples() * ratio, + tx_buffer[0].size())); + + // Limit number of samples to transmit + nof_samples = tx_buffer[0].size() / ratio; + } // If the interpolator have been set, interpolate if (interpolators[0].ratio > 1) { for (uint32_t ch = 0; ch < nof_channels; ch++) { // Perform actual interpolation - srslte_resampler_fft_run(&interpolators[ch], buffer.get(ch), tx_buffer[ch].data(), buffer.get_nof_samples()); + srslte_resampler_fft_run(&interpolators[ch], buffer.get(ch), tx_buffer[ch].data(), nof_samples); // Set the buffer pointer buffer.set(ch, tx_buffer[ch].data()); } - // Set new buffer size - buffer.set_nof_samples(buffer.get_nof_samples() * interpolators[0].ratio); + // Set buffer size after applying the interpolation + buffer.set_nof_samples(nof_samples * ratio); } for (uint32_t device_idx = 0; device_idx < (uint32_t)rf_devices.size(); device_idx++) { @@ -451,7 +467,7 @@ bool radio::open_dev(const uint32_t& device_idx, const std::string& device_name, dev_args ? dev_args : "default"); if (srslte_rf_open_devname(rf_device, dev_name, dev_args, nof_channels_x_dev)) { - log_h->error("Error opening RF device\n"); + logger.error("Error opening RF device"); return false; } @@ -508,7 +524,7 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons nof_samples = nof_samples - past_nsamples; // Subtracts the number of trimmed samples // Prints discarded samples - log_h->debug("Detected RF overlap of %.1f us. Discarding %d samples. Power=%+.1f dBfs\n", + logger.debug("Detected RF overlap of %.1f us. Discarding %d samples. Power=%+.1f dBfs", srslte_timestamp_real(&ts_overlap) * 1.0e6, past_nsamples, srslte_convert_power_to_dB(srslte_vec_avg_power_cf(&buffer.get(0)[nof_samples], past_nsamples))); @@ -516,10 +532,10 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons } else if (past_nsamples < 0 and not is_start_of_burst) { // if the gap is bigger than TX_MAX_GAP_ZEROS, stop burst if (fabs(srslte_timestamp_real(&ts_overlap)) > tx_max_gap_zeros) { - log_h->info("Detected RF gap of %.1f us. Sending end-of-burst.\n", srslte_timestamp_real(&ts_overlap) * 1.0e6); + logger.info("Detected RF gap of %.1f us. Sending end-of-burst.", srslte_timestamp_real(&ts_overlap) * 1.0e6); tx_end(); } else { - log_h->debug("Detected RF gap of %.1f us. Tx'ing zeroes.\n", srslte_timestamp_real(&ts_overlap) * 1.0e6); + logger.debug("Detected RF gap of %.1f us. Tx'ing zeroes.", srslte_timestamp_real(&ts_overlap) * 1.0e6); // Otherwise, transmit zeros uint32_t gap_nsamples = abs(past_nsamples); while (gap_nsamples > 0) { @@ -559,7 +575,7 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons } if (not map_channels(tx_channel_mapping, device_idx, sample_offset, buffer, radio_buffers)) { - log_h->error("Mapping logical channels to physical channels for transmission\n"); + logger.error("Mapping logical channels to physical channels for transmission"); return false; } @@ -606,7 +622,7 @@ void radio::set_rx_freq(const uint32_t& carrier_idx, const double& freq) // Map carrier index to physical channel if (rx_channel_mapping.allocate_freq(carrier_idx, freq)) { channel_mapping::device_mapping_t device_mapping = rx_channel_mapping.get_device_mapping(carrier_idx); - log_h->info("Mapping RF channel %d (device=%d, channel=%d) to logical carrier %d on f_rx=%.1f MHz\n", + logger.info("Mapping RF channel %d (device=%d, channel=%d) to logical carrier %d on f_rx=%.1f MHz", device_mapping.carrier_idx, device_mapping.device_idx, device_mapping.channel_idx, @@ -620,16 +636,16 @@ void radio::set_rx_freq(const uint32_t& carrier_idx, const double& freq) srslte_rf_set_rx_freq(&rf_devices[dm.device_idx], dm.channel_idx, freq + freq_offset); } } else { - log_h->error("set_rx_freq: physical_channel_idx=%d for %d antennas exceeds maximum channels (%d)\n", + logger.error("set_rx_freq: physical_channel_idx=%d for %d antennas exceeds maximum channels (%d)", device_mapping.carrier_idx, nof_antennas, nof_channels); } } else { - log_h->info("RF Rx channel %d already on freq\n", device_mapping.carrier_idx); + logger.info("RF Rx channel %d already on freq", device_mapping.carrier_idx); } } else { - log_h->error("set_rx_freq: Could not allocate frequency %.1f MHz to carrier %d\n", freq / 1e6, carrier_idx); + logger.error("set_rx_freq: Could not allocate frequency %.1f MHz to carrier %d", freq / 1e6, carrier_idx); } } @@ -655,7 +671,6 @@ void radio::set_rx_gain_th(const float& gain) void radio::set_rx_srate(const double& srate) { - if (!is_initialized) { return; } @@ -723,7 +738,7 @@ void radio::set_tx_freq(const uint32_t& carrier_idx, const double& freq) // Map carrier index to physical channel if (tx_channel_mapping.allocate_freq(carrier_idx, freq)) { channel_mapping::device_mapping_t device_mapping = tx_channel_mapping.get_device_mapping(carrier_idx); - log_h->info("Mapping RF channel %d (device=%d, channel=%d) to logical carrier %d on f_tx=%.1f MHz\n", + logger.info("Mapping RF channel %d (device=%d, channel=%d) to logical carrier %d on f_tx=%.1f MHz", device_mapping.carrier_idx, device_mapping.device_idx, device_mapping.channel_idx, @@ -738,16 +753,16 @@ void radio::set_tx_freq(const uint32_t& carrier_idx, const double& freq) srslte_rf_set_tx_freq(&rf_devices[device_mapping.device_idx], device_mapping.channel_idx, freq + freq_offset); } } else { - log_h->error("set_tx_freq: physical_channel_idx=%d for %d antennas exceeds maximum channels (%d)\n", + logger.error("set_tx_freq: physical_channel_idx=%d for %d antennas exceeds maximum channels (%d)", device_mapping.carrier_idx, nof_antennas, nof_channels); } } else { - log_h->info("RF Tx channel %d already on freq\n", device_mapping.carrier_idx); + logger.info("RF Tx channel %d already on freq", device_mapping.carrier_idx); } } else { - log_h->error("set_tx_freq: Could not allocate frequency %.1f MHz to carrier %d\n", freq / 1e6, carrier_idx); + logger.error("set_tx_freq: Could not allocate frequency %.1f MHz to carrier %d", freq / 1e6, carrier_idx); } } @@ -779,11 +794,9 @@ double radio::get_dev_cal_tx_adv_sec(const std::string& device_name) int nsamples = 0; /* Set time advance for each known device if in auto mode */ if (tx_adv_auto) { - /* This values have been calibrated using the prach_test_usrp tool in srsLTE */ if (device_name == "uhd_b200") { - double srate_khz = round(cur_tx_srate / 1e3); if (srate_khz == 1.92e3) { // 6 PRB @@ -856,11 +869,9 @@ double radio::get_dev_cal_tx_adv_sec(const std::string& device_name) } } else if (device_name == "uhd_x300") { - // In X300 TX/RX offset is independent of sampling rate nsamples = 45; } else if (device_name == "bladerf") { - double srate_khz = round(cur_tx_srate / 1e3); if (srate_khz == 1.92e3) { nsamples = 16; @@ -952,27 +963,26 @@ void radio::handle_rf_msg(srslte_rf_error_t error) if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { rf_metrics.rf_o++; rf_metrics.rf_error = true; - log_h->info("Overflow\n"); + logger.info("Overflow"); // inform PHY about overflow phy->radio_overflow(); } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_UNDERFLOW) { rf_metrics.rf_u++; rf_metrics.rf_error = true; - log_h->info("Underflow\n"); + logger.info("Underflow"); } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_LATE) { rf_metrics.rf_l++; rf_metrics.rf_error = true; - log_h->info("Late (detected in %s)\n", error.opt ? "rx call" : "asynchronous thread"); + logger.info("Late (detected in %s)", error.opt ? "rx call" : "asynchronous thread"); } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_RX) { - log_h->error("Fatal radio error occured.\n"); + logger.error("Fatal radio error occured."); phy->radio_failure(); } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OTHER) { std::string str(error.msg); str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); str.erase(std::remove(str.begin(), str.end(), '\r'), str.end()); - str.push_back('\n'); - log_h->info("%s\n", str.c_str()); + logger.info("%s", str.c_str()); } } @@ -1037,7 +1047,7 @@ bool radio::config_rf_channels(const rf_args_t& args) // Parse DL band for this channel c.band.set(args.ch_rx_bands[i].min, args.ch_rx_bands[i].max); dl_rf_channels.push_back(c); - log_h->info("Configuring physical DL channel %d with band-pass filter (%.1f, %.1f)\n", + logger.info("Configuring physical DL channel %d with band-pass filter (%.1f, %.1f)", i, c.band.get_low(), c.band.get_high()); @@ -1045,7 +1055,7 @@ bool radio::config_rf_channels(const rf_args_t& args) // Parse UL band for this channel c.band.set(args.ch_tx_bands[i].min, args.ch_tx_bands[i].max); ul_rf_channels.push_back(c); - log_h->info("Configuring physical UL channel %d with band-pass filter (%.1f, %.1f)\n", + logger.info("Configuring physical UL channel %d with band-pass filter (%.1f, %.1f)", i, c.band.get_low(), c.band.get_high()); diff --git a/lib/src/radio/test/benchmark_radio.cc b/lib/src/radio/test/benchmark_radio.cc index 6d261606c..b7fe6b1ec 100644 --- a/lib/src/radio/test/benchmark_radio.cc +++ b/lib/src/radio/test/benchmark_radio.cc @@ -44,7 +44,6 @@ using namespace srslte; static std::array radios_args = {}; static char radio_device[64]; -static log_filter log_h; static std::string file_pattern = "radio%d.dat"; static double freq = 2630e6; static uint32_t nof_radios = 1; @@ -216,7 +215,6 @@ static void* plot_thread_run(void* arg) static int init_plots(uint32_t frame_size) { - if (sem_init(&plot_sem, 0, 0)) { perror("sem_init"); exit(-1); @@ -227,7 +225,7 @@ static int init_plots(uint32_t frame_size) uint32_t plot_idx = r * nof_ports + p; fft_plot_buffer[plot_idx] = srslte_vec_cf_malloc(frame_size); if (!fft_plot_buffer[plot_idx]) { - ERROR("Error: Allocating buffer\n"); + ERROR("Error: Allocating buffer"); return SRSLTE_ERROR; } } @@ -235,12 +233,12 @@ static int init_plots(uint32_t frame_size) fft_plot_temp = srslte_vec_f_malloc(frame_size); if (!fft_plot_temp) { - ERROR("Error: Allocating buffer\n"); + ERROR("Error: Allocating buffer"); return SRSLTE_ERROR; } if (srslte_dft_plan_c(&dft_spectrum, frame_size, SRSLTE_DFT_FORWARD)) { - ERROR("Creating DFT spectrum plan\n"); + ERROR("Creating DFT spectrum plan"); return SRSLTE_ERROR; } @@ -302,7 +300,7 @@ static void* radio_thread_run(void* arg) /* Instanciate and allocate memory */ printf("Instantiating objects and allocating memory...\n"); for (uint32_t r = 0; r < nof_radios; r++) { - radio_h[r] = new radio(&log_h); + radio_h[r] = new radio; if (!radio_h[r]) { fprintf(stderr, "Error: Calling radio constructor\n"); goto clean_exit; @@ -317,7 +315,7 @@ static void* radio_thread_run(void* arg) for (uint32_t p = 0; p < nof_ports; p++) { buffers[r][p] = srslte_vec_cf_malloc(frame_size); if (!buffers[r][p]) { - ERROR("Error: Allocating buffer (%d,%d)\n", r, p); + ERROR("Error: Allocating buffer (%d,%d)", r, p); goto clean_exit; } } @@ -371,9 +369,9 @@ static void* radio_thread_run(void* arg) if (capture) { for (uint32_t r = 0; r < nof_radios; r++) { snprintf(filename, 256, file_pattern.c_str(), r); - INFO("Opening filesink %s for radio %d\n", filename, r); + INFO("Opening filesink %s for radio %d", filename, r); if (srslte_filesink_init(&filesink[r], filename, SRSLTE_COMPLEX_FLOAT_BIN)) { - ERROR("Initiating filesink for radio %d\n", r); + ERROR("Initiating filesink for radio %d", r); goto clean_exit; } } @@ -383,11 +381,11 @@ static void* radio_thread_run(void* arg) if (measure_delay) { if (nof_radios > 1) { if (srslte_dft_plan_c(&dft_plan, frame_size, SRSLTE_DFT_FORWARD)) { - ERROR("Creating DFT plan\n"); + ERROR("Creating DFT plan"); goto clean_exit; } if (srslte_dft_plan_c(&idft_plan, frame_size, SRSLTE_DFT_BACKWARD)) { - ERROR("Creating IDFT plan\n"); + ERROR("Creating IDFT plan"); goto clean_exit; } } else { @@ -499,7 +497,7 @@ static void* radio_thread_run(void* arg) } delay_idx[r] += relative_delay; - INFO("Radio %d relative delay is %d sample in frame %d/%d (average %.1f)\n", + INFO("Radio %d relative delay is %d sample in frame %d/%d (average %.1f)", r, relative_delay, i + 1, @@ -519,7 +517,7 @@ static void* radio_thread_run(void* arg) gap = (int32_t)round(srslte_timestamp_real(&ts_diff) * current_rate) - (int32_t)frame_size; if (gap != 0) { - INFO("Timestamp gap (%d samples) detected! Frame %d/%d. ts=%.9f+%.9f=%.9f\n", + INFO("Timestamp gap (%d samples) detected! Frame %d/%d. ts=%.9f+%.9f=%.9f", gap, i + 1, nof_frames, @@ -612,6 +610,8 @@ int main(int argc, char** argv) // Parse args parse_args(argc, argv); + srslog::init(); + if (pthread_create(&radio_thread, NULL, radio_thread_run, NULL)) { perror("pthread_create"); exit(-1); diff --git a/lib/src/srslog/formatters/text_formatter.cpp b/lib/src/srslog/formatters/text_formatter.cpp index 442a7be83..58244887f 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -69,7 +69,7 @@ static void format_metadata(const detail::log_entry_metadata& metadata, // Format optional fields if present. if (!metadata.log_name.empty()) { - fmt::format_to(buffer, "[{: <4.4}] ", metadata.log_name); + fmt::format_to(buffer, "[{: <4}] ", metadata.log_name); } if (metadata.log_tag != '\0') { fmt::format_to(buffer, "[{}] ", metadata.log_tag); diff --git a/lib/src/srslog/log_backend_impl.h b/lib/src/srslog/log_backend_impl.h index 3d91744de..18421d3c0 100644 --- a/lib/src/srslog/log_backend_impl.h +++ b/lib/src/srslog/log_backend_impl.h @@ -40,9 +40,9 @@ public: void start() override { worker.start(); } - void push(detail::log_entry&& entry) override + bool push(detail::log_entry&& entry) override { - queue.push(std::move(entry)); + return queue.push(std::move(entry)); } bool is_running() const override { return worker.is_running(); } diff --git a/lib/src/srslog/srslog.cpp b/lib/src/srslog/srslog.cpp index ed3b12449..75ad79260 100644 --- a/lib/src/srslog/srslog.cpp +++ b/lib/src/srslog/srslog.cpp @@ -210,7 +210,10 @@ void srslog::flush() cmd.flush_cmd = std::unique_ptr( new detail::flush_backend_cmd{completion_flag, std::move(sinks)}); - instance.get_backend().push(std::move(cmd)); + // Make sure the flush command gets into the backend, otherwise we will be + // stuck waiting forever for the command to succeed. + while (!instance.get_backend().push(std::move(cmd))) { + } // Block the caller thread until we are signaled that the flush is completed. while (!completion_flag) { diff --git a/lib/src/srslog/srslog_c.cpp b/lib/src/srslog/srslog_c.cpp index edd2d6c53..211f22205 100644 --- a/lib/src/srslog/srslog_c.cpp +++ b/lib/src/srslog/srslog_c.cpp @@ -154,6 +154,8 @@ const char* srslog_get_logger_id(srslog_logger* log) static basic_levels convert_c_enum_to_basic_levels(srslog_log_levels lvl) { switch (lvl) { + case srslog_lvl_none: + return basic_levels::none; case srslog_lvl_debug: return basic_levels::debug; case srslog_lvl_info: @@ -165,7 +167,7 @@ static basic_levels convert_c_enum_to_basic_levels(srslog_log_levels lvl) } assert(false && "Invalid enum value"); - return basic_levels::error; + return basic_levels::none; } void srslog_set_logger_level(srslog_logger* log, srslog_log_levels lvl) diff --git a/lib/src/upper/CMakeLists.txt b/lib/src/upper/CMakeLists.txt index ca301db65..4680a7286 100644 --- a/lib/src/upper/CMakeLists.txt +++ b/lib/src/upper/CMakeLists.txt @@ -27,11 +27,10 @@ set(SOURCES gtpu.cc rlc_um_base.cc rlc_um_lte.cc rlc_am_base.cc - rlc_am_lte.cc) - -if (ENABLE_5GNR) - set(SOURCES ${SOURCES} pdcp_entity_nr.cc rlc_um_nr.cc rlc_am_nr.cc) -endif(ENABLE_5GNR) + rlc_am_lte.cc + pdcp_entity_nr.cc + rlc_um_nr.cc + rlc_am_nr.cc) add_library(srslte_upper STATIC ${SOURCES}) target_link_libraries(srslte_upper srslte_common srslte_asn1) diff --git a/lib/src/upper/gtpu.cc b/lib/src/upper/gtpu.cc index d6515c1c2..6d8182567 100644 --- a/lib/src/upper/gtpu.cc +++ b/lib/src/upper/gtpu.cc @@ -26,35 +26,43 @@ namespace srslte { +const static size_t HEADER_PDCP_PDU_NUMBER_SIZE = 4; + /**************************************************************************** * Header pack/unpack helper functions * Ref: 3GPP TS 29.281 v10.1.0 Section 5 ***************************************************************************/ -bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslte::log_ref gtpu_log) +bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslog::basic_logger& logger) { // flags - if (!gtpu_supported_flags_check(header, gtpu_log)) { - gtpu_log->error("gtpu_write_header - Unhandled GTP-U Flags. Flags: 0x%x\n", header->flags); + if (!gtpu_supported_flags_check(header, logger)) { + logger.error("gtpu_write_header - Unhandled GTP-U Flags. Flags: 0x%x", header->flags); return false; } // msg type - if (!gtpu_supported_msg_type_check(header, gtpu_log)) { - gtpu_log->error("gtpu_write_header - Unhandled GTP-U Message Type. Message Type: 0x%x\n", header->message_type); + if (!gtpu_supported_msg_type_check(header, logger)) { + logger.error("gtpu_write_header - Unhandled GTP-U Message Type. Message Type: 0x%x", header->message_type); return false; } // If E, S or PN are set, the header is longer if (header->flags & (GTPU_FLAGS_EXTENDED_HDR | GTPU_FLAGS_SEQUENCE | GTPU_FLAGS_PACKET_NUM)) { if (pdu->get_headroom() < GTPU_EXTENDED_HEADER_LEN) { - gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); + logger.error("gtpu_write_header - No room in PDU for header"); return false; } pdu->msg -= GTPU_EXTENDED_HEADER_LEN; pdu->N_bytes += GTPU_EXTENDED_HEADER_LEN; + header->length += GTPU_EXTENDED_HEADER_LEN - GTPU_BASE_HEADER_LEN; + if (header->next_ext_hdr_type > 0) { + pdu->msg -= header->ext_buffer.size(); + pdu->N_bytes += header->ext_buffer.size(); + header->length += header->ext_buffer.size(); + } } else { if (pdu->get_headroom() < GTPU_BASE_HEADER_LEN) { - gtpu_log->error("gtpu_write_header - No room in PDU for header\n"); + logger.error("gtpu_write_header - No room in PDU for header"); return false; } pdu->msg -= GTPU_BASE_HEADER_LEN; @@ -85,20 +93,50 @@ bool gtpu_write_header(gtpu_header_t* header, srslte::byte_buffer_t* pdu, srslte *ptr = header->n_pdu; } else { header->n_pdu = 0; + *ptr = 0; } ptr++; // E if (header->flags & GTPU_FLAGS_EXTENDED_HDR) { *ptr = header->next_ext_hdr_type; + ptr++; + for (size_t i = 0; i < header->ext_buffer.size(); ++i) { + *ptr = header->ext_buffer[i]; + ptr++; + } } else { *ptr = 0; + ptr++; } - ptr++; } return true; } -bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslte::log_ref gtpu_log) +bool gtpu_read_ext_header(srslte::byte_buffer_t* pdu, + uint8_t** ptr, + gtpu_header_t* header, + srslog::basic_logger& logger) +{ + if ((header->flags & GTPU_FLAGS_EXTENDED_HDR) == 0 or header->next_ext_hdr_type == 0) { + return true; + } + + if (header->next_ext_hdr_type == GTPU_EXT_HEADER_PDCP_PDU_NUMBER) { + pdu->msg += HEADER_PDCP_PDU_NUMBER_SIZE; + pdu->N_bytes -= HEADER_PDCP_PDU_NUMBER_SIZE; + header->ext_buffer.resize(HEADER_PDCP_PDU_NUMBER_SIZE); + for (size_t i = 0; i < HEADER_PDCP_PDU_NUMBER_SIZE; ++i) { + header->ext_buffer[i] = **ptr; + (*ptr)++; + } + } else { + logger.error("gtpu_read_header - Unhandled GTP-U Extension Header Type: 0x%x", header->next_ext_hdr_type); + return false; + } + return true; +} + +bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslog::basic_logger& logger) { uint8_t* ptr = pdu->msg; @@ -109,16 +147,17 @@ bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslte: uint8_to_uint16(ptr, &header->length); ptr += 2; uint8_to_uint32(ptr, &header->teid); + ptr += 4; // flags - if (!gtpu_supported_flags_check(header, gtpu_log)) { - gtpu_log->error("gtpu_read_header - Unhandled GTP-U Flags. Flags: 0x%x\n", header->flags); + if (!gtpu_supported_flags_check(header, logger)) { + logger.error("gtpu_read_header - Unhandled GTP-U Flags. Flags: 0x%x", header->flags); return false; } // message_type - if (!gtpu_supported_msg_type_check(header, gtpu_log)) { - gtpu_log->error("gtpu_read_header - Unhandled GTP-U Message Type. Flags: 0x%x\n", header->message_type); + if (!gtpu_supported_msg_type_check(header, logger)) { + logger.error("gtpu_read_header - Unhandled GTP-U Message Type. Flags: 0x%x", header->message_type); return false; } @@ -135,6 +174,10 @@ bool gtpu_read_header(srslte::byte_buffer_t* pdu, gtpu_header_t* header, srslte: header->next_ext_hdr_type = *ptr; ptr++; + + if (not gtpu_read_ext_header(pdu, &ptr, header, logger)) { + return false; + } } else { pdu->msg += GTPU_BASE_HEADER_LEN; pdu->N_bytes -= GTPU_BASE_HEADER_LEN; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index f4ab86cea..1ae1cd2ed 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -20,13 +20,13 @@ */ #include "srslte/upper/pdcp.h" -#ifdef HAVE_5GNR #include "srslte/upper/pdcp_entity_nr.h" -#endif namespace srslte { -pdcp::pdcp(srslte::task_sched_handle task_sched_, const char* logname) : task_sched(task_sched_), pdcp_log(logname) {} +pdcp::pdcp(srslte::task_sched_handle task_sched_, const char* logname) : + task_sched(task_sched_), logger(srslog::fetch_basic_logger(logname)) +{} pdcp::~pdcp() { @@ -83,12 +83,12 @@ bool pdcp::is_lcid_enabled(uint32_t lcid) return valid_lcids_cached.count(lcid) > 0; } -void pdcp::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) +void pdcp::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu, int sn) { if (valid_lcid(lcid)) { - pdcp_array.at(lcid)->write_sdu(std::move(sdu)); + pdcp_array.at(lcid)->write_sdu(std::move(sdu), sn); } else { - pdcp_log->warning("Writing sdu: lcid=%d. Deallocating sdu\n", lcid); + logger.warning("Writing sdu: lcid=%d. Deallocating sdu", lcid); } } @@ -106,30 +106,25 @@ void pdcp::add_bearer(uint32_t lcid, pdcp_config_t cfg) if (cfg.sn_len == srslte::PDCP_SN_LEN_18) { // create NR entity for 18bit SN length -#ifdef HAVE_5GNR - entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_sched, pdcp_log, lcid, cfg}); -#else - pdcp_log->error("Invalid PDCP configuration.\n"); - return; -#endif + entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_sched, logger, lcid, cfg}); } else { - entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, pdcp_log, lcid, cfg}); + entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, logger, lcid, cfg}); } if (not pdcp_array.insert(std::make_pair(lcid, std::move(entity))).second) { - pdcp_log->error("Error inserting PDCP entity in to array.\n"); + logger.error("Error inserting PDCP entity in to array."); return; } - pdcp_log->info("Add %s (lcid=%d, bearer_id=%d, sn_len=%dbits)\n", - rrc->get_rb_name(lcid).c_str(), - lcid, - cfg.bearer_id, - cfg.sn_len); + logger.info("Add %s (lcid=%d, bearer_id=%d, sn_len=%dbits)", + rrc->get_rb_name(lcid).c_str(), + lcid, + cfg.bearer_id, + cfg.sn_len); { std::lock_guard lock(cache_mutex); valid_lcids_cached.insert(lcid); } } else { - pdcp_log->info("Bearer %s already configured.\n", rrc->get_rb_name(lcid).c_str()); + logger.info("Bearer %s already configured.", rrc->get_rb_name(lcid).c_str()); } } @@ -137,20 +132,20 @@ void pdcp::add_bearer_mrb(uint32_t lcid, pdcp_config_t cfg) { if (not valid_mch_lcid(lcid)) { if (not pdcp_array_mrb - .insert(std::make_pair(lcid, - std::unique_ptr( - new pdcp_entity_lte(rlc, rrc, gw, task_sched, pdcp_log, lcid, cfg)))) + .insert(std::make_pair( + lcid, + std::unique_ptr(new pdcp_entity_lte(rlc, rrc, gw, task_sched, logger, lcid, cfg)))) .second) { - pdcp_log->error("Error inserting PDCP entity in to array\n."); + logger.error("Error inserting PDCP entity in to array."); return; } - pdcp_log->info("Add %s (lcid=%d, bearer_id=%d, sn_len=%dbits)\n", - rrc->get_rb_name(lcid).c_str(), - lcid, - cfg.bearer_id, - cfg.sn_len); + logger.info("Add %s (lcid=%d, bearer_id=%d, sn_len=%dbits)", + rrc->get_rb_name(lcid).c_str(), + lcid, + cfg.bearer_id, + cfg.sn_len); } else { - pdcp_log->warning("Bearer %s already configured. Reconfiguration not supported\n", rrc->get_rb_name(lcid).c_str()); + logger.warning("Bearer %s already configured. Reconfiguration not supported", rrc->get_rb_name(lcid).c_str()); } } @@ -162,9 +157,9 @@ void pdcp::del_bearer(uint32_t lcid) } if (valid_lcid(lcid)) { pdcp_array.erase(lcid); - pdcp_log->warning("Deleted PDCP bearer %s\n", rrc->get_rb_name(lcid).c_str()); + logger.warning("Deleted PDCP bearer %s", rrc->get_rb_name(lcid).c_str()); } else { - pdcp_log->warning("Can't delete bearer %s. Bearer doesn't exist.\n", rrc->get_rb_name(lcid).c_str()); + logger.warning("Can't delete bearer %s. Bearer doesn't exist.", rrc->get_rb_name(lcid).c_str()); } } @@ -177,20 +172,19 @@ void pdcp::change_lcid(uint32_t old_lcid, uint32_t new_lcid) auto it = pdcp_array.find(old_lcid); std::unique_ptr pdcp_entity = std::move(it->second); if (not pdcp_array.insert(std::make_pair(new_lcid, std::move(pdcp_entity))).second) { - pdcp_log->error("Error inserting PDCP entity into array\n."); + logger.error("Error inserting PDCP entity into array."); return; } // erase from old position pdcp_array.erase(it); valid_lcids_cached.erase(old_lcid); valid_lcids_cached.insert(new_lcid); - pdcp_log->warning("Changed LCID of PDCP bearer from %d to %d\n", old_lcid, new_lcid); + logger.warning("Changed LCID of PDCP bearer from %d to %d", old_lcid, new_lcid); } else { - pdcp_log->error( - "Can't change PDCP of bearer %s from %d to %d. Bearer doesn't exist or new LCID already occupied.\n", - rrc->get_rb_name(old_lcid).c_str(), - old_lcid, - new_lcid); + logger.error("Can't change PDCP of bearer %s from %d to %d. Bearer doesn't exist or new LCID already occupied.", + rrc->get_rb_name(old_lcid).c_str(), + old_lcid, + new_lcid); } } @@ -229,6 +223,20 @@ void pdcp::enable_security_timed(uint32_t lcid, srslte_direction_t direction, ui } } +void pdcp::send_status_report() +{ + for (auto& lcid_it : pdcp_array) { + lcid_it.second->send_status_report(); + } +} + +void pdcp::send_status_report(uint32_t lcid) +{ + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->send_status_report(); + } +} + bool pdcp::get_bearer_state(uint32_t lcid, srslte::pdcp_lte_state_t* state) { if (not valid_lcid(lcid)) { @@ -247,6 +255,14 @@ bool pdcp::set_bearer_state(uint32_t lcid, const srslte::pdcp_lte_state_t& state return true; } +std::map pdcp::get_buffered_pdus(uint32_t lcid) +{ + if (not valid_lcid(lcid)) { + return {}; + } + return pdcp_array[lcid]->get_buffered_pdus(); +} + /******************************************************************************* RLC interface *******************************************************************************/ @@ -255,7 +271,7 @@ void pdcp::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) if (valid_lcid(lcid)) { pdcp_array.at(lcid)->write_pdu(std::move(pdu)); } else { - pdcp_log->warning("Writing pdu: lcid=%d. Deallocating pdu\n", lcid); + logger.warning("Writing pdu: lcid=%d. Deallocating pdu", lcid); } } @@ -283,10 +299,28 @@ void pdcp::write_pdu_mch(uint32_t lcid, unique_byte_buffer_t sdu) } } +void pdcp::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) +{ + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->notify_delivery(pdcp_sns); + } else { + logger.warning("Could not notify delivery: lcid=%d, nof_sn=%ld.", lcid, pdcp_sns.size()); + } +} + +void pdcp::notify_failure(uint32_t lcid, const std::vector& pdcp_sns) +{ + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->notify_failure(pdcp_sns); + } else { + logger.warning("Could not notify failure: lcid=%d, nof_sn=%ld.", lcid, pdcp_sns.size()); + } +} + bool pdcp::valid_lcid(uint32_t lcid) { if (lcid >= SRSLTE_N_RADIO_BEARERS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); + logger.error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } @@ -296,11 +330,47 @@ bool pdcp::valid_lcid(uint32_t lcid) bool pdcp::valid_mch_lcid(uint32_t lcid) { if (lcid >= SRSLTE_N_MCH_LCIDS) { - pdcp_log->error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); + logger.error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } return pdcp_array_mrb.find(lcid) != pdcp_array_mrb.end(); } +void pdcp::get_metrics(pdcp_metrics_t& m, const uint32_t nof_tti) +{ + std::chrono::duration secs = std::chrono::high_resolution_clock::now() - metrics_tp; + + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + pdcp_bearer_metrics_t metrics = it->second->get_metrics(); + + // Rx/Tx rate based on real time + double rx_rate_mbps_real_time = (metrics.num_rx_pdu_bytes * 8 / (double)1e6) / secs.count(); + double tx_rate_mbps_real_time = (metrics.num_tx_pdu_bytes * 8 / (double)1e6) / secs.count(); + + // Rx/Tx rate based on number of TTIs + double rx_rate_mbps = (nof_tti > 0) ? ((metrics.num_rx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; + double tx_rate_mbps = (nof_tti > 0) ? ((metrics.num_tx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; + + logger.info("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)", + it->first, + rx_rate_mbps, + rx_rate_mbps_real_time, + tx_rate_mbps, + tx_rate_mbps_real_time); + m.bearer[it->first] = metrics; + } + + reset_metrics(); +} + +void pdcp::reset_metrics() +{ + for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { + it->second->reset_metrics(); + } + + metrics_tp = std::chrono::high_resolution_clock::now(); +} + } // namespace srslte diff --git a/lib/src/upper/pdcp_entity_base.cc b/lib/src/upper/pdcp_entity_base.cc index 677e4a383..0634503f3 100644 --- a/lib/src/upper/pdcp_entity_base.cc +++ b/lib/src/upper/pdcp_entity_base.cc @@ -26,8 +26,8 @@ namespace srslte { -pdcp_entity_base::pdcp_entity_base(task_sched_handle task_sched_, srslte::log_ref log_) : - log(log_), task_sched(task_sched_) +pdcp_entity_base::pdcp_entity_base(task_sched_handle task_sched_, srslog::basic_logger& logger) : + logger(logger), task_sched(task_sched_) {} pdcp_entity_base::~pdcp_entity_base() {} @@ -36,14 +36,14 @@ void pdcp_entity_base::config_security(as_security_config_t sec_cfg_) { sec_cfg = sec_cfg_; - log->info("Configuring security with %s and %s\n", - integrity_algorithm_id_text[sec_cfg.integ_algo], - ciphering_algorithm_id_text[sec_cfg.cipher_algo]); + logger.info("Configuring security with %s and %s", + integrity_algorithm_id_text[sec_cfg.integ_algo], + ciphering_algorithm_id_text[sec_cfg.cipher_algo]); - log->debug_hex(sec_cfg.k_rrc_enc.data(), 32, "K_rrc_enc"); - log->debug_hex(sec_cfg.k_up_enc.data(), 32, "K_up_enc"); - log->debug_hex(sec_cfg.k_rrc_int.data(), 32, "K_rrc_int"); - log->debug_hex(sec_cfg.k_up_int.data(), 32, "K_up_int"); + logger.debug(sec_cfg.k_rrc_enc.data(), 32, "K_rrc_enc"); + logger.debug(sec_cfg.k_up_enc.data(), 32, "K_up_enc"); + logger.debug(sec_cfg.k_rrc_int.data(), 32, "K_rrc_int"); + logger.debug(sec_cfg.k_up_int.data(), 32, "K_up_int"); } /**************************************************************************** @@ -76,13 +76,13 @@ void pdcp_entity_base::integrity_generate(uint8_t* msg, uint32_t msg_len, uint32 break; } - log->debug("Integrity gen input: COUNT %" PRIu32 ", Bearer ID %d, Direction %s\n", - count, - cfg.bearer_id, - (cfg.tx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink")); - log->debug_hex(k_int, 32, "Integrity gen key:"); - log->debug_hex(msg, msg_len, "Integrity gen input msg:"); - log->debug_hex(mac, 4, "MAC (generated)"); + logger.debug("Integrity gen input: COUNT %" PRIu32 ", Bearer ID %d, Direction %s", + count, + cfg.bearer_id, + (cfg.tx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink")); + logger.debug(k_int, 32, "Integrity gen key:"); + logger.debug(msg, msg_len, "Integrity gen input msg:"); + logger.debug(mac, 4, "MAC (generated)"); } bool pdcp_entity_base::integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* mac) @@ -114,24 +114,24 @@ bool pdcp_entity_base::integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t break; } - log->debug("Integrity check input: COUNT %" PRIu32 ", Bearer ID %d, Direction %s\n", - count, - cfg.bearer_id, - cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); - log->debug_hex(k_int, 32, "Integrity check key:"); - log->debug_hex(msg, msg_len, "Integrity check input msg:"); + logger.debug("Integrity check input: COUNT %" PRIu32 ", Bearer ID %d, Direction %s", + count, + cfg.bearer_id, + cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); + logger.debug(k_int, 32, "Integrity check key:"); + logger.debug(msg, msg_len, "Integrity check input msg:"); if (sec_cfg.integ_algo != INTEGRITY_ALGORITHM_ID_EIA0) { for (uint8_t i = 0; i < 4; i++) { if (mac[i] != mac_exp[i]) { - log->error_hex(mac_exp, 4, "MAC mismatch (expected)"); - log->error_hex(mac, 4, "MAC mismatch (found)"); + logger.error(mac_exp, 4, "MAC mismatch (expected)"); + logger.error(mac, 4, "MAC mismatch (found)"); is_valid = false; break; } } if (is_valid) { - log->info_hex(mac_exp, 4, "MAC match"); + logger.info(mac_exp, 4, "MAC match"); } } @@ -150,12 +150,12 @@ void pdcp_entity_base::cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t c k_enc = sec_cfg.k_up_enc.data(); } - log->debug("Cipher encrypt input: COUNT: %" PRIu32 ", Bearer ID: %d, Direction %s\n", - count, - cfg.bearer_id, - cfg.tx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); - log->debug_hex(k_enc, 32, "Cipher encrypt key:"); - log->debug_hex(msg, msg_len, "Cipher encrypt input msg"); + logger.debug("Cipher encrypt input: COUNT: %" PRIu32 ", Bearer ID: %d, Direction %s", + count, + cfg.bearer_id, + cfg.tx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); + logger.debug(k_enc, 32, "Cipher encrypt key:"); + logger.debug(msg, msg_len, "Cipher encrypt input msg"); switch (sec_cfg.cipher_algo) { case CIPHERING_ALGORITHM_ID_EEA0: @@ -175,7 +175,7 @@ void pdcp_entity_base::cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t c default: break; } - log->debug_hex(ct, msg_len, "Cipher encrypt output msg"); + logger.debug(ct, msg_len, "Cipher encrypt output msg"); } void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint8_t* msg) @@ -190,12 +190,12 @@ void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t cou k_enc = sec_cfg.k_up_enc.data(); } - log->debug("Cipher decrypt input: COUNT: %" PRIu32 ", Bearer ID: %d, Direction %s\n", - count, - cfg.bearer_id, - (cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink"); - log->debug_hex(k_enc, 32, "Cipher decrypt key:"); - log->debug_hex(ct, ct_len, "Cipher decrypt input msg"); + logger.debug("Cipher decrypt input: COUNT: %" PRIu32 ", Bearer ID: %d, Direction %s", + count, + cfg.bearer_id, + (cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink"); + logger.debug(k_enc, 32, "Cipher decrypt key:"); + logger.debug(ct, ct_len, "Cipher decrypt input msg"); switch (sec_cfg.cipher_algo) { case CIPHERING_ALGORITHM_ID_EEA0: @@ -215,7 +215,7 @@ void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t cou default: break; } - log->debug_hex(msg, ct_len, "Cipher decrypt output msg"); + logger.debug(msg, ct_len, "Cipher decrypt output msg"); } /**************************************************************************** @@ -228,11 +228,16 @@ bool pdcp_entity_base::is_control_pdu(const unique_byte_buffer_t& pdu) return ((*(payload) >> 7) & 0x01) == PDCP_DC_FIELD_CONTROL_PDU; } +pdcp_pdu_type_t pdcp_entity_base::get_control_pdu_type(const unique_byte_buffer_t& pdu) +{ + return pdcp_pdu_type_t((pdu->msg[0] >> 4U) & 0x03U); +} + uint32_t pdcp_entity_base::read_data_header(const unique_byte_buffer_t& pdu) { // Check PDU is long enough to extract header if (pdu->N_bytes <= cfg.hdr_len_bytes) { - log->error("PDU too small to extract header\n"); + logger.error("PDU too small to extract header"); return 0; } @@ -255,7 +260,7 @@ uint32_t pdcp_entity_base::read_data_header(const unique_byte_buffer_t& pdu) rcvd_sn_32 = SN(rcvd_sn_32); break; default: - log->error("Cannot extract RCVD_SN, invalid SN length configured: %d\n", cfg.sn_len); + logger.error("Cannot extract RCVD_SN, invalid SN length configured: %d", cfg.sn_len); } return rcvd_sn_32; @@ -271,7 +276,7 @@ void pdcp_entity_base::write_data_header(const srslte::unique_byte_buffer_t& sdu { // Add room for header if (cfg.hdr_len_bytes > sdu->get_headroom()) { - log->error("Not enough space to add header\n"); + logger.error("Not enough space to add header"); return; } sdu->msg -= cfg.hdr_len_bytes; @@ -299,7 +304,7 @@ void pdcp_entity_base::write_data_header(const srslte::unique_byte_buffer_t& sdu sdu->msg[0] |= 0x80; // Data PDU and SN LEN 18 implies DRB, D flag must be present break; default: - log->error("Invalid SN length configuration: %d bits\n", cfg.sn_len); + logger.error("Invalid SN length configuration: %d bits", cfg.sn_len); } } @@ -307,7 +312,7 @@ void pdcp_entity_base::extract_mac(const unique_byte_buffer_t& pdu, uint8_t* mac { // Check enough space for MAC if (pdu->N_bytes < 4) { - log->error("PDU too small to extract MAC-I\n"); + logger.error("PDU too small to extract MAC-I"); return; } @@ -320,7 +325,7 @@ void pdcp_entity_base::append_mac(const unique_byte_buffer_t& sdu, uint8_t* mac) { // Check enough space for MAC if (sdu->N_bytes + 4 > sdu->get_tailroom()) { - log->error("Not enough space to add MAC-I\n"); + logger.error("Not enough space to add MAC-I"); return; } diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 914db111e..b118e1a1c 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -20,7 +20,9 @@ */ #include "srslte/upper/pdcp_entity_lte.h" +#include "srslte/common/int_helpers.h" #include "srslte/common/security.h" +#include namespace srslte { @@ -28,10 +30,10 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, srsue::rrc_interface_pdcp* rrc_, srsue::gw_interface_pdcp* gw_, srslte::task_sched_handle task_sched_, - srslte::log_ref log_, + srslog::basic_logger& logger, uint32_t lcid_, pdcp_config_t cfg_) : - pdcp_entity_base(task_sched_, log_), rlc(rlc_), rrc(rrc_), gw(gw_) + pdcp_entity_base(task_sched_, logger), rlc(rlc_), rrc(rrc_), gw(gw_) { lcid = lcid_; cfg = cfg_; @@ -45,6 +47,7 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, reordering_window = 2048; } + // Initial state st.next_pdcp_tx_sn = 0; st.tx_hfn = 0; st.rx_hfn = 0; @@ -52,13 +55,35 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, maximum_pdcp_sn = (1 << cfg.sn_len) - 1; st.last_submitted_pdcp_rx_sn = maximum_pdcp_sn; - log->info("Init %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); - log->info("SN len bits: %d, SN len bytes: %d, reordering window: %d, Maximum SN: %d, discard timer: %d ms\n", - cfg.sn_len, - cfg.hdr_len_bytes, - reordering_window, - maximum_pdcp_sn, - static_cast(cfg.discard_timer)); + uint32_t discard_time_value = static_cast(cfg.discard_timer); + if (discard_time_value > 0) { + // Note: One extra position is reserved at the end for the status report + discard_timers.reserve(maximum_pdcp_sn + 2); + for (uint32_t sn = 0; sn < maximum_pdcp_sn + 2; ++sn) { + discard_timers.emplace_back(task_sched.get_unique_timer()); + discard_callback discard_fnc(this, sn); + discard_timers[sn].set(discard_time_value, discard_fnc); + } + } + + // Queue Helpers + maximum_allocated_sns_window = (1 << cfg.sn_len) / 2; + + if (is_drb() && not rlc->rb_is_um(lcid) && cfg.discard_timer == pdcp_discard_timer_t::infinity) { + logger.warning( + "Setting discard timer to 1500ms, to avoid issues with lingering SDUs in the Unacknowledged SDUs map. LCID=%d", + lcid); + cfg.discard_timer = pdcp_discard_timer_t::ms1500; + } + + logger.info("Init %s with bearer ID: %d", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); + logger.info("SN len bits: %d, SN len bytes: %d, reordering window: %d, Maximum SN: %d, discard timer: %d ms", + cfg.sn_len, + cfg.hdr_len_bytes, + reordering_window, + maximum_pdcp_sn, + static_cast(cfg.discard_timer)); + logger.info("Status Report Required: %s", cfg.status_report_required ? "True" : "False"); // Check supported config if (!check_valid_config()) { @@ -74,43 +99,86 @@ pdcp_entity_lte::~pdcp_entity_lte() // Reestablishment procedure: 36.323 5.2 void pdcp_entity_lte::reestablish() { - log->info("Re-establish %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); + logger.info("Re-establish %s with bearer ID: %d", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); // For SRBs if (is_srb()) { st.next_pdcp_tx_sn = 0; st.tx_hfn = 0; st.rx_hfn = 0; st.next_pdcp_rx_sn = 0; - } else { + undelivered_sdus_queue.clear(); + } else if (rlc->rb_is_um(lcid)) { // Only reset counter in RLC-UM - if (rlc->rb_is_um(lcid)) { - st.next_pdcp_tx_sn = 0; - st.tx_hfn = 0; - st.rx_hfn = 0; - st.next_pdcp_rx_sn = 0; - } + st.next_pdcp_tx_sn = 0; + st.tx_hfn = 0; + st.rx_hfn = 0; + st.next_pdcp_rx_sn = 0; + } else { + // Send status report if required on reestablishment in RLC AM + // send_status_report(); + + // Re-transmit unacknowledged SDUs + /* + send_status_report(); + + // Re-transmit unacknowledged SDUs + std::map undelivered_sdus = std::move(undelivered_sdus_queue); + undelivered_sdus_queue.clear(); + + for (std::map::iterator it = undelivered_sdus.begin(); it != undelivered_sdus.end(); + ++it) { + write_sdu(std::move(it->second), it->first); + }*/ } } // Used to stop/pause the entity (called on RRC conn release) void pdcp_entity_lte::reset() { - if (active and log) { - log->debug("Reset %s\n", rrc->get_rb_name(lcid).c_str()); + if (active) { + logger.debug("Reset %s", rrc->get_rb_name(lcid).c_str()); } active = false; } // GW/RRC interface -void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu) +void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) { if (rlc->sdu_queue_is_full(lcid)) { - log->info_hex(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid).c_str()); + logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid).c_str()); return; } // Get COUNT to be used with this packet - uint32_t tx_count = COUNT(st.tx_hfn, st.next_pdcp_tx_sn); + uint32_t used_sn; + if (upper_sn == -1) { + used_sn = st.next_pdcp_tx_sn; // Normal scenario + } else { + used_sn = upper_sn; // SN provided by the upper layers, due to handover. + } + + uint32_t tx_count = COUNT(st.tx_hfn, used_sn); // Normal scenario + + // If the bearer is mapped to RLC AM, save TX_COUNT and a copy of the PDU. + // This will be used for reestablishment, where unack'ed PDUs will be re-transmitted. + // PDUs will be removed from the queue, either when the lower layers will report + // a succesfull transmission or when the discard timer expires. + // Status report will also use this queue, to know the First Missing SDU (FMS). + if (!rlc->rb_is_um(lcid)) { + if (not store_sdu(used_sn, sdu)) { + // Could not store the SDU, discarding + return; + } + + // Start discard timer + if (cfg.discard_timer != pdcp_discard_timer_t::infinity) { + unique_timer* timer = get_discard_timer(used_sn); + if (timer != nullptr) { + timer->run(); + logger.debug("Discard Timer set for SN %u. Timeout: %ums", used_sn, static_cast(cfg.discard_timer)); + } + } + } // check for pending security config in transmit direction if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast(tx_count)) { @@ -137,36 +205,45 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu) &sdu->msg[cfg.hdr_len_bytes], sdu->N_bytes - cfg.hdr_len_bytes, tx_count, &sdu->msg[cfg.hdr_len_bytes]); } - log->info_hex(sdu->msg, - sdu->N_bytes, - "TX %s PDU, SN=%d, integrity=%s, encryption=%s", - rrc->get_rb_name(lcid).c_str(), - st.next_pdcp_tx_sn, - srslte_direction_text[integrity_direction], - srslte_direction_text[encryption_direction]); + logger.info(sdu->msg, + sdu->N_bytes, + "TX %s PDU, SN=%d, integrity=%s, encryption=%s", + rrc->get_rb_name(lcid).c_str(), + used_sn, + srslte_direction_text[integrity_direction], + srslte_direction_text[encryption_direction]); - // Increment NEXT_PDCP_TX_SN and TX_HFN - st.next_pdcp_tx_sn++; - if (st.next_pdcp_tx_sn > maximum_pdcp_sn) { - st.tx_hfn++; - st.next_pdcp_tx_sn = 0; + // Set SDU metadata for RLC AM + sdu->md.pdcp_sn = used_sn; + + // Increment NEXT_PDCP_TX_SN and TX_HFN (only update variables if SN was not provided by upper layers) + if (upper_sn == -1) { + st.next_pdcp_tx_sn++; + if (st.next_pdcp_tx_sn > maximum_pdcp_sn) { + st.tx_hfn++; + st.next_pdcp_tx_sn = 0; + } } + // Pass PDU to lower layers + metrics.num_tx_pdus++; + metrics.num_tx_pdu_bytes += sdu->N_bytes; rlc->write_sdu(lcid, std::move(sdu)); } // RLC interface void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu) { - // drop control PDUs + // Handle control PDUs if (is_drb() && is_control_pdu(pdu)) { - log->info("Dropping PDCP control PDU\n"); + logger.info("Handling PDCP control PDU"); + handle_control_pdu(std::move(pdu)); return; } // Sanity check if (pdu->N_bytes <= cfg.hdr_len_bytes) { - log->error("PDCP PDU smaller than required header size.\n"); + logger.error("PDCP PDU smaller than required header size."); return; } @@ -180,14 +257,18 @@ void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu) enable_security_rx_sn = -1; } - log->info_hex(pdu->msg, - pdu->N_bytes, - "%s Rx PDU SN=%d (%d B, integrity=%s, encryption=%s)", - rrc->get_rb_name(lcid).c_str(), - sn, - pdu->N_bytes, - srslte_direction_text[integrity_direction], - srslte_direction_text[encryption_direction]); + logger.info(pdu->msg, + pdu->N_bytes, + "%s Rx PDU SN=%d (%d B, integrity=%s, encryption=%s)", + rrc->get_rb_name(lcid).c_str(), + sn, + pdu->N_bytes, + srslte_direction_text[integrity_direction], + srslte_direction_text[encryption_direction]); + + // Update metrics + metrics.num_rx_pdus++; + metrics.num_rx_pdu_bytes += pdu->N_bytes; if (is_srb()) { handle_srb_pdu(std::move(pdu)); @@ -196,12 +277,27 @@ void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu) } else if (is_drb() && !rlc->rb_is_um(lcid)) { handle_am_drb_pdu(std::move(pdu)); } else { - log->error("Invalid PDCP/RLC configuration"); + logger.error("Invalid PDCP/RLC configuration"); + return; } } +// Handle control PDU +void pdcp_entity_lte::handle_control_pdu(unique_byte_buffer_t pdu) +{ + switch (get_control_pdu_type(pdu)) { + case PDCP_PDU_TYPE_STATUS_REPORT: + handle_status_report_pdu(std::move(pdu)); + break; + default: + logger.warning("Unhandled control PDU"); + return; + } + return; +} + /**************************************************************************** - * Rx data/control handler functions + * Rx data handler functions * Ref: 3GPP TS 36.323 v10.1.0 Section 5.1.2 ***************************************************************************/ // SRBs (5.1.2.2) @@ -210,7 +306,7 @@ void pdcp_entity_lte::handle_srb_pdu(srslte::unique_byte_buffer_t pdu) // Read SN from header uint32_t sn = read_data_header(pdu); - log->debug("RX SRB PDU. Next_PDCP_RX_SN %d, SN %d", st.next_pdcp_rx_sn, sn); + logger.debug("RX SRB PDU. Next_PDCP_RX_SN %d, SN %d", st.next_pdcp_rx_sn, sn); // Estimate COUNT for integrity check and decryption uint32_t count; @@ -225,7 +321,7 @@ void pdcp_entity_lte::handle_srb_pdu(srslte::unique_byte_buffer_t pdu) cipher_decrypt(&pdu->msg[cfg.hdr_len_bytes], pdu->N_bytes - cfg.hdr_len_bytes, count, &pdu->msg[cfg.hdr_len_bytes]); } - log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx SDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn); + logger.debug(pdu->msg, pdu->N_bytes, "%s Rx SDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn); // Extract MAC uint8_t mac[4]; @@ -234,7 +330,7 @@ void pdcp_entity_lte::handle_srb_pdu(srslte::unique_byte_buffer_t pdu) // Perfrom integrity checks if (integrity_direction == DIRECTION_RX || integrity_direction == DIRECTION_TXRX) { if (not integrity_verify(pdu->msg, pdu->N_bytes, count, mac)) { - log->error_hex(pdu->msg, pdu->N_bytes, "%s Dropping PDU", rrc->get_rb_name(lcid).c_str()); + logger.error(pdu->msg, pdu->N_bytes, "%s Dropping PDU", rrc->get_rb_name(lcid).c_str()); return; // Discard } } @@ -272,7 +368,7 @@ void pdcp_entity_lte::handle_um_drb_pdu(srslte::unique_byte_buffer_t pdu) cipher_decrypt(pdu->msg, pdu->N_bytes, count, pdu->msg); } - log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn); + logger.debug(pdu->msg, pdu->N_bytes, "%s Rx PDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn); st.next_pdcp_rx_sn = sn + 1; if (st.next_pdcp_rx_sn > maximum_pdcp_sn) { @@ -294,33 +390,35 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) int32_t sn_diff_last_submit = sn - st.last_submitted_pdcp_rx_sn; int32_t sn_diff_next_pdcp_rx_sn = sn - st.next_pdcp_rx_sn; - log->debug("RX HFN: %d, SN=%d, Last_Submitted_PDCP_RX_SN=%d, Next_PDCP_RX_SN=%d\n", - st.rx_hfn, - sn, - st.last_submitted_pdcp_rx_sn, - st.next_pdcp_rx_sn); + logger.debug("RX HFN: %d, SN=%d, Last_Submitted_PDCP_RX_SN=%d, Next_PDCP_RX_SN=%d", + st.rx_hfn, + sn, + st.last_submitted_pdcp_rx_sn, + st.next_pdcp_rx_sn); // Handle PDU uint32_t count = 0; if ((0 <= sn_diff_last_submit && sn_diff_last_submit > (int32_t)reordering_window) || (0 <= last_submit_diff_sn && last_submit_diff_sn < (int32_t)reordering_window)) { // discard - log->debug("Discarding SN=%d (sn_diff_last_submit=%d, last_submit_diff_sn=%d, reordering_window=%d)\n", - sn, - sn_diff_last_submit, - last_submit_diff_sn, - reordering_window); - return; // Discard - } else if ((int32_t)(st.next_pdcp_rx_sn - sn) > (int32_t)reordering_window) { - log->debug("(Next_PDCP_RX_SN - SN) is larger than re-ordering window.\n"); + logger.debug("Discarding SN=%d (sn_diff_last_submit=%d, last_submit_diff_sn=%d, reordering_window=%d)", + sn, + sn_diff_last_submit, + last_submit_diff_sn, + reordering_window); + return; + } + + if ((int32_t)(st.next_pdcp_rx_sn - sn) > (int32_t)reordering_window) { + logger.debug("(Next_PDCP_RX_SN - SN) is larger than re-ordering window."); st.rx_hfn++; count = (st.rx_hfn << cfg.sn_len) | sn; st.next_pdcp_rx_sn = sn + 1; } else if (sn_diff_next_pdcp_rx_sn >= (int32_t)reordering_window) { - log->debug("(SN - Next_PDCP_RX_SN) is larger or equal than re-ordering window.\n"); + logger.debug("(SN - Next_PDCP_RX_SN) is larger or equal than re-ordering window."); count = ((st.rx_hfn - 1) << cfg.sn_len) | sn; } else if (sn >= st.next_pdcp_rx_sn) { - log->debug("SN is larger or equal than Next_PDCP_RX_SN.\n"); + logger.debug("SN is larger or equal than Next_PDCP_RX_SN."); count = (st.rx_hfn << cfg.sn_len) | sn; st.next_pdcp_rx_sn = sn + 1; if (st.next_pdcp_rx_sn > maximum_pdcp_sn) { @@ -328,13 +426,13 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) st.rx_hfn++; } } else if (sn < st.next_pdcp_rx_sn) { - log->debug("SN is smaller than Next_PDCP_RX_SN.\n"); + logger.debug("SN is smaller than Next_PDCP_RX_SN."); count = (st.rx_hfn << cfg.sn_len) | sn; } // Decrypt cipher_decrypt(pdu->msg, pdu->N_bytes, count, pdu->msg); - log->debug_hex(pdu->msg, pdu->N_bytes, "%s Rx SDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn); + logger.debug(pdu->msg, pdu->N_bytes, "%s Rx SDU SN=%d", rrc->get_rb_name(lcid).c_str(), sn); // Update info on last PDU submitted to upper layers st.last_submitted_pdcp_rx_sn = sn; @@ -343,25 +441,287 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) gw->write_pdu(lcid, std::move(pdu)); } +/**************************************************************************** + * Control handler functions (Status Report) + * Ref: 3GPP TS 36.323 v10.1.0 Section 5.1.3 + ***************************************************************************/ + +// Section 5.3.1 transmit operation +void pdcp_entity_lte::send_status_report() +{ + // Check wether RLC AM is being used. + if (rlc->rb_is_um(lcid)) { + logger.info("Trying to send PDCP Status Report and RLC is not AM"); + return; + } + + if (not cfg.status_report_required) { + logger.info("Not sending PDCP Status Report as status report required is not set"); + return; + } + + // Get First Missing Segment (FMS) + uint32_t fms = 0; + if (undelivered_sdus_queue.empty()) { + fms = st.next_pdcp_tx_sn; + } else { + fms = undelivered_sdus_queue.begin()->first; + } + + logger.debug("Status report: FMS=%d", fms); + + // Allocate Status Report PDU + unique_byte_buffer_t pdu = make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Error allocating buffer for status report"); + return; + } + + // Set control bit and type of PDU + pdu->msg[0] = ((uint8_t)PDCP_DC_FIELD_CONTROL_PDU << 7) | ((uint8_t)PDCP_PDU_TYPE_STATUS_REPORT << 4); + + // Set FMS + switch (cfg.sn_len) { + case PDCP_SN_LEN_12: + pdu->msg[0] = pdu->msg[0] | (0x0F & (fms >> 8)); + pdu->msg[1] = 0xFF & fms; + pdu->N_bytes = 2; + break; + case PDCP_SN_LEN_18: + pdu->msg[0] = pdu->msg[0] | (0x03 & (fms >> 16)); + pdu->msg[1] = 0xFF & (fms >> 8); + pdu->msg[2] = 0xFF & fms; + pdu->N_bytes = 3; + break; + default: + logger.error("Unsupported SN length for Status Report."); + return; + } + + // Add bitmap of missing PDUs, if necessary + if (not undelivered_sdus_queue.empty()) { + // First check size of bitmap + uint32_t last_sn = undelivered_sdus_queue.rbegin()->first; + uint32_t bitmap_sz = std::ceil((float)(last_sn - (fms - 1)) / 8); + memset(&pdu->msg[pdu->N_bytes], 0, bitmap_sz); + logger.debug( + "Setting status report bitmap. Last SN acked=%d, Last SN acked in sequence=%d, Bitmap size in bytes=%d", + last_sn, + fms - 1, + bitmap_sz); + for (auto it = undelivered_sdus_queue.begin(); it != undelivered_sdus_queue.end(); it++) { + uint32_t offset = it->first - fms; + uint32_t bit_offset = offset % 8; + uint32_t byte_offset = offset / 8; + pdu->msg[pdu->N_bytes + byte_offset] |= 1 << (7 - bit_offset); + } + pdu->N_bytes += bitmap_sz; + } + pdu->md.pdcp_sn = -1; + + // Write PDU to RLC + rlc->write_sdu(lcid, std::move(pdu)); + + return; +} + +// Section 5.3.2 receive operation +void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu) +{ + logger.info("Handling Status Report PDU. Size=%ld", pdu->N_bytes); + + uint32_t fms = 0; + std::vector acked_sns = {}; + uint32_t bitmap_offset = 0; + + // Get FMS + switch (cfg.sn_len) { + case PDCP_SN_LEN_12: { + uint16_t tmp16; + uint8_to_uint16(pdu->msg, &tmp16); + fms = tmp16 & 0x0FFF; + bitmap_offset = 2; + break; + } + case PDCP_SN_LEN_18: { + uint8_to_uint24(pdu->msg, &fms); + fms = fms & 0x3FFF; + bitmap_offset = 3; + break; + } + default: + logger.error("Unsupported SN length for Status Report."); + return; + } + + // Remove all SDUs with SN smaller than FMS + for (auto it = undelivered_sdus_queue.begin(); it != undelivered_sdus_queue.end();) { + if (it->first < fms) { + stop_discard_timer(it->first); + it = undelivered_sdus_queue.erase(it); + } else { + ++it; + } + } + + // Get acked SNs from bitmap + for (uint32_t i = 0; (i + bitmap_offset) < pdu->N_bytes; i++) { + std::bitset<8> bset{pdu->msg[bitmap_offset + i]}; + for (uint8_t j = 0; j < 8; j++) { + if (bset[8 - j]) { + uint32_t acked_sn = fms + i * 8 + j; + acked_sns.push_back(acked_sn); + } + } + } + + // Discard ACK'ed SDUs + for (uint32_t sn : acked_sns) { + logger.debug("Status report ACKed SN=%d.", sn); + undelivered_sdus_queue.erase(sn); + stop_discard_timer(sn); + } +} +/**************************************************************************** + * TX PDUs Queue Helper + ***************************************************************************/ +bool pdcp_entity_lte::store_sdu(uint32_t sn, const unique_byte_buffer_t& sdu) +{ + logger.debug("Storing SDU in undelivered SDUs queue. SN=%d, Queue size=%ld", sn, undelivered_sdus_queue.size()); + + // Check wether PDU is already in the queue + if (undelivered_sdus_queue.find(sn) != undelivered_sdus_queue.end()) { + logger.error("PDU already exists in the queue. TX_COUNT=%d", sn); + return false; + } + + // Make sure we don't associate more than half of the PDCP SN space of contiguous PDCP SDUs + if (not undelivered_sdus_queue.empty()) { + auto fms_it = undelivered_sdus_queue.begin(); + uint32_t fms_sn = fms_it->first; + int32_t diff = sn - fms_sn; + if (diff > (int32_t)maximum_allocated_sns_window) { + // This SN is too large to assign, it may cause HFN de-synchronization. + logger.info("This SN is too large to assign. Discarding. SN=%d, FMS=%d, diff=%d, window=%d, queue_size=%d", + sn, + fms_sn, + diff, + maximum_allocated_sns_window, + undelivered_sdus_queue.size()); + return false; + } + if (diff < 0 && diff > -((int32_t)maximum_allocated_sns_window)) { + // This SN is too large to assign, it may cause HFN de-synchronization. + logger.info("This SN is too large to assign. Discarding. SN=%d, FMS=%d, diff=%d, window=%d, queue_size=%d", + sn, + fms_sn, + diff, + maximum_allocated_sns_window, + undelivered_sdus_queue.size()); + return false; + } + } + + // Copy PDU contents into queue + unique_byte_buffer_t sdu_copy = make_byte_buffer(); + memcpy(sdu_copy->msg, sdu->msg, sdu->N_bytes); + sdu_copy->N_bytes = sdu->N_bytes; + + // Metrics + sdu_copy->set_timestamp(); + + undelivered_sdus_queue.insert(std::make_pair(sn, std::move(sdu_copy))); + return true; +} + +/**************************************************************************** + * Discard functionality + ***************************************************************************/ +// Discard Timer Callback (discardTimer) +void pdcp_entity_lte::discard_callback::operator()(uint32_t timer_id) +{ + parent->logger.debug("Discard timer expired for PDU with SN = %d", discard_sn); + + // Discard PDU if unacknowledged + if (parent->undelivered_sdus_queue.find(discard_sn) != parent->undelivered_sdus_queue.end()) { + parent->undelivered_sdus_queue.erase(discard_sn); + parent->logger.debug("Removed undelivered PDU with TX_COUNT=%d", discard_sn); + } else { + parent->logger.debug("Could not find PDU to discard. TX_COUNT=%d", discard_sn); + } + + // Notify the RLC of the discard. It's the RLC to actually discard, if no segment was transmitted yet. + parent->rlc->discard_sdu(parent->lcid, discard_sn); + + // Remove timer from map + parent->stop_discard_timer(discard_sn); +} + +/**************************************************************************** + * Handle delivery/failure notifications from RLC + ***************************************************************************/ +void pdcp_entity_lte::notify_delivery(const std::vector& pdcp_sns) +{ + logger.info("Received delivery notification from RLC. Number of PDU notified=%ld", pdcp_sns.size()); + + for (uint32_t sn : pdcp_sns) { + logger.debug("Delivery notification received for PDU with SN=%d", sn); + // Find undelivered PDU info + std::map::iterator it = undelivered_sdus_queue.find(sn); + if (it == undelivered_sdus_queue.end()) { + logger.warning("Could not find PDU for delivery notification. Notified SN=%d", sn); + } else { + // Metrics + tx_pdu_ack_latency_ms.push(std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - it->second->get_timestamp()) + .count()); + metrics.num_tx_acked_bytes += it->second->N_bytes; + metrics.num_tx_buffered_pdus_bytes -= it->second->N_bytes; + + // Remove PDU and disarm timer. + undelivered_sdus_queue.erase(sn); + stop_discard_timer(sn); + } + } +} + +void pdcp_entity_lte::notify_failure(const std::vector& pdcp_sns) +{ + logger.info("Received failure notification from RLC. Number of PDU notified=%ld", pdcp_sns.size()); + + for (uint32_t sn : pdcp_sns) { + logger.info("Failure notification received for PDU with SN=%d", sn); + // Find undelivered PDU info + std::map::iterator it = undelivered_sdus_queue.find(sn); + if (it == undelivered_sdus_queue.end()) { + logger.info("Could not find PDU for failure notification. Notified SN=%d", sn); + } else { + // Remove PDU and disarm timer. + undelivered_sdus_queue.erase(sn); + stop_discard_timer(sn); + } + } +} + /**************************************************************************** * Config checking helper ***************************************************************************/ bool pdcp_entity_lte::check_valid_config() { if (cfg.sn_len != PDCP_SN_LEN_5 && cfg.sn_len != PDCP_SN_LEN_7 && cfg.sn_len != PDCP_SN_LEN_12) { - log->error("Trying to configure bearer with invalid SN LEN=%d\n", cfg.sn_len); + logger.error("Trying to configure bearer with invalid SN LEN=%d", cfg.sn_len); return false; } if (cfg.sn_len == PDCP_SN_LEN_5 && is_drb()) { - log->error("Trying to configure DRB bearer with SN LEN of 5\n"); + logger.error("Trying to configure DRB bearer with SN LEN of 5"); return false; } if (cfg.sn_len == PDCP_SN_LEN_7 && (is_srb() || !rlc->rb_is_um(lcid))) { - log->error("Trying to configure SRB or RLC AM bearer with SN LEN of 7\n"); + logger.error("Trying to configure SRB or RLC AM bearer with SN LEN of 7"); return false; } if (cfg.sn_len == PDCP_SN_LEN_12 && is_srb()) { - log->error("Trying to configure SRB with SN LEN of 12.\n"); + logger.error("Trying to configure SRB with SN LEN of 12."); return false; } return true; @@ -380,4 +740,65 @@ void pdcp_entity_lte::set_bearer_state(const pdcp_lte_state_t& state) st = state; } +std::map pdcp_entity_lte::get_buffered_pdus() +{ + logger.info("Buffered PDUs requested, buffer_size=%d", undelivered_sdus_queue.size()); + + std::map cpy{}; + // Deep copy undelivered SDUs + // TODO: investigate wheter the deep copy can be avoided by moving the undelivered SDU queue. + // That can only be done just before the PDCP is disabled though. + for (auto it = undelivered_sdus_queue.begin(); it != undelivered_sdus_queue.end(); it++) { + cpy[it->first] = make_byte_buffer(); + (*cpy[it->first]) = *(it->second); + logger.debug(it->second->msg, it->second->N_bytes, "Forwarding buffered PDU with SN=%d", it->first); + } + return cpy; +} + +uint32_t pdcp_entity_lte::nof_discard_timers() const +{ + return std::count_if( + discard_timers.begin(), discard_timers.end(), [](const unique_timer& t) { return t.is_running(); }); +} + +unique_timer* pdcp_entity_lte::get_discard_timer(uint32_t sn) +{ + // Note: When SN>max PDCP SN (Status report case), the position will be the last in the vector of discard timers + if (not discard_timers.empty()) { + uint32_t sn_idx = std::min((uint32_t)sn, (uint32_t)(discard_timers.size() - 1)); + return &discard_timers[sn_idx]; + } + return nullptr; +} + +void pdcp_entity_lte::stop_discard_timer(uint32_t sn) +{ + unique_timer* timer = get_discard_timer(sn); + if (timer != nullptr) { + timer->stop(); + } +} + +/**************************************************************************** + * Metrics helpers + ***************************************************************************/ +pdcp_bearer_metrics_t pdcp_entity_lte::get_metrics() +{ + metrics.num_tx_buffered_pdus = undelivered_sdus_queue.size(); + metrics.num_tx_buffered_pdus_bytes = 0; + for (auto sdu_it = undelivered_sdus_queue.begin(); sdu_it != undelivered_sdus_queue.end(); ++sdu_it) { + metrics.num_tx_buffered_pdus_bytes += sdu_it->second->N_bytes; //< Number of bytes of PDUs waiting for ACK + } + metrics.tx_notification_latency_ms = + tx_pdu_ack_latency_ms.value(); //< Average time in ms from PDU delivery to RLC to ACK notification from RLC + return metrics; +} + +void pdcp_entity_lte::reset_metrics() +{ + // Only reset metrics that have are snapshots, leave the incremental ones untouched. + metrics.tx_notification_latency_ms = 0; +} + } // namespace srslte diff --git a/lib/src/upper/pdcp_entity_nr.cc b/lib/src/upper/pdcp_entity_nr.cc index ba543af3c..7aee3e3ba 100644 --- a/lib/src/upper/pdcp_entity_nr.cc +++ b/lib/src/upper/pdcp_entity_nr.cc @@ -28,10 +28,10 @@ pdcp_entity_nr::pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, srsue::rrc_interface_pdcp* rrc_, srsue::gw_interface_pdcp* gw_, srslte::task_sched_handle task_sched_, - srslte::log_ref log_, + srslog::basic_logger& logger, uint32_t lcid_, pdcp_config_t cfg_) : - pdcp_entity_base(task_sched_, log_), + pdcp_entity_base(task_sched_, logger), rlc(rlc_), rrc(rrc_), gw(gw_), @@ -59,7 +59,7 @@ pdcp_entity_nr::~pdcp_entity_nr() {} // Reestablishment procedure: 38.323 5.2 void pdcp_entity_nr::reestablish() { - log->info("Re-establish %s with bearer ID: %d\n", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); + logger.info("Re-establish %s with bearer ID: %d", rrc->get_rb_name(lcid).c_str(), cfg.bearer_id); // TODO } @@ -67,23 +67,23 @@ void pdcp_entity_nr::reestablish() void pdcp_entity_nr::reset() { active = false; - log->debug("Reset %s\n", rrc->get_rb_name(lcid).c_str()); + logger.debug("Reset %s", rrc->get_rb_name(lcid).c_str()); } // SDAP/RRC interface -void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu) +void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, int sn) { // Log SDU - log->info_hex(sdu->msg, - sdu->N_bytes, - "TX %s SDU, integrity=%s, encryption=%s", - rrc->get_rb_name(lcid).c_str(), - srslte_direction_text[integrity_direction], - srslte_direction_text[encryption_direction]); + logger.info(sdu->msg, + sdu->N_bytes, + "TX %s SDU, integrity=%s, encryption=%s", + rrc->get_rb_name(lcid).c_str(), + srslte_direction_text[integrity_direction], + srslte_direction_text[encryption_direction]); // Check for COUNT overflow if (tx_overflow) { - log->warning("TX_NEXT has overflowed. Dropping packet\n"); + logger.warning("TX_NEXT has overflowed. Dropping packet"); return; } if (tx_next + 1 == 0) { @@ -97,7 +97,7 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu) discard_timer.set(static_cast(cfg.discard_timer), discard_fnc); discard_timer.run(); discard_timers_map.insert(std::make_pair(tx_next, std::move(discard_timer))); - log->debug("Discard Timer set for SN %u. Timeout: %ums\n", tx_next, static_cast(cfg.discard_timer)); + logger.debug("Discard Timer set for SN %u. Timeout: %ums", tx_next, static_cast(cfg.discard_timer)); } // Perform header compression TODO @@ -115,25 +115,28 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu) // Append MAC-I append_mac(sdu, mac); - // Increment TX_NEXT - tx_next++; + // Set meta-data for RLC AM + sdu->md.pdcp_sn = tx_next; // Check if PDCP is associated with more than on RLC entity TODO // Write to lower layers rlc->write_sdu(lcid, std::move(sdu)); + + // Increment TX_NEXT + tx_next++; } // RLC interface void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) { // Log PDU - log->info_hex(pdu->msg, - pdu->N_bytes, - "RX %s PDU (%d B), integrity=%s, encryption=%s", - rrc->get_rb_name(lcid).c_str(), - pdu->N_bytes, - srslte_direction_text[integrity_direction], - srslte_direction_text[encryption_direction]); + logger.info(pdu->msg, + pdu->N_bytes, + "RX %s PDU (%d B), integrity=%s, encryption=%s", + rrc->get_rb_name(lcid).c_str(), + pdu->N_bytes, + srslte_direction_text[integrity_direction], + srslte_direction_text[encryption_direction]); // Sanity check if (pdu->N_bytes <= cfg.hdr_len_bytes) { @@ -159,7 +162,7 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) } rcvd_count = COUNT(rcvd_hfn, rcvd_sn); - log->debug("RCVD_HFN %u RCVD_SN %u, RCVD_COUNT %u\n", rcvd_hfn, rcvd_sn, rcvd_count); + logger.debug("RCVD_HFN %u RCVD_SN %u, RCVD_COUNT %u", rcvd_hfn, rcvd_sn, rcvd_count); // Decripting cipher_decrypt(pdu->msg, pdu->N_bytes, rcvd_count, pdu->msg); @@ -172,8 +175,8 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) // Check valid rcvd_count if (rcvd_count < rx_deliv) { - log->debug("Out-of-order after time-out, duplicate or COUNT wrap-around\n"); - log->debug("RCVD_COUNT %u, RCVD_COUNT %u\n", rcvd_count, rx_deliv); + logger.debug("Out-of-order after time-out, duplicate or COUNT wrap-around"); + logger.debug("RCVD_COUNT %u, RCVD_COUNT %u", rcvd_count, rx_deliv); return; // Invalid count, drop. } @@ -208,6 +211,17 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) } } +// Notification of delivery/failure +void pdcp_entity_nr::notify_delivery(const std::vector& pdcp_sns) +{ + logger.debug("Received delivery notification from RLC. Nof SNs=%ld", pdcp_sns.size()); +} + +void pdcp_entity_nr::notify_failure(const std::vector& pdcp_sns) +{ + logger.debug("Received failure notification from RLC. Nof SNs=%ld", pdcp_sns.size()); +} + /* * Packing / Unpacking Helpers */ @@ -219,11 +233,11 @@ void pdcp_entity_nr::deliver_all_consecutive_counts() for (std::map::iterator it = reorder_queue.begin(); it != reorder_queue.end() && it->first == rx_deliv; reorder_queue.erase(it++)) { - log->debug("Delivering SDU with RCVD_COUNT %u\n", it->first); + logger.debug("Delivering SDU with RCVD_COUNT %u", it->first); // Check RX_DELIV overflow if (rx_overflow) { - log->warning("RX_DELIV has overflowed. Droping packet\n"); + logger.warning("RX_DELIV has overflowed. Droping packet"); return; } if (rx_deliv + 1 == 0) { @@ -244,7 +258,7 @@ void pdcp_entity_nr::deliver_all_consecutive_counts() // Reordering Timer Callback (t-reordering) void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id) { - parent->log->debug("Reordering timer expired\n"); + parent->logger.debug("Reordering timer expired"); // Deliver all PDCP SDU(s) with associeted COUNT value(s) < RX_REORD for (std::map::iterator it = parent->reorder_queue.begin(); @@ -266,7 +280,7 @@ void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id) // Discard Timer Callback (discardTimer) void pdcp_entity_nr::discard_callback::operator()(uint32_t timer_id) { - parent->log->debug("Discard timer expired for PDU with SN = %d\n", discard_sn); + parent->logger.debug("Discard timer expired for PDU with SN = %d", discard_sn); // Notify the RLC of the discard. It's the RLC to actually discard, if no segment was transmitted yet. parent->rlc->discard_sdu(parent->lcid, discard_sn); @@ -286,4 +300,15 @@ void pdcp_entity_nr::set_bearer_state(const pdcp_lte_state_t& state) // TODO } +pdcp_bearer_metrics_t pdcp_entity_nr::get_metrics() +{ + // TODO + return metrics; +} + +void pdcp_entity_nr::reset_metrics() +{ + metrics = {}; +} + } // namespace srslte diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index d3ceee27e..ecb3b0f3c 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -28,7 +28,7 @@ namespace srslte { -rlc::rlc(const char* logname) : rlc_log(logname) +rlc::rlc(const char* logname) : logger(srslog::fetch_basic_logger(logname)) { pool = byte_buffer_pool::get_instance(); pthread_rwlock_init(&rwlock, NULL); @@ -118,21 +118,21 @@ void rlc::get_metrics(rlc_metrics_t& m, const uint32_t nof_tti) double rx_rate_mbps = (nof_tti > 0) ? ((metrics.num_rx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; double tx_rate_mbps = (nof_tti > 0) ? ((metrics.num_tx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; - rlc_log->info("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)\n", - it->first, - rx_rate_mbps, - rx_rate_mbps_real_time, - tx_rate_mbps, - tx_rate_mbps_real_time); + logger.info("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)", + it->first, + rx_rate_mbps, + rx_rate_mbps_real_time, + tx_rate_mbps, + tx_rate_mbps_real_time); m.bearer[it->first] = metrics; } // Add multicast metrics for (rlc_map_t::iterator it = rlc_array_mrb.begin(); it != rlc_array_mrb.end(); ++it) { rlc_bearer_metrics_t metrics = it->second->get_metrics(); - rlc_log->info("MCH_LCID=%d, rx_rate_mbps=%4.2f\n", - it->first, - (metrics.num_rx_pdu_bytes * 8 / static_cast(1e6)) / secs.count()); + logger.info("MCH_LCID=%d, rx_rate_mbps=%4.2f", + it->first, + (metrics.num_rx_pdu_bytes * 8 / static_cast(1e6)) / secs.count()); m.bearer[it->first] = metrics; } @@ -157,10 +157,10 @@ void rlc::reestablish() void rlc::reestablish(uint32_t lcid) { if (valid_lcid(lcid)) { - rlc_log->info("Reestablishing %s\n", rrc->get_rb_name(lcid).c_str()); + logger.info("Reestablishing %s", rrc->get_rb_name(lcid).c_str()); rlc_array.at(lcid)->reestablish(); } else { - rlc_log->warning("RLC LCID %d doesn't exist.\n", lcid); + logger.warning("RLC LCID %d doesn't exist.", lcid); } } @@ -200,7 +200,7 @@ void rlc::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) { // TODO: rework build PDU logic to allow large SDUs (without concatenation) if (sdu->N_bytes > RLC_MAX_SDU_SIZE) { - rlc_log->warning("Dropping too long SDU of size %d B (Max. size %d B).\n", sdu->N_bytes, RLC_MAX_SDU_SIZE); + logger.warning("Dropping too long SDU of size %d B (Max. size %d B).", sdu->N_bytes, RLC_MAX_SDU_SIZE); return; } @@ -208,7 +208,7 @@ void rlc::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) rlc_array.at(lcid)->write_sdu_s(std::move(sdu)); update_bsr(lcid); } else { - rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); + logger.warning("RLC LCID %d doesn't exist. Deallocating SDU", lcid); } } @@ -218,7 +218,7 @@ void rlc::write_sdu_mch(uint32_t lcid, unique_byte_buffer_t sdu) rlc_array_mrb.at(lcid)->write_sdu(std::move(sdu)); update_bsr_mch(lcid); } else { - rlc_log->warning("RLC LCID %d doesn't exist. Deallocating SDU\n", lcid); + logger.warning("RLC LCID %d doesn't exist. Deallocating SDU", lcid); } } @@ -229,7 +229,7 @@ bool rlc::rb_is_um(uint32_t lcid) if (valid_lcid(lcid)) { ret = rlc_array.at(lcid)->get_mode() == rlc_mode_t::um; } else { - rlc_log->warning("LCID %d doesn't exist.\n", lcid); + logger.warning("LCID %d doesn't exist.", lcid); } return ret; @@ -241,7 +241,7 @@ void rlc::discard_sdu(uint32_t lcid, uint32_t discard_sn) rlc_array.at(lcid)->discard_sdu(discard_sn); update_bsr(lcid); } else { - rlc_log->warning("RLC LCID %d doesn't exist. Ignoring discard SDU\n", lcid); + logger.warning("RLC LCID %d doesn't exist. Ignoring discard SDU", lcid); } } @@ -250,7 +250,7 @@ bool rlc::sdu_queue_is_full(uint32_t lcid) if (valid_lcid(lcid)) { return rlc_array.at(lcid)->sdu_queue_is_full(); } - rlc_log->warning("RLC LCID %d doesn't exist. Ignoring queue check\n", lcid); + logger.warning("RLC LCID %d doesn't exist. Ignoring queue check", lcid); return false; } @@ -300,7 +300,7 @@ int rlc::read_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) ret = rlc_array.at(lcid)->read_pdu(payload, nof_bytes); update_bsr(lcid); } else { - rlc_log->warning("LCID %d doesn't exist.\n", lcid); + logger.warning("LCID %d doesn't exist.", lcid); } return ret; @@ -315,7 +315,7 @@ int rlc::read_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) ret = rlc_array_mrb.at(lcid)->read_pdu(payload, nof_bytes); update_bsr_mch(lcid); } else { - rlc_log->warning("LCID %d doesn't exist.\n", lcid); + logger.warning("LCID %d doesn't exist.", lcid); } return ret; @@ -328,36 +328,36 @@ void rlc::write_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) rlc_array.at(lcid)->write_pdu_s(payload, nof_bytes); update_bsr(lcid); } else { - rlc_log->warning("LCID %d doesn't exist. Dropping PDU.\n", lcid); + logger.warning("LCID %d doesn't exist. Dropping PDU.", lcid); } } // Pass directly to PDCP, no DL througput counting done void rlc::write_pdu_bcch_bch(srslte::unique_byte_buffer_t pdu) { - rlc_log->info_hex(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); + logger.info(pdu->msg, pdu->N_bytes, "BCCH BCH message received."); pdcp->write_pdu_bcch_bch(std::move(pdu)); } // Pass directly to PDCP, no DL througput counting done void rlc::write_pdu_bcch_dlsch(uint8_t* payload, uint32_t nof_bytes) { - rlc_log->info_hex(payload, nof_bytes, "BCCH TXSCH message received."); - unique_byte_buffer_t buf = allocate_unique_buffer(*pool); + logger.info(payload, nof_bytes, "BCCH TXSCH message received."); + unique_byte_buffer_t buf = make_byte_buffer(); if (buf != NULL) { memcpy(buf->msg, payload, nof_bytes); buf->N_bytes = nof_bytes; buf->set_timestamp(); pdcp->write_pdu_bcch_dlsch(std::move(buf)); } else { - rlc_log->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_dlsch()\n"); + logger.error("Fatal error: Out of buffers from the pool in write_pdu_bcch_dlsch()"); } } // Pass directly to PDCP, no DL througput counting done void rlc::write_pdu_pcch(srslte::unique_byte_buffer_t pdu) { - rlc_log->info_hex(pdu->msg, pdu->N_bytes, "PCCH message received."); + logger.info(pdu->msg, pdu->N_bytes, "PCCH message received."); pdcp->write_pdu_pcch(std::move(pdu)); } @@ -402,7 +402,7 @@ void rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) if (cnfg.rlc_mode != rlc_mode_t::tm and rlc_array.find(lcid) != rlc_array.end()) { if (rlc_array[lcid]->get_mode() != cnfg.rlc_mode) { - rlc_log->info("Switching RLC entity type. Recreating it.\n"); + logger.info("Switching RLC entity type. Recreating it."); rlc_array.erase(lcid); } } @@ -411,57 +411,55 @@ void rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) if (cnfg.rat == srslte_rat_t::lte) { switch (cnfg.rlc_mode) { case rlc_mode_t::tm: - rlc_entity = new rlc_tm(rlc_log, lcid, pdcp, rrc); + rlc_entity = new rlc_tm(logger, lcid, pdcp, rrc); break; case rlc_mode_t::am: - rlc_entity = new rlc_am_lte(rlc_log, lcid, pdcp, rrc, timers); + rlc_entity = new rlc_am_lte(logger, lcid, pdcp, rrc, timers); break; case rlc_mode_t::um: - rlc_entity = new rlc_um_lte(rlc_log, lcid, pdcp, rrc, timers); + rlc_entity = new rlc_um_lte(logger, lcid, pdcp, rrc, timers); break; default: - rlc_log->error("Cannot add RLC entity - invalid mode\n"); + logger.error("Cannot add RLC entity - invalid mode"); return; } if (rlc_entity != nullptr) { rlc_entity->set_bsr_callback(bsr_callback); } -#ifdef HAVE_5GNR } else if (cnfg.rat == srslte_rat_t::nr) { switch (cnfg.rlc_mode) { case rlc_mode_t::tm: - rlc_entity = new rlc_tm(rlc_log, lcid, pdcp, rrc); + rlc_entity = new rlc_tm(logger, lcid, pdcp, rrc); break; case rlc_mode_t::um: - rlc_entity = new rlc_um_nr(rlc_log, lcid, pdcp, rrc, timers); + rlc_entity = new rlc_um_nr(logger, lcid, pdcp, rrc, timers); break; default: - rlc_log->error("Cannot add RLC entity - invalid mode\n"); + logger.error("Cannot add RLC entity - invalid mode"); return; } -#endif } else { - rlc_log->error("RAT not supported\n"); + logger.error("RAT not supported"); return; } if (not rlc_array.insert(rlc_map_pair_t(lcid, rlc_entity)).second) { - rlc_log->error("Error inserting RLC entity in to array\n."); + logger.error("Error inserting RLC entity in to array."); goto delete_and_exit; } - rlc_log->info("Added radio bearer %s in %s\n", rrc->get_rb_name(lcid).c_str(), to_string(cnfg.rlc_mode).c_str()); + logger.info("Added radio bearer %s in %s", rrc->get_rb_name(lcid).c_str(), to_string(cnfg.rlc_mode).c_str()); rlc_entity = NULL; } // configure and add to array if (cnfg.rlc_mode != rlc_mode_t::tm and rlc_array.find(lcid) != rlc_array.end()) { if (not rlc_array.at(lcid)->configure(cnfg)) { - rlc_log->error("Error configuring RLC entity\n."); + logger.error("Error configuring RLC entity."); goto delete_and_exit; } } - rlc_log->info("Configured radio bearer %s in %s\n", rrc->get_rb_name(lcid).c_str(), to_string(cnfg.rlc_mode).c_str()); + logger.info("Configured radio bearer %s in %s", rrc->get_rb_name(lcid).c_str(), to_string(cnfg.rlc_mode).c_str()); delete_and_exit: if (rlc_entity) { @@ -475,22 +473,22 @@ void rlc::add_bearer_mrb(uint32_t lcid) rlc_common* rlc_entity = NULL; if (not valid_lcid_mrb(lcid)) { - rlc_entity = new rlc_um_lte(rlc_log, lcid, pdcp, rrc, timers); + rlc_entity = new rlc_um_lte(logger, lcid, pdcp, rrc, timers); // configure and add to array if (not rlc_entity->configure(rlc_config_t::mch_config())) { - rlc_log->error("Error configuring RLC entity\n."); + logger.error("Error configuring RLC entity."); goto delete_and_exit; } if (rlc_array_mrb.count(lcid) == 0) { if (not rlc_array_mrb.insert(rlc_map_pair_t(lcid, rlc_entity)).second) { - rlc_log->error("Error inserting RLC entity in to array\n."); + logger.error("Error inserting RLC entity in to array."); goto delete_and_exit; } } - rlc_log->warning("Added bearer MRB%d with mode RLC_UM\n", lcid); + logger.warning("Added bearer MRB%d with mode RLC_UM", lcid); return; } else { - rlc_log->warning("Bearer MRB%d already created.\n", lcid); + logger.warning("Bearer MRB%d already created.", lcid); } delete_and_exit: @@ -508,9 +506,9 @@ void rlc::del_bearer(uint32_t lcid) it->second->stop(); delete (it->second); rlc_array.erase(it); - rlc_log->warning("Deleted RLC bearer %s\n", rrc->get_rb_name(lcid).c_str()); + logger.warning("Deleted RLC bearer %s", rrc->get_rb_name(lcid).c_str()); } else { - rlc_log->error("Can't delete bearer %s. Bearer doesn't exist.\n", rrc->get_rb_name(lcid).c_str()); + logger.error("Can't delete bearer %s. Bearer doesn't exist.", rrc->get_rb_name(lcid).c_str()); } } @@ -523,9 +521,9 @@ void rlc::del_bearer_mrb(uint32_t lcid) it->second->stop(); delete (it->second); rlc_array_mrb.erase(it); - rlc_log->warning("Deleted RLC MRB bearer %s\n", rrc->get_rb_name(lcid).c_str()); + logger.warning("Deleted RLC MRB bearer %s", rrc->get_rb_name(lcid).c_str()); } else { - rlc_log->error("Can't delete bearer %s. Bearer doesn't exist.\n", rrc->get_rb_name(lcid).c_str()); + logger.error("Can't delete bearer %s. Bearer doesn't exist.", rrc->get_rb_name(lcid).c_str()); } } @@ -539,22 +537,22 @@ void rlc::change_lcid(uint32_t old_lcid, uint32_t new_lcid) rlc_map_t::iterator it = rlc_array.find(old_lcid); rlc_common* rlc_entity = it->second; if (not rlc_array.insert(rlc_map_pair_t(new_lcid, rlc_entity)).second) { - rlc_log->error("Error inserting RLC entity into array\n."); + logger.error("Error inserting RLC entity into array."); return; } // erase from old position rlc_array.erase(it); if (valid_lcid(new_lcid) && not valid_lcid(old_lcid)) { - rlc_log->info("Successfully changed LCID of RLC bearer from %d to %d\n", old_lcid, new_lcid); + logger.info("Successfully changed LCID of RLC bearer from %d to %d", old_lcid, new_lcid); } else { - rlc_log->error("Error during LCID change of RLC bearer from %d to %d\n", old_lcid, new_lcid); + logger.error("Error during LCID change of RLC bearer from %d to %d", old_lcid, new_lcid); } } else { - rlc_log->error("Can't change LCID of bearer %s from %d to %d. Bearer doesn't exist or new LCID already occupied.\n", - rrc->get_rb_name(old_lcid).c_str(), - old_lcid, - new_lcid); + logger.error("Can't change LCID of bearer %s from %d to %d. Bearer doesn't exist or new LCID already occupied.", + rrc->get_rb_name(old_lcid).c_str(), + old_lcid, + new_lcid); } } @@ -563,26 +561,26 @@ void rlc::suspend_bearer(uint32_t lcid) { if (valid_lcid(lcid)) { if (rlc_array.at(lcid)->suspend()) { - rlc_log->info("Suspended radio bearer %s\n", rrc->get_rb_name(lcid).c_str()); + logger.info("Suspended radio bearer %s", rrc->get_rb_name(lcid).c_str()); } else { - rlc_log->error("Error suspending RLC entity: bearer already suspended\n."); + logger.error("Error suspending RLC entity: bearer already suspended."); } } else { - rlc_log->error("Suspending bearer: bearer %s not configured.\n", rrc->get_rb_name(lcid).c_str()); + logger.error("Suspending bearer: bearer %s not configured.", rrc->get_rb_name(lcid).c_str()); } } void rlc::resume_bearer(uint32_t lcid) { - rlc_log->info("Resuming radio bearer %s\n", rrc->get_rb_name(lcid).c_str()); + logger.info("Resuming radio bearer %s", rrc->get_rb_name(lcid).c_str()); if (valid_lcid(lcid)) { if (rlc_array.at(lcid)->resume()) { - rlc_log->info("Resumed radio bearer %s\n", rrc->get_rb_name(lcid).c_str()); + logger.info("Resumed radio bearer %s", rrc->get_rb_name(lcid).c_str()); } else { - rlc_log->error("Error resuming RLC entity: bearer not suspended\n."); + logger.error("Error resuming RLC entity: bearer not suspended."); } } else { - rlc_log->error("Resuming bearer: bearer %s not configured.\n", rrc->get_rb_name(lcid).c_str()); + logger.error("Resuming bearer: bearer %s not configured.", rrc->get_rb_name(lcid).c_str()); } } @@ -598,7 +596,7 @@ bool rlc::has_bearer(uint32_t lcid) bool rlc::valid_lcid(uint32_t lcid) { if (lcid >= SRSLTE_N_RADIO_BEARERS) { - rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); + logger.error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } @@ -612,7 +610,7 @@ bool rlc::valid_lcid(uint32_t lcid) bool rlc::valid_lcid_mrb(uint32_t lcid) { if (lcid >= SRSLTE_N_MCH_LCIDS) { - rlc_log->error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_RADIO_BEARERS, lcid); + logger.error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_RADIO_BEARERS, lcid); return false; } diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index 5a2c13a7a..5c1937c73 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -22,7 +22,6 @@ #include "srslte/upper/rlc_am_lte.h" #include -#include #define MOD 1024 #define RX_MOD_BASE(x) (((x)-vr_r) % 1024) @@ -32,12 +31,12 @@ namespace srslte { -rlc_am_lte::rlc_am_lte(srslte::log_ref log_, +rlc_am_lte::rlc_am_lte(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, srslte::timer_handler* timers_) : - log(log_), rrc(rrc_), pdcp(pdcp_), timers(timers_), lcid(lcid_), tx(this), rx(this) + logger(logger), rrc(rrc_), pdcp(pdcp_), timers(timers_), lcid(lcid_), tx(this), rx(this) {} // Applies new configuration. Must be just reestablished or initiated @@ -50,24 +49,24 @@ bool rlc_am_lte::configure(const rlc_config_t& cfg_) cfg = cfg_; if (not rx.configure(cfg.am)) { - log->error("Error configuring bearer (RX)\n"); + logger.error("Error configuring bearer (RX)"); return false; } if (not tx.configure(cfg)) { - log->error("Error configuring bearer (TX)\n"); + logger.error("Error configuring bearer (TX)"); return false; } - log->info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " - "t_reordering=%d, t_status_prohibit=%d\n", - rb_name.c_str(), - cfg.am.t_poll_retx, - cfg.am.poll_pdu, - cfg.am.poll_byte, - cfg.am.max_retx_thresh, - cfg.am.t_reordering, - cfg.am.t_status_prohibit); + logger.info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " + "t_reordering=%d, t_status_prohibit=%d", + rb_name.c_str(), + cfg.am.t_poll_retx, + cfg.am.poll_pdu, + cfg.am.poll_byte, + cfg.am.max_retx_thresh, + cfg.am.t_reordering, + cfg.am.t_status_prohibit); return true; } @@ -84,14 +83,14 @@ void rlc_am_lte::empty_queue() void rlc_am_lte::reestablish() { - log->debug("Reestablished bearer %s\n", rb_name.c_str()); + logger.debug("Reestablished bearer %s", rb_name.c_str()); tx.reestablish(); // calls stop and enables tx again rx.reestablish(); // calls only stop } void rlc_am_lte::stop() { - log->debug("Stopped bearer %s\n", rb_name.c_str()); + logger.debug("Stopped bearer %s", rb_name.c_str()); tx.stop(); rx.stop(); } @@ -176,7 +175,7 @@ void rlc_am_lte::write_pdu(uint8_t* payload, uint32_t nof_bytes) rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) : parent(parent_), - log(parent_->log), + logger(parent_->logger), pool(byte_buffer_pool::get_instance()), poll_retx_timer(parent_->timers->get_unique_timer()), status_prohibit_timer(parent_->timers->get_unique_timer()) @@ -201,7 +200,7 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) // check timers if (not poll_retx_timer.is_valid() or not status_prohibit_timer.is_valid()) { - log->error("Configuring RLC AM TX: timers not configured\n"); + logger.error("Configuring RLC AM TX: timers not configured"); return false; } @@ -251,6 +250,10 @@ void rlc_am_lte::rlc_am_lte_tx::stop() // Drop all messages in RETX queue retx_queue.clear(); + + // Drop all SDU info in queue + undelivered_sdu_info_queue.clear(); + pthread_mutex_unlock(&mutex); } @@ -295,36 +298,36 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() uint32_t n_bytes = 0; uint32_t n_sdus = 0; - log->debug("%s Buffer state - do_status=%s, status_prohibit_running=%s (%d/%d)\n", - RB_NAME, - do_status() ? "yes" : "no", - status_prohibit_timer.is_running() ? "yes" : "no", - status_prohibit_timer.time_elapsed(), - status_prohibit_timer.duration()); + logger.debug("%s Buffer state - do_status=%s, status_prohibit_running=%s (%d/%d)", + RB_NAME, + do_status() ? "yes" : "no", + status_prohibit_timer.is_running() ? "yes" : "no", + status_prohibit_timer.time_elapsed(), + status_prohibit_timer.duration()); // Bytes needed for status report if (do_status() && not status_prohibit_timer.is_running()) { n_bytes += parent->rx.get_status_pdu_length(); - log->debug("%s Buffer state - total status report: %d bytes\n", RB_NAME, n_bytes); + logger.debug("%s Buffer state - total status report: %d bytes", RB_NAME, n_bytes); } // Bytes needed for retx if (not retx_queue.empty()) { rlc_amd_retx_t retx = retx_queue.front(); - log->debug("%s Buffer state - retx - SN=%d, Segment: %s, %d:%d\n", - RB_NAME, - retx.sn, - retx.is_segment ? "true" : "false", - retx.so_start, - retx.so_end); - if (tx_window.end() != tx_window.find(retx.sn)) { + logger.debug("%s Buffer state - retx - SN=%d, Segment: %s, %d:%d", + RB_NAME, + retx.sn, + retx.is_segment ? "true" : "false", + retx.so_start, + retx.so_end); + if (tx_window.has_sn(retx.sn)) { int req_bytes = required_buffer_size(retx); if (req_bytes < 0) { - log->error("In get_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn); + logger.error("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn); retx_queue.pop_front(); } else { n_bytes += req_bytes; - log->debug("Buffer state - retx: %d bytes\n", n_bytes); + logger.debug("Buffer state - retx: %d bytes", n_bytes); } } } @@ -347,7 +350,7 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() // Room needed for fixed header of data PDUs if (n_bytes > 0 && n_sdus > 0) { n_bytes += 2; // Two bytes for fixed header with SN length = 10 - log->debug("%s Total buffer state - %d SDUs (%d B)\n", RB_NAME, n_sdus, n_bytes); + logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes); } pthread_mutex_unlock(&mutex); @@ -356,32 +359,52 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) { + pthread_mutex_lock(&mutex); + if (!tx_enabled) { + pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } if (sdu.get() == nullptr) { - log->warning("NULL SDU pointer in write_sdu()\n"); + logger.warning("NULL SDU pointer in write_sdu()"); + pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } + // Get SDU info + uint32_t sdu_pdcp_sn = sdu->md.pdcp_sn; + + // Store SDU uint8_t* msg_ptr = sdu->msg; uint32_t nof_bytes = sdu->N_bytes; srslte::error_type ret = tx_sdu_queue.try_write(std::move(sdu)); if (ret) { - log->info_hex( - msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)\n", RB_NAME, nof_bytes, tx_sdu_queue.size()); + logger.info(msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, nof_bytes, tx_sdu_queue.size()); } else { // in case of fail, the try_write returns back the sdu - log->warning_hex(ret.error()->msg, - ret.error()->N_bytes, - "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)\n", - RB_NAME, - ret.error()->N_bytes, - tx_sdu_queue.size()); + logger.warning(ret.error()->msg, + ret.error()->N_bytes, + "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", + RB_NAME, + ret.error()->N_bytes, + tx_sdu_queue.size()); + pthread_mutex_unlock(&mutex); return SRSLTE_ERROR; } + // Store SDU info + logger.debug( + "Storing PDCP SDU info in queue. PDCP_SN=%d, Queue Size=%ld", sdu_pdcp_sn, undelivered_sdu_info_queue.nof_sdus()); + + if (undelivered_sdu_info_queue.has_pdcp_sn(sdu_pdcp_sn)) { + logger.error("PDCP SDU info already exists. SN=%d", sdu_pdcp_sn); + pthread_mutex_unlock(&mutex); + return SRSLTE_ERROR; + } + + undelivered_sdu_info_queue.add_pdcp_sdu(sdu_pdcp_sn); + pthread_mutex_unlock(&mutex); return SRSLTE_SUCCESS; } @@ -390,7 +413,7 @@ void rlc_am_lte::rlc_am_lte_tx::discard_sdu(uint32_t discard_sn) if (!tx_enabled) { return; } - log->warning("Discard SDU not implemented yet\n"); + logger.warning("Discard SDU not implemented yet"); } bool rlc_am_lte::rlc_am_lte_tx::sdu_queue_is_full() @@ -404,11 +427,15 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) int pdu_size = 0; - log->debug("MAC opportunity - %d bytes\n", nof_bytes); - log->debug("tx_window size - %zu PDUs\n", tx_window.size()); + if (not tx_enabled) { + goto unlock_and_exit; + } + + logger.debug("MAC opportunity - %d bytes", nof_bytes); + logger.debug("tx_window size - %zu PDUs", tx_window.size()); if (not tx_enabled) { - log->debug("RLC entity not active. Not generating PDU.\n"); + logger.debug("RLC entity not active. Not generating PDU."); goto unlock_and_exit; } @@ -443,7 +470,7 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) { pthread_mutex_lock(&mutex); if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) { - log->debug("%s Poll reTx timer expired after %dms\n", RB_NAME, poll_retx_timer.duration()); + logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration()); // Section 5.2.2.3 in TS 36.311, schedule PDU for retransmission if // (a) both tx and retx buffer are empty, or // (b) no new data PDU can be transmitted (tx window is full) @@ -462,13 +489,13 @@ void rlc_am_lte::rlc_am_lte_tx::retransmit_pdu() { if (not tx_window.empty()) { // select PDU in tx window for retransmission - std::map::iterator it = tx_window.begin(); - log->info("%s Schedule SN=%d for reTx.\n", RB_NAME, it->first); + rlc_amd_tx_pdu_t& pdu = tx_window.front(); + logger.info("%s Schedule SN=%d for reTx.", RB_NAME, pdu.rlc_sn); rlc_amd_retx_t retx = {}; retx.is_segment = false; retx.so_start = 0; - retx.so_end = it->second.buf->N_bytes; - retx.sn = it->first; + retx.so_end = pdu.buf->N_bytes; + retx.sn = pdu.rlc_sn; retx_queue.push_back(retx); } } @@ -523,9 +550,9 @@ bool rlc_am_lte::rlc_am_lte_tx::poll_required() int rlc_am_lte::rlc_am_lte_tx::build_status_pdu(uint8_t* payload, uint32_t nof_bytes) { int pdu_len = parent->rx.get_status_pdu(&tx_status, nof_bytes); - log->debug("%s\n", rlc_am_status_pdu_to_string(&tx_status).c_str()); + logger.debug("%s", rlc_am_status_pdu_to_string(&tx_status).c_str()); if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { - log->info("%s Tx status PDU - %s\n", RB_NAME, rlc_am_status_pdu_to_string(&tx_status).c_str()); + logger.info("%s Tx status PDU - %s", RB_NAME, rlc_am_status_pdu_to_string(&tx_status).c_str()); parent->rx.reset_status(); @@ -536,7 +563,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_status_pdu(uint8_t* payload, uint32_t nof_b debug_state(); pdu_len = rlc_am_write_status_pdu(&tx_status, payload); } else { - log->info("%s Cannot tx status PDU - %d bytes available, %d bytes required\n", RB_NAME, nof_bytes, pdu_len); + logger.info("%s Cannot tx status PDU - %d bytes available, %d bytes required", RB_NAME, nof_bytes, pdu_len); pdu_len = 0; } @@ -547,19 +574,19 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt { // Check there is at least 1 element before calling front() if (retx_queue.empty()) { - log->error("In build_retx_pdu(): retx_queue is empty\n"); + logger.error("In build_retx_pdu(): retx_queue is empty"); return -1; } rlc_amd_retx_t retx = retx_queue.front(); // Sanity check - drop any retx SNs not present in tx_window - while (tx_window.end() == tx_window.find(retx.sn)) { + while (not tx_window.has_sn(retx.sn)) { retx_queue.pop_front(); if (!retx_queue.empty()) { retx = retx_queue.front(); } else { - log->info("In build_retx_pdu(): retx_queue is empty during sanity check, sn=%d\n", retx.sn); + logger.info("In build_retx_pdu(): retx_queue is empty during sanity check, sn=%d", retx.sn); return 0; } } @@ -567,13 +594,13 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt // Is resegmentation needed? int req_size = required_buffer_size(retx); if (req_size < 0) { - log->error("In build_retx_pdu(): Removing retx.sn=%d from queue\n", retx.sn); + logger.error("In build_retx_pdu(): Removing retx.sn=%d from queue", retx.sn); retx_queue.pop_front(); return -1; } if (retx.is_segment || req_size > static_cast(nof_bytes)) { - log->debug("%s build_retx_pdu - resegmentation required\n", RB_NAME); + logger.debug("%s build_retx_pdu - resegmentation required", RB_NAME); return build_segment(payload, nof_bytes, retx); } @@ -584,8 +611,8 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt // Set poll bit pdu_without_poll++; byte_without_poll += (tx_window[retx.sn].buf->N_bytes + rlc_am_packed_length(&new_header)); - log->info("%s pdu_without_poll: %d\n", RB_NAME, pdu_without_poll); - log->info("%s byte_without_poll: %d\n", RB_NAME, byte_without_poll); + logger.info("%s pdu_without_poll: %d", RB_NAME, pdu_without_poll); + logger.info("%s byte_without_poll: %d", RB_NAME, byte_without_poll); if (poll_required()) { new_header.p = 1; // vt_s won't change for reTx, so don't update poll_sn @@ -604,19 +631,20 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt retx_queue.pop_front(); tx_window[retx.sn].retx_count++; if (tx_window[retx.sn].retx_count >= cfg.max_retx_thresh) { - log->warning("%s Signaling max number of reTx=%d for for SN=%d\n", RB_NAME, tx_window[retx.sn].retx_count, retx.sn); + logger.warning("%s Signaling max number of reTx=%d for for SN=%d", RB_NAME, tx_window[retx.sn].retx_count, retx.sn); parent->rrc->max_retx_attempted(); + parent->pdcp->notify_failure(parent->lcid, tx_window[retx.sn].pdcp_sns); } - log->info_hex(payload, - tx_window[retx.sn].buf->N_bytes, - "%s Tx PDU SN=%d (%d B) (attempt %d/%d)\n", - RB_NAME, - retx.sn, - tx_window[retx.sn].buf->N_bytes, - tx_window[retx.sn].retx_count + 1, - cfg.max_retx_thresh); - log->debug("%s\n", rlc_amd_pdu_header_to_string(new_header).c_str()); + logger.info(payload, + tx_window[retx.sn].buf->N_bytes, + "%s Tx PDU SN=%d (%d B) (attempt %d/%d)", + RB_NAME, + retx.sn, + tx_window[retx.sn].buf->N_bytes, + tx_window[retx.sn].retx_count + 1, + cfg.max_retx_thresh); + logger.debug("%s", rlc_amd_pdu_header_to_string(new_header).c_str()); debug_state(); return (ptr - payload) + tx_window[retx.sn].buf->N_bytes; @@ -625,7 +653,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx) { if (tx_window[retx.sn].buf == NULL) { - log->error("In build_segment: retx.sn=%d has null buffer\n", retx.sn); + logger.error("In build_segment: retx.sn=%d has null buffer", retx.sn); return 0; } if (!retx.is_segment) { @@ -639,8 +667,8 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte pdu_without_poll++; byte_without_poll += (tx_window[retx.sn].buf->N_bytes + rlc_am_packed_length(&new_header)); - log->info("%s pdu_without_poll: %d\n", RB_NAME, pdu_without_poll); - log->info("%s byte_without_poll: %d\n", RB_NAME, byte_without_poll); + logger.info("%s pdu_without_poll: %d", RB_NAME, pdu_without_poll); + logger.info("%s byte_without_poll: %d", RB_NAME, byte_without_poll); new_header.dc = RLC_DC_FIELD_DATA_PDU; new_header.rf = 1; @@ -651,7 +679,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte new_header.N_li = 0; new_header.p = 0; if (poll_required()) { - log->debug("%s setting poll bit to request status\n", RB_NAME); + logger.debug("%s setting poll bit to request status", RB_NAME); new_header.p = 1; // vt_s won't change for reTx, so don't update poll_sn pdu_without_poll = 0; @@ -671,10 +699,10 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte } if (nof_bytes <= head_len) { - log->info("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header\n", - RB_NAME, - nof_bytes, - head_len); + logger.info("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header", + RB_NAME, + nof_bytes, + head_len); return 0; } @@ -767,24 +795,24 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte debug_state(); int pdu_len = (ptr - payload) + len; if (pdu_len > static_cast(nof_bytes)) { - log->error("%s Retx PDU segment length error. Available: %d, Used: %d\n", RB_NAME, nof_bytes, pdu_len); + logger.error("%s Retx PDU segment length error. Available: %d, Used: %d", RB_NAME, nof_bytes, pdu_len); int header_len = (ptr - payload); - log->debug("%s Retx PDU segment length error. Header len: %d, Payload len: %d, N_li: %d\n", - RB_NAME, - header_len, - len, - new_header.N_li); + logger.debug("%s Retx PDU segment length error. Header len: %d, Payload len: %d, N_li: %d", + RB_NAME, + header_len, + len, + new_header.N_li); } - log->info_hex(payload, - pdu_len, - "%s Retx PDU segment SN=%d [so=%d] (%d B) (attempt %d/%d)\n", - RB_NAME, - retx.sn, - retx.so_start, - pdu_len, - tx_window[retx.sn].retx_count + 1, - cfg.max_retx_thresh); + logger.info(payload, + pdu_len, + "%s Retx PDU segment SN=%d [so=%d] (%d B) (attempt %d/%d)", + RB_NAME, + retx.sn, + retx.so_start, + pdu_len, + tx_window[retx.sn].retx_count + 1, + cfg.max_retx_thresh); return pdu_len; } @@ -792,17 +820,17 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_bytes) { if (tx_sdu == NULL && tx_sdu_queue.is_empty()) { - log->info("No data available to be sent\n"); + logger.info("No data available to be sent"); return 0; } // do not build any more PDU if window is already full if (tx_sdu == NULL && tx_window.size() >= RLC_AM_WINDOW_SIZE) { - log->info("Tx window full.\n"); + logger.info("Tx window full."); return 0; } - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Could not allocate PDU in build_data_pdu()\n"); @@ -815,7 +843,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt } exit(-1); #else - log->error("Fatal Error: Couldn't allocate PDU in build_data_pdu().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in build_data_pdu()."); return 0; #endif } @@ -831,14 +859,15 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt uint8_t* pdu_ptr = pdu->msg; if (pdu_space <= head_len) { - log->info( - "%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", RB_NAME, nof_bytes, head_len); + logger.info( + "%s Cannot build a PDU - %d bytes available, %d bytes required for header", RB_NAME, nof_bytes, head_len); return 0; } - log->debug("%s Building PDU - pdu_space: %d, head_len: %d \n", RB_NAME, pdu_space, head_len); + logger.debug("%s Building PDU - pdu_space: %d, head_len: %d ", RB_NAME, pdu_space, head_len); // Check for SDU segment + std::vector pdcp_sns; if (tx_sdu != NULL) { to_move = ((pdu_space - head_len) >= tx_sdu->N_bytes) ? tx_sdu->N_bytes : pdu_space - head_len; memcpy(pdu_ptr, tx_sdu->msg, to_move); @@ -847,8 +876,16 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; + if (not undelivered_sdu_info_queue.has_pdcp_sn(tx_sdu->md.pdcp_sn)) { + logger.error("Could not find PDCP SN in SDU info queue (segment). PDCP_SN=%d", tx_sdu->md.pdcp_sn); + return 0; + } + pdcp_sdu_info_t& pdcp_sdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; + pdcp_sdu.rlc_sn_info_list.push_back({header.sn, false}); + pdcp_sns.push_back(tx_sdu->md.pdcp_sn); if (tx_sdu->N_bytes == 0) { - log->debug("%s Complete SDU scheduled for tx.\n", RB_NAME); + logger.debug("%s Complete SDU scheduled for tx.", RB_NAME); + pdcp_sdu.fully_txed = true; tx_sdu.reset(); } if (pdu_space > to_move) { @@ -858,11 +895,11 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt } header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU - log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n", - RB_NAME, - to_move, - pdu_space, - head_len); + logger.debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d ", + RB_NAME, + to_move, + pdu_space, + head_len); } // Pull SDUs from queue @@ -886,8 +923,16 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; + if (not undelivered_sdu_info_queue.has_pdcp_sn(tx_sdu->md.pdcp_sn)) { + logger.error("Could not find PDCP SN in SDU info queue. PDCP_SN=%d", tx_sdu->md.pdcp_sn); + return 0; + } + pdcp_sdu_info_t& pdcp_sdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; + pdcp_sdu.rlc_sn_info_list.push_back({header.sn, false}); + pdcp_sns.push_back(tx_sdu->md.pdcp_sn); if (tx_sdu->N_bytes == 0) { - log->debug("%s Complete SDU scheduled for tx.\n", RB_NAME); + logger.debug("%s Complete SDU scheduled for tx. PDCP SN=%d", RB_NAME, tx_sdu->md.pdcp_sn); + pdcp_sdu.fully_txed = true; tx_sdu.reset(); } if (pdu_space > to_move) { @@ -896,16 +941,16 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt pdu_space = 0; } - log->debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d \n", - RB_NAME, - to_move, - pdu_space, - head_len); + logger.debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d ", + RB_NAME, + to_move, + pdu_space, + head_len); } // Make sure, at least one SDU (segment) has been added until this point if (pdu->N_bytes == 0) { - log->error("Generated empty RLC PDU.\n"); + logger.error("Generated empty RLC PDU."); return 0; } @@ -916,10 +961,10 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt // Set Poll bit pdu_without_poll++; byte_without_poll += (pdu->N_bytes + head_len); - log->debug("%s pdu_without_poll: %d\n", RB_NAME, pdu_without_poll); - log->debug("%s byte_without_poll: %d\n", RB_NAME, byte_without_poll); + logger.debug("%s pdu_without_poll: %d", RB_NAME, pdu_without_poll); + logger.debug("%s byte_without_poll: %d", RB_NAME, byte_without_poll); if (poll_required()) { - log->debug("%s setting poll bit to request status\n", RB_NAME); + logger.debug("%s setting poll bit to request status", RB_NAME); header.p = 1; poll_sn = vt_s; pdu_without_poll = 0; @@ -934,18 +979,21 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt vt_s = (vt_s + 1) % MOD; // Place PDU in tx_window, write header and TX + tx_window.add_pdu(header.sn); tx_window[header.sn].buf = std::move(pdu); tx_window[header.sn].header = header; tx_window[header.sn].is_acked = false; tx_window[header.sn].retx_count = 0; + tx_window[header.sn].rlc_sn = header.sn; + tx_window[header.sn].pdcp_sns = std::move(pdcp_sns); const byte_buffer_t* buffer_ptr = tx_window[header.sn].buf.get(); uint8_t* ptr = payload; rlc_am_write_data_pdu_header(&header, &ptr); memcpy(ptr, buffer_ptr->msg, buffer_ptr->N_bytes); int total_len = (ptr - payload) + buffer_ptr->N_bytes; - log->info_hex(payload, total_len, "%s Tx PDU SN=%d (%d B)\n", RB_NAME, header.sn, total_len); - log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); + logger.info(payload, total_len, "%s Tx PDU SN=%d (%d B)", RB_NAME, header.sn, total_len); + logger.debug("%s", rlc_amd_pdu_header_to_string(header).c_str()); debug_state(); return total_len; @@ -953,19 +1001,23 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) { + if (not tx_enabled) { + return; + } + pthread_mutex_lock(&mutex); - log->info_hex(payload, nof_bytes, "%s Rx control PDU", RB_NAME); + logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME); rlc_status_pdu_t status; rlc_am_read_status_pdu(payload, nof_bytes, &status); - log->info("%s Rx Status PDU: %s\n", RB_NAME, rlc_am_status_pdu_to_string(&status).c_str()); + logger.info("%s Rx Status PDU: %s", RB_NAME, rlc_am_status_pdu_to_string(&status).c_str()); // Sec 5.2.2.2, stop poll reTx timer if status PDU comprises a positive _or_ negative acknowledgement // for the RLC data PDU with sequence number poll_sn if (poll_retx_timer.is_valid() && (TX_MOD_BASE(poll_sn) < TX_MOD_BASE(status.ack_sn))) { - log->debug("%s Stopping pollRetx timer\n", RB_NAME); + logger.debug("%s Stopping pollRetx timer", RB_NAME); poll_retx_timer.stop(); } @@ -975,9 +1027,9 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no } // Handle ACKs and NACKs - std::map::iterator it; - bool update_vt_a = true; - uint32_t i = vt_a; + bool update_vt_a = true; + uint32_t i = vt_a; + std::vector notify_info_vec; while (TX_MOD_BASE(i) < TX_MOD_BASE(status.ack_sn) && TX_MOD_BASE(i) < TX_MOD_BASE(vt_s)) { bool nack = false; @@ -985,43 +1037,41 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no if (status.nacks[j].nack_sn == i) { nack = true; update_vt_a = false; - it = tx_window.find(i); - if (tx_window.end() != it) { + if (tx_window.has_sn(i)) { + auto& pdu = tx_window[i]; if (!retx_queue_has_sn(i)) { rlc_amd_retx_t retx = {}; retx.sn = i; retx.is_segment = false; retx.so_start = 0; - retx.so_end = it->second.buf->N_bytes; + retx.so_end = pdu.buf->N_bytes; if (status.nacks[j].has_so) { // sanity check - if (status.nacks[j].so_start >= it->second.buf->N_bytes) { + if (status.nacks[j].so_start >= pdu.buf->N_bytes) { // print error but try to send original PDU again - log->info("SO_start is larger than original PDU (%d >= %d)\n", - status.nacks[j].so_start, - it->second.buf->N_bytes); + logger.info( + "SO_start is larger than original PDU (%d >= %d)", status.nacks[j].so_start, pdu.buf->N_bytes); status.nacks[j].so_start = 0; } // check for special SO_end value if (status.nacks[j].so_end == 0x7FFF) { - status.nacks[j].so_end = it->second.buf->N_bytes; + status.nacks[j].so_end = pdu.buf->N_bytes; } else { retx.so_end = status.nacks[j].so_end + 1; } - if (status.nacks[j].so_start < it->second.buf->N_bytes && - status.nacks[j].so_end <= it->second.buf->N_bytes) { + if (status.nacks[j].so_start < pdu.buf->N_bytes && status.nacks[j].so_end <= pdu.buf->N_bytes) { retx.is_segment = true; retx.so_start = status.nacks[j].so_start; } else { - log->warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d\n", - RB_NAME, - i, - status.nacks[j].so_start, - status.nacks[j].so_end, - it->second.buf->N_bytes); + logger.warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d", + RB_NAME, + i, + status.nacks[j].so_start, + status.nacks[j].so_end, + pdu.buf->N_bytes); } } retx_queue.push_back(retx); @@ -1032,42 +1082,97 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no if (!nack) { // ACKed SNs get marked and removed from tx_window if possible - if (tx_window.count(i) > 0) { - it = tx_window.find(i); - if (it != tx_window.end()) { - if (update_vt_a) { - tx_window.erase(it); - vt_a = (vt_a + 1) % MOD; - vt_ms = (vt_ms + 1) % MOD; - } + if (tx_window.has_sn(i)) { + auto& pdu = tx_window[i]; + update_notification_ack_info(pdu, notify_info_vec); + if (update_vt_a) { + tx_window.remove_pdu(i); + vt_a = (vt_a + 1) % MOD; + vt_ms = (vt_ms + 1) % MOD; } } } i = (i + 1) % MOD; } + if (not notify_info_vec.empty()) { + // Remove all SDUs that were fully acked + for (uint32_t acked_pdcp_sn : notify_info_vec) { + logger.debug("Erasing SDU info: PDCP_SN=%d", acked_pdcp_sn); + if (not undelivered_sdu_info_queue.has_pdcp_sn(acked_pdcp_sn)) { + logger.error("Could not find info to erase: SN=%d", acked_pdcp_sn); + } + undelivered_sdu_info_queue.clear_pdcp_sdu(acked_pdcp_sn); + } + } + debug_state(); pthread_mutex_unlock(&mutex); + + // Notify PDCP without holding Tx mutex + if (not notify_info_vec.empty()) { + parent->pdcp->notify_delivery(parent->lcid, notify_info_vec); + } +} + +/* + * Helper function to detect whether a PDU has been fully ack'ed and the PDCP needs to be notified about it + * @tx_pdu: RLC PDU that was ack'ed. + * @notify_info_vec: Vector which will keep track of the PDCP PDU SNs that have been fully ack'ed. + */ +void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu, + std::vector& notify_info_vec) +{ + logger.debug("Updating ACK info: RLC SN=%d, number of notified SDU=%ld, number of undelivered SDUs=%ld", + tx_pdu.header.sn, + notify_info_vec.size(), + undelivered_sdu_info_queue.nof_sdus()); + // Iterate over all undelivered SDUs + if (not tx_window.has_sn(tx_pdu.header.sn)) { + return; + } + std::vector& pdcp_sns = tx_window[tx_pdu.header.sn].pdcp_sns; + for (uint32_t pdcp_sn : pdcp_sns) { + // Iterate over all SNs that were TX'ed + auto& info = undelivered_sdu_info_queue[pdcp_sn]; + for (auto& rlc_sn_info : info.rlc_sn_info_list) { + // Mark this SN as acked, if necessary + if (rlc_sn_info.is_acked == false && rlc_sn_info.sn == tx_pdu.header.sn) { + rlc_sn_info.is_acked = true; + } + } + // Check wether the SDU was fully acked + if (info.fully_txed and not info.fully_acked) { + // Check if all SNs were ACK'ed + info.fully_acked = std::all_of(info.rlc_sn_info_list.begin(), + info.rlc_sn_info_list.end(), + [](rlc_sn_info_t rlc_sn_info) { return rlc_sn_info.is_acked; }); + if (info.fully_acked) { + notify_info_vec.push_back(pdcp_sn); + } + } + } + pdcp_sns.clear(); } void rlc_am_lte::rlc_am_lte_tx::debug_state() { - log->debug("%s vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d\n", RB_NAME, vt_a, vt_ms, vt_s, poll_sn); + logger.debug("%s vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d", RB_NAME, vt_a, vt_ms, vt_s, poll_sn); } int rlc_am_lte::rlc_am_lte_tx::required_buffer_size(rlc_amd_retx_t retx) { if (!retx.is_segment) { - if (tx_window.count(retx.sn) == 1) { + if (tx_window.has_sn(retx.sn)) { if (tx_window[retx.sn].buf) { return rlc_am_packed_length(&tx_window[retx.sn].header) + tx_window[retx.sn].buf->N_bytes; } else { - log->warning("retx.sn=%d has null ptr in required_buffer_size()\n", retx.sn); + logger.warning("retx.sn=%d has null ptr in required_buffer_size()", retx.sn); return -1; } } else { - log->warning("retx.sn=%d does not exist in required_buffer_size()\n", retx.sn); + logger.warning("retx.sn=%d does not exist in required_buffer_size()", retx.sn); return -1; } } @@ -1147,7 +1252,7 @@ bool rlc_am_lte::rlc_am_lte_tx::retx_queue_has_sn(uint32_t sn) rlc_am_lte::rlc_am_lte_rx::rlc_am_lte_rx(rlc_am_lte* parent_) : parent(parent_), pool(byte_buffer_pool::get_instance()), - log(parent_->log), + logger(parent_->logger), reordering_timer(parent_->timers->get_unique_timer()) { pthread_mutex_init(&mutex, NULL); @@ -1165,7 +1270,7 @@ bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_) // check timers if (not reordering_timer.is_valid()) { - log->error("Configuring RLC AM TX: timers not configured\n"); + logger.error("Configuring RLC AM TX: timers not configured"); return false; } @@ -1220,8 +1325,8 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b { std::map::iterator it; - log->info_hex(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", RB_NAME, header.sn, nof_bytes); - log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); + logger.info(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", RB_NAME, header.sn, nof_bytes); + logger.debug("%s", rlc_amd_pdu_header_to_string(header).c_str()); // sanity check for segments not exceeding PDU length if (header.N_li > 0) { @@ -1229,7 +1334,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b for (uint32_t i = 0; i < header.N_li; i++) { segments_len += header.li[i]; if (segments_len > nof_bytes) { - log->info("Dropping corrupted PDU (segments_len=%d > pdu_len=%d)\n", segments_len, nof_bytes); + logger.info("Dropping corrupted PDU (segments_len=%d > pdu_len=%d)", segments_len, nof_bytes); return; } } @@ -1237,32 +1342,32 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b if (!inside_rx_window(header.sn)) { if (header.p) { - log->info("%s Status packet requested through polling bit\n", RB_NAME); + logger.info("%s Status packet requested through polling bit", RB_NAME); do_status = true; } - log->info("%s SN=%d outside rx window [%d:%d] - discarding\n", RB_NAME, header.sn, vr_r, vr_mr); + logger.info("%s SN=%d outside rx window [%d:%d] - discarding", RB_NAME, header.sn, vr_r, vr_mr); return; } it = rx_window.find(header.sn); if (rx_window.end() != it) { if (header.p) { - log->info("%s Status packet requested through polling bit\n", RB_NAME); + logger.info("%s Status packet requested through polling bit", RB_NAME); do_status = true; } - log->info("%s Discarding duplicate SN=%d\n", RB_NAME, header.sn); + logger.info("%s Discarding duplicate SN=%d", RB_NAME, header.sn); return; } // Write to rx window rlc_amd_rx_pdu_t pdu; - pdu.buf = srslte::allocate_unique_buffer(*pool, true); + pdu.buf = srslte::make_byte_buffer(); if (pdu.buf == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); exit(-1); #else - log->error("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in handle_data_pdu()."); return; #endif } @@ -1270,11 +1375,11 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b // check available space for payload if (nof_bytes > pdu.buf->get_tailroom()) { - log->error("%s Discarding SN=%d of size %d B (available space %d B)\n", - RB_NAME, - header.sn, - nof_bytes, - pdu.buf->get_tailroom()); + logger.error("%s Discarding SN=%d of size %d B (available space %d B)", + RB_NAME, + header.sn, + nof_bytes, + pdu.buf->get_tailroom()); return; } memcpy(pdu.buf->msg, payload, nof_bytes); @@ -1297,7 +1402,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b // Check poll bit if (header.p) { - log->info("%s Status packet requested through polling bit\n", RB_NAME); + logger.info("%s Status packet requested through polling bit", RB_NAME); poll_received = true; // 36.322 v10 Section 5.2.3 @@ -1314,21 +1419,21 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b if (reordering_timer.is_valid()) { if (reordering_timer.is_running()) { if (vr_x == vr_r || (!inside_rx_window(vr_x) && vr_x != vr_mr)) { - log->debug("Stopping reordering timer.\n"); + logger.debug("Stopping reordering timer."); reordering_timer.stop(); } else { - log->debug("Leave reordering timer running.\n"); + logger.debug("Leave reordering timer running."); } debug_state(); } if (not reordering_timer.is_running()) { if (RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_r)) { - log->debug("Starting reordering timer.\n"); + logger.debug("Starting reordering timer."); reordering_timer.run(); vr_x = vr_h; } else { - log->debug("Leave reordering timer stopped.\n"); + logger.debug("Leave reordering timer stopped."); } debug_state(); } @@ -1343,40 +1448,40 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa { std::map::iterator it; - log->info_hex(payload, - nof_bytes, - "%s Rx data PDU segment of SN=%d (%d B), SO=%d, N_li=%d", - RB_NAME, - header.sn, - nof_bytes, - header.so, - header.N_li); - log->debug("%s\n", rlc_amd_pdu_header_to_string(header).c_str()); + logger.info(payload, + nof_bytes, + "%s Rx data PDU segment of SN=%d (%d B), SO=%d, N_li=%d", + RB_NAME, + header.sn, + nof_bytes, + header.so, + header.N_li); + logger.debug("%s", rlc_amd_pdu_header_to_string(header).c_str()); // Check inside rx window if (!inside_rx_window(header.sn)) { if (header.p) { - log->info("%s Status packet requested through polling bit\n", RB_NAME); + logger.info("%s Status packet requested through polling bit", RB_NAME); do_status = true; } - log->info("%s SN=%d outside rx window [%d:%d] - discarding\n", RB_NAME, header.sn, vr_r, vr_mr); + logger.info("%s SN=%d outside rx window [%d:%d] - discarding", RB_NAME, header.sn, vr_r, vr_mr); return; } rlc_amd_rx_pdu_t segment; - segment.buf = srslte::allocate_unique_buffer(*pool, true); + segment.buf = srslte::make_byte_buffer(); if (segment.buf == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n"); exit(-1); #else - log->error("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in handle_data_pdu_segment()."); return; #endif } if (segment.buf->get_tailroom() < nof_bytes) { - log->info("Dropping corrupted segment SN=%d, not enough space to fit %d B\n", header.sn, nof_bytes); + logger.info("Dropping corrupted segment SN=%d, not enough space to fit %d B", header.sn, nof_bytes); return; } @@ -1387,9 +1492,8 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa // Check if we already have a segment from the same PDU it = rx_segments.find(header.sn); if (rx_segments.end() != it) { - if (header.p) { - log->info("%s Status packet requested through polling bit\n", RB_NAME); + logger.info("%s Status packet requested through polling bit", RB_NAME); do_status = true; } @@ -1400,7 +1504,6 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa } } else { - // Create new PDU segment list and write to rx_segments rlc_amd_rx_pdu_segments_t pdu; pdu.segments.push_back(std::move(segment)); @@ -1413,7 +1516,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa // Check poll bit if (header.p) { - log->info("%s Status packet requested through polling bit\n", RB_NAME); + logger.info("%s Status packet requested through polling bit", RB_NAME); poll_received = true; // 36.322 v10 Section 5.2.3 @@ -1433,13 +1536,13 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() { uint32_t len = 0; if (rx_sdu == NULL) { - rx_sdu = allocate_unique_buffer(*pool, true); + rx_sdu = srslte::make_byte_buffer(); if (rx_sdu == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); exit(-1); #else - log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); + logger.error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)"); return; #endif } @@ -1451,13 +1554,13 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() for (uint32_t i = 0; i < rx_window[vr_r].header.N_li; i++) { len = rx_window[vr_r].header.li[i]; - log->debug_hex(rx_window[vr_r].buf->msg, - len, - "Handling segment %d/%d of length %d B of SN=%d\n", - i + 1, - rx_window[vr_r].header.N_li, - len, - vr_r); + logger.debug(rx_window[vr_r].buf->msg, + len, + "Handling segment %d/%d of length %d B of SN=%d", + i + 1, + rx_window[vr_r].header.N_li, + len, + vr_r); // sanity check to avoid zero-size SDUs if (len == 0) { @@ -1467,7 +1570,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() if (rx_sdu->get_tailroom() >= len) { if ((rx_window[vr_r].buf->msg - rx_window[vr_r].buf->buffer) + len < SRSLTE_MAX_BUFFER_SIZE_BYTES) { if (rx_window[vr_r].buf->N_bytes < len) { - log->error("Dropping corrupted SN=%d\n", vr_r); + logger.error("Dropping corrupted SN=%d", vr_r); rx_sdu.reset(); goto exit; } @@ -1481,31 +1584,31 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() rx_window[vr_r].buf->msg += len; rx_window[vr_r].buf->N_bytes -= len; - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); + logger.info(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); sdu_rx_latency_ms.push(std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - rx_sdu->get_timestamp()) .count()); parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu)); parent->metrics.num_rx_sdus++; - rx_sdu = allocate_unique_buffer(*pool, true); + rx_sdu = srslte::make_byte_buffer(); if (rx_sdu == nullptr) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); exit(-1); #else - log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); + logger.error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)"); return; #endif } } else { int buf_len = rx_window[vr_r].buf->msg - rx_window[vr_r].buf->buffer; - log->error("Cannot read %d bytes from rx_window. vr_r=%d, msg-buffer=%d B\n", len, vr_r, buf_len); + logger.error("Cannot read %d bytes from rx_window. vr_r=%d, msg-buffer=%d B", len, vr_r, buf_len); rx_sdu.reset(); goto exit; } } else { - log->error("Cannot fit RLC PDU in SDU buffer, dropping both.\n"); + logger.error("Cannot fit RLC PDU in SDU buffer, dropping both."); rx_sdu.reset(); goto exit; } @@ -1513,7 +1616,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() // Handle last segment len = rx_window[vr_r].buf->N_bytes; - log->debug_hex(rx_window[vr_r].buf->msg, len, "Handling last segment of length %d B of SN=%d\n", len, vr_r); + logger.debug(rx_window[vr_r].buf->msg, len, "Handling last segment of length %d B of SN=%d", len, vr_r); if (rx_sdu->get_tailroom() >= len) { // store timestamp of the first segment when starting to assemble SDUs if (rx_sdu->N_bytes == 0) { @@ -1531,20 +1634,20 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() } if (rlc_am_end_aligned(rx_window[vr_r].header.fi)) { - log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); + logger.info(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); sdu_rx_latency_ms.push(std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - rx_sdu->get_timestamp()) .count()); parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu)); parent->metrics.num_rx_sdus++; - rx_sdu = allocate_unique_buffer(*pool, true); + rx_sdu = srslte::make_byte_buffer(); if (rx_sdu == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); exit(-1); #else - log->error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); + logger.error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)"); return; #endif } @@ -1552,19 +1655,19 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() exit: // Move the rx_window - log->debug("Erasing SN=%d.\n", vr_r); + logger.debug("Erasing SN=%d.", vr_r); // also erase any segments of this SN std::map::iterator it; it = rx_segments.find(vr_r); if (rx_segments.end() != it) { - log->debug("Erasing segments of SN=%d\n", vr_r); + logger.debug("Erasing segments of SN=%d", vr_r); std::list::iterator segit; for (segit = it->second.segments.begin(); segit != it->second.segments.end(); ++segit) { - log->debug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d\n", - segit->header.sn, - segit->header.so, - segit->buf->N_bytes, - segit->header.N_li); + logger.debug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d", + segit->header.sn, + segit->header.so, + segit->buf->N_bytes, + segit->header.N_li); } it->second.segments.clear(); } @@ -1589,9 +1692,9 @@ bool rlc_am_lte::rlc_am_lte_rx::get_do_status() void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_bytes) { - if (nof_bytes < 1) + if (nof_bytes < 1) { return; - + } pthread_mutex_lock(&mutex); if (rlc_am_is_control_pdu(payload)) { @@ -1603,7 +1706,7 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b uint32_t payload_len = nof_bytes; rlc_am_read_data_pdu_header(&payload, &payload_len, &header); if (payload_len > nof_bytes) { - log->info("Dropping corrupted PDU (%d B). Remaining length after header %d B.\n", nof_bytes, payload_len); + logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len); pthread_mutex_unlock(&mutex); return; } @@ -1645,7 +1748,7 @@ void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id) { pthread_mutex_lock(&mutex); if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) { - log->debug("%s reordering timeout expiry - updating vr_ms (was %d)\n", RB_NAME, vr_ms); + logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms); // 36.322 v10 Section 5.1.3.2.4 vr_ms = vr_x; @@ -1689,21 +1792,21 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui // make sure we don't exceed grant size if (rlc_am_packed_length(status) > max_pdu_size) { - log->debug("Status PDU too big (%d > %d)\n", rlc_am_packed_length(status), max_pdu_size); + logger.debug("Status PDU too big (%d > %d)", rlc_am_packed_length(status), max_pdu_size); if (status->N_nack >= 1 && status->N_nack < RLC_AM_WINDOW_SIZE) { - log->debug("Removing last NACK SN=%d\n", status->nacks[status->N_nack].nack_sn); + logger.debug("Removing last NACK SN=%d", status->nacks[status->N_nack].nack_sn); status->N_nack--; // make sure we don't have the current ACK_SN in the NACK list if (rlc_am_is_valid_status_pdu(*status) == false) { // No space to send any NACKs - log->debug("Resetting N_nack to zero\n"); + logger.debug("Resetting N_nack to zero"); status->N_nack = 0; } } else { - log->warning("Failed to generate small enough status PDU (packed_len=%d, max_pdu_size=%d, status->N_nack=%d)\n", - rlc_am_packed_length(status), - max_pdu_size, - status->N_nack); + logger.warning("Failed to generate small enough status PDU (packed_len=%d, max_pdu_size=%d, status->N_nack=%d)", + rlc_am_packed_length(status), + max_pdu_size, + status->N_nack); } break; } @@ -1743,7 +1846,7 @@ void rlc_am_lte::rlc_am_lte_rx::print_rx_segments() << " N_li: " << segit->header.N_li << std::endl; } } - log->debug("%s\n", ss.str().c_str()); + logger.debug("%s", ss.str().c_str()); } // NOTE: Preference would be to capture by value, and then move; but header is stack allocated @@ -1817,25 +1920,25 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* header.fi |= (pdu->segments.front().header.fi & RLC_FI_FIELD_NOT_START_ALIGNED); header.fi |= (pdu->segments.back().header.fi & RLC_FI_FIELD_NOT_END_ALIGNED); - log->debug("Starting header reconstruction of %zd segments\n", pdu->segments.size()); + logger.debug("Starting header reconstruction of %zd segments", pdu->segments.size()); // Reconstruct li fields uint16_t count = 0; uint16_t carryover = 0; for (it = pdu->segments.begin(); it != pdu->segments.end(); it++) { - log->debug(" Handling %d PDU segments\n", it->header.N_li); + logger.debug(" Handling %d PDU segments", it->header.N_li); for (uint32_t i = 0; i < it->header.N_li; i++) { header.li[header.N_li] = it->header.li[i]; if (i == 0) { header.li[header.N_li] += carryover; } - log->debug(" - adding segment %d/%d (%d B, SO=%d, carryover=%d, count=%d)\n", - i + 1, - it->header.N_li, - header.li[header.N_li], - header.so, - carryover, - count); + logger.debug(" - adding segment %d/%d (%d B, SO=%d, carryover=%d, count=%d)", + i + 1, + it->header.N_li, + header.li[header.N_li], + header.so, + carryover, + count); header.N_li++; count += it->header.li[i]; carryover = 0; @@ -1843,24 +1946,24 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* if (count <= it->buf->N_bytes) { carryover += it->buf->N_bytes - count; - log->debug("Incremented carryover (it->buf->N_bytes=%d, count=%d). New carryover=%d\n", - it->buf->N_bytes, - count, - carryover); + logger.debug("Incremented carryover (it->buf->N_bytes=%d, count=%d). New carryover=%d", + it->buf->N_bytes, + count, + carryover); } else { // Next segment would be too long, recalculate carryover header.N_li--; carryover = it->buf->N_bytes - (count - header.li[header.N_li]); - log->debug("Recalculated carryover=%d (it->buf->N_bytes=%d, count=%d, header.li[header.N_li]=%d)\n", - carryover, - it->buf->N_bytes, - count, - header.li[header.N_li]); + logger.debug("Recalculated carryover=%d (it->buf->N_bytes=%d, count=%d, header.li[header.N_li]=%d)", + carryover, + it->buf->N_bytes, + count, + header.li[header.N_li]); } tmpit = it; if (rlc_am_end_aligned(it->header.fi) && ++tmpit != pdu->segments.end()) { - log->debug("Header is end-aligned, overwrite header.li[%d]=%d\n", header.N_li, carryover); + logger.debug("Header is end-aligned, overwrite header.li[%d]=%d", header.N_li, carryover); header.li[header.N_li] = carryover; header.N_li++; carryover = 0; @@ -1871,16 +1974,16 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* header.p |= it->header.p; } - log->debug("Finished header reconstruction of %zd segments\n", pdu->segments.size()); + logger.debug("Finished header reconstruction of %zd segments", pdu->segments.size()); // Copy data - unique_byte_buffer_t full_pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t full_pdu = srslte::make_byte_buffer(); if (full_pdu == NULL) { #ifdef RLC_AM_BUFFER_DEBUG srslte::console("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); exit(-1); #else - log->error("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); + logger.error("Fatal Error: Could not allocate PDU in add_segment_and_check()"); return false; #endif } @@ -1916,7 +2019,27 @@ bool rlc_am_lte::rlc_am_lte_rx::inside_rx_window(const int16_t sn) void rlc_am_lte::rlc_am_lte_rx::debug_state() { - log->debug("%s vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d\n", RB_NAME, vr_r, vr_mr, vr_x, vr_ms, vr_h); + logger.debug("%s vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d", RB_NAME, vr_r, vr_mr, vr_x, vr_ms, vr_h); +} + +const size_t buffered_pdcp_pdu_list::max_buffer_idx; + +buffered_pdcp_pdu_list::buffered_pdcp_pdu_list() : buffered_pdus(max_buffer_idx + 1) +{ + for (size_t i = 0; i < buffered_pdus.size(); ++i) { + buffered_pdus[i].rlc_sn_info_list.reserve(5); + } + clear(); +} + +void buffered_pdcp_pdu_list::clear() +{ + for (auto& b : buffered_pdus) { + b.sn = invalid_sn; + b.fully_acked = false; + b.fully_txed = false; + b.rlc_sn_info_list.clear(); + } } /**************************************************************************** @@ -2189,6 +2312,28 @@ std::string rlc_am_status_pdu_to_string(rlc_status_pdu_t* status) return ss.str(); } +std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue) +{ + std::string str = "\n"; + for (const auto& info_it : info_queue) { + uint32_t pdcp_sn = info_it.first; + auto info = info_it.second; + std::string tmp_str = fmt::format("\tPDCP_SN = {}, RLC_SNs = [", pdcp_sn); + for (auto rlc_sn_info : info.rlc_sn_info_list) { + std::string tmp_str2; + if (rlc_sn_info.is_acked) { + tmp_str2 = fmt::format("ACK={}, ", rlc_sn_info.sn); + } else { + tmp_str2 = fmt::format("NACK={}, ", rlc_sn_info.sn); + } + tmp_str += tmp_str2; + } + tmp_str += "]\n"; + str += tmp_str; + } + return str; +} + std::string rlc_amd_pdu_header_to_string(const rlc_amd_pdu_header_t& header) { std::stringstream ss; diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index baf489c54..74dcefa6a 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -23,8 +23,11 @@ namespace srslte { -rlc_tm::rlc_tm(srslte::log_ref log_, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_) : - log(log_), pdcp(pdcp_), rrc(rrc_), lcid(lcid_) +rlc_tm::rlc_tm(srslog::basic_logger& logger, + uint32_t lcid_, + srsue::pdcp_interface_rlc* pdcp_, + srsue::rrc_interface_rlc* rrc_) : + logger(logger), pdcp(pdcp_), rrc(rrc_), lcid(lcid_) { pool = byte_buffer_pool::get_instance(); } @@ -37,7 +40,7 @@ rlc_tm::~rlc_tm() bool rlc_tm::configure(const rlc_config_t& cnfg) { - log->error("Attempted to configure TM RLC entity\n"); + logger.error("Attempted to configure TM RLC entity"); return true; } @@ -83,23 +86,23 @@ void rlc_tm::write_sdu(unique_byte_buffer_t sdu) uint32_t nof_bytes = sdu->N_bytes; srslte::error_type ret = ul_queue.try_write(std::move(sdu)); if (ret) { - log->info_hex(msg_ptr, - nof_bytes, - "%s Tx SDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid).c_str(), - ul_queue.size(), - ul_queue.size_bytes()); + logger.info(msg_ptr, + nof_bytes, + "%s Tx SDU, queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), + ul_queue.size(), + ul_queue.size_bytes()); } else { - log->warning_hex(ret.error()->msg, - ret.error()->N_bytes, - "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid).c_str(), - ul_queue.size(), - ul_queue.size_bytes()); + logger.warning(ret.error()->msg, + ret.error()->N_bytes, + "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), + ul_queue.size(), + ul_queue.size_bytes()); } } else { - log->warning("NULL SDU pointer in write_sdu()\n"); + logger.warning("NULL SDU pointer in write_sdu()"); } } @@ -108,7 +111,7 @@ void rlc_tm::discard_sdu(uint32_t discard_sn) if (!tx_enabled) { return; } - log->warning("SDU discard not implemented on RLC TM\n"); + logger.warning("SDU discard not implemented on RLC TM"); } bool rlc_tm::sdu_queue_is_full() @@ -141,31 +144,31 @@ int rlc_tm::read_pdu(uint8_t* payload, uint32_t nof_bytes) { uint32_t pdu_size = ul_queue.size_tail_bytes(); if (pdu_size > nof_bytes) { - log->info( - "%s Tx PDU size larger than MAC opportunity (%d > %d)\n", rrc->get_rb_name(lcid).c_str(), pdu_size, nof_bytes); + logger.info( + "%s Tx PDU size larger than MAC opportunity (%d > %d)", rrc->get_rb_name(lcid).c_str(), pdu_size, nof_bytes); return -1; } unique_byte_buffer_t buf; if (ul_queue.try_read(&buf)) { pdu_size = buf->N_bytes; memcpy(payload, buf->msg, buf->N_bytes); - log->debug("%s Complete SDU scheduled for tx. Stack latency: %" PRIu64 " us\n", - rrc->get_rb_name(lcid).c_str(), - (uint64_t)buf->get_latency_us().count()); - log->info_hex(payload, - pdu_size, - "%s Tx %s PDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid).c_str(), - srslte::to_string(rlc_mode_t::tm).c_str(), - ul_queue.size(), - ul_queue.size_bytes()); + logger.debug("%s Complete SDU scheduled for tx. Stack latency: %" PRIu64 " us", + rrc->get_rb_name(lcid).c_str(), + (uint64_t)buf->get_latency_us().count()); + logger.info(payload, + pdu_size, + "%s Tx %s PDU, queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), + srslte::to_string(rlc_mode_t::tm).c_str(), + ul_queue.size(), + ul_queue.size_bytes()); metrics.num_tx_pdu_bytes += pdu_size; return pdu_size; } else { - log->warning("Queue empty while trying to read\n"); + logger.warning("Queue empty while trying to read"); if (ul_queue.size_bytes() > 0) { - log->warning("Corrupted queue: empty but size_bytes > 0. Resetting queue\n"); + logger.warning("Corrupted queue: empty but size_bytes > 0. Resetting queue"); ul_queue.reset(); } return 0; @@ -174,7 +177,7 @@ int rlc_tm::read_pdu(uint8_t* payload, uint32_t nof_bytes) void rlc_tm::write_pdu(uint8_t* payload, uint32_t nof_bytes) { - unique_byte_buffer_t buf = allocate_unique_buffer(*pool); + unique_byte_buffer_t buf = make_byte_buffer(); if (buf) { memcpy(buf->msg, payload, nof_bytes); buf->N_bytes = nof_bytes; @@ -187,7 +190,7 @@ void rlc_tm::write_pdu(uint8_t* payload, uint32_t nof_bytes) pdcp->write_pdu(lcid, std::move(buf)); } } else { - log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu()."); } } diff --git a/lib/src/upper/rlc_um_base.cc b/lib/src/upper/rlc_um_base.cc index 9976b9566..e69272a9f 100644 --- a/lib/src/upper/rlc_um_base.cc +++ b/lib/src/upper/rlc_um_base.cc @@ -24,12 +24,12 @@ namespace srslte { -rlc_um_base::rlc_um_base(srslte::log_ref log_, +rlc_um_base::rlc_um_base(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, srslte::timer_handler* timers_) : - log(log_), lcid(lcid_), pdcp(pdcp_), rrc(rrc_), timers(timers_), pool(byte_buffer_pool::get_instance()) + logger(logger), lcid(lcid_), pdcp(pdcp_), rrc(rrc_), timers(timers_), pool(byte_buffer_pool::get_instance()) {} rlc_um_base::~rlc_um_base() {} @@ -89,7 +89,7 @@ void rlc_um_base::empty_queue() void rlc_um_base::write_sdu(unique_byte_buffer_t sdu) { if (not tx_enabled || not tx) { - log->debug("%s is currently deactivated. Dropping SDU (%d B)\n", rb_name.c_str(), sdu->N_bytes); + logger.debug("%s is currently deactivated. Dropping SDU (%d B)", rb_name.c_str(), sdu->N_bytes); metrics.num_lost_sdus++; return; } @@ -106,7 +106,7 @@ void rlc_um_base::write_sdu(unique_byte_buffer_t sdu) void rlc_um_base::discard_sdu(uint32_t discard_sn) { if (not tx_enabled || not tx) { - log->debug("%s is currently deactivated. Ignoring SDU discard (SN=%u)\n", rb_name.c_str(), discard_sn); + logger.debug("%s is currently deactivated. Ignoring SDU discard (SN=%u)", rb_name.c_str(), discard_sn); return; } tx->discard_sdu(discard_sn); @@ -191,7 +191,7 @@ std::string rlc_um_base::get_rb_name(srsue::rrc_interface_rlc* rrc, uint32_t lci rlc_um_base::rlc_um_base_rx::rlc_um_base_rx(rlc_um_base* parent_) : pool(parent_->pool), - log(parent_->log), + logger(parent_->logger), timers(parent_->timers), pdcp(parent_->pdcp), rrc(parent_->rrc), @@ -207,7 +207,7 @@ rlc_um_base::rlc_um_base_rx::~rlc_um_base_rx() {} ***************************************************************************/ rlc_um_base::rlc_um_base_tx::rlc_um_base_tx(rlc_um_base* parent_) : - log(parent_->log), pool(parent_->pool), parent(parent_) + logger(parent_->logger), pool(parent_->pool), parent(parent_) {} rlc_um_base::rlc_um_base_tx::~rlc_um_base_tx() {} @@ -245,15 +245,15 @@ bool rlc_um_base::rlc_um_base_tx::has_data() void rlc_um_base::rlc_um_base_tx::write_sdu(unique_byte_buffer_t sdu) { if (sdu) { - log->info_hex(sdu->msg, - sdu->N_bytes, - "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", - rb_name.c_str(), - sdu->N_bytes, - tx_sdu_queue.size()); + logger.info(sdu->msg, + sdu->N_bytes, + "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", + rb_name.c_str(), + sdu->N_bytes, + tx_sdu_queue.size()); tx_sdu_queue.write(std::move(sdu)); } else { - log->warning("NULL SDU pointer in write_sdu()\n"); + logger.warning("NULL SDU pointer in write_sdu()"); } } @@ -264,26 +264,26 @@ int rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu) uint32_t nof_bytes = sdu->N_bytes; srslte::error_type ret = tx_sdu_queue.try_write(std::move(sdu)); if (ret) { - log->info_hex( + logger.info( msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rb_name.c_str(), nof_bytes, tx_sdu_queue.size()); return SRSLTE_SUCCESS; } else { - log->warning_hex(ret.error()->msg, - ret.error()->N_bytes, - "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", - rb_name.c_str(), - ret.error()->N_bytes, - tx_sdu_queue.size()); + logger.warning(ret.error()->msg, + ret.error()->N_bytes, + "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", + rb_name.c_str(), + ret.error()->N_bytes, + tx_sdu_queue.size()); } } else { - log->warning("NULL SDU pointer in write_sdu()\n"); + logger.warning("NULL SDU pointer in write_sdu()"); } return SRSLTE_ERROR; } void rlc_um_base::rlc_um_base_tx::discard_sdu(uint32_t discard_sn) { - log->warning("RLC UM: Discard SDU not implemented yet.\n"); + logger.warning("RLC UM: Discard SDU not implemented yet."); } bool rlc_um_base::rlc_um_base_tx::sdu_queue_is_full() @@ -296,16 +296,16 @@ int rlc_um_base::rlc_um_base_tx::build_data_pdu(uint8_t* payload, uint32_t nof_b unique_byte_buffer_t pdu; { std::lock_guard lock(mutex); - log->debug("MAC opportunity - %d bytes\n", nof_bytes); + logger.debug("MAC opportunity - %d bytes", nof_bytes); if (tx_sdu == nullptr && tx_sdu_queue.is_empty()) { - log->info("No data available to be sent\n"); + logger.info("No data available to be sent"); return 0; } - pdu = allocate_unique_buffer(*pool); + pdu = make_byte_buffer(); if (!pdu || pdu->N_bytes != 0) { - log->error("Failed to allocate PDU buffer\n"); + logger.error("Failed to allocate PDU buffer"); return 0; } } diff --git a/lib/src/upper/rlc_um_lte.cc b/lib/src/upper/rlc_um_lte.cc index 126c1c8df..46b095795 100644 --- a/lib/src/upper/rlc_um_lte.cc +++ b/lib/src/upper/rlc_um_lte.cc @@ -26,12 +26,12 @@ namespace srslte { -rlc_um_lte::rlc_um_lte(srslte::log_ref log_, +rlc_um_lte::rlc_um_lte(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, srslte::timer_handler* timers_) : - rlc_um_base(log_, lcid_, pdcp_, rrc_, timers_) + rlc_um_base(logger, lcid_, pdcp_, rrc_, timers_) {} // Warning: must call stop() to properly deallocate all buffers @@ -58,12 +58,12 @@ bool rlc_um_lte::configure(const rlc_config_t& cnfg_) return false; } - log->info("%s configured in %s: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits\n", - rb_name.c_str(), - srslte::to_string(cnfg_.rlc_mode).c_str(), - cfg.um.t_reordering, - srslte::to_number(cfg.um.rx_sn_field_length), - srslte::to_number(cfg.um.tx_sn_field_length)); + logger.info("%s configured in %s: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits", + rb_name.c_str(), + srslte::to_string(cnfg_.rlc_mode).c_str(), + cfg.um.t_reordering, + srslte::to_number(cfg.um.rx_sn_field_length), + srslte::to_number(cfg.um.tx_sn_field_length)); rx_enabled = true; tx_enabled = true; @@ -106,7 +106,7 @@ bool rlc_um_lte::rlc_um_lte_tx::configure(const rlc_config_t& cnfg_, std::string cfg = cnfg_; if (cfg.um.tx_mod == 0) { - log->error("Error configuring %s RLC UM: tx_mod==0\n", rb_name.c_str()); + logger.error("Error configuring %s RLC UM: tx_mod==0", rb_name.c_str()); return false; } @@ -134,10 +134,10 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* int pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom()); if (pdu_space <= head_len + 1) { - log->info("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", - rb_name.c_str(), - nof_bytes, - head_len); + logger.info("%s Cannot build a PDU - %d bytes available, %d bytes required for header", + rb_name.c_str(), + nof_bytes, + head_len); return 0; } @@ -145,8 +145,8 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* if (tx_sdu) { uint32_t space = pdu_space - head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; - log->debug( - "%s adding remainder of SDU segment - %d bytes of %d remaining\n", rb_name.c_str(), to_move, tx_sdu->N_bytes); + logger.debug( + "%s adding remainder of SDU segment - %d bytes of %d remaining", rb_name.c_str(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -157,12 +157,12 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* #ifdef ENABLE_TIMESTAMP auto latency_us = tx_sdu->get_latency_us().count(); mean_pdu_latency_us.push(latency_us); - log->debug("%s Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us\n", - rb_name.c_str(), - (uint64_t)latency_us, - (long)mean_pdu_latency_us.value()); + logger.debug("%s Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us", + rb_name.c_str(), + (uint64_t)latency_us, + (long)mean_pdu_latency_us.value()); #else - log->debug("%s Complete SDU scheduled for tx.\n", rb_name.c_str()); + logger.debug("%s Complete SDU scheduled for tx.", rb_name.c_str()); #endif tx_sdu.reset(); } @@ -172,7 +172,7 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* // Pull SDUs from queue while (pdu_space > head_len + 1 && tx_sdu_queue.size() > 0) { - log->debug("pdu_space=%d, head_len=%d\n", pdu_space, head_len); + logger.debug("pdu_space=%d, head_len=%d", pdu_space, head_len); if (last_li > 0) { header.li[header.N_li++] = last_li; } @@ -185,7 +185,7 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* } tx_sdu = tx_sdu_queue.read(); to_move = (space >= tx_sdu->N_bytes) ? tx_sdu->N_bytes : space; - log->debug("%s adding new SDU segment - %d bytes of %d remaining\n", rb_name.c_str(), to_move, tx_sdu->N_bytes); + logger.debug("%s adding new SDU segment - %d bytes of %d remaining", rb_name.c_str(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -196,12 +196,12 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* #ifdef ENABLE_TIMESTAMP auto latency_us = tx_sdu->get_latency_us().count(); mean_pdu_latency_us.push(latency_us); - log->debug("%s Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us\n", - rb_name.c_str(), - (uint64_t)latency_us, - (long)mean_pdu_latency_us.value()); + logger.debug("%s Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us", + rb_name.c_str(), + (uint64_t)latency_us, + (long)mean_pdu_latency_us.value()); #else - log->debug("%s Complete SDU scheduled for tx.\n", rb_name.c_str()); + logger.debug("%s Complete SDU scheduled for tx.", rb_name.c_str()); #endif tx_sdu.reset(); } @@ -220,7 +220,7 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* rlc_um_write_data_pdu_header(&header, pdu.get()); memcpy(payload, pdu->msg, pdu->N_bytes); - log->info_hex(payload, pdu->N_bytes, "%s Tx PDU SN=%d (%d B)\n", rb_name.c_str(), header.sn, pdu->N_bytes); + logger.info(payload, pdu->N_bytes, "%s Tx PDU SN=%d (%d B)", rb_name.c_str(), header.sn, pdu->N_bytes); debug_state(); @@ -229,7 +229,7 @@ int rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* void rlc_um_lte::rlc_um_lte_tx::debug_state() { - log->debug("%s vt_us = %d\n", rb_name.c_str(), vt_us); + logger.debug("%s vt_us = %d", rb_name.c_str(), vt_us); } void rlc_um_lte::rlc_um_lte_tx::reset() @@ -252,13 +252,13 @@ bool rlc_um_lte::rlc_um_lte_rx::configure(const rlc_config_t& cnfg_, std::string cfg = cnfg_; if (cfg.um.rx_mod == 0) { - log->error("Error configuring %s RLC UM: rx_mod==0\n", rb_name.c_str()); + logger.error("Error configuring %s RLC UM: rx_mod==0", rb_name.c_str()); return false; } // check timer if (not reordering_timer.is_valid()) { - log->error("Configuring RLC UM RX: timers not configured\n"); + logger.error("Configuring RLC UM RX: timers not configured"); return false; } @@ -307,25 +307,25 @@ void rlc_um_lte::rlc_um_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b { rlc_umd_pdu_header_t header; rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.um.rx_sn_field_length, &header); - log->info_hex(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", rb_name.c_str(), header.sn, nof_bytes); + logger.info(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", rb_name.c_str(), header.sn, nof_bytes); if (RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh - cfg.um.rx_window_size) && RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) { - log->info("%s SN=%d outside rx window [%d:%d] - discarding\n", rb_name.c_str(), header.sn, vr_ur, vr_uh); + logger.info("%s SN=%d outside rx window [%d:%d] - discarding", rb_name.c_str(), header.sn, vr_ur, vr_uh); return; } std::map::iterator it = rx_window.find(header.sn); if (rx_window.end() != it) { - log->info("%s Discarding duplicate SN=%d\n", rb_name.c_str(), header.sn); + logger.info("%s Discarding duplicate SN=%d", rb_name.c_str(), header.sn); return; } // Write to rx window rlc_umd_pdu_t pdu = {}; - pdu.buf = allocate_unique_buffer(*pool); + pdu.buf = make_byte_buffer(); if (!pdu.buf) { - log->error("Discarting packet: no space in buffer pool\n"); + logger.error("Discarting packet: no space in buffer pool"); return; } memcpy(pdu.buf->msg, payload, nof_bytes); @@ -343,9 +343,9 @@ void rlc_um_lte::rlc_um_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b } // Reassemble and deliver SDUs, while updating vr_ur - log->debug("Entering Reassemble from received PDU\n"); + logger.debug("Entering Reassemble from received PDU"); reassemble_rx_sdus(); - log->debug("Finished reassemble from received PDU\n"); + logger.debug("Finished reassemble from received PDU"); // Update reordering variables and timers if (reordering_timer.is_running()) { @@ -367,34 +367,34 @@ void rlc_um_lte::rlc_um_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() { if (!rx_sdu) { - rx_sdu = allocate_unique_buffer(*pool); + rx_sdu = make_byte_buffer(); if (!rx_sdu) { - log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } // First catch up with lower edge of reordering window while (!inside_reordering_window(vr_ur)) { - log->debug("SN=%d is not inside reordering windows\n", vr_ur); + logger.debug("SN=%d is not inside reordering windows", vr_ur); if (rx_window.end() == rx_window.find(vr_ur)) { - log->debug("SN=%d not in rx_window. Reset received SDU\n", vr_ur); + logger.debug("SN=%d not in rx_window. Reset received SDU", vr_ur); rx_sdu->clear(); } else { // Handle any SDU segments for (uint32_t i = 0; i < rx_window[vr_ur].header.N_li; i++) { int len = rx_window[vr_ur].header.li[i]; - log->debug_hex(rx_window[vr_ur].buf->msg, - len, - "Handling segment %d/%d of length %d B of SN=%d\n", - i + 1, - rx_window[vr_ur].header.N_li, - len, - vr_ur); + logger.debug(rx_window[vr_ur].buf->msg, + len, + "Handling segment %d/%d of length %d B of SN=%d", + i + 1, + rx_window[vr_ur].header.N_li, + len, + vr_ur); // Check if we received a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->warning("Dropping PDU %d in reassembly due to lost start segment\n", vr_ur); + logger.warning("Dropping PDU %d in reassembly due to lost start segment", vr_ur); // Advance data pointers and continue with next segment rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; @@ -409,18 +409,18 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() rx_window[vr_ur].buf->N_bytes -= len; if ((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu + 1) % cfg.um.rx_mod))) { - log->warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", - vr_ur, - vr_ur_in_rx_sdu); + logger.warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)", + vr_ur, + vr_ur_in_rx_sdu); rx_sdu->clear(); metrics.num_lost_pdus++; } else { - log->info_hex(rx_sdu->msg, - rx_sdu->N_bytes, - "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", - rb_name.c_str(), - vr_ur, - i); + logger.info(rx_sdu->msg, + rx_sdu->N_bytes, + "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", + rb_name.c_str(), + vr_ur, + i); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; metrics.num_rx_sdu_bytes += rx_sdu->N_bytes; @@ -429,9 +429,9 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } else { pdcp->write_pdu(lcid, std::move(rx_sdu)); } - rx_sdu = allocate_unique_buffer(*pool); + rx_sdu = make_byte_buffer(); if (!rx_sdu) { - log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } @@ -440,21 +440,21 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Handle last segment if (rx_sdu->N_bytes > 0 || rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->info("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d\n", - vr_ur, - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes); + logger.info("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d", + vr_ur, + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes); memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes); rx_sdu->N_bytes += rx_window[vr_ur].buf->N_bytes; vr_ur_in_rx_sdu = vr_ur; if (rlc_um_end_aligned(rx_window[vr_ur].header.fi)) { if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->warning("Dropping remainder of lost PDU (lower edge last segments)\n"); + logger.warning("Dropping remainder of lost PDU (lower edge last segments)"); rx_sdu->clear(); metrics.num_lost_pdus++; } else { - log->info_hex( + logger.info( rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rb_name.c_str(), vr_ur); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; @@ -464,9 +464,9 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } else { pdcp->write_pdu(lcid, std::move(rx_sdu)); } - rx_sdu = allocate_unique_buffer(*pool); + rx_sdu = make_byte_buffer(); if (!rx_sdu) { - log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } @@ -483,11 +483,11 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Now update vr_ur until we reach an SN we haven't yet received while (rx_window.end() != rx_window.find(vr_ur)) { - log->debug("Reassemble loop for vr_ur=%d\n", vr_ur); + logger.debug("Reassemble loop for vr_ur=%d", vr_ur); if (not pdu_belongs_to_rx_sdu()) { - log->warning( - "PDU SN=%d lost, stop reassambling SDU (vr_ur_in_rx_sdu=%d)\n", vr_ur_in_rx_sdu + 1, vr_ur_in_rx_sdu); + logger.warning( + "PDU SN=%d lost, stop reassambling SDU (vr_ur_in_rx_sdu=%d)", vr_ur_in_rx_sdu + 1, vr_ur_in_rx_sdu); pdu_lost = false; // Reset flag to not prevent reassembling of further segments rx_sdu->clear(); } @@ -495,22 +495,22 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Handle any SDU segments for (uint32_t i = 0; i < rx_window[vr_ur].header.N_li; i++) { uint16_t len = rx_window[vr_ur].header.li[i]; - log->debug("Handling SDU segment i=%d with len=%d of vr_ur=%d N_li=%d [%s]\n", - i, - len, - vr_ur, - rx_window[vr_ur].header.N_li, - rlc_fi_field_text[rx_window[vr_ur].header.fi]); + logger.debug("Handling SDU segment i=%d with len=%d of vr_ur=%d N_li=%d [%s]", + i, + len, + vr_ur, + rx_window[vr_ur].header.N_li, + rlc_fi_field_text[rx_window[vr_ur].header.fi]); // Check if the first part of the PDU is a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->warning_hex( - rx_window[vr_ur].buf->msg, len, "Dropping first %d B of SN=%d due to lost start segment\n", len, vr_ur); + logger.warning( + rx_window[vr_ur].buf->msg, len, "Dropping first %d B of SN=%d due to lost start segment", len, vr_ur); if (rx_window[vr_ur].buf->N_bytes < len) { - log->error("Dropping remaining remainder of SN=%d too (N_bytes=%u < len=%d)\n", - vr_ur, - rx_window[vr_ur].buf->N_bytes, - len); + logger.error("Dropping remaining remainder of SN=%d too (N_bytes=%u < len=%d)", + vr_ur, + rx_window[vr_ur].buf->N_bytes, + len); goto clean_up_rx_window; } @@ -527,31 +527,31 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Check available space in SDU if ((uint32_t)len > rx_sdu->get_tailroom()) { - log->error("Dropping PDU %d due to buffer mis-alignment (current segment len %d B, received %d B)\n", - vr_ur, - rx_sdu->N_bytes, - len); + logger.error("Dropping PDU %d due to buffer mis-alignment (current segment len %d B, received %d B)", + vr_ur, + rx_sdu->N_bytes, + len); rx_sdu->clear(); metrics.num_lost_pdus++; goto clean_up_rx_window; } if (not pdu_belongs_to_rx_sdu()) { - log->info_hex(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU\n", len); - log->info("Updating vr_ur_in_rx_sdu. old=%d, new=%d\n", vr_ur_in_rx_sdu, vr_ur); + logger.info(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU", len); + logger.info("Updating vr_ur_in_rx_sdu. old=%d, new=%d", vr_ur_in_rx_sdu, vr_ur); vr_ur_in_rx_sdu = vr_ur; } else { - log->info_hex(rx_window[vr_ur].buf->msg, - len, - "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, " - "vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d\n", - len, - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes, - vr_ur_in_rx_sdu, - vr_ur, - cfg.um.rx_mod, - (vr_ur_in_rx_sdu + 1) % cfg.um.rx_mod); + logger.info(rx_window[vr_ur].buf->msg, + len, + "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, " + "vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d", + len, + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes, + vr_ur_in_rx_sdu, + vr_ur, + cfg.um.rx_mod, + (vr_ur_in_rx_sdu + 1) % cfg.um.rx_mod); } memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len); @@ -561,12 +561,12 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() vr_ur_in_rx_sdu = vr_ur; if (pdu_belongs_to_rx_sdu()) { - log->info_hex(rx_sdu->msg, - rx_sdu->N_bytes, - "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", - rb_name.c_str(), - vr_ur, - i); + logger.info(rx_sdu->msg, + rx_sdu->N_bytes, + "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", + rb_name.c_str(), + vr_ur, + i); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; metrics.num_rx_sdu_bytes += rx_sdu->N_bytes; @@ -575,15 +575,15 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } else { pdcp->write_pdu(lcid, std::move(rx_sdu)); } - rx_sdu = allocate_unique_buffer(*pool); + rx_sdu = make_byte_buffer(); if (!rx_sdu) { - log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } else { - log->warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)\n", - vr_ur, - vr_ur_in_rx_sdu); + logger.warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)", + vr_ur, + vr_ur_in_rx_sdu); // Advance data pointers and continue with next segment rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; @@ -595,7 +595,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Handle last segment if (rx_sdu->N_bytes == 0 && rx_window[vr_ur].header.N_li == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->warning("Dropping PDU %d during last segment handling due to lost start segment\n", vr_ur); + logger.warning("Dropping PDU %d during last segment handling due to lost start segment", vr_ur); rx_sdu->clear(); metrics.num_lost_pdus++; goto clean_up_rx_window; @@ -604,30 +604,30 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() if (rx_sdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES && rx_window[vr_ur].buf->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES && rx_window[vr_ur].buf->N_bytes + rx_sdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BYTES) { - log->info_hex(rx_window[vr_ur].buf->msg, - rx_window[vr_ur].buf->N_bytes, - "Writing last segment in SDU buffer. Updating vr_ur=%d, vr_ur_in_rx_sdu=%d, Buffer size=%d, " - "segment size=%d\n", - vr_ur, - vr_ur_in_rx_sdu, - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes); + logger.info(rx_window[vr_ur].buf->msg, + rx_window[vr_ur].buf->N_bytes, + "Writing last segment in SDU buffer. Updating vr_ur=%d, vr_ur_in_rx_sdu=%d, Buffer size=%d, " + "segment size=%d", + vr_ur, + vr_ur_in_rx_sdu, + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes); memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes); rx_sdu->N_bytes += rx_window[vr_ur].buf->N_bytes; } else { - log->error("Out of bounds while reassembling SDU buffer in UM: sdu_len=%d, window_buffer_len=%d, vr_ur=%d\n", - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes, - vr_ur); + logger.error("Out of bounds while reassembling SDU buffer in UM: sdu_len=%d, window_buffer_len=%d, vr_ur=%d", + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes, + vr_ur); } vr_ur_in_rx_sdu = vr_ur; if (rlc_um_end_aligned(rx_window[vr_ur].header.fi)) { if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n"); + logger.warning("Dropping remainder of lost PDU (update vr_ur last segments)"); rx_sdu->clear(); metrics.num_lost_pdus++; } else { - log->info_hex( + logger.info( rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_name.c_str(), vr_ur); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; @@ -637,9 +637,9 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } else { pdcp->write_pdu(lcid, std::move(rx_sdu)); } - rx_sdu = allocate_unique_buffer(*pool); + rx_sdu = make_byte_buffer(); if (!rx_sdu) { - log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } @@ -686,9 +686,9 @@ void rlc_um_lte::rlc_um_lte_rx::timer_expired(uint32_t timeout_id) { if (reordering_timer.id() == timeout_id) { // 36.322 v10 Section 5.1.2.2.4 - log->info("%s reordering timeout expiry - updating vr_ur and reassembling\n", rb_name.c_str()); + logger.info("%s reordering timeout expiry - updating vr_ur and reassembling", rb_name.c_str()); - log->warning("Lost PDU SN=%d\n", vr_ur); + logger.warning("Lost PDU SN=%d", vr_ur); pdu_lost = true; if (rx_sdu != NULL) { @@ -697,9 +697,9 @@ void rlc_um_lte::rlc_um_lte_rx::timer_expired(uint32_t timeout_id) while (RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux)) { vr_ur = (vr_ur + 1) % cfg.um.rx_mod; - log->debug("Entering Reassemble from timeout id=%d\n", timeout_id); + logger.debug("Entering Reassemble from timeout id=%d", timeout_id); reassemble_rx_sdus(); - log->debug("Finished reassemble from timeout id=%d\n", timeout_id); + logger.debug("Finished reassemble from timeout id=%d", timeout_id); } if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) { @@ -717,7 +717,7 @@ void rlc_um_lte::rlc_um_lte_rx::timer_expired(uint32_t timeout_id) void rlc_um_lte::rlc_um_lte_rx::debug_state() { - log->debug("%s vr_ur = %d, vr_ux = %d, vr_uh = %d\n", rb_name.c_str(), vr_ur, vr_ux, vr_uh); + logger.debug("%s vr_ur = %d, vr_ux = %d, vr_uh = %d", rb_name.c_str(), vr_ur, vr_ux, vr_uh); } /**************************************************************************** diff --git a/lib/src/upper/rlc_um_nr.cc b/lib/src/upper/rlc_um_nr.cc index 0aba86d44..abb0dedc8 100644 --- a/lib/src/upper/rlc_um_nr.cc +++ b/lib/src/upper/rlc_um_nr.cc @@ -26,12 +26,12 @@ namespace srslte { -rlc_um_nr::rlc_um_nr(srslte::log_ref log_, +rlc_um_nr::rlc_um_nr(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, srslte::timer_handler* timers_) : - rlc_um_base(log_, lcid_, pdcp_, rrc_, timers_) + rlc_um_base(logger, lcid_, pdcp_, rrc_, timers_) {} rlc_um_nr::~rlc_um_nr() @@ -57,10 +57,10 @@ bool rlc_um_nr::configure(const rlc_config_t& cnfg_) return false; } - log->info("%s configured in %s: sn_field_length=%u bits\n", - rb_name.c_str(), - srslte::to_string(cnfg_.rlc_mode).c_str(), - srslte::to_number(cfg.um_nr.sn_field_length)); + logger.info("%s configured in %s: sn_field_length=%u bits", + rb_name.c_str(), + srslte::to_string(cnfg_.rlc_mode).c_str(), + srslte::to_number(cfg.um_nr.sn_field_length)); rx_enabled = true; tx_enabled = true; @@ -103,7 +103,7 @@ bool rlc_um_nr::rlc_um_nr_tx::configure(const rlc_config_t& cnfg_, std::string r cfg = cnfg_; if (cfg.um_nr.mod == 0) { - log->error("Error configuring %s RLC UM: tx_mod==0\n", rb_name.c_str()); + logger.error("Error configuring %s RLC UM: tx_mod==0", rb_name.c_str()); return false; } @@ -129,10 +129,10 @@ int rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* p int pdu_space = SRSLTE_MIN(nof_bytes, pdu->get_tailroom()); if (pdu_space <= head_len + 1) { - log->warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header\n", - rb_name.c_str(), - nof_bytes, - head_len); + logger.warning("%s Cannot build a PDU - %d bytes available, %d bytes required for header", + rb_name.c_str(), + nof_bytes, + head_len); return 0; } @@ -140,17 +140,16 @@ int rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* p if (tx_sdu) { uint32_t space = pdu_space - head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; - log->debug( - "%s adding remainder of SDU segment - %d bytes of %d remaining\n", rb_name.c_str(), to_move, tx_sdu->N_bytes); + logger.debug( + "%s adding remainder of SDU segment - %d bytes of %d remaining", rb_name.c_str(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); pdu_ptr += to_move; pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; if (tx_sdu->N_bytes == 0) { - log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_name.c_str(), - tx_sdu->get_latency_us().count()); + logger.debug( + "%s Complete SDU scheduled for tx. Stack latency: %ld us", rb_name.c_str(), tx_sdu->get_latency_us().count()); tx_sdu.reset(); header.si = rlc_nr_si_field_t::last_segment; } else { @@ -160,22 +159,21 @@ int rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* p header.so = next_so; } else { // Pull SDU from queue - log->debug("pdu_space=%d, head_len=%d\n", pdu_space, head_len); + logger.debug("pdu_space=%d, head_len=%d", pdu_space, head_len); head_len = rlc_um_nr_packed_length(header); tx_sdu = tx_sdu_queue.read(); uint32_t space = pdu_space - head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; - log->debug("%s adding new SDU - %d bytes of %d remaining\n", rb_name.c_str(), to_move, tx_sdu->N_bytes); + logger.debug("%s adding new SDU - %d bytes of %d remaining", rb_name.c_str(), to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); pdu_ptr += to_move; pdu->N_bytes += to_move; tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; if (tx_sdu->N_bytes == 0) { - log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", - rb_name.c_str(), - tx_sdu->get_latency_us().count()); + logger.debug( + "%s Complete SDU scheduled for tx. Stack latency: %ld us", rb_name.c_str(), tx_sdu->get_latency_us().count()); tx_sdu.reset(); header.si = rlc_nr_si_field_t::full_sdu; } else { @@ -198,7 +196,7 @@ int rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* p memcpy(payload, pdu->msg, pdu->N_bytes); uint32_t ret = pdu->N_bytes; - log->info_hex(payload, ret, "%s Tx PDU SN=%d (%d B)\n", rb_name.c_str(), header.sn, pdu->N_bytes); + logger.info(payload, ret, "%s Tx PDU SN=%d (%d B)", rb_name.c_str(), header.sn, pdu->N_bytes); debug_state(); @@ -207,7 +205,7 @@ int rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* p void rlc_um_nr::rlc_um_nr_tx::debug_state() { - log->debug("%s TX_Next=%d, next_so=%d\n", rb_name.c_str(), TX_Next, next_so); + logger.debug("%s TX_Next=%d, next_so=%d", rb_name.c_str(), TX_Next, next_so); } void rlc_um_nr::rlc_um_nr_tx::reset() @@ -221,20 +219,19 @@ void rlc_um_nr::rlc_um_nr_tx::reset() ***************************************************************************/ rlc_um_nr::rlc_um_nr_rx::rlc_um_nr_rx(rlc_um_base* parent_) : - rlc_um_base_rx(parent_), - reassembly_timer(timers->get_unique_timer()) + rlc_um_base_rx(parent_), reassembly_timer(timers->get_unique_timer()) {} bool rlc_um_nr::rlc_um_nr_rx::configure(const rlc_config_t& cnfg_, std::string rb_name_) { if (cfg.um_nr.mod == 0) { - log->error("Error configuring %s RLC UM: rx_mod==0\n", rb_name.c_str()); + logger.error("Error configuring %s RLC UM: rx_mod==0", rb_name.c_str()); return false; } // check timer if (not reassembly_timer.is_valid()) { - log->error("Configuring RLC UM NR RX: timers not configured\n"); + logger.error("Configuring RLC UM NR RX: timers not configured"); return false; } @@ -283,9 +280,9 @@ void rlc_um_nr::rlc_um_nr_rx::timer_expired(uint32_t timeout_id) { std::lock_guard lock(mutex); if (reassembly_timer.id() == timeout_id) { - log->info("%s reassembly timeout expiry - updating RX_Next_Reassembly and reassembling\n", rb_name.c_str()); + logger.info("%s reassembly timeout expiry - updating RX_Next_Reassembly and reassembling", rb_name.c_str()); - log->warning("Lost PDU SN: %d\n", RX_Next_Reassembly); + logger.warning("Lost PDU SN: %d", RX_Next_Reassembly); metrics.num_lost_pdus++; if (rx_sdu != nullptr) { @@ -338,9 +335,9 @@ unique_byte_buffer_t rlc_um_nr::rlc_um_nr_rx::rlc_um_nr_strip_pdu_header(const r const uint8_t* payload, const uint32_t nof_bytes) { - unique_byte_buffer_t sdu = allocate_unique_buffer(*pool); + unique_byte_buffer_t sdu = make_byte_buffer(); if (!sdu) { - log->error("Discarting packet: no space in buffer pool\n"); + logger.error("Discarting packet: no space in buffer pool"); return nullptr; } memcpy(sdu->msg, payload, nof_bytes); @@ -367,32 +364,32 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) // iterate over received segments and try to assemble full SDU auto& pdu = rx_window.at(sn); for (auto it = pdu.segments.begin(); it != pdu.segments.end();) { - log->debug("Have %s segment with SO=%d for SN=%d\n", - to_string_short(it->second.header.si).c_str(), - it->second.header.so, - it->second.header.sn); + logger.debug("Have %s segment with SO=%d for SN=%d", + to_string_short(it->second.header.si).c_str(), + it->second.header.so, + it->second.header.sn); if (it->second.header.so == pdu.next_expected_so) { if (pdu.next_expected_so == 0) { if (pdu.sdu == nullptr) { // reuse buffer of first segment for final SDU pdu.sdu = std::move(it->second.buf); pdu.next_expected_so = pdu.sdu->N_bytes; - log->debug("Reusing first segment of SN=%d for final SDU\n", it->second.header.sn); + logger.debug("Reusing first segment of SN=%d for final SDU", it->second.header.sn); it = pdu.segments.erase(it); } else { - log->debug("SDU buffer already allocated. Possible retransmission of first segment.\n"); + logger.debug("SDU buffer already allocated. Possible retransmission of first segment."); if (it->second.header.so != pdu.next_expected_so) { - log->error("Invalid PDU. SO doesn't match. Discarting all segments of SN=%d.\n", sn); + logger.error("Invalid PDU. SO doesn't match. Discarting all segments of SN=%d.", sn); rx_window.erase(sn); return; } } } else { if (it->second.buf->N_bytes > pdu.sdu->get_tailroom()) { - log->error("Cannot fit RLC PDU in SDU buffer (tailroom=%d, len=%d), dropping both. Erasing SN=%d.\n", - rx_sdu->get_tailroom(), - it->second.buf->N_bytes, - it->second.header.sn); + logger.error("Cannot fit RLC PDU in SDU buffer (tailroom=%d, len=%d), dropping both. Erasing SN=%d.", + rx_sdu->get_tailroom(), + it->second.buf->N_bytes, + it->second.header.sn); rx_window.erase(sn); metrics.num_lost_pdus++; return; @@ -402,12 +399,12 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) memcpy(pdu.sdu->msg + pdu.sdu->N_bytes, it->second.buf->msg, it->second.buf->N_bytes); pdu.sdu->N_bytes += it->second.buf->N_bytes; pdu.next_expected_so += it->second.buf->N_bytes; - log->debug("Appended SO=%d of SN=%d\n", it->second.header.so, it->second.header.sn); + logger.debug("Appended SO=%d of SN=%d", it->second.header.so, it->second.header.sn); it = pdu.segments.erase(it); if (pdu.next_expected_so == pdu.total_sdu_length) { // deliver full SDU to upper layers - log->info("Delivering %s SDU SN=%d (%d B)", rb_name.c_str(), sn, pdu.sdu->N_bytes); + logger.info("Delivering %s SDU SN=%d (%d B)", rb_name.c_str(), sn, pdu.sdu->N_bytes); pdcp->write_pdu(lcid, std::move(pdu.sdu)); // find next SN in rx buffer @@ -416,7 +413,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) while (RX_MOD_NR_BASE(RX_Next_Reassembly) < RX_MOD_NR_BASE(RX_Next_Highest)) { RX_Next_Reassembly = (RX_Next_Reassembly + 1) % cfg.um_nr.mod; } - log->debug("Updating RX_Next_Reassembly=%d\n", RX_Next_Reassembly); + logger.debug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly); } // delete PDU from rx_window @@ -434,16 +431,16 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) if (not sn_in_reassembly_window(sn)) { // update RX_Next_highest RX_Next_Highest = sn + 1; - log->debug("Updating RX_Next_Highest=%d\n", RX_Next_Highest); + logger.debug("Updating RX_Next_Highest=%d", RX_Next_Highest); // drop all SNs outside of new rx window for (auto it = rx_window.begin(); it != rx_window.end();) { if (not sn_in_reassembly_window(it->first)) { - log->info("%s SN: %d outside rx window [%d:%d] - discarding\n", - rb_name.c_str(), - it->first, - RX_Next_Highest - cfg.um_nr.UM_Window_Size, - RX_Next_Highest); + logger.info("%s SN: %d outside rx window [%d:%d] - discarding", + rb_name.c_str(), + it->first, + RX_Next_Highest - cfg.um_nr.UM_Window_Size, + RX_Next_Highest); it = rx_window.erase(it); metrics.num_lost_pdus++; } else { @@ -456,7 +453,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) for (const auto& rx_pdu : rx_window) { if (rx_pdu.first >= RX_MOD_NR_BASE(RX_Next_Highest - cfg.um_nr.UM_Window_Size)) { RX_Next_Reassembly = rx_pdu.first; - log->debug("Updating RX_Next_Reassembly=%d\n", RX_Next_Reassembly); + logger.debug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly); break; } } @@ -478,7 +475,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) } } } else { - log->error("SN=%d does not exist in Rx buffer\n", sn); + logger.error("SN=%d does not exist in Rx buffer", sn); } } @@ -487,10 +484,10 @@ inline void rlc_um_nr::rlc_um_nr_rx::update_total_sdu_length(rlc_umd_pdu_segment { if (rx_pdu.header.si == rlc_nr_si_field_t::last_segment) { pdu_segments.total_sdu_length = rx_pdu.header.so + rx_pdu.buf->N_bytes; - log->info("%s updating total SDU length for SN=%d to %d B\n", - rb_name.c_str(), - rx_pdu.header.sn, - pdu_segments.total_sdu_length); + logger.info("%s updating total SDU length for SN=%d to %d B", + rb_name.c_str(), + rx_pdu.header.sn, + pdu_segments.total_sdu_length); } }; @@ -501,7 +498,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt rlc_um_nr_pdu_header_t header = {}; rlc_um_nr_read_data_pdu_header(payload, nof_bytes, cfg.um_nr.sn_field_length, &header); - log->debug_hex(payload, nof_bytes, "RX %s Rx data PDU (%d B)", rb_name.c_str(), nof_bytes); + logger.debug(payload, nof_bytes, "RX %s Rx data PDU (%d B)", rb_name.c_str(), nof_bytes); // check if PDU contains a SN if (header.si == rlc_nr_si_field_t::full_sdu) { @@ -509,10 +506,10 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt unique_byte_buffer_t sdu = rlc_um_nr_strip_pdu_header(header, payload, nof_bytes); // deliver to PDCP - log->info("Delivering %s SDU (%d B)", rb_name.c_str(), sdu->N_bytes); + logger.info("Delivering %s SDU (%d B)", rb_name.c_str(), sdu->N_bytes); pdcp->write_pdu(lcid, std::move(sdu)); } else if (sn_invalid_for_rx_buffer(header.sn)) { - log->info("%s Discarding SN=%d\n", rb_name.c_str(), header.sn); + logger.info("%s Discarding SN=%d", rb_name.c_str(), header.sn); // Nothing else to do here .. } else { // place PDU in receive buffer @@ -523,21 +520,21 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt // check if this SN is already present in rx buffer if (rx_window.find(header.sn) == rx_window.end()) { // first received segment of this SN, add to rx buffer - log->info("%s placing %s segment of SN=%d in Rx buffer\n", - rb_name.c_str(), - to_string_short(header.si).c_str(), - header.sn); + logger.info("%s placing %s segment of SN=%d in Rx buffer", + rb_name.c_str(), + to_string_short(header.si).c_str(), + header.sn); rlc_umd_pdu_segments_nr_t pdu_segments = {}; update_total_sdu_length(pdu_segments, rx_pdu); pdu_segments.segments.emplace(header.so, std::move(rx_pdu)); rx_window[header.sn] = std::move(pdu_segments); } else { // other segment for this SN already present, update received data - log->info("%s updating SN=%d at SO=%d with %d B\n", - rb_name.c_str(), - rx_pdu.header.sn, - rx_pdu.header.so, - rx_pdu.buf->N_bytes); + logger.info("%s updating SN=%d at SO=%d with %d B", + rb_name.c_str(), + rx_pdu.header.sn, + rx_pdu.header.so, + rx_pdu.buf->N_bytes); auto& pdu_segments = rx_window.at(header.sn); @@ -557,12 +554,12 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt void rlc_um_nr::rlc_um_nr_rx::debug_state() { - log->debug("%s RX_Next_Reassembly=%d, RX_Timer_Trigger=%d, RX_Next_Highest=%d, t_Reassembly=%s\n", - rb_name.c_str(), - RX_Next_Reassembly, - RX_Timer_Trigger, - RX_Next_Highest, - reassembly_timer.is_running() ? "running" : "stopped"); + logger.debug("%s RX_Next_Reassembly=%d, RX_Timer_Trigger=%d, RX_Next_Highest=%d, t_Reassembly=%s", + rb_name.c_str(), + RX_Next_Reassembly, + RX_Timer_Trigger, + RX_Next_Highest, + reassembly_timer.is_running() ? "running" : "stopped"); } /**************************************************************************** * Header pack/unpack helper functions @@ -603,7 +600,7 @@ uint32_t rlc_um_nr_read_data_pdu_header(const uint8_t* payload, if (header->si == rlc_nr_si_field_t::first_segment) { // make sure two reserved bits are not set if (((*ptr >> 4) & 0x03) != 0) { - fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + fprintf(stderr, "Malformed PDU, reserved bits are set."); return 0; } } diff --git a/lib/test/asn1/CMakeLists.txt b/lib/test/asn1/CMakeLists.txt index d322a9f58..b1592fd68 100644 --- a/lib/test/asn1/CMakeLists.txt +++ b/lib/test/asn1/CMakeLists.txt @@ -27,11 +27,7 @@ target_link_libraries(srslte_asn1_rrc_mcch_test rrc_asn1 srslte_common) add_test(srslte_asn1_rrc_mcch_test srslte_asn1_rrc_mcch_test) add_executable(srslte_asn1_rrc_meas_test srslte_asn1_rrc_meas_test.cc) -if (ENABLE_5GNR) target_link_libraries(srslte_asn1_rrc_meas_test rrc_asn1 rrc_nr_asn1 srslte_common) -else() -target_link_libraries(srslte_asn1_rrc_meas_test rrc_asn1 srslte_common) -endif(ENABLE_5GNR) add_test(srslte_asn1_rrc_meas_test srslte_asn1_rrc_meas_test) add_executable(srslte_asn1_rrc_ul_dcch_test srslte_asn1_rrc_ul_dcch_test.cc) @@ -58,19 +54,17 @@ add_executable(rrc_asn1_test rrc_test.cc) target_link_libraries(rrc_asn1_test rrc_asn1 asn1_utils srslte_common) add_test(rrc_asn1_test rrc_asn1_test) -if (ENABLE_5GNR) - add_executable(rrc_nr_asn1_test rrc_nr_test.cc) - target_link_libraries(rrc_nr_asn1_test rrc_nr_asn1 asn1_utils srslte_common) - add_test(rrc_nr_asn1_test rrc_nr_asn1_test) +add_executable(srslte_asn1_rrc_nr_test srslte_asn1_rrc_nr_test.cc) +target_link_libraries(srslte_asn1_rrc_nr_test rrc_nr_asn1 asn1_utils srslte_common) +add_test(srslte_asn1_rrc_nr_test srslte_asn1_rrc_nr_test) - add_executable(ngap_asn1_test ngap_test.cc) - target_link_libraries(ngap_asn1_test ngap_nr_asn1 srslte_common) - add_test(ngap_asn1_test ngap_asn1_test) +add_executable(ngap_asn1_test ngap_test.cc) +target_link_libraries(ngap_asn1_test ngap_nr_asn1 srslte_common) +add_test(ngap_asn1_test ngap_asn1_test) - add_executable(rrc_nr_utils_test rrc_nr_utils_test.cc) - target_link_libraries(rrc_nr_utils_test ngap_nr_asn1 srslte_common rrc_nr_asn1) - add_test(rrc_nr_utils_test rrc_nr_utils_test) -endif(ENABLE_5GNR) +add_executable(rrc_nr_utils_test rrc_nr_utils_test.cc) +target_link_libraries(rrc_nr_utils_test ngap_nr_asn1 srslte_common rrc_nr_asn1) +add_test(rrc_nr_utils_test rrc_nr_utils_test) add_executable(rrc_asn1_decoder rrc_asn1_decoder.cc) target_link_libraries(rrc_asn1_decoder rrc_asn1) diff --git a/lib/test/asn1/asn1_utils_test.cc b/lib/test/asn1/asn1_utils_test.cc index 9a4a75031..264e92c89 100644 --- a/lib/test/asn1/asn1_utils_test.cc +++ b/lib/test/asn1/asn1_utils_test.cc @@ -653,6 +653,13 @@ int test_big_integers() int main() { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + // Start the log backend. + srslog::init(); + TESTASSERT(test_arrays() == 0); TESTASSERT(test_bit_ref() == 0); TESTASSERT(test_oct_string() == 0); @@ -662,5 +669,8 @@ int main() TESTASSERT(test_enum() == 0); TESTASSERT(test_big_integers() == 0); // TESTASSERT(test_json_writer()==0); + + srslog::flush(); + printf("Success\n"); } diff --git a/lib/test/asn1/ngap_test.cc b/lib/test/asn1/ngap_test.cc index a8edc59c3..e484dbeac 100644 --- a/lib/test/asn1/ngap_test.cc +++ b/lib/test/asn1/ngap_test.cc @@ -347,6 +347,12 @@ int test_session_res_setup_request() int main() { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + // Start the log backend. + srslog::init(); TESTASSERT(test_amf_upd() == 0); TESTASSERT(test_ngsetup_request() == 0); @@ -358,6 +364,8 @@ int main() TESTASSERT(test_ue_context_release_complete() == 0); TESTASSERT(test_session_res_setup_request() == 0); + srslog::flush(); + printf("Success\n"); return 0; } diff --git a/lib/test/asn1/rrc_asn1_decoder.cc b/lib/test/asn1/rrc_asn1_decoder.cc index ffbc2af6b..312fbe00c 100644 --- a/lib/test/asn1/rrc_asn1_decoder.cc +++ b/lib/test/asn1/rrc_asn1_decoder.cc @@ -122,6 +122,13 @@ int main(int argc, char** argv) return -1; } + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + // Start the log backend. + srslog::init(); + asn1::cbit_ref bref(rrc_msg, fsize); // TODO do other rrc messages and type diff --git a/lib/test/asn1/rrc_nr_utils_test.cc b/lib/test/asn1/rrc_nr_utils_test.cc index 09b293804..63bedf229 100644 --- a/lib/test/asn1/rrc_nr_utils_test.cc +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -42,7 +42,7 @@ int test_rlc_config() rlc_cfg_asn1.um_bi_dir().ul_um_rlc.sn_field_len = asn1::rrc_nr::sn_field_len_um_e::size12; asn1::json_writer jw; rlc_cfg_asn1.to_json(jw); - logmap::get("RRC")->info_long("RLC NR Config: \n %s \n", jw.to_string().c_str()); + srslog::fetch_basic_logger("RRC").info("RLC NR Config: \n %s", jw.to_string().c_str()); rlc_config_t rlc_cfg = make_rlc_config_t(rlc_cfg_asn1); TESTASSERT(rlc_cfg.rat == srslte_rat_t::nr); @@ -51,11 +51,49 @@ int test_rlc_config() return SRSLTE_SUCCESS; } +int test_mac_rach_common_config() +{ + asn1::rrc_nr::rach_cfg_common_s rach_common_config_asn1; + rach_common_config_asn1.ra_contention_resolution_timer = + asn1::rrc_nr::rach_cfg_common_s::ra_contention_resolution_timer_opts::sf64; + rach_common_config_asn1.rach_cfg_generic.ra_resp_win = asn1::rrc_nr::rach_cfg_generic_s::ra_resp_win_opts::sl10; + rach_common_config_asn1.rach_cfg_generic.prach_cfg_idx = 160; + rach_common_config_asn1.rach_cfg_generic.preamb_rx_target_pwr = -110; + rach_common_config_asn1.rach_cfg_generic.pwr_ramp_step = asn1::rrc_nr::rach_cfg_generic_s::pwr_ramp_step_opts::db4; + rach_common_config_asn1.rach_cfg_generic.preamb_trans_max = + asn1::rrc_nr::rach_cfg_generic_s::preamb_trans_max_opts::n7; + + asn1::json_writer jw; + rach_common_config_asn1.to_json(jw); + srslog::fetch_basic_logger("RRC").info("MAC NR RACH Common config: \n %s", jw.to_string().c_str()); + + rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(rach_common_config_asn1); + TESTASSERT(rach_nr_cfg.ra_responseWindow == 10); + TESTASSERT(rach_nr_cfg.ra_ContentionResolutionTimer == 64); + TESTASSERT(rach_nr_cfg.prach_ConfigurationIndex == 160); + TESTASSERT(rach_nr_cfg.PreambleReceivedTargetPower == -110); + TESTASSERT(rach_nr_cfg.preambleTransMax == 7); + TESTASSERT(rach_nr_cfg.powerRampingStep == 4); + return SRSLTE_SUCCESS; +} + int main() { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(-1); - TESTASSERT(test_rlc_config() == 0); + // Start the log backend. + srslog::init(); + + TESTASSERT(test_rlc_config() == SRSLTE_SUCCESS); + TESTASSERT(test_mac_rach_common_config() == SRSLTE_SUCCESS); + + srslog::flush(); printf("Success\n"); return 0; diff --git a/lib/test/asn1/rrc_test.cc b/lib/test/asn1/rrc_test.cc index d55811be5..da4b3da12 100644 --- a/lib/test/asn1/rrc_test.cc +++ b/lib/test/asn1/rrc_test.cc @@ -35,16 +35,6 @@ int test_generic() // make suce a choice is always started in null mode TESTASSERT(choice_type1.type() == pusch_enhance_cfg_r14_c::types::nulltype); - // test logger handler - { - srslte::scoped_log null_log("ASN1"); - null_log->set_level(srslte::LOG_LEVEL_INFO); - asn1::log_info("This is a console test to see if the RRC logger is working fine\n"); - TESTASSERT(null_log->last_log_msg == "This is a console test to see if the RRC logger is working fine\n"); - TESTASSERT(null_log->last_log_level == srslte::LOG_LEVEL_INFO); - // go back to original logger - } - // Test deep copy of choice types sib_type14_r11_s::eab_param_r11_c_ choice2; choice2.set_eab_per_plmn_list_r11(); @@ -713,6 +703,12 @@ int test_rrc_conn_reconf_r15_3() int main() { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + // Start the log backend. + srslog::init(); TESTASSERT(test_generic() == 0); TESTASSERT(test_json_printer() == 0); @@ -729,6 +725,9 @@ int main() TESTASSERT(test_rrc_conn_reconf_r15_2() == 0); TESTASSERT(test_rrc_conn_reconf_v2() == 0); TESTASSERT(test_rrc_conn_reconf_r15_3() == 0); + + srslog::flush(); + printf("Success\n"); return 0; } diff --git a/lib/test/asn1/s1ap_test.cc b/lib/test/asn1/s1ap_test.cc index c33df3e19..1fd1dbdc1 100644 --- a/lib/test/asn1/s1ap_test.cc +++ b/lib/test/asn1/s1ap_test.cc @@ -125,7 +125,7 @@ bool is_same_type(U& u) return std::is_same::value; } -int test_proc_id_consistency() +int test_proc_id_consistency(srslte::log_sink_spy& spy) { s1ap_pdu_c pdu; @@ -150,11 +150,9 @@ int test_proc_id_consistency() TESTASSERT(unsuc.value.type().value == s1ap_elem_procs_o::unsuccessful_outcome_c::types_opts::ho_fail); TESTASSERT(is_same_type(unsuc.value.ho_fail())); // e-RABSetup (No Unsuccessful Outcome) - { - srslte::scoped_log sink("ASN1"); - TESTASSERT(not unsuc.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP)); - TESTASSERT(sink->error_counter == 1); - } + spy.reset_counters(); + TESTASSERT(not unsuc.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP)); + TESTASSERT(spy.get_error_counter() == 1); // initialContextSetup TESTASSERT(unsuc.load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP)); TESTASSERT(unsuc.proc_code == ASN1_S1AP_ID_INIT_CONTEXT_SETUP); @@ -225,7 +223,7 @@ int test_enb_status_transfer() asn1::bit_ref bref{buffer, sizeof(buffer)}; TESTASSERT(pdu.pack(bref) == SRSASN_SUCCESS); - srslte::logmap::get("ASN1")->info_hex( + srslog::fetch_basic_logger("ASN1").info( buffer, bref.distance_bytes(), "eNB Status Transfer (%d bytes)", (int)bref.distance_bytes()); asn1::cbit_ref bref2{buffer, sizeof(buffer)}; @@ -300,8 +298,8 @@ int test_initial_ctxt_setup_response() asn1::bit_ref bref(buffer, sizeof(buffer)); TESTASSERT(tx_pdu.pack(bref) == SRSLTE_SUCCESS); - srslte::logmap::get("TEST")->info_hex( - buffer, bref.distance_bytes(), "message (nof bytes = %d):\n", bref.distance_bytes()); + srslog::fetch_basic_logger("TEST").info( + buffer, bref.distance_bytes(), "message (nof bytes = %d):", bref.distance_bytes()); return SRSLTE_SUCCESS; } @@ -343,7 +341,7 @@ int test_eci_pack() TESTASSERT(buffer[1] == 0x19); TESTASSERT(buffer[2] == 0xC0); - srslte::logmap::get("TEST")->info_hex(buffer, bref.distance_bytes(), "Packed cell id:\n"); + srslog::fetch_basic_logger("TEST").info(buffer, bref.distance_bytes(), "Packed cell id:"); return SRSLTE_SUCCESS; } @@ -370,10 +368,32 @@ int main() srslte::logmap::set_default_hex_limit(4096); TESTASSERT(srslte::logmap::get("ASN1")->get_level() == srslte::LOG_LEVEL_DEBUG); + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srslte::log_sink_spy::name(), + std::unique_ptr(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSLTE_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srslte::log_sink_spy::name())); + if (!spy) { + return SRSLTE_ERROR; + } + + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", *spy, false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + auto& test_logger = srslog::fetch_basic_logger("TEST", false); + test_logger.set_level(srslog::basic_levels::debug); + test_logger.set_hex_dump_max_size(-1); + + // Start the log backend. + srslog::init(); + TESTASSERT(test_s1setup_request() == 0); TESTASSERT(test_init_ctxt_setup_req() == 0); TESTASSERT(test_ue_ctxt_release_req() == 0); - TESTASSERT(test_proc_id_consistency() == 0); + TESTASSERT(test_proc_id_consistency(*spy) == 0); TESTASSERT(test_ho_request() == 0); TESTASSERT(test_enb_status_transfer() == 0); TESTASSERT(unpack_test_served_gummeis_with_multiple_plmns() == 0); @@ -382,6 +402,8 @@ int main() TESTASSERT(test_eci_pack() == 0); TESTASSERT(test_paging() == 0); + srslog::flush(); + printf("Success\n"); return 0; } diff --git a/lib/test/asn1/srslte_asn1_nas_test.cc b/lib/test/asn1/srslte_asn1_nas_test.cc index 748136d19..41aa21f63 100644 --- a/lib/test/asn1/srslte_asn1_nas_test.cc +++ b/lib/test/asn1/srslte_asn1_nas_test.cc @@ -21,6 +21,7 @@ #include "srslte/asn1/liblte_mme.h" #include "srslte/common/log_filter.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -37,14 +38,13 @@ int nas_dedicated_eps_bearer_context_setup_request_test() { - srslte::log_filter log1("NAS"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + auto& nas_logger = srslog::fetch_basic_logger("NAS", false); + nas_logger.set_level(srslog::basic_levels::debug); + nas_logger.set_hex_dump_max_size(128); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::unique_byte_buffer_t tst_msg, out_msg; - tst_msg = allocate_unique_buffer(*pool); - out_msg = allocate_unique_buffer(*pool); + tst_msg = srslte::make_byte_buffer(); + out_msg = srslte::make_byte_buffer(); LIBLTE_MME_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT ded_bearer_req; @@ -56,7 +56,7 @@ int nas_dedicated_eps_bearer_context_setup_request_test() // Unpack Activate Dedicated EPS bearer context setup request tst_msg->N_bytes = nas_message_len; memcpy(tst_msg->msg, nas_message, nas_message_len); - log1.info_hex(tst_msg->msg, tst_msg->N_bytes, "NAS Activate Dedicated EPS Bearer Context Request original message\n"); + nas_logger.info(tst_msg->msg, tst_msg->N_bytes, "NAS Activate Dedicated EPS Bearer Context Request original message"); // Test message type and protocol discriminator uint8_t pd, msg_type; @@ -110,12 +110,21 @@ int nas_dedicated_eps_bearer_context_setup_request_test() TESTASSERT(ded_bearer_req.packet_flow_id == 77); // Test flow id // NAS Activate Dedicated EPS Bearer Context Setup Request Pack Test (TODO) + + srslog::flush(); printf("Test NAS Activate Dedicated EPS Bearer Context Request successfull\n"); return 0; } int main(int argc, char** argv) { + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + srslog::init(); + int result = nas_dedicated_eps_bearer_context_setup_request_test(); + return result; } diff --git a/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc b/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc index 8fec982c5..b9e54623a 100644 --- a/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_dl_ccch_test.cc @@ -37,10 +37,6 @@ using namespace asn1::rrc; int rrc_conn_setup_test1() { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); - uint8_t rrc_msg[] = {0x60, 0x12, 0x98, 0x0b, 0xfd, 0xd2, 0x04, 0xfa, 0x18, 0x3e, 0xd5, 0xe6, 0xc2, 0x59, 0x90, 0xc1, 0xa6, 0x00, 0x01, 0x31, 0x40, 0x42, 0x50, 0x80, 0x00, 0xf8}; uint32_t rrc_msg_len = sizeof(rrc_msg); @@ -90,9 +86,9 @@ int rrc_conn_setup_test1() // Only packing implemented int rrc_reestablishment_reject_test() { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(128); dl_ccch_msg_s dl_ccch_msg; dl_ccch_msg.msg.set(dl_ccch_msg_type_c::types::c1); @@ -111,14 +107,21 @@ int rrc_reestablishment_reject_test() } int actual_len = bref.distance_bytes(rrc_msg); - log1.info_hex(rrc_msg, actual_len, "DL-CCCH message (%d/%zd B)\n", actual_len, sizeof(rrc_msg)); + rrc_logger.info(rrc_msg, actual_len, "DL-CCCH message (%d/%zd B)", actual_len, sizeof(rrc_msg)); return 0; } int main(int argc, char** argv) { + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + srslog::init(); + TESTASSERT(rrc_conn_setup_test1() == 0); TESTASSERT(rrc_reestablishment_reject_test() == 0); + return 0; } \ No newline at end of file diff --git a/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc b/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc index 2e127a794..89ec48123 100644 --- a/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_dl_dcch_test.cc @@ -37,10 +37,6 @@ using namespace asn1::rrc; int rrc_conn_reconfig_ho_test1() { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); - uint8_t rrc_msg[] = {0x20, 0x1b, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x01, 0xa9, 0x08, 0x80, 0x00, 0x00, 0x29, 0x00, 0x97, 0x80, 0x00, 0x00, 0x00, 0x01, 0x04, 0x22, 0x14, 0x00, 0xf8, 0x02, 0x0a, 0xc0, 0x60, 0x00, 0xa0, 0x0c, 0x80, 0x42, 0x02, 0x9f, 0x43, 0x07, 0xda, 0xbc, 0xf8, 0x4b, 0x32, 0x18, @@ -73,6 +69,13 @@ int rrc_conn_reconfig_ho_test1() int main(int argc, char** argv) { + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + srslog::init(); + TESTASSERT(rrc_conn_reconfig_ho_test1() == 0); + return 0; } diff --git a/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc b/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc index e3cca5ea6..e860e5bd6 100644 --- a/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_mcch_test.cc @@ -38,10 +38,6 @@ using namespace asn1::rrc; int meas_obj_test() { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(1024); - uint8_t known_reference[] = {0x0d, 0x8f, 0xdf, 0xff, 0xff, 0xff, 0xe2, 0x2f, 0xfc, 0x38, 0x5e, 0x61, 0xec, 0xa8, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x20, 0x05, 0xe6, 0x1e, 0xca, 0x80, 0x00, 0x00, 0x40, 0x42}; @@ -130,6 +126,13 @@ int meas_obj_test() int main(int argc, char** argv) { + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + srslog::init(); + TESTASSERT(meas_obj_test() == 0); + return 0; } diff --git a/lib/test/asn1/srslte_asn1_rrc_meas_test.cc b/lib/test/asn1/srslte_asn1_rrc_meas_test.cc index 9d44c23be..82efbf9cb 100644 --- a/lib/test/asn1/srslte_asn1_rrc_meas_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_meas_test.cc @@ -40,10 +40,6 @@ using namespace asn1::rrc; int meas_obj_test() { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); - uint8_t rrc_msg[] = { 0x08, 0x10, 0x49, 0x3C, 0x0D, 0x97, 0x89, 0x83, 0xC0, 0x84, 0x20, 0x82, 0x08, 0x21, 0x00, 0x01, 0xBC, 0x48}; uint32_t rrc_msg_len = sizeof(rrc_msg); @@ -100,6 +96,13 @@ int meas_obj_test() int main(int argc, char** argv) { + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + srslog::init(); + TESTASSERT(meas_obj_test() == 0); + return 0; } diff --git a/lib/test/asn1/rrc_nr_test.cc b/lib/test/asn1/srslte_asn1_rrc_nr_test.cc similarity index 60% rename from lib/test/asn1/rrc_nr_test.cc rename to lib/test/asn1/srslte_asn1_rrc_nr_test.cc index 7022c3493..d9c8a98e4 100644 --- a/lib/test/asn1/rrc_nr_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_nr_test.cc @@ -128,8 +128,8 @@ int test_eutra_nr_capabilities() TESTASSERT(test_pack_unpack_consistency(mrdc_cap) == SRSASN_SUCCESS); - srslte::logmap::get("RRC")->info_hex( - buffer, bref.distance_bytes(), "Packed cap struct (%d bytes):\n", bref.distance_bytes()); + srslog::fetch_basic_logger("RRC").info( + buffer, bref.distance_bytes(), "Packed cap struct (%d bytes):", bref.distance_bytes()); return SRSLTE_SUCCESS; } @@ -186,7 +186,7 @@ int test_ue_rrc_reconfiguration() TESTASSERT(rrc_recfg.rrc_transaction_id == 0); json_writer jw; rrc_recfg.to_json(jw); - srslte::logmap::get("RRC")->info_long("RRC Reconfig: \n %s \n", jw.to_string().c_str()); + srslog::fetch_basic_logger("RRC").info("RRC Reconfig: \n %s", jw.to_string().c_str()); TESTASSERT(rrc_recfg.crit_exts.type() == asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg); TESTASSERT(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group_present == true); @@ -195,9 +195,9 @@ int test_ue_rrc_reconfiguration() cbit_ref bref0(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.data(), rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.size()); TESTASSERT(cell_group_cfg.unpack(bref0) == SRSASN_SUCCESS); - json_writer jw1; - cell_group_cfg.to_json(jw1); - srslte::logmap::get("RRC")->info_long("RRC Secondary Cell Group: \n %s \n", jw1.to_string().c_str()); + // json_writer jw1; + // cell_group_cfg.to_json(jw1); + // srslog::fetch_basic_logger("RRC").info("RRC Secondary Cell Group: \n %s", jw1.to_string().c_str()); TESTASSERT(cell_group_cfg.cell_group_id == 1); TESTASSERT(cell_group_cfg.rlc_bearer_to_add_mod_list_present == true); TESTASSERT(cell_group_cfg.rlc_bearer_to_add_mod_list.size() == 1); @@ -214,9 +214,9 @@ int test_radio_bearer_config() cbit_ref bref(&rrc_msg[0], sizeof(rrc_msg)); radio_bearer_cfg_s radio_bearer_cfg; TESTASSERT(radio_bearer_cfg.unpack(bref) == SRSASN_SUCCESS); - json_writer jw; - radio_bearer_cfg.to_json(jw); - srslte::logmap::get("RRC")->info_long("RRC Bearer CFG Message: \n %s \n", jw.to_string().c_str()); + // json_writer jw; + // radio_bearer_cfg.to_json(jw); + // srslog::fetch_basic_logger("RRC").info("RRC Bearer CFG Message: \n %s", jw.to_string().c_str()); TESTASSERT(radio_bearer_cfg.drb_to_add_mod_list_present == true); TESTASSERT(radio_bearer_cfg.drb_to_add_mod_list.size() == 1); TESTASSERT(radio_bearer_cfg.security_cfg_present == true); @@ -225,15 +225,105 @@ int test_radio_bearer_config() return SRSLTE_SUCCESS; } +int test_cell_group_config() +{ + uint8_t cell_group_config_raw[] = "\x5c\x40\xb1\xc0\x33\xc8\x53\xe0\x12\x0f\x05\x38\x0f\x80\x41\x15" + "\x07\xad\x40\x00\xba\x14\xe6\x37\xd1\xa4\xd3\xa0\x01\x34\x9a\x5f" + "\xc0\x00\x00\x33\x63\x6c\x91\x28\x80\x7f\xc0\x00\x00\x00\x00\x46" + "\xe0\x88\x40\x00\x01\x01\x00\x34\x45\x03\x9c\x00\x00\x00\x33\x71" + "\xb6\x48\x90\x04\x00\x08\x2e\x25\x18\xf0\x02\x4a\x31\x06\xe2\x8d" + "\xb8\x44\x70\x0c\x02\x10\x38\x1d\x80\x48\xf1\x18\x5e\xea\x00\x08" + "\x0e\x01\x25\xc0\xca\x80\x01\x7f\x80\x00\x00\x00\x00\x83\x70\x88" + "\x20\x00\x08\x81\x65\x00\x20\xc8\x20\x00\x02\x06\x98\x10\x14\x50" + "\xa0\x00\xe4\x81\x80\x00\x13\x35\x56\x48\x41\xc0\x01\x04\x0c\x20" + "\x50\xc1\xc9\xc4\x09\x14\x2c\x60\xd1\xc3\xc8\xe0\x00\x03\x32\x14" + "\x03\x02\x00\x19\x94\xa0\x18\x20\x00\xcc\xc5\x00\xc1\x80\x06\x64" + "\x28\x0e\x10\x00\x33\x29\x40\x70\xa0\x01\x99\x8a\x03\x86\x00\x0c" + "\xc8\x50\x2c\x38\x00\x66\x52\x81\x62\x06\x60\x04\x16\xc4\x80\x46" + "\x48\x21\x8a\x00\x8c\x90\x4b\x16\x01\x19\x20\xa6\x30\x02\x32\x41" + "\x6c\x68\x04\x64\x83\x18\xe0\x08\xc9\x06\xb1\xe0\x11\x92\x0e\x64" + "\x00\x03\x33\x14\x0b\x22\x32\x00\xa0\x84\x09\x08\x60\x51\x04\x34" + "\x3b\x2a\x65\xcd\x01\xa4\x92\x1e\x2e\xe0\x0c\x10\xe0\x00\x00\x01" + "\x8f\xfd\x29\x49\x8c\x63\x72\x81\x60\x00\x02\x19\x70\x00\x00\x00" + "\x00\x00\x00\x62\xf0\x0f\xa0\x84\x8a\xd5\x45\x00\x47\x00\x18\x00" + "\x08\x20\x00\xe2\x10\x02\x40\x80\x70\x10\x10\x84\x00\x0e\x21\x00" + "\x1c\xb0\x0e\x04\x02\x20\x80\x01\xc4\x20\x03\x96\x01\xc0\xc0\x42" + "\x10\x00\x38\x84\x00\x73\x00\x38\x20\x08\x82\x00\x07\x10\x80\x0e" + "\x60\x00\x40\x00\x00\x04\x10\xc0\x40\x80\xc1\x00\xe0\xd0\x00\x0e" + "\x48\x10\x00\x00\x02\x00\x40\x00\x80\x60\x00\x80\x90\x02\x20\x0a" + "\x40\x00\x02\x38\x90\x11\x31\xc8"; + + asn1::SRSASN_CODE err; + + cbit_ref bref(&cell_group_config_raw[0], sizeof(cell_group_config_raw)); + cell_group_cfg_s cell_group_cfg; + + TESTASSERT(cell_group_cfg.unpack(bref) == SRSASN_SUCCESS); + + TESTASSERT(test_pack_unpack_consistency(cell_group_cfg) == SRSASN_SUCCESS); + + TESTASSERT(cell_group_cfg.sp_cell_cfg_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.serv_cell_idx_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.pdcch_serving_cell_cfg_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync_present = true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci == 500); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present == true); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp_present == true); + TESTASSERT( + cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common_present == + true); + + TESTASSERT( + cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == + asn1::rrc_nr::setup_release_c::types_opts::setup); + + asn1::rrc_nr::rach_cfg_common_s& rach_cfg_common = + cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(); + + TESTASSERT(rach_cfg_common.rach_cfg_generic.prach_cfg_idx == 16); + TESTASSERT(rach_cfg_common.rach_cfg_generic.msg1_fdm == asn1::rrc_nr::rach_cfg_generic_s::msg1_fdm_opts::one); + TESTASSERT(rach_cfg_common.rach_cfg_generic.zero_correlation_zone_cfg == 0); + TESTASSERT(rach_cfg_common.rach_cfg_generic.preamb_rx_target_pwr == -110); + TESTASSERT(rach_cfg_common.rach_cfg_generic.preamb_trans_max == asn1::rrc_nr::rach_cfg_generic_s::preamb_trans_max_opts::n7); + TESTASSERT(rach_cfg_common.rach_cfg_generic.pwr_ramp_step == asn1::rrc_nr::rach_cfg_generic_s::pwr_ramp_step_opts::db4); + TESTASSERT(rach_cfg_common.rach_cfg_generic.ra_resp_win == asn1::rrc_nr::rach_cfg_generic_s::ra_resp_win_opts::sl10); + TESTASSERT(rach_cfg_common.ssb_per_rach_occasion_and_cb_preambs_per_ssb_present == true); + + // asn1::json_writer json_writer; + // cell_group_cfg.to_json(json_writer); + // srslog::fetch_basic_logger("RRC").info("RRC Secondary Cell Group: Content: %s\n", json_writer.to_string().c_str()); + return SRSLTE_SUCCESS; +} + int main() { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(-1); - TESTASSERT(test_eutra_nr_capabilities() == 0); - TESTASSERT(test_ue_mrdc_capabilities() == 0); - TESTASSERT(test_ue_rrc_reconfiguration() == 0); - TESTASSERT(test_radio_bearer_config() == 0); + // Start the log backend. + srslog::init(); + TESTASSERT(test_eutra_nr_capabilities() == SRSLTE_SUCCESS); + TESTASSERT(test_ue_mrdc_capabilities() == SRSLTE_SUCCESS); + TESTASSERT(test_ue_rrc_reconfiguration() == SRSLTE_SUCCESS); + TESTASSERT(test_radio_bearer_config() == SRSLTE_SUCCESS); + TESTASSERT(test_cell_group_config() == SRSLTE_SUCCESS); + + srslog::flush(); printf("Success\n"); return 0; } diff --git a/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc b/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc index 2766d3a5b..f08ccdd8e 100644 --- a/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc +++ b/lib/test/asn1/srslte_asn1_rrc_ul_dcch_test.cc @@ -39,9 +39,9 @@ using namespace asn1::rrc; int rrc_ue_cap_info_test(srslte::mac_pcap* pcap) { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(128); rrc_args_t args = {}; args.feature_group = 0xe6041c00; @@ -89,7 +89,7 @@ int rrc_ue_cap_info_test(srslte::mac_pcap* pcap) info->ue_cap_rat_container_list[0].ue_cap_rat_container.resize(cap_len); memcpy(info->ue_cap_rat_container_list[0].ue_cap_rat_container.data(), buf, cap_len); - log1.debug_hex(buf, cap_len, "UE-Cap (%d/%zd B)\n", cap_len, sizeof(buf)); + rrc_logger.debug(buf, cap_len, "UE-Cap (%d/%zd B)", cap_len, sizeof(buf)); // pack the message uint8_t byte_buf[32]; @@ -99,7 +99,7 @@ int rrc_ue_cap_info_test(srslte::mac_pcap* pcap) bref3.align_bytes_zero(); uint32_t len = (uint32_t)bref3.distance_bytes(byte_buf); - log1.debug_hex(byte_buf, len, "UL-DCCH (%d/%zd B)\n", len, sizeof(byte_buf)); + rrc_logger.debug(byte_buf, len, "UL-DCCH (%d/%zd B)", len, sizeof(byte_buf)); if (pcap != NULL) { pcap->write_ul_rrc_pdu(byte_buf, len); @@ -110,10 +110,6 @@ int rrc_ue_cap_info_test(srslte::mac_pcap* pcap) int pack_fail_test() { - srslte::log_filter log1("RRC"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); - rrc_args_t args = {}; args.feature_group = 0xe6041c00; args.nof_supported_bands = 1; @@ -163,6 +159,12 @@ int pack_fail_test() int main(int argc, char** argv) { + auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); + asn1_logger.set_level(srslog::basic_levels::debug); + asn1_logger.set_hex_dump_max_size(-1); + + srslog::init(); + #if PCAP srslte::mac_pcap pcap; pcap.open("ul_dcch.pcap"); diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index 126bf7c65..c62951b5f 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -95,11 +95,8 @@ add_executable(task_scheduler_test task_scheduler_test.cc) target_link_libraries(task_scheduler_test srslte_common) add_test(task_scheduler_test task_scheduler_test) -if(ENABLE_5GNR) - add_executable(pnf_dummy pnf_dummy.cc) - target_link_libraries(pnf_dummy srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) - - add_executable(pnf_bridge pnf_bridge.cc) - target_link_libraries(pnf_bridge srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -endif() +add_executable(pnf_dummy pnf_dummy.cc) +target_link_libraries(pnf_dummy srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) +add_executable(pnf_bridge pnf_bridge.cc) +target_link_libraries(pnf_bridge srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) diff --git a/lib/test/common/byte_buffer_queue_test.cc b/lib/test/common/byte_buffer_queue_test.cc index 1d6251c65..4d0d4c074 100644 --- a/lib/test/common/byte_buffer_queue_test.cc +++ b/lib/test/common/byte_buffer_queue_test.cc @@ -33,10 +33,9 @@ typedef struct { void* write_thread(void* a) { - args_t* args = (args_t*)a; - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); + args_t* args = (args_t*)a; for (uint32_t i = 0; i < NMSGS; i++) { - unique_byte_buffer_t b = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t b = srslte::make_byte_buffer(); memcpy(b->msg, &i, 4); b->N_bytes = 4; args->q->write(std::move(b)); diff --git a/lib/test/common/choice_type_test.cc b/lib/test/common/choice_type_test.cc index d57967f1c..77e4f881d 100644 --- a/lib/test/common/choice_type_test.cc +++ b/lib/test/common/choice_type_test.cc @@ -180,7 +180,7 @@ int test_choice() } struct E { - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance()); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); }; struct EVisitor { @@ -207,7 +207,7 @@ int test_visit() // TEST: visitor hits type E and steals pdu E e; - e.pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance()); + e.pdu = srslte::make_byte_buffer(); c = std::move(e); TESTASSERT(c.is() and srslte::get(c).pdu != nullptr); srslte::visit(v, c); @@ -216,7 +216,7 @@ int test_visit() // TEST: visitor hits type E and steals pdu. Second type called there is no pdu to steal. v.pdu = nullptr; - e.pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance()); + e.pdu = srslte::make_byte_buffer(); c = std::move(e); srslte::visit(v, c); TESTASSERT(v.pdu != nullptr); diff --git a/lib/test/common/fsm_test.cc b/lib/test/common/fsm_test.cc index 7a18cb2e5..e8f08ceff 100644 --- a/lib/test/common/fsm_test.cc +++ b/lib/test/common/fsm_test.cc @@ -29,11 +29,12 @@ struct ev1 {}; struct ev2 {}; std::vector calls; + template -void call_log_helper(State* state, srslte::log_ref log_h, const char* type) +void call_log_helper(State* state, srslog::basic_logger& logger, const char* type) { std::string callname = srslte::get_type_name() + "::" + type; - log_h->info("%s custom called\n", callname.c_str()); + logger.info("%s custom called", callname.c_str()); calls.push_back(callname); } @@ -54,7 +55,7 @@ public: void exit(fsm1* f); }; - explicit fsm1(srslte::log_ref log_) : srslte::fsm_t(log_) {} + explicit fsm1(srslog::basic_logger& logger) : srslte::fsm_t(logger) {} // this state is another FSM class fsm2 : public subfsm_t @@ -64,22 +65,22 @@ public: struct state_inner { void enter(fsm2* f) { - call_log_helper(this, f->get_log(), "enter"); + call_log_helper(this, f->get_logger(), "enter"); f->parent_fsm()->inner_enter_counter++; } }; struct state_inner2 { - void enter(fsm2* f) { call_log_helper(this, f->get_log(), "enter"); } - void exit(fsm2* f) { call_log_helper(this, f->get_log(), "exit"); } + void enter(fsm2* f) { call_log_helper(this, f->get_logger(), "enter"); } + void exit(fsm2* f) { call_log_helper(this, f->get_logger(), "exit"); } }; explicit fsm2(fsm1* f_) : composite_fsm_t(f_) {} fsm2(fsm2&&) = default; fsm2& operator=(fsm2&&) = default; - ~fsm2() { get_log()->info("%s being destroyed!", get_type_name(*this).c_str()); } + ~fsm2() { get_logger().info("%s being destroyed!", get_type_name(*this).c_str()); } - void enter(fsm1* f) { call_log_helper(this, get_log(), "enter"); } - void exit(fsm1* f) { call_log_helper(this, get_log(), "exit"); } + void enter(fsm1* f) { call_log_helper(this, get_logger(), "enter"); } + void exit(fsm1* f) { call_log_helper(this, get_logger(), "exit"); } private: void inner_action1(state_inner& s, const ev1& e); @@ -126,54 +127,54 @@ protected: void fsm1::idle_st::enter(fsm1* f) { - call_log_helper(this, f->log_h, "enter"); + call_log_helper(this, f->logger, "enter"); f->idle_enter_counter++; } void fsm1::state1::enter(fsm1* f, const ev1& ev) { - call_log_helper(this, f->log_h, "enter"); + call_log_helper(this, f->logger, "enter"); f->state1_enter_counter++; } void fsm1::state1::enter(fsm1* f, const ev2& ev) { - call_log_helper(this, f->log_h, "enter2"); + call_log_helper(this, f->logger, "enter2"); f->state1_enter_counter++; } void fsm1::state1::exit(fsm1* f) { - call_log_helper(this, f->log_h, "exit"); + call_log_helper(this, f->logger, "exit"); } // FSM event handlers void fsm1::fsm2::inner_action1(state_inner& s, const ev1& e) { - call_log_helper(this, get_log(), "inner_action1"); + call_log_helper(this, get_logger(), "inner_action1"); } void fsm1::fsm2::inner_action2(state_inner& s, const ev2& e) { - call_log_helper(this, get_log(), "inner_action2"); + call_log_helper(this, get_logger(), "inner_action2"); } void fsm1::fsm2::inner_action3(state_inner2& s, const ev2& e) { - get_log()->info("fsm2::state_inner2::react called\n"); + get_logger().info("fsm2::state_inner2::react called"); } void fsm1::action1(idle_st& s, const ev1& e) { - call_log_helper(this, log_h, "action1"); + call_log_helper(this, logger, "action1"); foo(e); } void fsm1::action2(state1& s, const ev1& ev) { - call_log_helper(this, log_h, "action2"); + call_log_helper(this, logger, "action2"); } void fsm1::action3(state1& s, const ev2& ev) { - call_log_helper(this, log_h, "action3"); + call_log_helper(this, logger, "action3"); } // Static Checks @@ -181,17 +182,16 @@ void fsm1::action3(state1& s, const ev2& ev) namespace srslte { namespace fsm_details { -static_assert(is_fsm::value, "invalid metafunction\n"); -static_assert(is_composite_fsm::value, "invalid metafunction\n"); +static_assert(is_fsm::value, "invalid metafunction"); +static_assert(is_composite_fsm::value, "invalid metafunction"); static_assert(type_list_size(typename filter_transition_type >::type{}) > 0, - "invalid filter metafunction\n"); + "invalid filter metafunction"); static_assert( std::is_same, fsm1::state_list >::value, - "get state list failed\n"); -static_assert(fsm1::can_hold_state(), "failed can_hold_state check\n"); -static_assert(std::is_same, void>::value, "get state list failed\n"); -static_assert(std::is_same, void>::value, - "get state list failed\n"); + "get state list failed"); +static_assert(fsm1::can_hold_state(), "failed can_hold_state check"); +static_assert(std::is_same, void>::value, "get state list failed"); +static_assert(std::is_same, void>::value, "get state list failed"); } // namespace fsm_details } // namespace srslte @@ -200,10 +200,10 @@ static_assert(std::is_same, int test_hsm() { - srslte::log_ref log_h{"HSM"}; - log_h->set_level(srslte::LOG_LEVEL_INFO); + srslog::basic_logger& logger = srslog::fetch_basic_logger("HSM", false); + logger.set_level(srslog::basic_levels::info); - fsm1 f{log_h}; + fsm1 f{logger}; TESTASSERT(f.idle_enter_counter == 1); TESTASSERT(get_type_name(f) == "fsm1"); TESTASSERT(f.current_state_name() == "idle_st"); @@ -289,7 +289,7 @@ public: void enter(proc1* f, const srslte::proc_launch_ev& ev); }; - explicit proc1(srslte::log_ref log_) : base_t(log_) {} + explicit proc1(srslog::basic_logger& logger) : base_t(logger) {} protected: // Transitions @@ -316,18 +316,18 @@ protected: void proc1::procstate1::enter(proc1* f, const launch_ev& ev) { - f->log_h->info("started!\n"); + f->logger.info("started!"); } void proc1::handle_success(procstate1& s, const procevent1& ev) { - log_h->info("success!\n"); + logger.info("success!"); trigger(complete_ev{5}); } void proc1::handle_failure(procstate1& s, const procevent1& ev) { - log_h->info("failure!\n"); + logger.info("failure!"); trigger(complete_ev{3}); } @@ -337,9 +337,8 @@ public: struct st2 {}; using proc1_st = srslte::proc_wait_st; - explicit proc_listener_fsm(srslte::log_ref log_, proc1* proc_ptr_) : - base_t(log_), - states(this, st1{}, st2{}, proc1_st{proc_ptr_}) + proc_listener_fsm(srslog::basic_logger& logger, proc1* proc_ptr_) : + base_t(logger), states(this, st1{}, st2{}, proc1_st{proc_ptr_}) {} protected: @@ -361,9 +360,9 @@ protected: int test_fsm_proc() { - proc1 proc{srslte::logmap::get("PROC")}; - proc.get_log()->set_level(srslte::LOG_LEVEL_INFO); - proc.set_fsm_event_log_level(srslte::LOG_LEVEL_INFO); + proc1 proc{srslog::fetch_basic_logger("PROC", false)}; + proc.get_logger().set_level(srslog::basic_levels::info); + proc.set_fsm_event_log_level(srslog::basic_levels::info); int v = 2; TESTASSERT(proc.current_state_name() == "idle_st"); @@ -383,7 +382,7 @@ int test_fsm_proc() TESTASSERT(proc.get_result() == 3); { - proc_listener_fsm outer_fsm{srslte::logmap::get("TEST"), &proc}; + proc_listener_fsm outer_fsm{srslog::fetch_basic_logger("TEST"), &proc}; TESTASSERT(outer_fsm.is_in_state()); outer_fsm.trigger(6); TESTASSERT(outer_fsm.is_in_state()); @@ -394,7 +393,7 @@ int test_fsm_proc() } { - proc_listener_fsm outer_fsm{srslte::logmap::get("TEST"), &proc}; + proc_listener_fsm outer_fsm{srslog::fetch_basic_logger("TEST"), &proc}; TESTASSERT(outer_fsm.is_in_state()); proc.trigger(srslte::proc_launch_ev{v}); TESTASSERT(proc.is_running()); @@ -435,7 +434,7 @@ public: struct detach_request_ev {}; struct detach_accept_ev {}; - nas_fsm(srslte::log_ref log_) : fsm_t(log_) {} + explicit nas_fsm(srslog::basic_logger& logger) : fsm_t(logger) {} protected: state_listset_level(srslte::LOG_LEVEL_INFO); - nas_fsm fsm{log_h}; + auto& logger = srslog::fetch_basic_logger("NAS", false); + logger.set_level(srslog::basic_levels::info); + + nas_fsm fsm{logger}; + TESTASSERT(fsm.is_in_state()); // NULL -> EMM-DEREGISTERED @@ -548,7 +549,7 @@ struct fsm3 : public srslte::fsm_t { } }; - fsm3() : base_t(srslte::log_ref{"TEST"}) {} + fsm3() : base_t(srslog::fetch_basic_logger("TEST")) {} std::vector events; @@ -600,16 +601,18 @@ int test_fsm_self_trigger() int main() { - srslte::log_ref testlog{"TEST"}; - testlog->set_level(srslte::LOG_LEVEL_INFO); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TEST", false); + logger.set_level(srslog::basic_levels::info); + srslog::init(); + TESTASSERT(test_hsm() == SRSLTE_SUCCESS); - testlog->info("TEST \"hsm\" finished successfully\n\n"); + logger.info("TEST \"hsm\" finished successfully\n"); TESTASSERT(test_fsm_proc() == SRSLTE_SUCCESS); - testlog->info("TEST \"proc\" finished successfully\n\n"); + logger.info("TEST \"proc\" finished successfully\n"); TESTASSERT(test_nas_fsm() == SRSLTE_SUCCESS); - testlog->info("TEST \"nas fsm\" finished successfully\n\n"); + logger.info("TEST \"nas fsm\" finished successfully\n"); TESTASSERT(test_fsm_self_trigger() == SRSLTE_SUCCESS); - testlog->info("TEST \"fsm self trigger\" finished successfully\n\n"); + logger.info("TEST \"fsm self trigger\" finished successfully\n"); return SRSLTE_SUCCESS; } diff --git a/lib/test/common/network_utils_test.cc b/lib/test/common/network_utils_test.cc index 177558d77..05a52c3ee 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -33,20 +33,18 @@ int test_socket_handler() { - srslte::log_ref log("S1AP"); - log->set_level(srslte::LOG_LEVEL_DEBUG); - log->set_hex_limit(128); + auto& logger = srslog::fetch_basic_logger("S1AP", false); int counter = 0; srslte::socket_handler_t server_socket, client_socket, client_socket2; - srslte::rx_multisocket_handler sockhandler("RXSOCKETS", log); + srslte::rx_multisocket_handler sockhandler("RXSOCKETS", logger); int server_port = 36412; const char* server_addr = "127.0.100.1"; using namespace srslte::net_utils; TESTASSERT(sctp_init_server(&server_socket, socket_type::seqpacket, server_addr, server_port)); - log->info("Listening from fd=%d\n", server_socket.fd()); + logger.info("Listening from fd=%d", server_socket.fd()); TESTASSERT(sctp_init_client(&client_socket, socket_type::seqpacket, "127.0.0.1")); TESTASSERT(sctp_init_client(&client_socket2, socket_type::seqpacket, "127.0.0.2")); @@ -55,10 +53,10 @@ int test_socket_handler() // register server Rx handler auto pdu_handler = - [log, + [&logger, &counter](srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags) { if (pdu->N_bytes > 0) { - log->info_hex(pdu->msg, pdu->N_bytes, "Received msg from %s:", get_ip(from).c_str()); + logger.info(pdu->msg, pdu->N_bytes, "Received msg from %s:", get_ip(from).c_str()); counter++; } }; @@ -89,7 +87,7 @@ int test_socket_handler() 0); TESTASSERT(n_sent >= 0); usleep(1000); - log->info("Message %d sent.\n", i); + logger.info("Message %d sent.", i); } uint32_t time_elapsed = 0; @@ -107,6 +105,13 @@ int test_socket_handler() int main() { + auto& logger = srslog::fetch_basic_logger("S1AP", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); + + srslog::init(); + TESTASSERT(test_socket_handler() == 0); + return 0; } diff --git a/lib/test/common/timer_test.cc b/lib/test/common/timer_test.cc index 1a3008d8e..2e4a33913 100644 --- a/lib/test/common/timer_test.cc +++ b/lib/test/common/timer_test.cc @@ -331,7 +331,7 @@ int timers_test5() timers.defer_callback(2, [&vals, string]() { vals.push_back(2); if (string != "test string") { - ERROR("string was not captured correctly\n"); + ERROR("string was not captured correctly"); exit(-1); } }); diff --git a/lib/test/common/tti_point_test.cc b/lib/test/common/tti_point_test.cc index 1dfb1705b..f82843630 100644 --- a/lib/test/common/tti_point_test.cc +++ b/lib/test/common/tti_point_test.cc @@ -77,6 +77,7 @@ int test_tti_type() int main() { + srslog::init(); TESTASSERT(test_tti_type() == SRSLTE_SUCCESS); return 0; } diff --git a/lib/test/mac/CMakeLists.txt b/lib/test/mac/CMakeLists.txt index 80b2fda75..75a54d866 100644 --- a/lib/test/mac/CMakeLists.txt +++ b/lib/test/mac/CMakeLists.txt @@ -26,8 +26,7 @@ add_executable(mac_pcap_test mac_pcap_test.cc) target_link_libraries(mac_pcap_test srslte_common srslte_mac ${SCTP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) add_test(mac_pcap_test mac_pcap_test) -if (ENABLE_5GNR) - add_executable(mac_nr_pdu_test mac_nr_pdu_test.cc) - target_link_libraries(mac_nr_pdu_test srslte_phy srslte_mac srslte_common ${CMAKE_THREAD_LIBS_INIT}) - add_test(mac_nr_pdu_test mac_nr_pdu_test) -endif (ENABLE_5GNR) +add_executable(mac_pdu_nr_test mac_pdu_nr_test.cc) +target_link_libraries(mac_pdu_nr_test srslte_mac srslte_common ${CMAKE_THREAD_LIBS_INIT}) +add_test(mac_pdu_nr_test mac_pdu_nr_test) + diff --git a/lib/test/mac/mac_pcap_test.cc b/lib/test/mac/mac_pcap_test.cc index 18eac7b22..653eedfe1 100644 --- a/lib/test/mac/mac_pcap_test.cc +++ b/lib/test/mac/mac_pcap_test.cc @@ -25,7 +25,10 @@ #include #include -void write_pcap_thread_function(srslte::mac_pcap* pcap_handle, const std::array& pdu, uint32_t num_pdus) +// Write #num_pdus UL MAC PDUs using PCAP handle +void write_pcap_eutra_thread_function(srslte::mac_pcap* pcap_handle, + const std::array& pdu, + uint32_t num_pdus) { for (uint32_t i = 0; i < num_pdus; i++) { pcap_handle->write_ul_crnti(const_cast(pdu.data()), pdu.size(), 0x1001, true, 1, 0); @@ -34,7 +37,17 @@ void write_pcap_thread_function(srslte::mac_pcap* pcap_handle, const std::array< std::cout << "Finished thread " << std::this_thread::get_id() << "\n"; } -int main() +// Write #num_pdus DL MAC NR PDUs using PCAP handle +void write_pcap_nr_thread_function(srslte::mac_pcap* pcap_handle, const std::array& pdu, uint32_t num_pdus) +{ + for (uint32_t i = 0; i < num_pdus; i++) { + pcap_handle->write_dl_crnti_nr(const_cast(pdu.data()), pdu.size(), 0x1001, 0, 1); + } + + std::cout << "Finished thread " << std::this_thread::get_id() << "\n"; +} + +int mac_pcap_eutra_test() { std::array tv = { 0x21, 0x08, 0x22, 0x80, 0x82, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, @@ -49,14 +62,15 @@ int main() uint32_t num_threads = 10; uint32_t num_pdus_per_thread = 100; - std::unique_ptr pcap_handle = std::unique_ptr(new srslte::mac_pcap()); + std::unique_ptr pcap_handle = + std::unique_ptr(new srslte::mac_pcap(srslte::srslte_rat_t::lte)); TESTASSERT(pcap_handle->open("mac_pcap_test.pcap") == SRSLTE_SUCCESS); TESTASSERT(pcap_handle->open("mac_pcap_test.pcap") != SRSLTE_SUCCESS); // open again will fail std::vector writer_threads; for (uint32_t i = 0; i < num_threads; i++) { - writer_threads.push_back(std::thread(write_pcap_thread_function, pcap_handle.get(), tv, num_pdus_per_thread)); + writer_threads.push_back(std::thread(write_pcap_eutra_thread_function, pcap_handle.get(), tv, num_pdus_per_thread)); } // wait for threads to finish @@ -69,3 +83,38 @@ int main() return SRSLTE_SUCCESS; } + +int mac_pcap_nr_test() +{ + std::array tv = {0x42, 0x00, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; + + uint32_t num_threads = 10; + uint32_t num_pdus_per_thread = 100; + + std::unique_ptr pcap_handle = + std::unique_ptr(new srslte::mac_pcap(srslte::srslte_rat_t::nr)); + TESTASSERT(pcap_handle->open("mac_pcap_nr_test.pcap") == SRSLTE_SUCCESS); + TESTASSERT(pcap_handle->open("mac_pcap_nr_test.pcap") != SRSLTE_SUCCESS); // open again will fail + + std::vector writer_threads; + + for (uint32_t i = 0; i < num_threads; i++) { + writer_threads.push_back(std::thread(write_pcap_nr_thread_function, pcap_handle.get(), tv, num_pdus_per_thread)); + } + + // wait for threads to finish + for (std::thread& thread : writer_threads) { + thread.join(); + } + + TESTASSERT(pcap_handle->close() == SRSLTE_SUCCESS); + TESTASSERT(pcap_handle->close() != 0); // closing twice will fail + + return SRSLTE_SUCCESS; +} + +int main() +{ + TESTASSERT(mac_pcap_eutra_test() == SRSLTE_SUCCESS); + TESTASSERT(mac_pcap_nr_test() == SRSLTE_SUCCESS); +} diff --git a/lib/test/mac/mac_nr_pdu_test.cc b/lib/test/mac/mac_pdu_nr_test.cc similarity index 56% rename from lib/test/mac/mac_nr_pdu_test.cc rename to lib/test/mac/mac_pdu_nr_test.cc index 8fe354972..0d651a974 100644 --- a/lib/test/mac/mac_nr_pdu_test.cc +++ b/lib/test/mac/mac_pdu_nr_test.cc @@ -20,30 +20,24 @@ */ #include "srslte/common/log_filter.h" -#include "srslte/common/mac_nr_pcap.h" +#include "srslte/common/mac_pcap.h" +#include "srslte/common/test_common.h" #include "srslte/config.h" -#include "srslte/mac/mac_nr_pdu.h" +#include "srslte/mac/mac_rar_pdu_nr.h" +#include "srslte/mac/mac_sch_pdu_nr.h" #include #include #include #include -#define TESTASSERT(cond) \ - { \ - if (!(cond)) { \ - std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \ - return -1; \ - } \ - } - #define PCAP 0 #define PCAP_CRNTI (0x1001) #define PCAP_TTI (666) using namespace srslte; -static std::unique_ptr pcap_handle = nullptr; +static std::unique_ptr pcap_handle = nullptr; int mac_dl_sch_pdu_unpack_and_pack_test1() { @@ -57,14 +51,14 @@ int mac_dl_sch_pdu_unpack_and_pack_test1() uint8_t mac_dl_sch_pdu_1[] = {0x00, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; if (pcap_handle) { - pcap_handle->write_dl_crnti(mac_dl_sch_pdu_1, sizeof(mac_dl_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(mac_dl_sch_pdu_1, sizeof(mac_dl_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu; + srslte::mac_sch_pdu_nr pdu; pdu.unpack(mac_dl_sch_pdu_1, sizeof(mac_dl_sch_pdu_1)); TESTASSERT(pdu.get_num_subpdus() == 1); - mac_nr_sch_subpdu subpdu = pdu.get_subpdu(0); + mac_sch_subpdu_nr subpdu = pdu.get_subpdu(0); TESTASSERT(subpdu.get_total_length() == 10); TESTASSERT(subpdu.get_sdu_length() == 8); TESTASSERT(subpdu.get_lcid() == 0); @@ -72,7 +66,7 @@ int mac_dl_sch_pdu_unpack_and_pack_test1() // pack PDU again byte_buffer_t tx_buffer; - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, sizeof(mac_dl_sch_pdu_1)); // Add SDU part of TV from above @@ -83,13 +77,11 @@ int mac_dl_sch_pdu_unpack_and_pack_test1() TESTASSERT(memcmp(tx_buffer.msg, mac_dl_sch_pdu_1, tx_buffer.N_bytes) == 0); if (pcap_handle) { - pcap_handle->write_dl_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -109,13 +101,13 @@ int mac_dl_sch_pdu_unpack_test2() uint8_t mac_dl_sch_pdu_2[] = {0x42, 0x00, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; if (pcap_handle) { - pcap_handle->write_dl_crnti(mac_dl_sch_pdu_2, sizeof(mac_dl_sch_pdu_2), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(mac_dl_sch_pdu_2, sizeof(mac_dl_sch_pdu_2), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu; + srslte::mac_sch_pdu_nr pdu; pdu.unpack(mac_dl_sch_pdu_2, sizeof(mac_dl_sch_pdu_2)); TESTASSERT(pdu.get_num_subpdus() == 1); - mac_nr_sch_subpdu subpdu = pdu.get_subpdu(0); + mac_sch_subpdu_nr subpdu = pdu.get_subpdu(0); TESTASSERT(subpdu.get_total_length() == 11); TESTASSERT(subpdu.get_sdu_length() == 8); TESTASSERT(subpdu.get_lcid() == 2); @@ -142,7 +134,7 @@ int mac_dl_sch_pdu_pack_test3() // pack buffer byte_buffer_t tx_buffer; - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, 1024); // Add SDU @@ -152,13 +144,11 @@ int mac_dl_sch_pdu_pack_test3() TESTASSERT(tx_buffer.N_bytes == 515); if (pcap_handle) { - pcap_handle->write_dl_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -180,7 +170,7 @@ int mac_dl_sch_pdu_pack_test4() // modify buffer (to be nulled during PDU packing tx_buffer.msg[4] = 0xaa; - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, pdu_size); TESTASSERT(tx_pdu.get_remaing_len() == pdu_size); @@ -191,13 +181,11 @@ int mac_dl_sch_pdu_pack_test4() TESTASSERT(memcmp(tx_buffer.msg, tv, tx_buffer.N_bytes) == 0); if (pcap_handle) { - pcap_handle->write_dl_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -220,7 +208,7 @@ int mac_dl_sch_pdu_pack_test5() byte_buffer_t tx_buffer; tx_buffer.clear(); - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, pdu_size); // Add SDU part of TV from above @@ -236,13 +224,11 @@ int mac_dl_sch_pdu_pack_test5() TESTASSERT(memcmp(tx_buffer.msg, tv, tx_buffer.N_bytes) == 0); if (pcap_handle) { - pcap_handle->write_dl_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -259,16 +245,97 @@ int mac_dl_sch_pdu_unpack_test6() uint8_t mac_dl_sch_pdu_2[] = {0x2e, 0x04, 0x11, 0x22, 0x33, 0x44}; if (pcap_handle) { - pcap_handle->write_dl_crnti(mac_dl_sch_pdu_2, sizeof(mac_dl_sch_pdu_2), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(mac_dl_sch_pdu_2, sizeof(mac_dl_sch_pdu_2), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu; + srslte::mac_sch_pdu_nr pdu; pdu.unpack(mac_dl_sch_pdu_2, sizeof(mac_dl_sch_pdu_2)); TESTASSERT(pdu.get_num_subpdus() == 0); return SRSLTE_SUCCESS; } +int mac_rar_pdu_unpack_test7() +{ + // MAC PDU with RAR PDU with single RAPID=0 + // rapid=0 + // ta=180 + // ul_grant: + // hopping_flag=0 + // riv=0x1 + // time_domain_rsc=1 + // mcs=4 + // tpc_command=3 + // csi_request=0 + // tc-rnti=0x4616 + + // Bit 1-8 + // | | | | | | | | | + // | R |T=1| RAPID=0 | Octet 1 + // | RAR | Octet 2-8 + const uint32_t tv_rapid = 0; + const uint32_t tv_ta = 180; + const uint16_t tv_tcrnti = 0x4616; + const uint8_t tv_msg3_grant[mac_rar_subpdu_nr::UL_GRANT_NBITS] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}; // unpacked UL grant + + uint8_t mac_dl_rar_pdu[] = {0x40, 0x05, 0xa0, 0x00, 0x11, 0x46, 0x46, 0x16, 0x00, 0x00, 0x00}; + + if (pcap_handle) { + pcap_handle->write_dl_ra_rnti_nr(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu), 0x0016, true, PCAP_TTI); + } + + srslte::mac_rar_pdu_nr pdu; + TESTASSERT(pdu.unpack(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu)) == true); + + std::cout << pdu.to_string() << std::endl; + + TESTASSERT(pdu.get_num_subpdus() == 1); + + mac_rar_subpdu_nr subpdu = pdu.get_subpdu(0); + TESTASSERT(subpdu.has_rapid() == true); + TESTASSERT(subpdu.has_backoff() == false); + TESTASSERT(subpdu.get_temp_crnti() == tv_tcrnti); + TESTASSERT(subpdu.get_ta() == tv_ta); + TESTASSERT(subpdu.get_rapid() == tv_rapid); + + std::array msg3_grant = subpdu.get_ul_grant(); + TESTASSERT(memcmp(msg3_grant.data(), tv_msg3_grant, msg3_grant.size()) == 0); + + return SRSLTE_SUCCESS; +} + +int mac_rar_pdu_unpack_test8() +{ + // Malformed MAC PDU, says it has RAR PDU but is too short to include MAC RAR + + // Bit 1-8 + // | | | | | | | | | + // | E |T=1| RAPID=0 | Octet 1 + // | RAR_fragment | Octet 2 + uint8_t mac_dl_rar_pdu[] = {0x40, 0x05}; + + if (pcap_handle) { + pcap_handle->write_dl_ra_rnti_nr(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu), 0x0016, true, PCAP_TTI); + } + + // unpacking should fail + srslte::mac_rar_pdu_nr pdu; + TESTASSERT(pdu.unpack(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu)) == false); + TESTASSERT(pdu.get_num_subpdus() == 0); + + // Malformed PDU with reserved bits set + // Bit 1-8 + // | | | | | | | | | + // | E |T=0| R | R | BI | Octet 1 + uint8_t mac_dl_rar_pdu2[] = {0x10}; + TESTASSERT(pdu.unpack(mac_dl_rar_pdu2, sizeof(mac_dl_rar_pdu2)) == false); + TESTASSERT(pdu.get_num_subpdus() == 0); + + return SRSLTE_SUCCESS; +} + int mac_ul_sch_pdu_unpack_test1() { // UL-SCH MAC PDU with fixed-size CE and DL-SCH subheader with 16-bit length field @@ -288,22 +355,22 @@ int mac_ul_sch_pdu_unpack_test1() uint8_t mac_ul_sch_pdu_1[] = {0x3a, 0x11, 0x22, 0x43, 0x00, 0x04, 0x11, 0x22, 0x33, 0x44}; if (pcap_handle) { - pcap_handle->write_ul_crnti(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu(true); + srslte::mac_sch_pdu_nr pdu(true); pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1)); TESTASSERT(pdu.get_num_subpdus() == 2); // First subpdu is C-RNTI CE - mac_nr_sch_subpdu subpdu0 = pdu.get_subpdu(0); + mac_sch_subpdu_nr subpdu0 = pdu.get_subpdu(0); TESTASSERT(subpdu0.get_total_length() == 3); TESTASSERT(subpdu0.get_sdu_length() == 2); - TESTASSERT(subpdu0.get_lcid() == mac_nr_sch_subpdu::CRNTI); + TESTASSERT(subpdu0.get_lcid() == mac_sch_subpdu_nr::CRNTI); TESTASSERT(memcmp(subpdu0.get_sdu(), (uint8_t*)&ul_sch_crnti, sizeof(ul_sch_crnti)) == 0); // Second subpdu is UL-SCH - mac_nr_sch_subpdu subpdu1 = pdu.get_subpdu(1); + mac_sch_subpdu_nr subpdu1 = pdu.get_subpdu(1); TESTASSERT(subpdu1.get_total_length() == 7); TESTASSERT(subpdu1.get_sdu_length() == 4); TESTASSERT(subpdu1.get_lcid() == 3); @@ -322,14 +389,14 @@ int mac_ul_sch_pdu_unpack_and_pack_test2() uint8_t mac_ul_sch_pdu_1[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; if (pcap_handle) { - pcap_handle->write_ul_crnti(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu(true); + srslte::mac_sch_pdu_nr pdu(true); pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1)); TESTASSERT(pdu.get_num_subpdus() == 1); - mac_nr_sch_subpdu subpdu = pdu.get_subpdu(0); + mac_sch_subpdu_nr subpdu = pdu.get_subpdu(0); TESTASSERT(subpdu.get_total_length() == 9); TESTASSERT(subpdu.get_sdu_length() == 8); TESTASSERT(subpdu.get_lcid() == 0); @@ -337,7 +404,7 @@ int mac_ul_sch_pdu_unpack_and_pack_test2() // pack PDU again byte_buffer_t tx_buffer; - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, sizeof(mac_ul_sch_pdu_1), true); // Add SDU part of TV from above @@ -348,13 +415,11 @@ int mac_ul_sch_pdu_unpack_and_pack_test2() TESTASSERT(memcmp(tx_buffer.msg, mac_ul_sch_pdu_1, tx_buffer.N_bytes) == 0); if (pcap_handle) { - pcap_handle->write_ul_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -371,14 +436,14 @@ int mac_ul_sch_pdu_unpack_and_pack_test3() uint8_t mac_ul_sch_pdu_1[] = {0x02, 0x0a, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa}; if (pcap_handle) { - pcap_handle->write_ul_crnti(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu(true); + srslte::mac_sch_pdu_nr pdu(true); pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1)); TESTASSERT(pdu.get_num_subpdus() == 1); - mac_nr_sch_subpdu subpdu = pdu.get_subpdu(0); + mac_sch_subpdu_nr subpdu = pdu.get_subpdu(0); TESTASSERT(subpdu.get_total_length() == 12); TESTASSERT(subpdu.get_sdu_length() == 10); TESTASSERT(subpdu.get_lcid() == 2); @@ -386,7 +451,7 @@ int mac_ul_sch_pdu_unpack_and_pack_test3() // pack PDU again byte_buffer_t tx_buffer; - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, sizeof(mac_ul_sch_pdu_1), true); // Add SDU part of TV from above @@ -397,13 +462,11 @@ int mac_ul_sch_pdu_unpack_and_pack_test3() TESTASSERT(memcmp(tx_buffer.msg, mac_ul_sch_pdu_1, tx_buffer.N_bytes) == 0); if (pcap_handle) { - pcap_handle->write_ul_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -427,7 +490,7 @@ int mac_ul_sch_pdu_pack_test4() // pack PDU again byte_buffer_t tx_buffer; - srslte::mac_nr_sch_pdu tx_pdu; + srslte::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, sizeof(sdu) + 3, true); // Add SDU part of TV from above @@ -437,13 +500,11 @@ int mac_ul_sch_pdu_pack_test4() TESTASSERT(tx_buffer.N_bytes == sizeof(sdu) + 3); if (pcap_handle) { - pcap_handle->write_ul_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); } - srslte::log_filter log("MAC"); - log.set_level(srslte::LOG_LEVEL_DEBUG); - log.set_hex_limit(100000); - log.info_hex(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer.N_bytes); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info(tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B)", tx_buffer.N_bytes); return SRSLTE_SUCCESS; } @@ -460,23 +521,112 @@ int mac_ul_sch_pdu_unpack_test5() uint8_t mac_ul_sch_pdu_1[] = {0x21, 0x0a, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa}; if (pcap_handle) { - pcap_handle->write_ul_crnti(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); } - srslte::mac_nr_sch_pdu pdu(true); + srslte::mac_sch_pdu_nr pdu(true); pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1)); TESTASSERT(pdu.get_num_subpdus() == 0); return SRSLTE_SUCCESS; } +int mac_dl_sch_pdu_unpack_and_pack_test6() +{ + // MAC PDU with UL-SCH: CRNTI, SE PHR, SBDR and padding + + // CRNTI:0x4601 SE PHR:ph=63 pc=52 SBSR: lcg=6 bs=0 PAD: len=0 + uint8_t tv[] = {0x3a, 0x46, 0x01, 0x39, 0x3f, 0x34, 0x3d, 0xc0, 0x3f}; + + const uint16_t TV_CRNTI = 0x4601; + const uint8_t TV_PHR = 63; + const uint8_t TV_PC = 52; + const uint8_t TV_LCG = 6; + const uint8_t TV_BUFF_SIZE = 0; + + if (pcap_handle) { + pcap_handle->write_ul_crnti_nr(tv, sizeof(tv), PCAP_CRNTI, true, PCAP_TTI); + } + + // Unpack TV + { + srslte::mac_sch_pdu_nr pdu_rx(true); + pdu_rx.unpack(tv, sizeof(tv)); + TESTASSERT(pdu_rx.get_num_subpdus() == 4); + + // 1st C-RNTI + mac_sch_subpdu_nr subpdu = pdu_rx.get_subpdu(0); + TESTASSERT(subpdu.get_total_length() == 3); + TESTASSERT(subpdu.get_sdu_length() == 2); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::CRNTI); + TESTASSERT(subpdu.get_c_rnti() == TV_CRNTI); + + // 2nd subPDU is SE PHR + subpdu = pdu_rx.get_subpdu(1); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::SE_PHR); + TESTASSERT(subpdu.get_phr() == TV_PHR); + TESTASSERT(subpdu.get_pcmax() == TV_PC); + + // 3rd subPDU is SBSR + subpdu = pdu_rx.get_subpdu(2); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::SHORT_BSR); + mac_sch_subpdu_nr::lcg_bsr_t sbsr = subpdu.get_sbsr(); + TESTASSERT(sbsr.lcg_id == TV_LCG); + TESTASSERT(sbsr.buffer_size == TV_BUFF_SIZE); + + // 4th is padding + subpdu = pdu_rx.get_subpdu(3); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::PADDING); + } + + // Let's pack the entire PDU again + { + byte_buffer_t tx_buffer; + srslte::mac_sch_pdu_nr pdu_tx(true); + + pdu_tx.init_tx(&tx_buffer, sizeof(tv), true); // same size as TV + + TESTASSERT(pdu_tx.get_remaing_len() == 9); + TESTASSERT(pdu_tx.add_crnti_ce(TV_CRNTI) == SRSLTE_SUCCESS); + + TESTASSERT(pdu_tx.get_remaing_len() == 6); + TESTASSERT(pdu_tx.add_se_phr_ce(TV_PHR, TV_PC) == SRSLTE_SUCCESS); + + TESTASSERT(pdu_tx.get_remaing_len() == 3); + mac_sch_subpdu_nr::lcg_bsr_t sbsr = {}; + sbsr.lcg_id = TV_LCG; + sbsr.buffer_size = TV_BUFF_SIZE; + TESTASSERT(pdu_tx.add_sbsr_ce(sbsr) == SRSLTE_SUCCESS); + TESTASSERT(pdu_tx.get_remaing_len() == 1); + + // finish PDU packing + pdu_tx.pack(); + + // compare PDUs + TESTASSERT(tx_buffer.N_bytes == sizeof(tv)); + TESTASSERT(memcmp(tx_buffer.msg, tv, tx_buffer.N_bytes) == 0); + + if (pcap_handle) { + pcap_handle->write_ul_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + } + } + + return SRSLTE_SUCCESS; +} + int main(int argc, char** argv) { #if PCAP - pcap_handle = std::unique_ptr(new srslte::mac_nr_pcap()); + pcap_handle = std::unique_ptr(new srslte::mac_pcap(srslte::srslte_rat_t::nr)); pcap_handle->open("mac_nr_pdu_test.pcap"); #endif + auto& mac_logger = srslog::fetch_basic_logger("MAC", false); + mac_logger.set_level(srslog::basic_levels::debug); + mac_logger.set_hex_dump_max_size(-1); + + srslog::init(); + if (mac_dl_sch_pdu_unpack_and_pack_test1()) { fprintf(stderr, "mac_dl_sch_pdu_unpack_and_pack_test1() failed.\n"); return SRSLTE_ERROR; @@ -507,6 +657,16 @@ int main(int argc, char** argv) return SRSLTE_ERROR; } + if (mac_rar_pdu_unpack_test7()) { + fprintf(stderr, "mac_rar_pdu_unpack_test7() failed.\n"); + return SRSLTE_ERROR; + } + + if (mac_rar_pdu_unpack_test8()) { + fprintf(stderr, "mac_rar_pdu_unpack_test8() failed.\n"); + return SRSLTE_ERROR; + } + if (mac_ul_sch_pdu_unpack_test1()) { fprintf(stderr, "mac_ul_sch_pdu_unpack_test1() failed.\n"); return SRSLTE_ERROR; @@ -532,5 +692,14 @@ int main(int argc, char** argv) return SRSLTE_ERROR; } + if (mac_dl_sch_pdu_unpack_and_pack_test6()) { + fprintf(stderr, "mac_dl_sch_pdu_unpack_and_pack_test6() failed.\n"); + return SRSLTE_ERROR; + } + + if (pcap_handle) { + pcap_handle->close(); + } + return SRSLTE_SUCCESS; } diff --git a/lib/test/mac/pdu_test.cc b/lib/test/mac/pdu_test.cc index 5e0ec4ddf..80f20c9f0 100644 --- a/lib/test/mac/pdu_test.cc +++ b/lib/test/mac/pdu_test.cc @@ -196,23 +196,17 @@ int mac_sch_pdu_pack_test1() static uint8_t tv[] = {0x21, 0x08, 0x22, 0x08, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); rlc_dummy rlc; - srslte::log_ref mac_log = srslte::logmap::get("MAC"); - mac_log->set_level(srslte::LOG_LEVEL_DEBUG); - mac_log->set_hex_limit(100000); - // create RLC SDUs const uint32_t sdu_len = 8; rlc.write_sdu(1, sdu_len); rlc.write_sdu(2, sdu_len); const uint32_t pdu_size = 25; - srslte::sch_pdu pdu(10, mac_log); + srslte::sch_pdu pdu(10, mac_logger); byte_buffer_t buffer; pdu.init_tx(&buffer, pdu_size, true); @@ -235,11 +229,11 @@ int mac_sch_pdu_pack_test1() TESTASSERT(pdu.rem_size() == pdu_size - 16 - 3); // write PDU - TESTASSERT(pdu.write_packet(mac_log) == buffer.msg); + TESTASSERT(pdu.write_packet(mac_logger) == buffer.msg); TESTASSERT(buffer.N_bytes == pdu_size); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -258,16 +252,10 @@ int mac_sch_pdu_pack_test2() static uint8_t tv[] = {0x3f, 0x3f, 0x21, 0x08, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); rlc_dummy rlc; - srslte::log_ref mac_log = srslte::logmap::get("MAC"); - mac_log->set_level(srslte::LOG_LEVEL_DEBUG); - mac_log->set_hex_limit(100000); - // create RLC SDUs const uint32_t sdu_len = 8; rlc.write_sdu(1, sdu_len); @@ -275,7 +263,7 @@ int mac_sch_pdu_pack_test2() const uint32_t pdu_size = 21; - srslte::sch_pdu pdu(10, mac_log); + srslte::sch_pdu pdu(10, mac_logger); byte_buffer_t buffer; pdu.init_tx(&buffer, pdu_size, true); @@ -298,10 +286,10 @@ int mac_sch_pdu_pack_test2() TESTASSERT(pdu.rem_size() == pdu_size - 16 - 3); // write PDU - pdu.write_packet(mac_log); + pdu.write_packet(mac_logger); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -326,21 +314,17 @@ int mac_sch_pdu_pack_test3() 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); rlc_dummy rlc; - srslte::log_ref mac_log("MAC"); - // create RLC SDUs // const uint32_t sdu_len = 130; rlc.write_sdu(1, 8); rlc.write_sdu(2, 130); const uint32_t pdu_size = 150; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); byte_buffer_t buffer; pdu.init_tx(&buffer, pdu_size, true); @@ -363,10 +347,10 @@ int mac_sch_pdu_pack_test3() TESTASSERT(pdu.rem_size() == pdu_size - 138 - 3); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -383,16 +367,12 @@ int mac_sch_pdu_pack_test4() { static uint8_t tv[] = {0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); rlc_dummy rlc; - srslte::log_ref mac_log("MAC"); - const uint32_t pdu_size = 10; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); byte_buffer_t buffer; pdu.init_tx(&buffer, pdu_size, true); @@ -410,13 +390,13 @@ int mac_sch_pdu_pack_test4() pdu.del_subh(); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // make sure full PDU has been written TESTASSERT(buffer.N_bytes == pdu_size); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -433,13 +413,13 @@ int mac_sch_pdu_pack_test5() { rlc_dummy rlc; - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); // write big SDU rlc.write_sdu(2, 20000); const uint32_t pdu_size = SRSLTE_MAX_TBSIZE_BITS / 8; // Max. DL allocation for a single TB using 256 QAM - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); byte_buffer_t buffer; pdu.init_tx(&buffer, pdu_size, true); @@ -454,13 +434,13 @@ int mac_sch_pdu_pack_test5() TESTASSERT(pdu.get()->set_sdu(2, pdu_size - 1, &rlc) != 0); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // make sure full PDU has been written TESTASSERT(buffer.N_bytes == pdu_size); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -472,10 +452,10 @@ int mac_sch_pdu_pack_test5() // Test for Long BSR CE int mac_sch_pdu_pack_test6() { - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); const uint32_t pdu_size = 8; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); uint8_t tv[pdu_size] = {0x3e, 0x1f, 0x86, 0x18, 0x61, 0x00, 0x00, 0x00}; // upper edge case uint8_t tv2[pdu_size] = {0x3e, 0x1f, 0x04, 0x10, 0x41, 0x00, 0x00, 0x00}; // lower edge case @@ -498,7 +478,7 @@ int mac_sch_pdu_pack_test6() TESTASSERT(pdu.get()->set_bsr(buff_size_tx, srslte::ul_sch_lcid::LONG_BSR)); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // compare with tv TESTASSERT(memcmp(buffer.msg, tv, buffer.N_bytes) == 0); @@ -526,10 +506,10 @@ int mac_sch_pdu_pack_test6() TESTASSERT(buff_size_rx[i] == buff_size_tx[i]); } - mac_log->info("%s\n", pdu.to_string().c_str()); + mac_logger.info("%s", pdu.to_string().c_str()); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -554,13 +534,13 @@ int mac_sch_pdu_pack_test6() TESTASSERT(pdu.get()->set_bsr(buff_size_tx_low_edge, srslte::ul_sch_lcid::LONG_BSR)); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); - mac_log->info("%s\n", pdu.to_string().c_str()); + pdu.write_packet(mac_logger); + mac_logger.info("%s", pdu.to_string().c_str()); TESTASSERT(memcmp(buffer.msg, tv2, buffer.N_bytes) == 0); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -607,13 +587,13 @@ int mac_sch_pdu_pack_test6() TESTASSERT(pdu.get()->set_bsr(buff_size_max_idx, srslte::ul_sch_lcid::LONG_BSR)); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); - mac_log->info("%s\n", pdu.to_string().c_str()); + pdu.write_packet(mac_logger); + mac_logger.info("%s", pdu.to_string().c_str()); TESTASSERT(memcmp(buffer.msg, tv3, buffer.N_bytes) == 0); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -649,13 +629,13 @@ int mac_sch_pdu_pack_test6() // Test for short MAC PDU containing padding only int mac_sch_pdu_pack_test7() { - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); rlc_dummy rlc; rlc.write_sdu(1, 8); const uint32_t pdu_size = 2; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); uint8_t tv[pdu_size] = {0x1f, 0x1f}; @@ -677,13 +657,13 @@ int mac_sch_pdu_pack_test7() pdu.del_subh(); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // compare with tv TESTASSERT(memcmp(buffer.msg, tv, buffer.N_bytes) == 0); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -695,10 +675,10 @@ int mac_sch_pdu_pack_test7() // Test Packing of SCell Activation CE command int mac_sch_pdu_pack_test8() { - srslte::log_ref log_h{"MAC"}; + auto& mac_logger = srslog::fetch_basic_logger("MAC"); const uint32_t pdu_size = 2; - srslte::sch_pdu pdu(10, log_h); + srslte::sch_pdu pdu(10, mac_logger); std::bitset<8> cc_mask(uniform_dist_u8(rand_gen)); // subheader: R|F2|E|LCID = 0|0|0|11011 @@ -725,14 +705,14 @@ int mac_sch_pdu_pack_test8() TESTASSERT(pdu.get()->set_scell_activation_cmd(cc_activ_list)); // write PDU - pdu.write_packet(log_h); + pdu.write_packet(mac_logger); // compare with tv TESTASSERT(memcmp(buffer.msg, tv, buffer.N_bytes) == 0); // log - log_h->info("Activation mask chosen was 0x%x", tv[1]); - log_h->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU with SCell Activation CE (%d B):\n", buffer.N_bytes); + mac_logger.info("Activation mask chosen was 0x%x", tv[1]); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU with SCell Activation CE (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_dl_crnti(tv, sizeof(tv), 0x1001, true, 1, 0); @@ -744,10 +724,10 @@ int mac_sch_pdu_pack_test8() // Test for Short BSR CE int mac_sch_pdu_pack_test9() { - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); const uint32_t pdu_size = 3; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); uint8_t tv[pdu_size] = {0x3f, 0x1d, 0x09}; @@ -766,13 +746,13 @@ int mac_sch_pdu_pack_test9() TESTASSERT(pdu.new_subh() == false); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // compare with tv TESTASSERT(memcmp(buffer.msg, tv, buffer.N_bytes) == 0); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -784,10 +764,10 @@ int mac_sch_pdu_pack_test9() // Test for Short BSR CE + PHR CE int mac_sch_pdu_pack_test10() { - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); const uint32_t pdu_size = 4; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); uint8_t tv[pdu_size] = {0x3d, 0x1a, 0x1f, 0x21}; @@ -809,13 +789,13 @@ int mac_sch_pdu_pack_test10() TESTASSERT(pdu.get()->set_phr(10.1)); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // compare with tv TESTASSERT(memcmp(buffer.msg, tv, buffer.N_bytes) == 0); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -827,10 +807,10 @@ int mac_sch_pdu_pack_test10() // Pack test for short MAC PDU, trying to add long BSR but no space left int mac_sch_pdu_pack_test11() { - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); const uint32_t pdu_size = 3; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); uint8_t tv[pdu_size] = {0x1f, 0x00, 0x00}; @@ -851,13 +831,13 @@ int mac_sch_pdu_pack_test11() pdu.del_subh(); // write PDU - pdu.write_packet(srslte::log_ref{"MAC"}); + pdu.write_packet(mac_logger); // compare with tv TESTASSERT(memcmp(buffer.msg, tv, buffer.N_bytes) == 0); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); @@ -869,19 +849,14 @@ int mac_sch_pdu_pack_test11() // Test for checking error cases int mac_sch_pdu_pack_error_test() { - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - rlc_dummy rlc; - - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); // create RLC SDUs rlc.write_sdu(1, 8); const uint32_t pdu_size = 150; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, mac_logger); byte_buffer_t buffer; pdu.init_tx(&buffer, pdu_size, true); @@ -902,7 +877,7 @@ int mac_sch_pdu_pack_error_test() TESTASSERT(pdu.get()->set_sdu(1, 8, &rlc) == SRSLTE_ERROR); // writing PDU fails - TESTASSERT(pdu.write_packet(srslte::log_ref{"MAC"}) == nullptr); + TESTASSERT(pdu.write_packet(mac_logger) == nullptr); // reset buffer buffer.clear(); @@ -912,13 +887,13 @@ int mac_sch_pdu_pack_error_test() TESTASSERT(pdu.get()->set_sdu(1, 100, &rlc) == 8); // only 8 bytes in RLC buffer // writing PDU fails - TESTASSERT(pdu.write_packet(srslte::log_ref{"MAC"})); + TESTASSERT(pdu.write_packet(mac_logger)); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP - pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1,0); + pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); #endif return SRSLTE_SUCCESS; @@ -929,10 +904,10 @@ int mac_mch_pdu_pack_test1() static uint8_t tv[] = {0x3e, 0x02, 0x20, 0x05, 0x21, 0x0a, 0x1f, 0x0f, 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - srslte::log_ref mac_log("MAC"); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); const uint32_t pdu_size = 30; - srslte::mch_pdu mch_pdu(10, srslte::log_ref{"MAC"}); + srslte::mch_pdu mch_pdu(10, mac_logger); byte_buffer_t buffer; mch_pdu.init_tx(&buffer, pdu_size, true); @@ -954,13 +929,13 @@ int mac_mch_pdu_pack_test1() mch_pdu.get()->set_sdu(1, 10, sdu1); // write PDU - TESTASSERT(mch_pdu.write_packet(srslte::log_ref{"MAC"}) == buffer.msg); + TESTASSERT(mch_pdu.write_packet(mac_logger) == buffer.msg); // log - mac_log->info_hex(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):\n", buffer.N_bytes); + mac_logger.info(buffer.msg, buffer.N_bytes, "MAC PDU (%d B):", buffer.N_bytes); #if HAVE_PCAP - pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1,0); + pcap_handle->write_ul_crnti(buffer.msg, buffer.N_bytes, 0x1001, true, 1, 0); #endif // compare with TV @@ -978,7 +953,7 @@ int mac_sch_pdu_unpack_test1() { static uint8_t tv[] = {0x3f, 0x3f, 0x21, 0x3f, 0x03, 0x00, 0x04, 0x00, 0x04}; - srslte::sch_pdu pdu(10, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(10, srslog::fetch_basic_logger("MAC")); pdu.init_rx(sizeof(tv), false); pdu.parse_packet(tv); @@ -987,7 +962,7 @@ int mac_sch_pdu_unpack_test1() TESTASSERT(pdu.next() == false); #if HAVE_PCAP - pcap_handle->write_ul_crnti(tv, sizeof(tv), 0x1001, true, 1,0); + pcap_handle->write_ul_crnti(tv, sizeof(tv), 0x1001, true, 1, 0); #endif return SRSLTE_SUCCESS; @@ -998,7 +973,7 @@ int mac_sch_pdu_unpack_test2() { static uint8_t tv[] = {0x3f, 0x3f}; - srslte::sch_pdu pdu(20, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(20, srslog::fetch_basic_logger("MAC")); pdu.init_rx(sizeof(tv), false); pdu.parse_packet(tv); @@ -1007,7 +982,7 @@ int mac_sch_pdu_unpack_test2() TESTASSERT(pdu.next() == false); #if HAVE_PCAP - pcap_handle->write_ul_crnti(tv, sizeof(tv), 0x1001, true, 1,0); + pcap_handle->write_ul_crnti(tv, sizeof(tv), 0x1001, true, 1, 0); #endif return SRSLTE_SUCCESS; @@ -1018,7 +993,7 @@ int mac_sch_pdu_unpack_test3() { static uint8_t tv[] = {0x3d, 0x1f, 0x1f, 0x00}; - srslte::sch_pdu pdu(20, srslte::log_ref{"MAC"}); + srslte::sch_pdu pdu(20, srslog::fetch_basic_logger("MAC")); pdu.init_rx(sizeof(tv), false); pdu.parse_packet(tv); @@ -1047,10 +1022,6 @@ int mac_slsch_pdu_unpack_test1() 0x18, 0x6A, 0x07, 0x20, 0x7C, 0xE1, 0xE0, 0x04, 0x40, 0x02, 0x04, 0x80, 0x60, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - srslte::log_filter mac_log("MAC"); - mac_log.set_level(srslte::LOG_LEVEL_DEBUG); - mac_log.set_hex_limit(100000); - #if HAVE_PCAP pcap_handle->write_sl_crnti(tv, sizeof(tv), CRNTI, true, 1, 0); #endif @@ -1064,12 +1035,14 @@ int main(int argc, char** argv) pcap_handle = std::unique_ptr(new srslte::mac_pcap()); pcap_handle->open("mac_pdu_test.pcap"); #endif - logmap::set_default_hex_limit(100000); - logmap::set_default_log_level(LOG_LEVEL_DEBUG); + auto& mac_logger = srslog::fetch_basic_logger("MAC", false); + mac_logger.set_level(srslog::basic_levels::debug); + mac_logger.set_hex_dump_max_size(-1); + auto& rlc_logger = srslog::fetch_basic_logger("RLC", false); + rlc_logger.set_level(srslog::basic_levels::debug); + rlc_logger.set_hex_dump_max_size(-1); - srslte::log_ref mac_log{"MAC"}; - mac_log->set_level(srslte::LOG_LEVEL_DEBUG); - mac_log->set_hex_limit(100000); + srslog::init(); TESTASSERT(mac_rar_pdu_unpack_test1() == SRSLTE_SUCCESS); TESTASSERT(mac_rar_pdu_unpack_test2() == SRSLTE_SUCCESS); diff --git a/lib/test/phy/CMakeLists.txt b/lib/test/phy/CMakeLists.txt index 05e8180a2..8fe7ef87b 100644 --- a/lib/test/phy/CMakeLists.txt +++ b/lib/test/phy/CMakeLists.txt @@ -21,6 +21,8 @@ ####################################################################### # PHY TESTS ####################################################################### +set(CTEST_LABELS "lib;phy") + add_executable(phy_dl_test phy_dl_test.c) target_link_libraries(phy_dl_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) @@ -50,8 +52,7 @@ foreach (cell_n_prb 6 15 25 50 75 100) endif (${allow_256}) set(phy_dl_test_args ${phy_dl_test_args} -m ${ue_dl_mcs}) string(REGEX REPLACE "\ " "" test_name_args ${phy_dl_test_args}) - add_test(phy_dl_test${test_name_args} phy_dl_test ${phy_dl_test_args}) - set_tests_properties(phy_dl_test${test_name_args} PROPERTIES LABELS "long;phy") + add_lte_test(phy_dl_test${test_name_args} phy_dl_test ${phy_dl_test_args}) endforeach (ue_dl_mcs) endforeach (ue_dl_tm) endforeach (allow_256 0 1) @@ -59,9 +60,8 @@ endforeach (cell_n_prb) add_executable(pucch_ca_test pucch_ca_test.c) target_link_libraries(pucch_ca_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -add_test(pucch_ca_test pucch_ca_test) -set_tests_properties(pucch_ca_test PROPERTIES LABELS "long;phy") +add_lte_test(pucch_ca_test pucch_ca_test) add_executable(phy_dl_nr_test phy_dl_nr_test.c) target_link_libraries(phy_dl_nr_test srslte_phy srslte_common srslte_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -add_test(phy_dl_nr_test phy_dl_nr_test -p 100 -m 28) \ No newline at end of file +add_nr_test(phy_dl_nr_test phy_dl_nr_test -p 100 -m 28) \ No newline at end of file diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index c6ae6cde5..30f9fb356 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -44,7 +44,7 @@ static srslte_sch_grant_nr_t pdsch_grant = {}; static uint16_t rnti = 0x1234; static uint32_t nof_slots = 10; -void usage(char* prog) +static void usage(char* prog) { printf("Usage: %s [pTL] \n", prog); printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb); @@ -57,7 +57,7 @@ void usage(char* prog) printf("\t-v [set srslte_verbose to debug, default none]\n"); } -int parse_args(int argc, char** argv) +static int parse_args(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "PpmnTLv")) != -1) { @@ -92,15 +92,15 @@ int parse_args(int argc, char** argv) return SRSLTE_SUCCESS; } -int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl, - srslte_dl_slot_cfg_t* slot, - srslte_search_space_t* search_space, - srslte_dci_dl_nr_t* dci_dl, - srslte_dci_location_t* dci_location, - uint8_t** data_tx) +static int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl, + srslte_slot_cfg_t* slot, + srslte_search_space_t* search_space, + srslte_dci_dl_nr_t* dci_dl, + srslte_dci_location_t* dci_location, + uint8_t** data_tx) { if (srslte_enb_dl_nr_base_zero(enb_dl) < SRSLTE_SUCCESS) { - ERROR("Error setting base to zero\n"); + ERROR("Error setting base to zero"); return SRSLTE_ERROR; } @@ -108,19 +108,19 @@ int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl, dci_dl->format = srslte_dci_format_nr_1_0; dci_dl->rnti_type = srslte_rnti_type_c; dci_dl->location = *dci_location; - dci_dl->search_space = *search_space; + dci_dl->search_space = search_space->type; dci_dl->rnti = rnti; // Put actual DCI if (srslte_enb_dl_nr_pdcch_put(enb_dl, slot, dci_dl) < SRSLTE_SUCCESS) { - ERROR("Error putting PDCCH\n"); + ERROR("Error putting PDCCH"); return SRSLTE_ERROR; } // Put PDSCH transmission pdsch_cfg.grant = pdsch_grant; if (srslte_enb_dl_nr_pdsch_put(enb_dl, slot, &pdsch_cfg, data_tx) < SRSLTE_SUCCESS) { - ERROR("Error putting PDSCH\n"); + ERROR("Error putting PDSCH"); return SRSLTE_ERROR; } @@ -129,28 +129,25 @@ int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl, return SRSLTE_SUCCESS; } -int work_ue_dl(srslte_ue_dl_nr_t* ue_dl, - srslte_dl_slot_cfg_t* slot, - srslte_search_space_t* search_space, - srslte_pdsch_res_nr_t* pdsch_res) +static int work_ue_dl(srslte_ue_dl_nr_t* ue_dl, srslte_slot_cfg_t* slot, srslte_pdsch_res_nr_t* pdsch_res) { srslte_ue_dl_nr_estimate_fft(ue_dl, slot); srslte_dci_dl_nr_t dci_dl_rx = {}; - int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(ue_dl, search_space, slot, rnti, &dci_dl_rx, 1); + int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(ue_dl, slot, rnti, srslte_rnti_type_c, &dci_dl_rx, 1); if (nof_found_dci < SRSLTE_SUCCESS) { - ERROR("Error decoding\n"); + ERROR("Error decoding"); return SRSLTE_ERROR; } if (nof_found_dci < 1) { - ERROR("Error DCI not found\n"); + ERROR("Error DCI not found"); return SRSLTE_ERROR; } pdsch_cfg.grant = pdsch_grant; if (srslte_ue_dl_nr_decode_pdsch(ue_dl, slot, &pdsch_cfg, pdsch_res) < SRSLTE_SUCCESS) { - ERROR("Error decoding\n"); + ERROR("Error decoding"); return SRSLTE_ERROR; } @@ -164,7 +161,7 @@ int main(int argc, char** argv) srslte_ue_dl_nr_t ue_dl = {}; srslte_pdsch_res_nr_t pdsch_res[SRSLTE_MAX_TB] = {}; srslte_random_t rand_gen = srslte_random_init(1234); - srslte_dl_slot_cfg_t slot = {}; + srslte_slot_cfg_t slot = {}; struct timeval t[3] = {}; uint64_t pdsch_encode_us = 0; uint64_t pdsch_decode_us = 0; @@ -176,7 +173,7 @@ int main(int argc, char** argv) buffer = srslte_vec_cf_malloc(SRSLTE_SF_LEN_PRB(carrier.nof_prb)); if (buffer == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } @@ -201,47 +198,51 @@ int main(int argc, char** argv) goto clean_exit; } + srslte_ue_dl_nr_pdcch_cfg_t pdcch_cfg = {}; + // Configure CORESET - srslte_coreset_t coreset = {}; - coreset.duration = 2; + srslte_coreset_t* coreset = &pdcch_cfg.coreset[0]; + pdcch_cfg.coreset_present[0] = true; + coreset->duration = 2; for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { - coreset.freq_resources[i] = i < carrier.nof_prb / 6; + coreset->freq_resources[i] = i < carrier.nof_prb / 6; } // Configure Search Space - srslte_search_space_t search_space = {}; - search_space.type = srslte_search_space_type_ue; + srslte_search_space_t* search_space = &pdcch_cfg.search_space[0]; + pdcch_cfg.search_space_present[0] = true; + search_space->type = srslte_search_space_type_ue; for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - search_space.nof_candidates[L] = srslte_pdcch_nr_max_candidates_coreset(&coreset, L); + search_space->nof_candidates[L] = srslte_pdcch_nr_max_candidates_coreset(coreset, L); } if (srslte_ue_dl_nr_init(&ue_dl, &buffer, &ue_dl_args)) { - ERROR("Error UE DL\n"); + ERROR("Error UE DL"); goto clean_exit; } if (srslte_enb_dl_nr_init(&enb_dl, &buffer, &enb_dl_args)) { - ERROR("Error UE DL\n"); + ERROR("Error UE DL"); goto clean_exit; } if (srslte_ue_dl_nr_set_carrier(&ue_dl, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } - if (srslte_ue_dl_nr_set_coreset(&ue_dl, &coreset)) { - ERROR("Error setting CORESET\n"); + if (srslte_ue_dl_nr_set_pdcch_config(&ue_dl, &pdcch_cfg)) { + ERROR("Error setting CORESET"); goto clean_exit; } if (srslte_enb_dl_nr_set_carrier(&enb_dl, &carrier)) { - ERROR("Error setting SCH NR carrier\n"); + ERROR("Error setting SCH NR carrier"); goto clean_exit; } - if (srslte_enb_dl_nr_set_coreset(&enb_dl, &coreset)) { - ERROR("Error setting CORESET\n"); + if (srslte_enb_dl_nr_set_coreset(&enb_dl, coreset)) { + ERROR("Error setting CORESET"); goto clean_exit; } @@ -249,7 +250,7 @@ int main(int argc, char** argv) data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); if (data_tx[i] == NULL || data_rx[i] == NULL) { - ERROR("Error malloc\n"); + ERROR("Error malloc"); goto clean_exit; } @@ -261,19 +262,19 @@ int main(int argc, char** argv) if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); goto clean_exit; } // Use grant default A time resources with m=0 - if (srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { - ERROR("Error loading default grant\n"); + if (srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading default grant"); goto clean_exit; } pdsch_grant.nof_layers = carrier.max_mimo_layers; @@ -298,13 +299,12 @@ int main(int argc, char** argv) for (slot.idx = 0; slot.idx < nof_slots; slot.idx++) { for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { for (mcs = mcs_start; mcs < mcs_end; mcs++, slot_count++) { - for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { pdsch_grant.prb_idx[n] = (n < n_prb); } if (srslte_ra_nr_fill_tb(&pdsch_cfg, &pdsch_grant, mcs, &pdsch_grant.tb[0]) < SRSLTE_SUCCESS) { - ERROR("Error filing tb\n"); + ERROR("Error filing tb"); goto clean_exit; } @@ -324,9 +324,9 @@ int main(int argc, char** argv) uint32_t L = 0; uint32_t ncce_candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {}; int nof_candidates = - srslte_pdcch_nr_locations_coreset(&coreset, &search_space, rnti, L, slot.idx, ncce_candidates); + srslte_pdcch_nr_locations_coreset(coreset, search_space, rnti, L, slot.idx, ncce_candidates); if (nof_candidates < SRSLTE_SUCCESS) { - ERROR("Error getting PDCCH candidates\n"); + ERROR("Error getting PDCCH candidates"); goto clean_exit; } @@ -339,8 +339,8 @@ int main(int argc, char** argv) srslte_dci_dl_nr_t dci_dl = {}; gettimeofday(&t[1], NULL); - if (work_gnb_dl(&enb_dl, &slot, &search_space, &dci_dl, &dci_location, data_tx) < SRSLTE_ERROR) { - ERROR("Error running eNb DL\n"); + if (work_gnb_dl(&enb_dl, &slot, search_space, &dci_dl, &dci_location, data_tx) < SRSLTE_ERROR) { + ERROR("Error running eNb DL"); goto clean_exit; } gettimeofday(&t[2], NULL); @@ -353,8 +353,8 @@ int main(int argc, char** argv) } gettimeofday(&t[1], NULL); - if (work_ue_dl(&ue_dl, &slot, &search_space, pdsch_res) < SRSLTE_SUCCESS) { - ERROR("Error running UE DL\n"); + if (work_ue_dl(&ue_dl, &slot, pdsch_res) < SRSLTE_SUCCESS) { + ERROR("Error running UE DL"); goto clean_exit; } gettimeofday(&t[2], NULL); @@ -362,17 +362,17 @@ int main(int argc, char** argv) pdsch_decode_us += (size_t)(t[0].tv_sec * 1e6 + t[0].tv_usec); if (pdsch_res->evm > 0.001f) { - ERROR("Error PDSCH EVM is too high %f\n", pdsch_res->evm); + ERROR("Error PDSCH EVM is too high %f", pdsch_res->evm); goto clean_exit; } if (!pdsch_res[0].crc) { - ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pdsch_grant.tb[0].tbs); + ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_grant.tb[0].tbs); goto clean_exit; } if (memcmp(data_tx[0], data_rx[0], pdsch_grant.tb[0].tbs / 8) != 0) { - ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pdsch_grant.tb[0].tbs); + ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_grant.tb[0].tbs); printf("Tx data: "); srslte_vec_fprint_byte(stdout, data_tx[0], pdsch_grant.tb[0].tbs / 8); printf("Rx data: "); @@ -380,7 +380,7 @@ int main(int argc, char** argv) goto clean_exit; } - INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pdsch_grant.tb[0].tbs, pdsch_res[0].evm); + INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!", n_prb, mcs, pdsch_grant.tb[0].tbs, pdsch_res[0].evm); // Count the Tx/Rx'd number of bits nof_bits += pdsch_grant.tb[0].tbs; diff --git a/lib/test/phy/phy_dl_test.c b/lib/test/phy/phy_dl_test.c index e0fedd845..aaf3ab615 100644 --- a/lib/test/phy/phy_dl_test.c +++ b/lib/test/phy/phy_dl_test.c @@ -75,7 +75,7 @@ void parse_extensive_param(char* param, char* arg) } if (ext_code) { - ERROR("Error parsing parameter '%s' and argument '%s'\n", param, arg); + ERROR("Error parsing parameter '%s' and argument '%s'", param, arg); exit(ext_code); } } @@ -151,19 +151,19 @@ int work_enb(srslte_enb_dl_t* enb_dl, srslte_enb_dl_put_base(enb_dl, dl_sf); if (srslte_enb_dl_put_pdcch_dl(enb_dl, dci_cfg, dci)) { - ERROR("Error putting PDCCH sf_idx=%d\n", dl_sf->tti); + ERROR("Error putting PDCCH sf_idx=%d", dl_sf->tti); goto quit; } // Create pdsch config srslte_pdsch_cfg_t pdsch_cfg; if (srslte_ra_dl_dci_to_grant(&cell, dl_sf, transmission_mode, enable_256qam, dci, &pdsch_cfg.grant)) { - ERROR("Computing DL grant sf_idx=%d\n", dl_sf->tti); + ERROR("Computing DL grant sf_idx=%d", dl_sf->tti); goto quit; } char str[512]; srslte_dci_dl_info(dci, str, 512); - INFO("eNb PDCCH: rnti=0x%x, %s\n", rnti, str); + INFO("eNb PDCCH: rnti=0x%x, %s", rnti, str); for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { pdsch_cfg.softbuffers.tx[i] = softbuffer_tx[i]; @@ -177,11 +177,11 @@ int work_enb(srslte_enb_dl_t* enb_dl, pdsch_cfg.meas_time_en = false; if (srslte_enb_dl_put_pdsch(enb_dl, &pdsch_cfg, data_tx) < 0) { - ERROR("Error putting PDSCH sf_idx=%d\n", dl_sf->tti); + ERROR("Error putting PDSCH sf_idx=%d", dl_sf->tti); goto quit; } srslte_pdsch_tx_info(&pdsch_cfg, str, 512); - INFO("eNb PDSCH: rnti=0x%x, %s\n", rnti, str); + INFO("eNb PDSCH: rnti=0x%x, %s", rnti, str); srslte_enb_dl_gen_signal(enb_dl); @@ -199,16 +199,16 @@ int work_ue(srslte_ue_dl_t* ue_dl, srslte_pdsch_res_t pdsch_res[SRSLTE_MAX_CODEWORDS]) { if (srslte_ue_dl_decode_fft_estimate(ue_dl, sf_cfg_dl, ue_dl_cfg) < 0) { - ERROR("Getting PDCCH FFT estimate sf_idx=%d\n", sf_idx); + ERROR("Getting PDCCH FFT estimate sf_idx=%d", sf_idx); return SRSLTE_ERROR; } int nof_grants = srslte_ue_dl_find_dl_dci(ue_dl, sf_cfg_dl, ue_dl_cfg, rnti, dci_dl); if (nof_grants < 0) { - ERROR("Looking for DL grants sf_idx=%d\n", sf_idx); + ERROR("Looking for DL grants sf_idx=%d", sf_idx); return SRSLTE_ERROR; } else if (nof_grants == 0) { - ERROR("Failed to find DCI in sf_idx=%d\n", sf_idx); + ERROR("Failed to find DCI in sf_idx=%d", sf_idx); return SRSLTE_ERROR; } @@ -223,12 +223,12 @@ int work_ue(srslte_ue_dl_t* ue_dl, if (srslte_verbose >= SRSLTE_VERBOSE_INFO) { char str[512]; srslte_dci_dl_info(&dci_dl[0], str, 512); - INFO("UE PDCCH: rnti=0x%x, %s\n", rnti, str); + INFO("UE PDCCH: rnti=0x%x, %s", rnti, str); } if (srslte_ra_dl_dci_to_grant( &cell, sf_cfg_dl, transmission_mode, enable_256qam, &dci_dl[0], &ue_dl_cfg->cfg.pdsch.grant)) { - ERROR("Computing DL grant sf_idx=%d\n", sf_idx); + ERROR("Computing DL grant sf_idx=%d", sf_idx); return SRSLTE_ERROR; } @@ -240,14 +240,14 @@ int work_ue(srslte_ue_dl_t* ue_dl, } if (srslte_ue_dl_decode_pdsch(ue_dl, sf_cfg_dl, &ue_dl_cfg->cfg.pdsch, pdsch_res)) { - ERROR("ERROR: Decoding PDSCH sf_idx=%d\n", sf_idx); + ERROR("ERROR: Decoding PDSCH sf_idx=%d", sf_idx); return SRSLTE_ERROR; } if (srslte_verbose >= SRSLTE_VERBOSE_INFO) { char str[512]; srslte_pdsch_rx_info(&ue_dl_cfg->cfg.pdsch, pdsch_res, str, 512); - INFO("eNb PDSCH: rnti=0x%x, %s\n", rnti, str); + INFO("eNb PDSCH: rnti=0x%x, %s", rnti, str); } return SRSLTE_SUCCESS; @@ -332,7 +332,7 @@ int main(int argc, char** argv) for (int i = 0; i < cell.nof_ports; i++) { signal_buffer[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (!signal_buffer[i]) { - ERROR("Error allocating buffer\n"); + ERROR("Error allocating buffer"); goto quit; } } @@ -340,35 +340,35 @@ int main(int argc, char** argv) for (int i = 0; i < SRSLTE_MAX_TB; i++) { softbuffer_tx[i] = (srslte_softbuffer_tx_t*)calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffer_tx[i]) { - ERROR("Error allocating softbuffer_tx\n"); + ERROR("Error allocating softbuffer_tx"); goto quit; } if (srslte_softbuffer_tx_init(softbuffer_tx[i], cell.nof_prb)) { - ERROR("Error initiating softbuffer_tx\n"); + ERROR("Error initiating softbuffer_tx"); goto quit; } softbuffer_rx[i] = (srslte_softbuffer_rx_t*)calloc(sizeof(srslte_softbuffer_rx_t), 1); if (!softbuffer_rx[i]) { - ERROR("Error allocating softbuffer_rx\n"); + ERROR("Error allocating softbuffer_rx"); goto quit; } if (srslte_softbuffer_rx_init(softbuffer_rx[i], cell.nof_prb)) { - ERROR("Error initiating softbuffer_rx\n"); + ERROR("Error initiating softbuffer_rx"); goto quit; } data_tx[i] = srslte_vec_u8_malloc(MAX_DATABUFFER_SIZE); if (!data_tx[i]) { - ERROR("Error allocating data tx\n"); + ERROR("Error allocating data tx"); goto quit; } data_rx[i] = srslte_vec_u8_malloc(MAX_DATABUFFER_SIZE); if (!data_rx[i]) { - ERROR("Error allocating data tx\n"); + ERROR("Error allocating data tx"); goto quit; } } @@ -377,17 +377,17 @@ int main(int argc, char** argv) * Initialise eNb */ if (srslte_enb_dl_init(enb_dl, signal_buffer, cell.nof_prb)) { - ERROR("Error initiating eNb downlink\n"); + ERROR("Error initiating eNb downlink"); goto quit; } if (srslte_enb_dl_set_cell(enb_dl, cell)) { - ERROR("Error setting eNb DL cell\n"); + ERROR("Error setting eNb DL cell"); goto quit; } if (srslte_enb_dl_add_rnti(enb_dl, rnti)) { - ERROR("Error adding RNTI\n"); + ERROR("Error adding RNTI"); goto quit; } @@ -395,12 +395,12 @@ int main(int argc, char** argv) * Initialise UE */ if (srslte_ue_dl_init(ue_dl, signal_buffer, cell.nof_prb, nof_rx_ant)) { - ERROR("Error initiating UE downlink\n"); + ERROR("Error initiating UE downlink"); goto quit; } if (srslte_ue_dl_set_cell(ue_dl, cell)) { - ERROR("Error setting UE downlink cell\n"); + ERROR("Error setting UE downlink cell"); goto quit; } @@ -501,13 +501,13 @@ int main(int argc, char** argv) dci.tb[i].cw_idx = i; } } else { - ERROR("Wrong transmission mode (%d)\n", transmission_mode); + ERROR("Wrong transmission mode (%d)", transmission_mode); } /* * Loop */ - INFO("--- Starting test ---\n"); + INFO("--- Starting test ---"); for (uint32_t sf_idx = 0; sf_idx < nof_subframes; sf_idx++) { /* Generate random data */ for (int j = 0; j < SRSLTE_MAX_TB; j++) { @@ -520,9 +520,9 @@ int main(int argc, char** argv) * Run eNodeB */ srslte_dl_sf_cfg_t sf_cfg_dl = {}; - sf_cfg_dl.tti = sf_idx % 10; - sf_cfg_dl.cfi = cfi; - sf_cfg_dl.sf_type = SRSLTE_SF_NORM; + sf_cfg_dl.tti = sf_idx % 10; + sf_cfg_dl.cfi = cfi; + sf_cfg_dl.sf_type = SRSLTE_SF_NORM; // Set DCI Location dci.location = dci_locations[sf_idx % 10][(sf_idx / 10) % nof_locations[sf_idx % 10]]; @@ -535,7 +535,7 @@ int main(int argc, char** argv) dci.tb[i].mcs_idx = (sf_idx % 5 == 0) ? SRSLTE_MIN(mcs, 27) : mcs; } } - INFO("--- Process eNb ---\n"); + INFO("--- Process eNb ---"); gettimeofday(&t[1], NULL); if (work_enb(enb_dl, &sf_cfg_dl, &dci_cfg, &dci, softbuffer_tx, data_tx)) { @@ -562,7 +562,7 @@ int main(int argc, char** argv) /* * Run UE */ - INFO("--- Process UE ---\n"); + INFO("--- Process UE ---"); gettimeofday(&t[1], NULL); srslte_ue_dl_cfg_t ue_dl_cfg = {}; diff --git a/lib/test/phy/pucch_ca_test.c b/lib/test/phy/pucch_ca_test.c index 5da6c1e15..8742259ca 100644 --- a/lib/test/phy/pucch_ca_test.c +++ b/lib/test/phy/pucch_ca_test.c @@ -96,7 +96,6 @@ static int test_pucch_ca(srslte_ack_nack_feedback_mode_t ack_nack_feedback_mode, // The test itself starts here for (ul_sf.tti = 0; ul_sf.tti < (1U << (nof_carriers * 2U)); ul_sf.tti++) { - // Generate new data pusch_data.uci.ack.valid = true; for (uint32_t i = 0, k = 0; i < nof_carriers; i++) { @@ -122,7 +121,7 @@ static int test_pucch_ca(srslte_ack_nack_feedback_mode_t ack_nack_feedback_mode, // Check results for (int i = 0, k = 0; i < nof_carriers; i++) { for (int j = 0; j < nof_tb[i]; j++, k++) { - INFO("cc=%d; tb=%d; tx_ack=%d; rx_ack=%d;\n", + INFO("cc=%d; tb=%d; tx_ack=%d; rx_ack=%d;", i, j, pusch_data.uci.ack.ack_value[k], diff --git a/lib/test/srslog/event_trace_test.cpp b/lib/test/srslog/event_trace_test.cpp index 7932b67a3..194f81299 100644 --- a/lib/test/srslog/event_trace_test.cpp +++ b/lib/test/srslog/event_trace_test.cpp @@ -35,7 +35,11 @@ class backend_spy : public detail::log_backend public: void start() override {} - void push(detail::log_entry&& entry) override { ++count; } + bool push(detail::log_entry&& entry) override + { + ++count; + return true; + } bool is_running() const override { return true; } diff --git a/lib/test/srslog/log_channel_test.cpp b/lib/test/srslog/log_channel_test.cpp index 462141869..3c7b6dbd8 100644 --- a/lib/test/srslog/log_channel_test.cpp +++ b/lib/test/srslog/log_channel_test.cpp @@ -71,10 +71,11 @@ class backend_spy : public detail::log_backend public: void start() override {} - void push(detail::log_entry&& entry) override + bool push(detail::log_entry&& entry) override { e = std::move(entry); ++count; + return true; } bool is_running() const override { return true; } diff --git a/lib/test/srslog/logger_test.cpp b/lib/test/srslog/logger_test.cpp index 612a07f8b..054d974cb 100644 --- a/lib/test/srslog/logger_test.cpp +++ b/lib/test/srslog/logger_test.cpp @@ -30,7 +30,7 @@ static constexpr char logger_id[] = "TestLogger"; namespace { /// Definition of a three level logger -enum class test_logger_levels { error, warning, info, LAST }; +enum class test_logger_levels { none, error, warning, info, LAST }; struct test_logger_channels { log_channel& error; log_channel& warning; @@ -109,12 +109,31 @@ static bool when_level_is_set_to_info_then_all_are_enabled() return true; } +static bool when_level_is_set_to_none_then_all_are_disabled() +{ + test_dummies::backend_dummy backend; + test_dummies::sink_dummy s; + log_channel error("err", s, backend); + log_channel warning("warning", s, backend); + log_channel info("info", s, backend); + + test_logger logger(logger_id, error, warning, info); + logger.set_level(test_logger_levels::none); + + ASSERT_EQ(logger.error.enabled(), false); + ASSERT_EQ(logger.warning.enabled(), false); + ASSERT_EQ(logger.info.enabled(), false); + + return true; +} + int main() { TEST_FUNCTION(when_logger_is_created_then_id_matches_expected_value); TEST_FUNCTION(when_level_is_set_to_error_then_info_and_warning_is_disabled); TEST_FUNCTION(when_level_is_set_to_warning_then_info_is_disabled); TEST_FUNCTION(when_level_is_set_to_info_then_all_are_enabled); + TEST_FUNCTION(when_level_is_set_to_none_then_all_are_disabled); return 0; } diff --git a/lib/test/srslog/srslog_test.cpp b/lib/test/srslog/srslog_test.cpp index 0ba4fa380..f2990aca4 100644 --- a/lib/test/srslog/srslog_test.cpp +++ b/lib/test/srslog/srslog_test.cpp @@ -174,7 +174,7 @@ static bool when_invalid_id_with_valid_type_is_passed_then_no_logger_is_found() } /// Dummy logger type -enum class dummy_levels { error, LAST }; +enum class dummy_levels { none, error, LAST }; struct dummy_logger_channels { log_channel& error; }; diff --git a/lib/test/srslog/test_dummies.h b/lib/test/srslog/test_dummies.h index 2c18b70d3..7b65725ee 100644 --- a/lib/test/srslog/test_dummies.h +++ b/lib/test/srslog/test_dummies.h @@ -97,7 +97,7 @@ class backend_dummy : public srslog::detail::log_backend public: void start() override {} - void push(srslog::detail::log_entry&& entry) override {} + bool push(srslog::detail::log_entry&& entry) override { return true; } bool is_running() const override { return true; } }; diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index ba1bbc9b9..24ed5c6e8 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -18,36 +18,31 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "lib;upper") + add_executable(rlc_am_data_test rlc_am_data_test.cc) target_link_libraries(rlc_am_data_test srslte_upper srslte_phy srslte_common) -add_test(rlc_am_data_test rlc_am_data_test) +add_lte_test(rlc_am_data_test rlc_am_data_test) add_executable(rlc_am_control_test rlc_am_control_test.cc) target_link_libraries(rlc_am_control_test srslte_upper srslte_phy) -add_test(rlc_am_control_test rlc_am_control_test) +add_lte_test(rlc_am_control_test rlc_am_control_test) add_executable(rlc_am_test rlc_am_test.cc) target_link_libraries(rlc_am_test srslte_upper srslte_phy srslte_common) -add_test(rlc_am_test rlc_am_test) +add_lte_test(rlc_am_test rlc_am_test) -if (ENABLE_5GNR) - add_executable(rlc_am_nr_pdu_test rlc_am_nr_pdu_test.cc) - target_link_libraries(rlc_am_nr_pdu_test srslte_upper srslte_phy) - add_test(rlc_am_nr_pdu_test rlc_am_nr_pdu_test) -endif(ENABLE_5GNR) +add_executable(rlc_am_nr_pdu_test rlc_am_nr_pdu_test.cc) +target_link_libraries(rlc_am_nr_pdu_test srslte_upper srslte_phy) +add_nr_test(rlc_am_nr_pdu_test rlc_am_nr_pdu_test) add_executable(rlc_stress_test rlc_stress_test.cc) target_link_libraries(rlc_stress_test srslte_upper srslte_mac srslte_phy srslte_common ${Boost_LIBRARIES}) -add_test(rlc_am_stress_test rlc_stress_test --mode=AM --loglevel 1 --sdu_gen_delay 250) -add_test(rlc_um_stress_test rlc_stress_test --mode=UM --loglevel 1) -add_test(rlc_tm_stress_test rlc_stress_test --mode=TM --loglevel 1 --random_opp=false) -if (ENABLE_5GNR) - add_test(rlc_um_nr_stress_test rlc_stress_test --rat NR --mode=UM --loglevel 1) - set_tests_properties(rlc_um_nr_stress_test PROPERTIES LABELS "long;upper;lib;nr") -endif(ENABLE_5GNR) -set_tests_properties(rlc_am_stress_test PROPERTIES TIMEOUT 3000) -set_tests_properties(rlc_um_stress_test PROPERTIES TIMEOUT 3000) -set_tests_properties(rlc_tm_stress_test PROPERTIES TIMEOUT 3000) +add_lte_test(rlc_am_stress_test rlc_stress_test --mode=AM --loglevel 1 --sdu_gen_delay 250) +add_lte_test(rlc_um_stress_test rlc_stress_test --mode=UM --loglevel 1) +add_lte_test(rlc_tm_stress_test rlc_stress_test --mode=TM --loglevel 1 --random_opp=false) + +add_nr_test(rlc_um_nr_stress_test rlc_stress_test --rat NR --mode=UM --loglevel 1) add_executable(rlc_um_data_test rlc_um_data_test.cc) target_link_libraries(rlc_um_data_test srslte_upper srslte_phy srslte_common) @@ -61,33 +56,38 @@ add_executable(rlc_common_test rlc_common_test.cc) target_link_libraries(rlc_common_test srslte_upper srslte_phy) add_test(rlc_common_test rlc_common_test) -if (ENABLE_5GNR) - add_executable(rlc_um_nr_pdu_test rlc_um_nr_pdu_test.cc) - target_link_libraries(rlc_um_nr_pdu_test srslte_upper srslte_phy) - add_test(rlc_um_nr_pdu_test rlc_um_nr_pdu_test) +add_executable(rlc_um_nr_pdu_test rlc_um_nr_pdu_test.cc) +target_link_libraries(rlc_um_nr_pdu_test srslte_upper srslte_phy) +add_nr_test(rlc_um_nr_pdu_test rlc_um_nr_pdu_test) - add_executable(rlc_um_nr_test rlc_um_nr_test.cc) - target_link_libraries(rlc_um_nr_test srslte_upper srslte_phy) - add_test(rlc_um_nr_test rlc_um_nr_test) +add_executable(rlc_um_nr_test rlc_um_nr_test.cc) +target_link_libraries(rlc_um_nr_test srslte_upper srslte_phy) +add_nr_test(rlc_um_nr_test rlc_um_nr_test) - add_executable(pdcp_nr_test_tx pdcp_nr_test_tx.cc) - target_link_libraries(pdcp_nr_test_tx srslte_upper srslte_common) - add_test(pdcp_nr_test_tx pdcp_nr_test_tx) - set_tests_properties(pdcp_nr_test_tx PROPERTIES LABELS "long;upper") +add_executable(pdcp_nr_test_tx pdcp_nr_test_tx.cc) +target_link_libraries(pdcp_nr_test_tx srslte_upper srslte_common) +add_nr_test(pdcp_nr_test_tx pdcp_nr_test_tx) - add_executable(pdcp_nr_test_rx pdcp_nr_test_rx.cc) - target_link_libraries(pdcp_nr_test_rx srslte_upper srslte_common) - add_test(pdcp_nr_test_rx pdcp_nr_test_rx) +add_executable(pdcp_nr_test_rx pdcp_nr_test_rx.cc) +target_link_libraries(pdcp_nr_test_rx srslte_upper srslte_common) +add_nr_test(pdcp_nr_test_rx pdcp_nr_test_rx) - add_executable(pdcp_nr_test_discard_sdu pdcp_nr_test_discard_sdu.cc) - target_link_libraries(pdcp_nr_test_discard_sdu srslte_upper srslte_common) - add_test(pdcp_nr_test_discard_sdu pdcp_nr_test_discard_sdu) -endif(ENABLE_5GNR) +add_executable(pdcp_nr_test_discard_sdu pdcp_nr_test_discard_sdu.cc) +target_link_libraries(pdcp_nr_test_discard_sdu srslte_upper srslte_common) +add_nr_test(pdcp_nr_test_discard_sdu pdcp_nr_test_discard_sdu) add_executable(pdcp_lte_test_rx pdcp_lte_test_rx.cc) target_link_libraries(pdcp_lte_test_rx srslte_upper srslte_common) add_test(pdcp_lte_test_rx pdcp_lte_test_rx) +add_executable(pdcp_lte_test_discard_sdu pdcp_lte_test_discard_sdu.cc) +target_link_libraries(pdcp_lte_test_discard_sdu srslte_upper srslte_common) +add_test(pdcp_lte_test_discard_sdu pdcp_lte_test_discard_sdu) + +add_executable(pdcp_lte_test_status_report pdcp_lte_test_status_report.cc) +target_link_libraries(pdcp_lte_test_status_report srslte_upper srslte_common) +add_test(pdcp_lte_test_status_report pdcp_lte_test_status_report) + ######################################################################## # Option to run command after build (useful for remote builds) ######################################################################## diff --git a/lib/test/upper/pdcp_base_test.h b/lib/test/upper/pdcp_base_test.h index e0e3ac547..c2c64a532 100644 --- a/lib/test/upper/pdcp_base_test.h +++ b/lib/test/upper/pdcp_base_test.h @@ -43,32 +43,31 @@ int compare_two_packets(const srslte::unique_byte_buffer_t& msg1, const srslte:: class rlc_dummy : public srsue::rlc_interface_pdcp { public: - rlc_dummy(srslte::log_ref log_) : log(log_) {} + explicit rlc_dummy(srslog::basic_logger& logger) : logger(logger) {} void get_last_sdu(const srslte::unique_byte_buffer_t& pdu) { memcpy(pdu->msg, last_pdcp_pdu->msg, last_pdcp_pdu->N_bytes); pdu->N_bytes = last_pdcp_pdu->N_bytes; - return; } void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "RLC SDU"); + logger.info(sdu->msg, sdu->N_bytes, "RLC SDU"); last_pdcp_pdu.swap(sdu); rx_count++; } void discard_sdu(uint32_t lcid, uint32_t discard_sn) { - log->info("Notifing RLC to discard SDU (SN=%u)\n", discard_sn); + logger.info("Notifing RLC to discard SDU (SN=%u)", discard_sn); discard_count++; - log->info("Discard_count=%" PRIu64 "\n", discard_count); + logger.info("Discard_count=%" PRIu64 "", discard_count); } uint64_t rx_count = 0; uint64_t discard_count = 0; private: - srslte::log_ref log; + srslog::basic_logger& logger; srslte::unique_byte_buffer_t last_pdcp_pdu; bool rb_is_um(uint32_t lcid) { return false; } @@ -78,7 +77,7 @@ private: class rrc_dummy : public srsue::rrc_interface_pdcp { public: - rrc_dummy(srslte::log_ref log_) { log = log_; } + explicit rrc_dummy(srslog::basic_logger& logger) : logger(logger) {} void write_pdu_bcch_bch(srslte::unique_byte_buffer_t pdu) {} void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) {} @@ -87,7 +86,7 @@ public: std::string get_rb_name(uint32_t lcid) { return "None"; } - srslte::log_ref log; + srslog::basic_logger& logger; // Members for testing uint32_t rx_count = 0; @@ -98,12 +97,11 @@ public: { memcpy(pdu->msg, last_pdu->msg, last_pdu->N_bytes); pdu->N_bytes = last_pdu->N_bytes; - return; } void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { - log->info_hex(pdu->msg, pdu->N_bytes, "RRC PDU"); + logger.info(pdu->msg, pdu->N_bytes, "RRC PDU"); rx_count++; last_pdu.swap(pdu); } @@ -112,7 +110,7 @@ public: class gw_dummy : public srsue::gw_interface_pdcp { public: - gw_dummy(srslte::log_ref log_) : log(log_) {} + explicit gw_dummy(srslog::basic_logger& logger) : logger(logger) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} uint32_t rx_count = 0; @@ -121,17 +119,16 @@ public: { memcpy(pdu->msg, last_pdu->msg, last_pdu->N_bytes); pdu->N_bytes = last_pdu->N_bytes; - return; } void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { - log->info_hex(pdu->msg, pdu->N_bytes, "GW PDU"); + logger.info(pdu->msg, pdu->N_bytes, "GW PDU"); rx_count++; last_pdu.swap(pdu); } private: - srslte::log_ref log; + srslog::basic_logger& logger; srslte::unique_byte_buffer_t last_pdu; }; diff --git a/lib/test/upper/pdcp_lte_test.h b/lib/test/upper/pdcp_lte_test.h index cff6a0875..6cdc345fa 100644 --- a/lib/test/upper/pdcp_lte_test.h +++ b/lib/test/upper/pdcp_lte_test.h @@ -68,11 +68,8 @@ srslte::pdcp_lte_state_t normal_init_state = {}; class pdcp_lte_test_helper { public: - pdcp_lte_test_helper(srslte::pdcp_config_t cfg, srslte::as_security_config_t sec_cfg_, srslte::log_ref log) : - rlc(log), - rrc(log), - gw(log), - pdcp(&rlc, &rrc, &gw, &stack.task_sched, log, 0, cfg) + pdcp_lte_test_helper(srslte::pdcp_config_t cfg, srslte::as_security_config_t sec_cfg_, srslog::basic_logger& logger) : + rlc(logger), rrc(logger), gw(logger), pdcp(&rlc, &rrc, &gw, &stack.task_sched, logger, 0, cfg) { pdcp.config_security(sec_cfg_); pdcp.enable_integrity(srslte::DIRECTION_TXRX); @@ -94,8 +91,7 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t uint8_t pdcp_sn_len, srslte::pdcp_rb_type_t rb_type, srslte::as_security_config_t sec_cfg, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { srslte::pdcp_config_t cfg = {1, rb_type, @@ -103,9 +99,10 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t srslte::SECURITY_DIRECTION_DOWNLINK, pdcp_sn_len, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::infinity}; + srslte::pdcp_discard_timer_t::infinity, + false}; - pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, log); + pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; rlc_dummy* rlc = &pdcp_hlp.rlc; @@ -114,10 +111,10 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t init_state.next_pdcp_tx_sn = pdcp->SN(count); pdcp_hlp.set_pdcp_initial_state(init_state); - srslte::unique_byte_buffer_t sdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); *sdu = *in_sdu; pdcp->write_sdu(std::move(sdu)); - srslte::unique_byte_buffer_t out_pdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); rlc->get_last_sdu(out_pdu); return out_pdu; @@ -129,13 +126,12 @@ std::vector gen_expected_pdus_vector(const srslte::unique_byt uint8_t pdcp_sn_len, srslte::pdcp_rb_type_t rb_type, srslte::as_security_config_t sec_cfg_, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { std::vector pdu_vec; for (uint32_t tx_next : tx_nexts) { pdcp_test_event_t event; - event.pkt = gen_expected_pdu(in_sdu, tx_next, pdcp_sn_len, rb_type, sec_cfg_, pool, log); + event.pkt = gen_expected_pdu(in_sdu, tx_next, pdcp_sn_len, rb_type, sec_cfg_, logger); event.ticks = 0; pdu_vec.push_back(std::move(event)); } diff --git a/lib/test/upper/pdcp_lte_test_discard_sdu.cc b/lib/test/upper/pdcp_lte_test_discard_sdu.cc new file mode 100644 index 000000000..d5582e307 --- /dev/null +++ b/lib/test/upper/pdcp_lte_test_discard_sdu.cc @@ -0,0 +1,152 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 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 "pdcp_lte_test.h" +#include + +/* + * Test of imediate notification from RLC + */ +int test_tx_sdu_notify(const srslte::pdcp_lte_state_t& init_state, + srslte::pdcp_discard_timer_t discard_timeout, + srslog::basic_logger& logger) +{ + srslte::pdcp_config_t cfg = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + discard_timeout, + false}; + + pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; + rlc_dummy* rlc = &pdcp_hlp.rlc; + srsue::stack_test_dummy* stack = &pdcp_hlp.stack; + + pdcp_hlp.set_pdcp_initial_state(init_state); + + // Write test SDU + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp->write_sdu(std::move(sdu)); + + srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); + rlc->get_last_sdu(out_pdu); + TESTASSERT(out_pdu->N_bytes == 4); + + TESTASSERT(pdcp->nof_discard_timers() == 1); // One timer should be running + std::vector sns_notified = {0}; + pdcp->notify_delivery(sns_notified); + TESTASSERT(pdcp->nof_discard_timers() == 0); // Timer should have been difused after + + // RLC should not be notified of SDU discard + TESTASSERT(rlc->discard_count == 0); + + // Make sure there are no timers still left on the map + TESTASSERT(pdcp->nof_discard_timers() == 0); + + return 0; +} + +/* + * Test discard timer expiry + */ +int test_tx_sdu_discard(const srslte::pdcp_lte_state_t& init_state, + srslte::pdcp_discard_timer_t discard_timeout, + srslog::basic_logger& logger) +{ + srslte::pdcp_config_t cfg = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + discard_timeout, + false}; + + pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; + rlc_dummy* rlc = &pdcp_hlp.rlc; + srsue::stack_test_dummy* stack = &pdcp_hlp.stack; + + pdcp_hlp.set_pdcp_initial_state(init_state); + + // Write test SDU + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp->write_sdu(std::move(sdu)); + + srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); + rlc->get_last_sdu(out_pdu); + TESTASSERT(out_pdu->N_bytes == 4); + + // Run TTIs for Discard timers + for (uint32_t i = 0; i < static_cast(cfg.discard_timer) - 1; ++i) { + stack->run_tti(); + } + TESTASSERT(pdcp->nof_discard_timers() == 1); // One timer should be running + TESTASSERT(rlc->discard_count == 0); // No discard yet + + // Last timer step + stack->run_tti(); + + TESTASSERT(pdcp->nof_discard_timers() == 0); // Timer should have been difused after expiry + TESTASSERT(rlc->discard_count == 1); // RLC should be notified of discard + + std::vector sns_notified = {0}; + pdcp->notify_delivery(sns_notified); // PDCP should not find PDU to notify. + return 0; +} +/* + * TX Test: PDCP Entity with SN LEN = 12 and 18. + * PDCP entity configured with EIA2 and EEA2 + */ +int test_tx_discard_all(srslog::basic_logger& logger) +{ + /* + * TX Test 1: PDCP Entity with SN LEN = 12 + * Test TX PDU discard. + */ + TESTASSERT(test_tx_sdu_notify(normal_init_state, srslte::pdcp_discard_timer_t::ms50, logger) == 0); + + /* + * TX Test 2: PDCP Entity with SN LEN = 12 + * Test TX PDU discard. + */ + TESTASSERT(test_tx_sdu_discard(normal_init_state, srslte::pdcp_discard_timer_t::ms50, logger) == 0); + return 0; +} + +// Setup all tests +int run_all_tests() +{ + // Setup log + auto& logger = srslog::fetch_basic_logger("PDCP LTE Test", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); + + TESTASSERT(test_tx_discard_all(logger) == 0); + return 0; +} + +int main() +{ + srslog::init(); + + if (run_all_tests() != SRSLTE_SUCCESS) { + fprintf(stderr, "pdcp_lte_tests() failed\n"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} diff --git a/lib/test/upper/pdcp_lte_test_rx.cc b/lib/test/upper/pdcp_lte_test_rx.cc index 5c30d08d7..2477d95f8 100644 --- a/lib/test/upper/pdcp_lte_test_rx.cc +++ b/lib/test/upper/pdcp_lte_test_rx.cc @@ -30,8 +30,7 @@ int test_rx(std::vector events, srslte::pdcp_rb_type_t rb_type, uint32_t n_sdus_exp, const srslte::unique_byte_buffer_t& sdu_exp, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { srslte::pdcp_config_t cfg_rx = {1, @@ -40,9 +39,10 @@ int test_rx(std::vector events, srslte::SECURITY_DIRECTION_UPLINK, pdcp_sn_len, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::infinity}; + srslte::pdcp_discard_timer_t::infinity, + false}; - pdcp_lte_test_helper pdcp_hlp_rx(cfg_rx, sec_cfg, log); + pdcp_lte_test_helper pdcp_hlp_rx(cfg_rx, sec_cfg, logger); srslte::pdcp_entity_lte* pdcp_rx = &pdcp_hlp_rx.pdcp; gw_dummy* gw_rx = &pdcp_hlp_rx.gw; rrc_dummy* rrc_rx = &pdcp_hlp_rx.rrc; @@ -51,7 +51,6 @@ int test_rx(std::vector events, // Generate test message and encript/decript SDU. for (pdcp_test_event_t& event : events) { - // Decript and integrity check the PDU pdcp_rx->write_pdu(std::move(event.pkt)); for (uint32_t i = 0; i < event.ticks; ++i) { @@ -63,7 +62,7 @@ int test_rx(std::vector events, if (rb_type == srslte::PDCP_RB_IS_DRB) { TESTASSERT(gw_rx->rx_count == n_sdus_exp); if (n_sdus_exp > 0) { - srslte::unique_byte_buffer_t sdu_act = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu_act = srslte::make_byte_buffer(); gw_rx->get_last_pdu(sdu_act); TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0); } @@ -71,7 +70,7 @@ int test_rx(std::vector events, } else { TESTASSERT(rrc_rx->rx_count == n_sdus_exp); if (n_sdus_exp > 0) { - srslte::unique_byte_buffer_t sdu_act = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu_act = srslte::make_byte_buffer(); rrc_rx->get_last_pdu(sdu_act); TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0); } @@ -83,12 +82,12 @@ int test_rx(std::vector events, * RX Test: PDCP Entity with SN LEN = 5 and 12. * PDCP entity configured with EIA2 and EEA2 */ -int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) +int test_rx_all(srslog::basic_logger& logger) { // Test SDUs - srslte::unique_byte_buffer_t tst_sdu1 = allocate_unique_buffer(*pool); // SDU 1 + srslte::unique_byte_buffer_t tst_sdu1 = srslte::make_byte_buffer(); // SDU 1 tst_sdu1->append_bytes(sdu1, sizeof(sdu1)); - srslte::unique_byte_buffer_t tst_sdu2 = allocate_unique_buffer(*pool); // SDU 2 + srslte::unique_byte_buffer_t tst_sdu2 = srslte::make_byte_buffer(); // SDU 2 tst_sdu2->append_bytes(sdu2, sizeof(sdu2)); /* @@ -100,7 +99,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test1_counts(2); // Test two packets std::iota(test1_counts.begin(), test1_counts.end(), 31); // Starting at COUNT 31 std::vector test1_pdus = gen_expected_pdus_vector( - tst_sdu1, test1_counts, srslte::PDCP_SN_LEN_5, srslte::PDCP_RB_IS_SRB, sec_cfg, pool, log); + tst_sdu1, test1_counts, srslte::PDCP_SN_LEN_5, srslte::PDCP_RB_IS_SRB, sec_cfg, logger); srslte::pdcp_lte_state_t test1_init_state = { .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 31, .last_submitted_pdcp_rx_sn = 30}; TESTASSERT(test_rx(std::move(test1_pdus), @@ -109,8 +108,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) srslte::PDCP_RB_IS_SRB, 2, tst_sdu1, - pool, - log) == 0); + logger) == 0); } /* @@ -122,7 +120,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test_counts(2); // Test two packets std::iota(test_counts.begin(), test_counts.end(), 4095); // Starting at COUNT 4095 std::vector test_pdus = gen_expected_pdus_vector( - tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, pool, log); + tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, logger); srslte::pdcp_lte_state_t test_init_state = { .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 4095, .last_submitted_pdcp_rx_sn = 4094}; TESTASSERT(test_rx(std::move(test_pdus), @@ -131,8 +129,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) srslte::PDCP_RB_IS_DRB, 2, tst_sdu1, - pool, - log) == 0); + logger) == 0); } /* @@ -143,7 +140,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test_counts(2); // Test two packets std::iota(test_counts.begin(), test_counts.end(), 31); // Starting at COUNT 31 std::vector test_pdus = gen_expected_pdus_vector( - tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, pool, log); + tst_sdu1, test_counts, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, sec_cfg, logger); srslte::pdcp_lte_state_t test_init_state = { .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 32, .last_submitted_pdcp_rx_sn = 31}; TESTASSERT(test_rx(std::move(test_pdus), @@ -152,8 +149,7 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) srslte::PDCP_RB_IS_DRB, test_counts.size() - 1, tst_sdu1, - pool, - log) == 0); + logger) == 0); } return SRSLTE_SUCCESS; @@ -161,51 +157,49 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) // Basic test to verify the correct handling of PDCP status PDUs on DRBs // As long as we don't implement status reporting, the PDU shall be dropped -int test_rx_control_pdu(srslte::byte_buffer_pool* pool, srslte::log_ref log) +int test_rx_control_pdu(srslog::basic_logger& logger) { const uint8_t pdcp_status_report_long[] = {0x0a, 0xc9, 0x3c}; std::vector pdu_vec; pdcp_test_event_t event; - event.pkt = allocate_unique_buffer(*pool); + event.pkt = srslte::make_byte_buffer(); memcpy(event.pkt->msg, pdcp_status_report_long, sizeof(pdcp_status_report_long)); event.pkt->N_bytes = sizeof(pdcp_status_report_long); pdu_vec.push_back(std::move(event)); - srslte::unique_byte_buffer_t tst_sdu1 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t tst_sdu1 = srslte::make_byte_buffer(); srslte::pdcp_lte_state_t test_init_state = { .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 32, .last_submitted_pdcp_rx_sn = 31}; - TESTASSERT(test_rx(std::move(pdu_vec), - test_init_state, - srslte::PDCP_SN_LEN_12, - srslte::PDCP_RB_IS_DRB, - 0, - tst_sdu1, - pool, - log) == 0); + TESTASSERT( + test_rx( + std::move(pdu_vec), test_init_state, srslte::PDCP_SN_LEN_12, srslte::PDCP_RB_IS_DRB, 0, tst_sdu1, logger) == + 0); return SRSLTE_SUCCESS; } // Setup all tests -int run_all_tests(srslte::byte_buffer_pool* pool) +int run_all_tests() { // Setup log - srslte::log_ref log("PDCP LTE Test RX"); - log->set_level(srslte::LOG_LEVEL_DEBUG); - log->set_hex_limit(128); + auto& logger = srslog::fetch_basic_logger("PDCP LTE Test RX", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); - TESTASSERT(test_rx_all(pool, log) == 0); - TESTASSERT(test_rx_control_pdu(pool, log) == 0); + TESTASSERT(test_rx_all(logger) == 0); + TESTASSERT(test_rx_control_pdu(logger) == 0); return 0; } int main() { - if (run_all_tests(srslte::byte_buffer_pool::get_instance()) != SRSLTE_SUCCESS) { + srslog::init(); + + if (run_all_tests() != SRSLTE_SUCCESS) { fprintf(stderr, "pdcp_nr_tests_rx() failed\n"); return SRSLTE_ERROR; } diff --git a/lib/test/upper/pdcp_lte_test_status_report.cc b/lib/test/upper/pdcp_lte_test_status_report.cc new file mode 100644 index 000000000..6a6930d61 --- /dev/null +++ b/lib/test/upper/pdcp_lte_test_status_report.cc @@ -0,0 +1,199 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 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 "pdcp_lte_test.h" +#include + +/* + * Test correct transmission of FMS and Bitmap in status report + */ +int test_tx_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::basic_logger& logger) +{ + srslte::pdcp_config_t cfg = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t::ms500, + true}; + + pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; + rlc_dummy* rlc = &pdcp_hlp.rlc; + srsue::stack_test_dummy* stack = &pdcp_hlp.stack; + + pdcp_hlp.set_pdcp_initial_state(init_state); + srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); + + // Write 256 SDUs and notify imediatly -> FMS 0001 0000 0001 + for (uint32_t i = 0; i < 257; i++) { + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp->write_sdu(std::move(sdu)); + pdcp->notify_delivery({i}); + } + + // Check undelivered SDUs queue size + TESTASSERT(pdcp->nof_discard_timers() == 0); // 0 timers should be running + + // Generate the status report + pdcp->send_status_report(); + rlc->get_last_sdu(out_pdu); + logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); + + // Check status PDU + /* + * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | + * | FMS | -> | 00000001 | + */ + TESTASSERT(out_pdu->msg[0] == 1); + TESTASSERT(out_pdu->msg[1] == 1); + TESTASSERT(out_pdu->N_bytes == 2); + + // Write another 16 SDUs but don't notify SN=257, SN=258, SN=271 and SN=272 + for (uint32_t i = 257; i < 273; i++) { + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp->write_sdu(std::move(sdu)); + if (i != 257 && i != 258 && i != 271 && i != 272) { + pdcp->notify_delivery({i}); + } + } + + // Check undelivered SDUs queue size + TESTASSERT(pdcp->nof_discard_timers() == 4); + + // Generate the status report + pdcp->send_status_report(); + rlc->get_last_sdu(out_pdu); + logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); + + // Check status PDU + /* + * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | + * | FMS | -> | 00000001 | + * | bitmap | -> | 11000000 | + * | bitmap (cont.) | -> | 00000011 | + */ + TESTASSERT(out_pdu->N_bytes == 4); + TESTASSERT(out_pdu->msg[0] == 0b00000001); + TESTASSERT(out_pdu->msg[1] == 0b00000001); + TESTASSERT(out_pdu->msg[2] == 0b11000000); + TESTASSERT(out_pdu->msg[3] == 0b00000011); + return 0; +} + +/* + * Test reception of status report + */ +int test_rx_status_report(const srslte::pdcp_lte_state_t& init_state, srslog::basic_logger& logger) +{ + srslte::pdcp_config_t cfg = {1, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::PDCP_SN_LEN_12, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t::ms500, + true}; + + pdcp_lte_test_helper pdcp_hlp(cfg, sec_cfg, logger); + srslte::pdcp_entity_lte* pdcp = &pdcp_hlp.pdcp; + rlc_dummy* rlc = &pdcp_hlp.rlc; + srsue::stack_test_dummy* stack = &pdcp_hlp.stack; + + pdcp_hlp.set_pdcp_initial_state(init_state); + srslte::unique_byte_buffer_t status_pdu = srslte::make_byte_buffer(); + srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); + + // Write 256 SDUs and notify imediatly -> FMS 0001 0000 0001 + for (uint32_t i = 0; i < 257; i++) { + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp->write_sdu(std::move(sdu)); + pdcp->notify_delivery({i}); + } + + // Write another 16 SDUs but don't notify SN=257, SN=258, SN=271 and SN=272 + for (uint32_t i = 257; i < 273; i++) { + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp->write_sdu(std::move(sdu)); + if (i != 257 && i != 258 && i != 271 && i != 272) { + pdcp->notify_delivery({i}); + } + } + + // Check undelivered SDUs queue size + TESTASSERT(pdcp->nof_discard_timers() == 4); + + // Set status PDU + // Notify up to 270 wit FMS + // Notify 272 with bitmap + /* + * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | + * | FMS | -> | 00001110 | + * | bitmap | -> | 01000000 | + */ + status_pdu->N_bytes = 3; + status_pdu->msg[0] = 0b00000001; + status_pdu->msg[1] = 0b00001110; + status_pdu->msg[2] = 0b01000000; + + pdcp->write_pdu(std::move(status_pdu)); + + TESTASSERT(pdcp->nof_discard_timers() == 1); + + // Check if the SDUs were correctly discarded with the status report + pdcp->send_status_report(); + rlc->get_last_sdu(out_pdu); + logger.debug(out_pdu->msg, out_pdu->N_bytes, "Status PDU:"); + + // Check status PDU, only 271 is missing => FMS = 271 + /* + * | D/C | TYPE | FMS | -> | 0 | 0 | 0001 | + * | FMS | -> | 00001111 | + */ + TESTASSERT(out_pdu->N_bytes == 3); + TESTASSERT(out_pdu->msg[0] == 0b00000001); + TESTASSERT(out_pdu->msg[1] == 0b00001111); + return 0; +} + +// Setup all tests +int run_all_tests() +{ + // Setup log + srslog::basic_logger& logger = srslog::fetch_basic_logger("PDCP", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); + + // This is the normal initial state. All state variables are set to zero + srslte::pdcp_lte_state_t normal_init_state = {}; + + TESTASSERT(test_tx_status_report(normal_init_state, logger) == 0); + + TESTASSERT(test_rx_status_report(normal_init_state, logger) == 0); + return 0; +} + +int main() +{ + srslog::init(); + + if (run_all_tests() != SRSLTE_SUCCESS) { + fprintf(stderr, "pdcp_lte_tests() failed\n"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} diff --git a/lib/test/upper/pdcp_nr_test.h b/lib/test/upper/pdcp_nr_test.h index 56dffc222..38cb56cb3 100644 --- a/lib/test/upper/pdcp_nr_test.h +++ b/lib/test/upper/pdcp_nr_test.h @@ -96,11 +96,8 @@ pdcp_initial_state near_wraparound_init_state = {.tx_next = 4294967295, class pdcp_nr_test_helper { public: - pdcp_nr_test_helper(srslte::pdcp_config_t cfg, srslte::as_security_config_t sec_cfg_, srslte::log_ref log) : - rlc(log), - rrc(log), - gw(log), - pdcp(&rlc, &rrc, &gw, &stack.task_sched, log, 0, cfg) + pdcp_nr_test_helper(srslte::pdcp_config_t cfg, srslte::as_security_config_t sec_cfg_, srslog::basic_logger& logger) : + rlc(logger), rrc(logger), gw(logger), pdcp(&rlc, &rrc, &gw, &stack.task_sched, logger, 0, cfg) { pdcp.config_security(sec_cfg_); pdcp.enable_integrity(srslte::DIRECTION_TXRX); @@ -127,8 +124,7 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t uint32_t count, uint8_t pdcp_sn_len, srslte::as_security_config_t sec_cfg, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { srslte::pdcp_config_t cfg = {1, srslte::PDCP_RB_IS_DRB, @@ -136,9 +132,10 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t srslte::SECURITY_DIRECTION_DOWNLINK, pdcp_sn_len, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::infinity}; + srslte::pdcp_discard_timer_t::infinity, + false}; - pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, log); + pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, logger); srslte::pdcp_entity_nr* pdcp = &pdcp_hlp.pdcp; rlc_dummy* rlc = &pdcp_hlp.rlc; @@ -146,10 +143,10 @@ srslte::unique_byte_buffer_t gen_expected_pdu(const srslte::unique_byte_buffer_t init_state.tx_next = count; pdcp_hlp.set_pdcp_initial_state(init_state); - srslte::unique_byte_buffer_t sdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); *sdu = *in_sdu; pdcp->write_sdu(std::move(sdu)); - srslte::unique_byte_buffer_t out_pdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t out_pdu = srslte::make_byte_buffer(); rlc->get_last_sdu(out_pdu); return out_pdu; @@ -160,13 +157,12 @@ std::vector gen_expected_pdus_vector(const srslte::unique_byt const std::vector& tx_nexts, uint8_t pdcp_sn_len, srslte::as_security_config_t sec_cfg_, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { std::vector pdu_vec; for (uint32_t tx_next : tx_nexts) { pdcp_test_event_t event; - event.pkt = gen_expected_pdu(in_sdu, tx_next, pdcp_sn_len, sec_cfg_, pool, log); + event.pkt = gen_expected_pdu(in_sdu, tx_next, pdcp_sn_len, sec_cfg_, logger); event.ticks = 0; pdu_vec.push_back(std::move(event)); } diff --git a/lib/test/upper/pdcp_nr_test_discard_sdu.cc b/lib/test/upper/pdcp_nr_test_discard_sdu.cc index 94753767b..8869392dc 100644 --- a/lib/test/upper/pdcp_nr_test_discard_sdu.cc +++ b/lib/test/upper/pdcp_nr_test_discard_sdu.cc @@ -27,8 +27,7 @@ int test_tx_sdu_discard(const pdcp_initial_state& init_state, srslte::pdcp_discard_timer_t discard_timeout, bool imediate_notify, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { srslte::pdcp_config_t cfg = {1, srslte::PDCP_RB_IS_DRB, @@ -36,9 +35,10 @@ int test_tx_sdu_discard(const pdcp_initial_state& init_state, srslte::SECURITY_DIRECTION_DOWNLINK, srslte::PDCP_SN_LEN_12, srslte::pdcp_t_reordering_t::ms500, - discard_timeout}; + discard_timeout, + false}; - pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, log); + pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, logger); srslte::pdcp_entity_nr* pdcp = &pdcp_hlp.pdcp; rlc_dummy* rlc = &pdcp_hlp.rlc; srsue::stack_test_dummy* stack = &pdcp_hlp.stack; @@ -46,7 +46,7 @@ int test_tx_sdu_discard(const pdcp_initial_state& init_state, pdcp_hlp.set_pdcp_initial_state(init_state); // Test SDU - srslte::unique_byte_buffer_t sdu = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); sdu->append_bytes(sdu1, sizeof(sdu1)); pdcp->write_sdu(std::move(sdu)); @@ -82,42 +82,42 @@ int test_tx_sdu_discard(const pdcp_initial_state& init_state, * TX Test: PDCP Entity with SN LEN = 12 and 18. * PDCP entity configured with EIA2 and EEA2 */ -int test_tx_discard_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) +int test_tx_discard_all(srslog::basic_logger& logger) { - /* * TX Test 1: PDCP Entity with SN LEN = 12 * Test TX PDU discard. */ - TESTASSERT(test_tx_sdu_discard(normal_init_state, srslte::pdcp_discard_timer_t::ms50, false, pool, log) == 0); + TESTASSERT(test_tx_sdu_discard(normal_init_state, srslte::pdcp_discard_timer_t::ms50, false, logger) == 0); /* * TX Test 2: PDCP Entity with SN LEN = 12 * Test TX PDU discard. */ - // TESTASSERT(test_tx_sdu_discard(normal_init_state, srslte::pdcp_discard_timer_t::ms50, true, pool, log) == 0); + // TESTASSERT(test_tx_sdu_discard(normal_init_state, srslte::pdcp_discard_timer_t::ms50, true, logger) == 0); return 0; } // Setup all tests -int run_all_tests(srslte::byte_buffer_pool* pool) +int run_all_tests() { // Setup log - srslte::log_ref log("PDCP NR Test"); - log->set_level(srslte::LOG_LEVEL_DEBUG); - log->set_hex_limit(128); + auto& logger = srslog::fetch_basic_logger("PDCP NR Test", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); - TESTASSERT(test_tx_discard_all(pool, log) == 0); + TESTASSERT(test_tx_discard_all(logger) == 0); return 0; } int main() { - if (run_all_tests(srslte::byte_buffer_pool::get_instance()) != SRSLTE_SUCCESS) { + srslog::init(); + + if (run_all_tests() != SRSLTE_SUCCESS) { fprintf(stderr, "pdcp_nr_tests() failed\n"); return SRSLTE_ERROR; } - srslte::byte_buffer_pool::cleanup(); return SRSLTE_SUCCESS; } diff --git a/lib/test/upper/pdcp_nr_test_rx.cc b/lib/test/upper/pdcp_nr_test_rx.cc index 8661dd505..a619f3dae 100644 --- a/lib/test/upper/pdcp_nr_test_rx.cc +++ b/lib/test/upper/pdcp_nr_test_rx.cc @@ -29,20 +29,19 @@ int test_rx(std::vector events, uint8_t pdcp_sn_len, uint32_t n_sdus_exp, const srslte::unique_byte_buffer_t& sdu_exp, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { - srslte::pdcp_config_t cfg_rx = {1, srslte::PDCP_RB_IS_DRB, srslte::SECURITY_DIRECTION_DOWNLINK, srslte::SECURITY_DIRECTION_UPLINK, pdcp_sn_len, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::infinity}; + srslte::pdcp_discard_timer_t::infinity, + false}; - pdcp_nr_test_helper pdcp_hlp_rx(cfg_rx, sec_cfg, log); + pdcp_nr_test_helper pdcp_hlp_rx(cfg_rx, sec_cfg, logger); srslte::pdcp_entity_nr* pdcp_rx = &pdcp_hlp_rx.pdcp; gw_dummy* gw_rx = &pdcp_hlp_rx.gw; srsue::stack_test_dummy* stack = &pdcp_hlp_rx.stack; @@ -50,7 +49,6 @@ int test_rx(std::vector events, // Generate test message and encript/decript SDU. for (pdcp_test_event_t& event : events) { - // Decript and integrity check the PDU pdcp_rx->write_pdu(std::move(event.pkt)); for (uint32_t i = 0; i < event.ticks; ++i) { @@ -60,7 +58,7 @@ int test_rx(std::vector events, // Test if the number of RX packets TESTASSERT(gw_rx->rx_count == n_sdus_exp); - srslte::unique_byte_buffer_t sdu_act = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu_act = srslte::make_byte_buffer(); gw_rx->get_last_pdu(sdu_act); TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0); return 0; @@ -70,12 +68,12 @@ int test_rx(std::vector events, * RX Test: PDCP Entity with SN LEN = 12 and 18. * PDCP entity configured with EIA2 and EEA2 */ -int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) +int test_rx_all(srslog::basic_logger& logger) { // Test SDUs - srslte::unique_byte_buffer_t tst_sdu1 = allocate_unique_buffer(*pool); // SDU 1 + srslte::unique_byte_buffer_t tst_sdu1 = srslte::make_byte_buffer(); // SDU 1 tst_sdu1->append_bytes(sdu1, sizeof(sdu1)); - srslte::unique_byte_buffer_t tst_sdu2 = allocate_unique_buffer(*pool); // SDU 2 + srslte::unique_byte_buffer_t tst_sdu2 = srslte::make_byte_buffer(); // SDU 2 tst_sdu2->append_bytes(sdu2, sizeof(sdu2)); /* @@ -87,9 +85,9 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test1_counts(2); // Test two packets std::iota(test1_counts.begin(), test1_counts.end(), 4095); // Starting at COUNT 4095 std::vector test1_pdus = - gen_expected_pdus_vector(tst_sdu1, test1_counts, srslte::PDCP_SN_LEN_12, sec_cfg, pool, log); + gen_expected_pdus_vector(tst_sdu1, test1_counts, srslte::PDCP_SN_LEN_12, sec_cfg, logger); pdcp_initial_state test1_init_state = {.tx_next = 4095, .rx_next = 4095, .rx_deliv = 4095, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test1_pdus), test1_init_state, srslte::PDCP_SN_LEN_12, 2, tst_sdu1, pool, log) == 0); + TESTASSERT(test_rx(std::move(test1_pdus), test1_init_state, srslte::PDCP_SN_LEN_12, 2, tst_sdu1, logger) == 0); } /* * RX Test 2: PDCP Entity with SN LEN = 12 @@ -101,10 +99,10 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test2_counts(2); // Test two packets std::iota(test2_counts.begin(), test2_counts.end(), 4294967295); // Starting at COUNT 4294967295 std::vector test2_pdus = - gen_expected_pdus_vector(tst_sdu1, test2_counts, srslte::PDCP_SN_LEN_12, sec_cfg, pool, log); + gen_expected_pdus_vector(tst_sdu1, test2_counts, srslte::PDCP_SN_LEN_12, sec_cfg, logger); pdcp_initial_state test2_init_state = { .tx_next = 4294967295, .rx_next = 4294967295, .rx_deliv = 4294967295, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test2_pdus), test2_init_state, srslte::PDCP_SN_LEN_12, 1, tst_sdu1, pool, log) == 0); + TESTASSERT(test_rx(std::move(test2_pdus), test2_init_state, srslte::PDCP_SN_LEN_12, 1, tst_sdu1, logger) == 0); } /* * RX Test 3: PDCP Entity with SN LEN = 18 @@ -115,9 +113,9 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test3_counts(2); // Test two packets std::iota(test3_counts.begin(), test3_counts.end(), 262144); // Starting at COUNT 262144 std::vector test3_pdus = - gen_expected_pdus_vector(tst_sdu1, test3_counts, srslte::PDCP_SN_LEN_18, sec_cfg, pool, log); + gen_expected_pdus_vector(tst_sdu1, test3_counts, srslte::PDCP_SN_LEN_18, sec_cfg, logger); pdcp_initial_state test3_init_state = {.tx_next = 262144, .rx_next = 262144, .rx_deliv = 262144, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test3_pdus), test3_init_state, srslte::PDCP_SN_LEN_18, 2, tst_sdu1, pool, log) == 0); + TESTASSERT(test_rx(std::move(test3_pdus), test3_init_state, srslte::PDCP_SN_LEN_18, 2, tst_sdu1, logger) == 0); } /* @@ -129,10 +127,10 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) std::vector test4_counts(2); // Test two packets std::iota(test4_counts.begin(), test4_counts.end(), 4294967295); // Starting at COUNT 4294967295 std::vector test4_pdus = - gen_expected_pdus_vector(tst_sdu1, test4_counts, srslte::PDCP_SN_LEN_18, sec_cfg, pool, log); + gen_expected_pdus_vector(tst_sdu1, test4_counts, srslte::PDCP_SN_LEN_18, sec_cfg, logger); pdcp_initial_state test4_init_state = { .tx_next = 4294967295, .rx_next = 4294967295, .rx_deliv = 4294967295, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test4_pdus), test4_init_state, srslte::PDCP_SN_LEN_18, 1, tst_sdu1, pool, log) == 0); + TESTASSERT(test_rx(std::move(test4_pdus), test4_init_state, srslte::PDCP_SN_LEN_18, 1, tst_sdu1, logger) == 0); } /* @@ -145,18 +143,18 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) // First PDU pdcp_test_event_t event_pdu1; - event_pdu1.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu1.pkt = srslte::make_byte_buffer(); event_pdu1.pkt->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); // Second PDU pdcp_test_event_t event_pdu2; - event_pdu2.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu2.pkt = srslte::make_byte_buffer(); event_pdu2.pkt->append_bytes(pdu2_count1_snlen12, sizeof(pdu2_count1_snlen12)); // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test5_pdus.push_back(std::move(event_pdu2)); test5_pdus.push_back(std::move(event_pdu1)); - TESTASSERT(test_rx(std::move(test5_pdus), test5_init_state, srslte::PDCP_SN_LEN_12, 2, tst_sdu2, pool, log) == 0); + TESTASSERT(test_rx(std::move(test5_pdus), test5_init_state, srslte::PDCP_SN_LEN_12, 2, tst_sdu2, logger) == 0); } /* @@ -169,18 +167,18 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) // First PDU pdcp_test_event_t event_pdu1; - event_pdu1.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu1.pkt = srslte::make_byte_buffer(); event_pdu1.pkt->append_bytes(pdu1_count0_snlen18, sizeof(pdu1_count0_snlen18)); // Second PDU pdcp_test_event_t event_pdu2; - event_pdu2.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu2.pkt = srslte::make_byte_buffer(); event_pdu2.pkt->append_bytes(pdu2_count1_snlen18, sizeof(pdu2_count1_snlen18)); // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test6_pdus.push_back(std::move(event_pdu2)); test6_pdus.push_back(std::move(event_pdu1)); - TESTASSERT(test_rx(std::move(test6_pdus), test6_init_state, srslte::PDCP_SN_LEN_18, 2, tst_sdu2, pool, log) == 0); + TESTASSERT(test_rx(std::move(test6_pdus), test6_init_state, srslte::PDCP_SN_LEN_18, 2, tst_sdu2, logger) == 0); } /* @@ -193,13 +191,13 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) // First PDU pdcp_test_event_t event_pdu1; - event_pdu1.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu1.pkt = srslte::make_byte_buffer(); event_pdu1.pkt->append_bytes(pdu2_count1_snlen12, sizeof(pdu2_count1_snlen12)); event_pdu1.ticks = 500; // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test7_pdus.push_back(std::move(event_pdu1)); - TESTASSERT(test_rx(std::move(test7_pdus), test7_init_state, srslte::PDCP_SN_LEN_12, 1, tst_sdu2, pool, log) == 0); + TESTASSERT(test_rx(std::move(test7_pdus), test7_init_state, srslte::PDCP_SN_LEN_12, 1, tst_sdu2, logger) == 0); } /* @@ -212,41 +210,41 @@ int test_rx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) // First PDU pdcp_test_event_t event_pdu1; - event_pdu1.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu1.pkt = srslte::make_byte_buffer(); event_pdu1.pkt->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); // Second PDU pdcp_test_event_t event_pdu2; - event_pdu2.pkt = srslte::allocate_unique_buffer(*pool); + event_pdu2.pkt = srslte::make_byte_buffer(); event_pdu2.pkt->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test8_pdus.push_back(std::move(event_pdu1)); test8_pdus.push_back(std::move(event_pdu2)); - TESTASSERT(test_rx(std::move(test8_pdus), test8_init_state, srslte::PDCP_SN_LEN_12, 1, tst_sdu1, pool, log) == 0); + TESTASSERT(test_rx(std::move(test8_pdus), test8_init_state, srslte::PDCP_SN_LEN_12, 1, tst_sdu1, logger) == 0); } return 0; } // Setup all tests -int run_all_tests(srslte::byte_buffer_pool* pool) +int run_all_tests() { // Setup log - srslte::log_ref log("PDCP NR Test RX"); - log->set_level(srslte::LOG_LEVEL_DEBUG); - log->set_hex_limit(128); + auto& logger = srslog::fetch_basic_logger("PDCP NR Test RX", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); - TESTASSERT(test_rx_all(pool, log) == 0); + TESTASSERT(test_rx_all(logger) == 0); return 0; } int main() { - if (run_all_tests(srslte::byte_buffer_pool::get_instance()) != SRSLTE_SUCCESS) { + srslog::init(); + + if (run_all_tests() != SRSLTE_SUCCESS) { fprintf(stderr, "pdcp_nr_tests_rx() failed\n"); return SRSLTE_ERROR; } - srslte::byte_buffer_pool::cleanup(); - return SRSLTE_SUCCESS; } diff --git a/lib/test/upper/pdcp_nr_test_tx.cc b/lib/test/upper/pdcp_nr_test_tx.cc index fc7a112f9..c2d57f5fd 100644 --- a/lib/test/upper/pdcp_nr_test_tx.cc +++ b/lib/test/upper/pdcp_nr_test_tx.cc @@ -29,8 +29,7 @@ int test_tx(uint32_t n_packets, uint8_t pdcp_sn_len, uint64_t n_pdus_exp, srslte::unique_byte_buffer_t pdu_exp, - srslte::byte_buffer_pool* pool, - srslte::log_ref log) + srslog::basic_logger& logger) { srslte::pdcp_config_t cfg = {1, srslte::PDCP_RB_IS_DRB, @@ -38,9 +37,10 @@ int test_tx(uint32_t n_packets, srslte::SECURITY_DIRECTION_DOWNLINK, pdcp_sn_len, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::infinity}; + srslte::pdcp_discard_timer_t::infinity, + false}; - pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, log); + pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, logger); srslte::pdcp_entity_nr* pdcp = &pdcp_hlp.pdcp; rlc_dummy* rlc = &pdcp_hlp.rlc; @@ -49,12 +49,12 @@ int test_tx(uint32_t n_packets, // Run test for (uint32_t i = 0; i < n_packets; ++i) { // Test SDU - srslte::unique_byte_buffer_t sdu = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); sdu->append_bytes(sdu1, sizeof(sdu1)); pdcp->write_sdu(std::move(sdu)); } - srslte::unique_byte_buffer_t pdu_act = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_act = srslte::make_byte_buffer(); rlc->get_last_sdu(pdu_act); TESTASSERT(rlc->rx_count == n_pdus_exp); @@ -66,7 +66,7 @@ int test_tx(uint32_t n_packets, * TX Test: PDCP Entity with SN LEN = 12 and 18. * PDCP entity configured with EIA2 and EEA2 */ -int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) +int test_tx_all(srslog::basic_logger& logger) { uint64_t n_packets; /* @@ -76,15 +76,12 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Output: PDCP Header {0x80, 0x00}, Ciphered Text {0x8f, 0xe3}, MAC-I {0xe0, 0xdf, 0x82, 0x92} */ n_packets = 1; - srslte::unique_byte_buffer_t pdu_exp_count0_len12 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count0_len12 = srslte::make_byte_buffer(); pdu_exp_count0_len12->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); - TESTASSERT(test_tx(n_packets, - normal_init_state, - srslte::PDCP_SN_LEN_12, - n_packets, - std::move(pdu_exp_count0_len12), - pool, - log) == 0); + TESTASSERT( + test_tx( + n_packets, normal_init_state, srslte::PDCP_SN_LEN_12, n_packets, std::move(pdu_exp_count0_len12), logger) == + 0); /* * TX Test 2: PDCP Entity with SN LEN = 12 @@ -93,15 +90,14 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Output: PDCP Header {0x88, 0x00}, Ciphered Text {0x8d, 0x2c}, MAC-I {0x47, 0x5e, 0xb1, 0x5b} */ n_packets = 2049; - srslte::unique_byte_buffer_t pdu_exp_count2048_len12 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count2048_len12 = srslte::make_byte_buffer(); pdu_exp_count2048_len12->append_bytes(pdu1_count2048_snlen12, sizeof(pdu1_count2048_snlen12)); TESTASSERT(test_tx(n_packets, normal_init_state, srslte::PDCP_SN_LEN_12, n_packets, std::move(pdu_exp_count2048_len12), - pool, - log) == 0); + logger) == 0); /* * TX Test 3: PDCP Entity with SN LEN = 12 @@ -110,15 +106,14 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Output: PDCP Header {0x80,0x00}, Ciphered Text {0x97, 0xbe}, MAC-I {0xa3, 0x32, 0xfa, 0x61} */ n_packets = 4097; - srslte::unique_byte_buffer_t pdu_exp_count4096_len12 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count4096_len12 = srslte::make_byte_buffer(); pdu_exp_count4096_len12->append_bytes(pdu1_count4096_snlen12, sizeof(pdu1_count4096_snlen12)); TESTASSERT(test_tx(n_packets, normal_init_state, srslte::PDCP_SN_LEN_12, n_packets, std::move(pdu_exp_count4096_len12), - pool, - log) == 0); + logger) == 0); /* * TX Test 4: PDCP Entity with SN LEN = 18 @@ -127,15 +122,12 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Output: PDCP Header {0x80, 0x80, 0x00}, Ciphered Text {0x8f, 0xe3}, MAC-I {0xe0, 0xdf, 0x82, 0x92} */ n_packets = 1; - srslte::unique_byte_buffer_t pdu_exp_count0_len18 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count0_len18 = srslte::make_byte_buffer(); pdu_exp_count0_len18->append_bytes(pdu1_count0_snlen18, sizeof(pdu1_count0_snlen18)); - TESTASSERT(test_tx(n_packets, - normal_init_state, - srslte::PDCP_SN_LEN_18, - n_packets, - std::move(pdu_exp_count0_len18), - pool, - log) == 0); + TESTASSERT( + test_tx( + n_packets, normal_init_state, srslte::PDCP_SN_LEN_18, n_packets, std::move(pdu_exp_count0_len18), logger) == + 0); /* * TX Test 5: PDCP Entity with SN LEN = 18 @@ -144,15 +136,12 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Output: PDCP Header {0x82, 0x00, 0x00}, Ciphered Text {0x15, 0x01}, MAC-I {0xf4, 0xb0, 0xfc, 0xc5} */ n_packets = 131073; - srslte::unique_byte_buffer_t pdu_exp_sn131072_len18 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_sn131072_len18 = srslte::make_byte_buffer(); pdu_exp_sn131072_len18->append_bytes(pdu1_count131072_snlen18, sizeof(pdu1_count131072_snlen18)); - TESTASSERT(test_tx(n_packets, - normal_init_state, - srslte::PDCP_SN_LEN_18, - n_packets, - std::move(pdu_exp_sn131072_len18), - pool, - log) == 0); + TESTASSERT( + test_tx( + n_packets, normal_init_state, srslte::PDCP_SN_LEN_18, n_packets, std::move(pdu_exp_sn131072_len18), logger) == + 0); /* * TX Test 6: PDCP Entity with SN LEN = 18 @@ -161,15 +150,14 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Output: PDCP Header {0x80, 0x00, 0x00}, Ciphered Text {0xc2, 0x47}, MAC-I {0xa8, 0xdd, 0xc0, 0x73} */ n_packets = 262145; - srslte::unique_byte_buffer_t pdu_exp_count262144_len18 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count262144_len18 = srslte::make_byte_buffer(); pdu_exp_count262144_len18->append_bytes(pdu1_count262144_snlen18, sizeof(pdu1_count262144_snlen18)); TESTASSERT(test_tx(n_packets, normal_init_state, srslte::PDCP_SN_LEN_18, n_packets, std::move(pdu_exp_count262144_len18), - pool, - log) == 0); + logger) == 0); /* * TX Test 7: PDCP Entity with SN LEN = 12 @@ -177,15 +165,14 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Should print a warning and drop all packets after wraparound. */ n_packets = 5; - srslte::unique_byte_buffer_t pdu_exp_count4294967295_len12 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count4294967295_len12 = srslte::make_byte_buffer(); pdu_exp_count4294967295_len12->append_bytes(pdu1_count4294967295_snlen12, sizeof(pdu1_count4294967295_snlen12)); TESTASSERT(test_tx(n_packets, near_wraparound_init_state, srslte::PDCP_SN_LEN_12, 1, std::move(pdu_exp_count4294967295_len12), - pool, - log) == 0); + logger) == 0); /* * TX Test 8: PDCP Entity with SN LEN = 18 @@ -193,37 +180,36 @@ int test_tx_all(srslte::byte_buffer_pool* pool, srslte::log_ref log) * Should print a warning and drop all packets after wraparound. */ n_packets = 5; - srslte::unique_byte_buffer_t pdu_exp_count4294967295_len18 = allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu_exp_count4294967295_len18 = srslte::make_byte_buffer(); pdu_exp_count4294967295_len18->append_bytes(pdu1_count4294967295_snlen18, sizeof(pdu1_count4294967295_snlen18)); TESTASSERT(test_tx(n_packets, near_wraparound_init_state, srslte::PDCP_SN_LEN_18, 1, std::move(pdu_exp_count4294967295_len18), - pool, - log) == 0); + logger) == 0); return 0; } // Setup all tests -int run_all_tests(srslte::byte_buffer_pool* pool) +int run_all_tests() { // Setup log - srslte::log_ref log("PDCP NR Test TX"); - log->set_level(srslte::LOG_LEVEL_DEBUG); - log->set_hex_limit(128); + auto& logger = srslog::fetch_basic_logger("PDCP NR Test TX", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); - TESTASSERT(test_tx_all(pool, log) == 0); + TESTASSERT(test_tx_all(logger) == 0); return 0; } int main() { - if (run_all_tests(srslte::byte_buffer_pool::get_instance()) != SRSLTE_SUCCESS) { + srslog::init(); + + if (run_all_tests() != SRSLTE_SUCCESS) { fprintf(stderr, "pdcp_nr_tests_tx() failed\n"); return SRSLTE_ERROR; } - srslte::byte_buffer_pool::cleanup(); - return SRSLTE_SUCCESS; } diff --git a/lib/test/upper/rlc_am_control_test.cc b/lib/test/upper/rlc_am_control_test.cc index 017c416b7..a85cb3943 100644 --- a/lib/test/upper/rlc_am_control_test.cc +++ b/lib/test/upper/rlc_am_control_test.cc @@ -73,6 +73,8 @@ int status_pdu_with_nacks_test1() int main(int argc, char** argv) { + srslog::init(); + TESTASSERT(simple_status_pdu_test1() == SRSLTE_SUCCESS); TESTASSERT(status_pdu_with_nacks_test1() == SRSLTE_SUCCESS); diff --git a/lib/test/upper/rlc_am_data_test.cc b/lib/test/upper/rlc_am_data_test.cc index ebcdc7b2b..2507efbc4 100644 --- a/lib/test/upper/rlc_am_data_test.cc +++ b/lib/test/upper/rlc_am_data_test.cc @@ -152,9 +152,12 @@ int test4() int main(int argc, char** argv) { + srslog::init(); + TESTASSERT(test1() == SRSLTE_SUCCESS); TESTASSERT(test2() == SRSLTE_SUCCESS); TESTASSERT(test3() == SRSLTE_SUCCESS); TESTASSERT(test4() == SRSLTE_SUCCESS); + return SRSLTE_SUCCESS; } diff --git a/lib/test/upper/rlc_am_nr_pdu_test.cc b/lib/test/upper/rlc_am_nr_pdu_test.cc index 42752c248..b78f206a5 100644 --- a/lib/test/upper/rlc_am_nr_pdu_test.cc +++ b/lib/test/upper/rlc_am_nr_pdu_test.cc @@ -301,6 +301,8 @@ int main(int argc, char** argv) pcap_handle->open("rlc_am_nr_pdu_test.pcap"); #endif + srslog::init(); + if (rlc_am_nr_pdu_test1()) { fprintf(stderr, "rlc_am_nr_pdu_test1() failed.\n"); return SRSLTE_ERROR; diff --git a/lib/test/upper/rlc_am_test.cc b/lib/test/upper/rlc_am_test.cc index 2f499690a..ac4ab983a 100644 --- a/lib/test/upper/rlc_am_test.cc +++ b/lib/test/upper/rlc_am_test.cc @@ -32,9 +32,6 @@ using namespace srsue; using namespace srslte; -srslte::log_ref rrc_log1("RLC_AM_1"); -srslte::log_ref rrc_log2("RLC_AM_2"); - bool rx_is_tx(const rlc_bearer_metrics_t& rlc1_metrics, const rlc_bearer_metrics_t& rlc2_metrics) { if (rlc1_metrics.num_tx_pdu_bytes != rlc2_metrics.num_rx_pdu_bytes) { @@ -66,6 +63,21 @@ public: void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} + void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn_vec) + { + assert(lcid == 1); + for (uint32_t pdcp_sn : pdcp_sn_vec) { + if (notified_counts.find(pdcp_sn) == notified_counts.end()) { + notified_counts[pdcp_sn] = 0; + } + notified_counts[pdcp_sn] += 1; + } + } + void notify_failure(uint32_t lcid, const std::vector& pdcp_sn_vec) + { + assert(lcid == 1); + // TODO + } // RRC interface void max_retx_attempted() {} @@ -74,6 +86,8 @@ public: unique_byte_buffer_t sdus[10]; int n_sdus; rlc_pcap* pcap; + + std::map notified_counts; // Map of PDCP SNs to number of notifications }; class ul_writer : public thread @@ -98,8 +112,7 @@ private: int sn = 0; running = true; while (running) { - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, "rlc_tester::run_thread", true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); // backoff for a bit @@ -122,14 +135,13 @@ private: int basic_test_tx(rlc_am_lte* rlc, byte_buffer_t pdu_bufs[NBUFS]) { - // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); - sdu_bufs[i]->msg[0] = i; // Write the index into the buffer - sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i] = srslte::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications rlc->write_sdu(std::move(sdu_bufs[i])); } @@ -152,8 +164,8 @@ int basic_test() timer_handler timers(8); byte_buffer_t pdu_bufs[NBUFS]; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); // before configuring entity TESTASSERT(0 == rlc1.get_buffer_state()); @@ -190,9 +202,12 @@ int basic_test() // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); - for (int i = 0; i < tester.n_sdus; i++) { + // Check PDCP notifications + TESTASSERT(tester.notified_counts.size() == 5); + for (uint16_t i = 0; i < tester.n_sdus; i++) { TESTASSERT(tester.sdus[i]->N_bytes == 1); TESTASSERT(*(tester.sdus[i]->msg) == i); + TESTASSERT(tester.notified_counts[i] == 1); } // Check statistics @@ -206,8 +221,8 @@ int concat_test() rlc_am_tester tester; srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -218,12 +233,12 @@ int concat_test() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); - sdu_bufs[i]->msg[0] = i; // Write the index into the buffer - sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i] = srslte::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -261,6 +276,14 @@ int concat_test() TESTASSERT(*(tester.sdus[i]->msg) == i); } + // Check PDCP notifications + TESTASSERT(tester.notified_counts.size() == 5); + for (uint16_t i = 0; i < tester.n_sdus; i++) { + TESTASSERT(tester.sdus[i]->N_bytes == 1); + TESTASSERT(*(tester.sdus[i]->msg) == i); + TESTASSERT(tester.notified_counts[i] == 1); + } + // Check statistics TESTASSERT(rx_is_tx(rlc1.get_metrics(), rlc2.get_metrics())); @@ -273,8 +296,8 @@ int segment_test(bool in_seq_rx) srslte::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -285,13 +308,13 @@ int segment_test(bool in_seq_rx) } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -337,6 +360,13 @@ int segment_test(bool in_seq_rx) // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check all notification of ack'ed PDUs + TESTASSERT(tester.notified_counts.size() == 5); + for (int i = 0; i < NBUFS; i++) { + auto not_it = tester.notified_counts.find(i); + TESTASSERT(not_it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } } TESTASSERT(0 == rlc2.get_buffer_state()); @@ -360,8 +390,8 @@ int retx_test() timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -372,12 +402,12 @@ int retx_test() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); - sdu_bufs[i]->msg[0] = i; // Write the index into the buffer - sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i] = srslte::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -422,14 +452,26 @@ int retx_test() // Assert status is correct rlc_status_pdu_t status_check = {}; rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); - TESTASSERT(status_check.N_nack == 1); // 1 packet was lost. - TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 4. + TESTASSERT(status_check.N_nack == 1); // 1 packet was lost. + TESTASSERT(status_check.nacks[0].nack_sn == 1); // SN 1 was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 4. // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); TESTASSERT(3 == rlc1.get_buffer_state()); // 2 byte header + 1 byte payload + // Check notifications of ack'ed PDUs + TESTASSERT(tester.notified_counts.size() == 4); + for (int i = 0; i < NBUFS; i++) { + auto not_it = tester.notified_counts.find(i); + if (i != 1) { + TESTASSERT(not_it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } else { + TESTASSERT(not_it == tester.notified_counts.end()); + } + } + // Read the retx PDU from RLC1 byte_buffer_t retx; len = rlc1.read_pdu(retx.msg, 3); // 2 byte header + 1 byte payload @@ -446,6 +488,33 @@ int retx_test() return -1; } + // Step timers until poll Retx timeout expires + for (int cnt = 0; cnt < 5; cnt++) { + timers.step_all(); + } + + // Get status report of RETX PDU + buffer_state = rlc2.get_buffer_state(); + TESTASSERT(2 == buffer_state); + len = rlc2.read_pdu(status_buf.msg, buffer_state); // provide exactly the reported buffer state + status_buf.N_bytes = len; + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // No packet was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 4. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check all notification of ack'ed PDUs + TESTASSERT(tester.notified_counts.size() == 5); + for (int i = 0; i < NBUFS; i++) { + auto not_it = tester.notified_counts.find(i); + TESTASSERT(not_it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } + return 0; } @@ -456,8 +525,8 @@ int segment_retx_test() timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -468,14 +537,14 @@ int segment_retx_test() } // Push SDU(s) into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); const uint32_t nof_sdus = 1; // just one SDU to make sure the transmitter sets polling bit unique_byte_buffer_t sdu_bufs[nof_sdus]; for (uint32_t i = 0; i < nof_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); - sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i] = srslte::make_byte_buffer(); sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + std::fill(sdu_bufs[i]->msg, sdu_bufs[i]->msg + sdu_bufs[i]->N_bytes, 0); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -490,8 +559,7 @@ int segment_retx_test() TESTASSERT(rlc1.get_buffer_state() == 0); // Step timers until poll Retx timeout expires - int cnt = 5; - while (cnt--) { + for (int cnt = 0; cnt < 5; cnt++) { timers.step_all(); } @@ -514,12 +582,20 @@ int segment_retx_test() len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status status_buf.N_bytes = len; + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // No packet was lost. + TESTASSERT(status_check.ack_sn == 1); // Delivered up to SN 0. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + // Make sure no notifications yet + TESTASSERT(tester.notified_counts.size() == 0); + // Step timers again until poll Retx timeout expires - cnt = 5; - while (cnt--) { + for (int cnt = 0; cnt < 5; cnt++) { timers.step_all(); } @@ -540,6 +616,16 @@ int segment_retx_test() status_buf.N_bytes = len; rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // No packet was lost. + TESTASSERT(status_check.ack_sn == 2); // Delivered up to SN 0. + + // Make sure SDU was notified + TESTASSERT(tester.notified_counts.size() == 1); + TESTASSERT(tester.notified_counts.find(0) != tester.notified_counts.end() && tester.notified_counts[0] == 1); + TESTASSERT(tester.n_sdus == nof_sdus); for (int i = 0; i < tester.n_sdus; i++) { if (tester.sdus[i]->N_bytes != 10) { @@ -557,14 +643,14 @@ int resegment_test_1() { // SDUs: | 10 | 10 | 10 | 10 | 10 | // PDUs: | 10 | 10 | 10 | 10 | 10 | - // Retx PDU segments: | 5 | 5| + // Retx PDU segments: | 5 | 5| rlc_am_tester tester; timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -575,13 +661,13 @@ int resegment_test_1() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -603,8 +689,7 @@ int resegment_test_1() } // Step timers until reordering timeout expires - int cnt = 5; - while (cnt--) { + for (int cnt = 0; cnt < 5; cnt++) { timers.step_all(); } @@ -615,11 +700,30 @@ int resegment_test_1() len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status status_buf.N_bytes = len; + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // 1 packet was lost. + TESTASSERT(status_check.nacks[0].nack_sn == 1); // SN 1 was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); TESTASSERT(12 == rlc1.get_buffer_state()); // 2 byte header + 10 data + // Check notifications + srslog::fetch_basic_logger("RLC_AM_1").debug("%ld", tester.notified_counts.size()); + TESTASSERT(tester.notified_counts.size() == 4); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + if (i != 1) { + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } else { + TESTASSERT(it == tester.notified_counts.end()); + } + } + // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; len = rlc1.read_pdu(retx1.msg, 9); // 4 byte header + 5 data @@ -630,6 +734,23 @@ int resegment_test_1() TESTASSERT(9 == rlc1.get_buffer_state()); + // Step timers to get status report + for (int cnt = 0; cnt < 5; cnt++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf = {}; + len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + status_buf.N_bytes = len; + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // 1 packet was lost. + TESTASSERT(status_check.nacks[0].nack_sn == 1); // SN 1 was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Read the remaining segment byte_buffer_t retx2; len = rlc1.read_pdu(retx2.msg, 9); // 4 byte header + 5 data @@ -647,22 +768,46 @@ int resegment_test_1() return -1; } + // Step timers to get status report + for (int cnt = 0; cnt < 5; cnt++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf = {}; + len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + status_buf.N_bytes = len; + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check notifications + TESTASSERT(tester.notified_counts.size() == 5); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } + return 0; } int resegment_test_2() { - // SDUs: | 10 | 10 | 10 | 10 | 10 | // PDUs: | 5 | 10 | 20 | 10 | 5 | // Retx PDU segments: | 10 | 10 | rlc_am_tester tester; timer_handler timers(8); - int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -673,13 +818,13 @@ int resegment_test_2() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; // Give each buffer a size of 10 bytes rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -702,8 +847,7 @@ int resegment_test_2() } // Step timers until reordering timeout expires - int cnt = 5; - while (cnt--) { + for (int cnt = 0; cnt < 5; cnt++) { timers.step_all(); } @@ -713,11 +857,28 @@ int resegment_test_2() byte_buffer_t status_buf; status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // One packet was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); TESTASSERT(25 == rlc1.get_buffer_state()); // 4 byte header + 20 data + // Check notifications + TESTASSERT(tester.notified_counts.size() == 2); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + if (i == 0 || i == 4) { + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } else { + TESTASSERT(it == tester.notified_counts.end()); + } + } + // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 6 byte header + 10 data @@ -743,12 +904,33 @@ int resegment_test_2() return -1; } + // Step timers until reordering timeout expires + for (int cnt = 0; cnt < 5; cnt++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + TESTASSERT(tester.notified_counts.size() == 5); + + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } return 0; } int resegment_test_3() { - // SDUs: | 10 | 10 | 10 | 10 | 10 | // PDUs: | 5 | 5| 20 | 10 | 10 | // Retx PDU segments: | 10 | 10 | @@ -756,8 +938,8 @@ int resegment_test_3() rlc_am_tester tester; srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -768,13 +950,13 @@ int resegment_test_3() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -797,8 +979,7 @@ int resegment_test_3() } // Step timers until reordering timeout expires - int cnt = 5; - while (cnt--) { + for (int cnt = 0; cnt < 5; cnt++) { timers.step_all(); } @@ -808,9 +989,27 @@ int resegment_test_3() byte_buffer_t status_buf; status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // One packet was lost. + TESTASSERT(status_check.nacks[0].nack_sn == 2); // SN 2 was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + // Check notifications + TESTASSERT(tester.notified_counts.size() == 3); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + if (i == 0 || i == 3 || i == 4) { + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } else { + TESTASSERT(it == tester.notified_counts.end()); + } + } + // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; retx1.N_bytes = rlc1.read_pdu(retx1.msg, 16); // 6 byte header + 10 data @@ -834,6 +1033,29 @@ int resegment_test_3() return -1; } + // Get status from RLC 2 + for (int cnt = 0; cnt < 5; cnt++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check final notifications + TESTASSERT(tester.notified_counts.size() == 5); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } return 0; } @@ -846,8 +1068,8 @@ int resegment_test_4() rlc_am_tester tester; srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -858,13 +1080,13 @@ int resegment_test_4() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -898,9 +1120,26 @@ int resegment_test_4() byte_buffer_t status_buf; status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // one packet lost. + TESTASSERT(status_check.nacks[0].nack_sn == 2); // SN 2 was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + TESTASSERT(tester.notified_counts.size() == 2); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + if (i == 0 || i == 4) { + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } else { + TESTASSERT(it == tester.notified_counts.end()); + } + } + // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; retx1.N_bytes = rlc1.read_pdu(retx1.msg, 21); // 6 byte header + 15 data @@ -926,6 +1165,29 @@ int resegment_test_4() return -1; } + // Get status from RLC 2 + for (int i = 0; i < 5; i++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check final notifications + TESTASSERT(tester.notified_counts.size() == 5); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } return 0; } @@ -938,8 +1200,8 @@ int resegment_test_5() rlc_am_tester tester; srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -950,13 +1212,13 @@ int resegment_test_5() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -990,9 +1252,19 @@ int resegment_test_5() byte_buffer_t status_buf; status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // one packet was lost. + TESTASSERT(status_check.nacks[0].nack_sn == 2); // SN 2 was lost. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + // Check notifications + TESTASSERT(tester.notified_counts.size() == 0); + // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; retx1.N_bytes = rlc1.read_pdu(retx1.msg, 27); // 7 byte header + 20 data @@ -1018,6 +1290,30 @@ int resegment_test_5() return -1; } + // Get status from RLC 2 + for (int i = 0; i < 5; i++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check final notifications + TESTASSERT(tester.notified_counts.size() == 5); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } + return 0; } @@ -1031,8 +1327,8 @@ int resegment_test_6() srslte::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1043,20 +1339,21 @@ int resegment_test_6() } // Push SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[9]; for (int i = 0; i < 3; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 10; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 10 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } for (int i = 3; i < 9; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int j = 0; j < 54; j++) sdu_bufs[i]->msg[j] = j; - sdu_bufs[i]->N_bytes = 54; + sdu_bufs[i]->N_bytes = 54; + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -1094,11 +1391,29 @@ int resegment_test_6() len = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status status_buf.N_bytes = len; + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // One packet was lost. + TESTASSERT(status_check.nacks[0].nack_sn == 3); // SN 3 was lost. + TESTASSERT(status_check.ack_sn == 5); + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); TESTASSERT(278 == rlc1.get_buffer_state()); + // Check notifications + TESTASSERT(tester.notified_counts.size() == 4); + for (int i = 0; i < 5; i++) { + auto it = tester.notified_counts.find(i); + if (i == 0 || i == 1 || i == 2 || i == 8) { + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } else { + TESTASSERT(it == tester.notified_counts.end()); + } + } + // Read the retx PDU from RLC1 and force resegmentation byte_buffer_t retx1; len = rlc1.read_pdu(retx1.msg, 129); @@ -1134,6 +1449,30 @@ int resegment_test_6() } } + // Get status from RLC 2 + for (int i = 0; i < 5; i++) { + timers.step_all(); + } + + // Read status PDU from RLC2 + status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check final notifications + TESTASSERT(tester.notified_counts.size() == 9); + for (int i = 0; i < 9; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } + return 0; } @@ -1158,8 +1497,8 @@ int resegment_test_7() #endif srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1170,14 +1509,14 @@ int resegment_test_7() } // Push 2 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[N_SDU_BUFS]; for (uint32_t i = 0; i < N_SDU_BUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (uint32_t j = 0; j < sdu_size; j++) { sdu_bufs[i]->msg[j] = i; } - sdu_bufs[i]->N_bytes = sdu_size; // Give each buffer a size of 15 bytes + sdu_bufs[i]->N_bytes = sdu_size; // Give each buffer a size of 15 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -1239,6 +1578,13 @@ int resegment_test_7() byte_buffer_t status_buf; status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 1); // one packet dropped. + TESTASSERT(status_check.nacks[0].nack_sn == 2); // SN 2 dropped. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); #if HAVE_PCAP @@ -1247,6 +1593,9 @@ int resegment_test_7() TESTASSERT(15 == rlc1.get_buffer_state()); + // Check notifications + TESTASSERT(tester.notified_counts.size() == 0); + // second round of retx, forcing resegmentation byte_buffer_t retx2[4]; for (uint32_t i = 0; i < 4; i++) { @@ -1273,6 +1622,12 @@ int resegment_test_7() TESTASSERT(rlc2.get_buffer_state()); status_buf.N_bytes = rlc2.read_pdu(status_buf.msg, 10); // 10 bytes is enough to hold the status + // Assert status is correct + status_check = {}; + rlc_am_read_status_pdu(status_buf.msg, status_buf.N_bytes, &status_check); + TESTASSERT(status_check.N_nack == 0); // all packets delivered. + TESTASSERT(status_check.ack_sn == 5); // Delivered up to SN 5. + // Write status PDU to RLC1 rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); #if HAVE_PCAP @@ -1294,6 +1649,13 @@ int resegment_test_7() } } + // Check final notifications + TESTASSERT(tester.notified_counts.size() == 2); + for (int i = 0; i < 2; i++) { + auto it = tester.notified_counts.find(i); + TESTASSERT(it != tester.notified_counts.end() && tester.notified_counts[i] == 1); + } + #if HAVE_PCAP pcap.close(); #endif @@ -1322,8 +1684,8 @@ int resegment_test_8() #endif srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1334,14 +1696,14 @@ int resegment_test_8() } // Push 2 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[N_SDU_BUFS]; for (uint32_t i = 0; i < N_SDU_BUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (uint32_t j = 0; j < sdu_size; j++) { sdu_bufs[i]->msg[j] = i; } - sdu_bufs[i]->N_bytes = sdu_size; // Give each buffer a size of 15 bytes + sdu_bufs[i]->N_bytes = sdu_size; // Give each buffer a size of 30 bytes + sdu_bufs[i]->md.pdcp_sn = i; rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -1463,17 +1825,17 @@ bool reset_test() srslte::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } // Push 1 SDU of size 10 into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - unique_byte_buffer_t sdu_buf = srslte::allocate_unique_buffer(*pool, true); - sdu_buf->msg[0] = 1; // Write the index into the buffer + unique_byte_buffer_t sdu_buf = srslte::make_byte_buffer(); sdu_buf->N_bytes = 100; + std::fill(sdu_buf->msg, sdu_buf->msg + sdu_buf->N_bytes, 0); + sdu_buf->msg[0] = 1; // Write the index into the buffer rlc1.write_sdu(std::move(sdu_buf)); // read 1 PDU from RLC1 and force segmentation @@ -1505,17 +1867,17 @@ bool resume_test() srslte::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } // Push 1 SDU of size 10 into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - unique_byte_buffer_t sdu_buf = srslte::allocate_unique_buffer(*pool, true); - sdu_buf->msg[0] = 1; // Write the index into the buffer + unique_byte_buffer_t sdu_buf = srslte::make_byte_buffer(); sdu_buf->N_bytes = 100; + std::fill(sdu_buf->msg, sdu_buf->msg + sdu_buf->N_bytes, 0); + sdu_buf->msg[0] = 1; // Write the index into the buffer rlc1.write_sdu(std::move(sdu_buf)); // read 1 PDU from RLC1 and force segmentation @@ -1546,7 +1908,7 @@ bool stop_test() rlc_am_tester tester; srslte::timer_handler timers(8); - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1573,8 +1935,8 @@ bool status_pdu_test() srslte::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(rrc_log1, 1, &tester, &tester, &timers); - rlc_am_lte rlc2(rrc_log2, 1, &tester, &tester, &timers); + rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1585,12 +1947,11 @@ bool status_pdu_test() } // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); - sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i] = srslte::make_byte_buffer(); sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer rlc1.write_sdu(std::move(sdu_bufs[i])); } @@ -1686,122 +2047,108 @@ bool status_pdu_test() int main(int argc, char** argv) { - rrc_log1->set_level(srslte::LOG_LEVEL_DEBUG); - rrc_log2->set_level(srslte::LOG_LEVEL_DEBUG); - rrc_log1->set_hex_limit(-1); - rrc_log2->set_hex_limit(-1); + srslog::init(); + + auto& logger_rrc1 = srslog::fetch_basic_logger("RLC_AM_1", false); + logger_rrc1.set_level(srslog::basic_levels::debug); + logger_rrc1.set_hex_dump_max_size(-1); + auto& logger_rrc2 = srslog::fetch_basic_logger("RLC_AM_2", false); + logger_rrc2.set_level(srslog::basic_levels::debug); + logger_rrc2.set_hex_dump_max_size(-1); if (basic_test()) { printf("basic_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (concat_test()) { printf("concat_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (segment_test(true)) { printf("segment_test with in-order PDU reception failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (segment_test(false)) { printf("segment_test with out-of-order PDU reception failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (retx_test()) { printf("retx_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (segment_retx_test()) { printf("segment_retx_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_1()) { printf("resegment_test_1 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_2()) { printf("resegment_test_2 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_3()) { printf("resegment_test_3 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_4()) { printf("resegment_test_4 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_5()) { printf("resegment_test_5 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_6()) { printf("resegment_test_6 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); - rrc_log1->set_hex_limit(100); - rrc_log2->set_hex_limit(100); + logger_rrc1.set_hex_dump_max_size(100); + logger_rrc2.set_hex_dump_max_size(100); if (resegment_test_7()) { printf("resegment_test_7 failed\n"); exit(-1); } - byte_buffer_pool::get_instance()->cleanup(); if (resegment_test_8()) { printf("resegment_test_8 failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); - rrc_log1->set_hex_limit(-1); - rrc_log2->set_hex_limit(-1); + logger_rrc1.set_hex_dump_max_size(-1); + logger_rrc2.set_hex_dump_max_size(-1); if (reset_test()) { printf("reset_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (stop_test()) { printf("stop_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (resume_test()) { printf("resume_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); if (status_pdu_test()) { printf("status_pdu_test failed\n"); exit(-1); }; - byte_buffer_pool::get_instance()->cleanup(); return 0; } diff --git a/lib/test/upper/rlc_common_test.cc b/lib/test/upper/rlc_common_test.cc index f4ac3ea5d..e6d7f3b18 100644 --- a/lib/test/upper/rlc_common_test.cc +++ b/lib/test/upper/rlc_common_test.cc @@ -55,6 +55,8 @@ public: } sdus[n_sdus++] = std::move(sdu); } + void notify_delivery(uint32_t lcid, const std::vector& pdcp_sn) {} + void notify_failure(uint32_t lcid, const std::vector& pdcp_sn) {} void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} @@ -72,19 +74,20 @@ public: int meas_obj_test() { - srslte::log_ref log1("RLC_1"); - srslte::log_ref log2("RLC_2"); - log1->set_level(srslte::LOG_LEVEL_DEBUG); - log2->set_level(srslte::LOG_LEVEL_DEBUG); - log1->set_hex_limit(-1); - log2->set_hex_limit(-1); + auto& logger_rlc1 = srslog::fetch_basic_logger("RLC_1", false); + logger_rlc1.set_level(srslog::basic_levels::debug); + logger_rlc1.set_hex_dump_max_size(-1); + auto& logger_rlc2 = srslog::fetch_basic_logger("RLC_2", false); + logger_rlc2.set_level(srslog::basic_levels::debug); + logger_rlc2.set_hex_dump_max_size(-1); + rlc_tester tester; srslte::timer_handler timers(1); int len = 0; - rlc rlc1(log1->get_service_name().c_str()); - rlc rlc2(log2->get_service_name().c_str()); + rlc rlc1(logger_rlc1.id().c_str()); + rlc rlc2(logger_rlc2.id().c_str()); rlc1.init(&tester, &tester, &timers, 0); rlc2.init(&tester, &tester, &timers, 0); @@ -109,7 +112,7 @@ int meas_obj_test() // Push 5 SDUs into RLC1 for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); *sdu_bufs[i]->msg = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte rlc1.write_sdu(lcid, std::move(sdu_bufs[i])); @@ -124,7 +127,7 @@ int meas_obj_test() // Push again 5 SDUs, SN should start from 0 for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); *sdu_bufs[i]->msg = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte rlc1.write_sdu(lcid, std::move(sdu_bufs[i])); @@ -203,6 +206,8 @@ int meas_obj_test() int main(int argc, char** argv) { + srslog::init(); + if (meas_obj_test()) { return -1; } diff --git a/lib/test/upper/rlc_stress_test.cc b/lib/test/upper/rlc_stress_test.cc index 91b7a62a1..213d8f0e6 100644 --- a/lib/test/upper/rlc_stress_test.cc +++ b/lib/test/upper/rlc_stress_test.cc @@ -94,7 +94,6 @@ typedef struct { void parse_args(stress_test_args_t* args, int argc, char* argv[]) { - // Command line only options bpo::options_description general("General options"); @@ -163,14 +162,14 @@ public: pcap(pcap_), lcid(lcid_), timers(timers_), - log("MAC "), + logger(srslog::fetch_basic_logger("MAC", false)), thread("MAC_DUMMY"), real_dist(0.0, 1.0), mt19937(1234), pool(byte_buffer_pool::get_instance()) { - log.set_level(static_cast(args.log_level)); - log.set_hex_limit(LOG_HEX_LIMIT); + logger.set_level(static_cast(args.log_level)); + logger.set_hex_dump_max_size(LOG_HEX_LIMIT); } void stop() @@ -187,7 +186,7 @@ private: // Generate A number of MAC PDUs for (uint32_t i = 0; i < args.nof_pdu_tti; i++) { // Create PDU unique buffer - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n"); exit(-1); @@ -237,7 +236,7 @@ private: // Cut if ((real_dist(mt19937) < args.pdu_cut_rate)) { int cut_pdu_len = static_cast(pdu_len * real_dist(mt19937)); - log.info("Cutting MAC PDU len (%d B -> %d B)\n", pdu_len, cut_pdu_len); + logger.info("Cutting MAC PDU len (%d B -> %d B)", pdu_len, cut_pdu_len); pdu_len = cut_pdu_len; } @@ -252,7 +251,7 @@ private: pcap->write_ul_ccch(pdu->msg, pdu_len); } } else { - log.warning_hex(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)\n", pdu->N_bytes); + logger.warning(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)", pdu->N_bytes); skip_action = true; // Avoid drop duplicating this PDU } @@ -261,7 +260,7 @@ private: it++; skip_action = false; // Allow action on the next PDU } else { - log.warning_hex(pdu->msg, pdu->N_bytes, "Duplicating RLC PDU (%d B)\n", pdu->N_bytes); + logger.warning(pdu->msg, pdu->N_bytes, "Duplicating RLC PDU (%d B)", pdu->N_bytes); skip_action = true; // Avoid drop of this PDU } } @@ -310,14 +309,14 @@ private: stress_test_args_t args; rlc_pcap* pcap; uint32_t lcid; - srslte::log_filter log; + srslog::basic_logger& logger; srslte::timer_handler* timers = nullptr; srslte::block_queue pending_tasks; std::mt19937 mt19937; std::uniform_real_distribution real_dist; - byte_buffer_pool* pool = nullptr; + byte_buffer_pool* pool = nullptr; }; class rlc_tester : public pdcp_interface_rlc, public rrc_interface_rlc, public thread @@ -325,6 +324,7 @@ class rlc_tester : public pdcp_interface_rlc, public rrc_interface_rlc, public t public: rlc_tester(rlc_interface_pdcp* rlc_, std::string name_, stress_test_args_t args_, uint32_t lcid_) : log("TEST"), + logger(srslog::fetch_basic_logger("TEST", false)), rlc(rlc_), run_enable(true), rx_pdus(), @@ -333,8 +333,8 @@ public: lcid(lcid_), thread("RLC_TESTER") { - log.set_level(srslte::LOG_LEVEL_ERROR); - log.set_hex_limit(LOG_HEX_LIMIT); + logger.set_level(srslog::basic_levels::error); + logger.set_hex_dump_max_size(LOG_HEX_LIMIT); } void stop() @@ -348,7 +348,7 @@ public: { assert(rx_lcid == lcid); if (sdu->N_bytes != args.sdu_size) { - log.error_hex(sdu->msg, sdu->N_bytes, "Received SDU with size %d, expected %d.\n", sdu->N_bytes, args.sdu_size); + logger.error(sdu->msg, sdu->N_bytes, "Received SDU with size %d, expected %d.", sdu->N_bytes, args.sdu_size); if (args.pedantic_sdu_check) { exit(-1); } @@ -360,6 +360,8 @@ public: void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} + void notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) {} + void notify_failure(uint32_t lcid, const std::vector& pdcp_sns) {} // RRC interface void max_retx_attempted() {} @@ -370,20 +372,21 @@ public: private: void run_thread() { - uint8_t sn = 0; - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); + uint32_t pdcp_sn = 0; + byte_buffer_pool* pool = byte_buffer_pool::get_instance(); while (run_enable) { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, "rlc_tester::run_thread", true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu == NULL) { printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); // backoff for a bit usleep(1000); continue; } + pdu->md.pdcp_sn = pdcp_sn; for (uint32_t i = 0; i < args.sdu_size; i++) { - pdu->msg[i] = sn; + pdu->msg[i] = pdcp_sn & 0xFF; } - sn++; + pdcp_sn++; pdu->N_bytes = args.sdu_size; rlc->write_sdu(lcid, std::move(pdu)); if (args.sdu_gen_delay_usec > 0) { @@ -392,10 +395,11 @@ private: } } - bool run_enable; - uint64_t rx_pdus; - uint32_t lcid; - srslte::log_filter log; + bool run_enable; + uint64_t rx_pdus; + uint32_t lcid; + srslte::log_filter log; + srslog::basic_logger& logger; std::string name; @@ -406,12 +410,13 @@ private: void stress_test(stress_test_args_t args) { - srslte::log_ref log1("RLC_1"); - srslte::log_ref log2("RLC_2"); - log1->set_level(static_cast(args.log_level)); - log2->set_level(static_cast(args.log_level)); - log1->set_hex_limit(LOG_HEX_LIMIT); - log2->set_hex_limit(LOG_HEX_LIMIT); + auto& log1 = srslog::fetch_basic_logger("RLC_1", false); + log1.set_level(static_cast(args.log_level)); + log1.set_hex_dump_max_size(LOG_HEX_LIMIT); + auto& log2 = srslog::fetch_basic_logger("RLC_2", false); + log2.set_level(static_cast(args.log_level)); + log2.set_hex_dump_max_size(LOG_HEX_LIMIT); + rlc_pcap pcap; uint32_t lcid = 1; @@ -470,8 +475,8 @@ void stress_test(stress_test_args_t args) srslte::timer_handler timers(8); - rlc rlc1(log1->get_service_name().c_str()); - rlc rlc2(log2->get_service_name().c_str()); + rlc rlc1(log1.id().c_str()); + rlc rlc2(log2.id().c_str()); rlc_tester tester1(&rlc1, "tester1", args, lcid); rlc_tester tester2(&rlc2, "tester2", args, lcid); @@ -554,6 +559,8 @@ int main(int argc, char** argv) stress_test_args_t args = {}; parse_args(&args, argc, argv); + srslog::init(); + if (args.zero_seed) { srand(0); } else { diff --git a/lib/test/upper/rlc_test_common.h b/lib/test/upper/rlc_test_common.h index 0bf9b0993..d4cb5367f 100644 --- a/lib/test/upper/rlc_test_common.h +++ b/lib/test/upper/rlc_test_common.h @@ -58,6 +58,8 @@ public: void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} void write_pdu_pcch(unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) { sdus.push_back(std::move(sdu)); } + void notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) {} + void notify_failure(uint32_t lcid, const std::vector& pdcp_sns) {} // RRC interface void max_retx_attempted() {} diff --git a/lib/test/upper/rlc_um_data_test.cc b/lib/test/upper/rlc_um_data_test.cc index a3d92e502..26f4c0cb2 100644 --- a/lib/test/upper/rlc_um_data_test.cc +++ b/lib/test/upper/rlc_um_data_test.cc @@ -33,6 +33,8 @@ uint32_t PDU2_LEN = 4; int main(int argc, char** argv) { + srslog::init(); + srslte::rlc_umd_pdu_header_t h; srslte::byte_buffer_t b1, b2; diff --git a/lib/test/upper/rlc_um_nr_pdu_test.cc b/lib/test/upper/rlc_um_nr_pdu_test.cc index 20cca97d7..b9cae4150 100644 --- a/lib/test/upper/rlc_um_nr_pdu_test.cc +++ b/lib/test/upper/rlc_um_nr_pdu_test.cc @@ -211,6 +211,8 @@ int main(int argc, char** argv) pcap_handle->open("rlc_um_nr_pdu_test.pcap"); #endif + srslog::init(); + if (rlc_um_nr_pdu_test1()) { fprintf(stderr, "rlc_um_nr_pdu_test1() failed.\n"); return SRSLTE_ERROR; diff --git a/lib/test/upper/rlc_um_nr_test.cc b/lib/test/upper/rlc_um_nr_test.cc index 423ea9acf..7403fd489 100644 --- a/lib/test/upper/rlc_um_nr_test.cc +++ b/lib/test/upper/rlc_um_nr_test.cc @@ -81,17 +81,17 @@ class rlc_um_nr_test_context1 { public: rlc_um_nr_test_context1() : - log1("RLC_UM_1"), - log2("RLC_UM_2"), + logger1(srslog::fetch_basic_logger("RLC_UM_1", false)), + logger2(srslog::fetch_basic_logger("RLC_UM_2", false)), timers(16), - rlc1(log1, 3, &tester, &tester, &timers), - rlc2(log2, 3, &tester, &tester, &timers) + rlc1(logger1, 3, &tester, &tester, &timers), + rlc2(logger2, 3, &tester, &tester, &timers) { // setup logging - log1->set_level(srslte::LOG_LEVEL_DEBUG); - log2->set_level(srslte::LOG_LEVEL_DEBUG); - log1->set_hex_limit(-1); - log2->set_hex_limit(-1); + logger1.set_level(srslog::basic_levels::debug); + logger1.set_hex_dump_max_size(-1); + logger2.set_level(srslog::basic_levels::debug); + logger2.set_hex_dump_max_size(-1); // configure RLC entities rlc_config_t cnfg = rlc_config_t::default_rlc_um_nr_config(6); @@ -105,7 +105,8 @@ public: tester.set_expected_sdu_len(1); } - srslte::log_ref log1, log2; + srslog::basic_logger& logger1; + srslog::basic_logger& logger2; srslte::timer_handler timers; rlc_um_tester tester; rlc_um_nr rlc1, rlc2; @@ -122,7 +123,7 @@ int rlc_um_nr_test1() byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); *sdu_bufs[i]->msg = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte ctxt.rlc1.write_sdu(std::move(sdu_bufs[i])); @@ -133,7 +134,7 @@ int rlc_um_nr_test1() // Read 5 PDUs from RLC1 (1 byte each) unique_byte_buffer_t pdu_bufs[num_pdus]; for (uint32_t i = 0; i < num_pdus; i++) { - pdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[i] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[i]->msg, 4); // 3 bytes for header + payload pdu_bufs[i]->N_bytes = len; @@ -173,7 +174,7 @@ int rlc_um_nr_test2(bool reverse_rx = false) byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); // Write the index into the buffer for (uint32_t k = 0; k < sdu_size; ++k) { sdu_bufs[i]->msg[k] = i; @@ -191,7 +192,7 @@ int rlc_um_nr_test2(bool reverse_rx = false) unique_byte_buffer_t pdu_bufs[max_num_pdus]; while (ctxt.rlc1.get_buffer_state() != 0 && num_pdus < max_num_pdus) { - pdu_bufs[num_pdus] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[num_pdus] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[num_pdus]->msg, 25); // 3 bytes for header + payload pdu_bufs[num_pdus]->N_bytes = len; @@ -241,7 +242,7 @@ int rlc_um_nr_test4() byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); // Write the index into the buffer for (uint32_t k = 0; k < sdu_size; ++k) { sdu_bufs[i]->msg[k] = i; @@ -260,7 +261,7 @@ int rlc_um_nr_test4() unique_byte_buffer_t pdu_bufs[max_num_pdus]; while (ctxt.rlc1.get_buffer_state() != 0 && num_pdus < max_num_pdus) { - pdu_bufs[num_pdus] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[num_pdus] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[num_pdus]->msg, 25); // 3 bytes for header + payload pdu_bufs[num_pdus]->N_bytes = len; num_pdus++; @@ -317,7 +318,7 @@ int rlc_um_nr_test5(const uint32_t last_sn) byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); // Write the index into the buffer for (uint32_t k = 0; k < sdu_size; ++k) { sdu_bufs[i]->msg[k] = i; @@ -335,7 +336,7 @@ int rlc_um_nr_test5(const uint32_t last_sn) unique_byte_buffer_t pdu_bufs[max_num_pdus]; while (ctxt.rlc1.get_buffer_state() != 0 && num_pdus < max_num_pdus) { - pdu_bufs[num_pdus] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[num_pdus] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[num_pdus]->msg, 25); // 3 bytes for header + payload pdu_bufs[num_pdus]->N_bytes = len; @@ -384,7 +385,7 @@ int rlc_um_nr_test6() byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); // Write the index into the buffer for (uint32_t k = 0; k < sdu_size; ++k) { sdu_bufs[i]->msg[k] = i; @@ -402,7 +403,7 @@ int rlc_um_nr_test6() unique_byte_buffer_t pdu_bufs[max_num_pdus]; while (ctxt.rlc1.get_buffer_state() != 0 && num_pdus < max_num_pdus) { - pdu_bufs[num_pdus] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[num_pdus] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[num_pdus]->msg, 8); // 3 bytes for header + payload pdu_bufs[num_pdus]->N_bytes = len; @@ -444,7 +445,7 @@ int rlc_um_nr_test7() byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); // Write the index into the buffer for (uint32_t k = 0; k < sdu_size; ++k) { sdu_bufs[i]->msg[k] = i; @@ -462,7 +463,7 @@ int rlc_um_nr_test7() unique_byte_buffer_t pdu_bufs[max_num_pdus]; while (ctxt.rlc1.get_buffer_state() != 0 && num_pdus < max_num_pdus) { - pdu_bufs[num_pdus] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[num_pdus] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[num_pdus]->msg, 8); // 3 bytes for header + payload pdu_bufs[num_pdus]->N_bytes = len; @@ -508,7 +509,7 @@ int rlc_um_nr_test8() byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (uint32_t i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); // Write the index into the buffer for (uint32_t k = 0; k < sdu_size; ++k) { sdu_bufs[i]->msg[k] = i; @@ -526,7 +527,7 @@ int rlc_um_nr_test8() unique_byte_buffer_t pdu_bufs[max_num_pdus]; while (ctxt.rlc1.get_buffer_state() != 0 && num_pdus < max_num_pdus) { - pdu_bufs[num_pdus] = srslte::allocate_unique_buffer(*pool, true); + pdu_bufs[num_pdus] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[num_pdus]->msg, 8); // 3 bytes for header + payload pdu_bufs[num_pdus]->N_bytes = len; @@ -570,6 +571,8 @@ int main(int argc, char** argv) pcap_handle->open("rlc_um_nr_test.pcap"); #endif + srslog::init(); + if (rlc_um_nr_test1()) { fprintf(stderr, "rlc_um_nr_test1() failed.\n"); return SRSLTE_ERROR; @@ -613,7 +616,5 @@ int main(int argc, char** argv) return SRSLTE_ERROR; } - byte_buffer_pool::get_instance()->cleanup(); - return SRSLTE_SUCCESS; } diff --git a/lib/test/upper/rlc_um_test.cc b/lib/test/upper/rlc_um_test.cc index 2e7feae38..3f60c0fac 100644 --- a/lib/test/upper/rlc_um_test.cc +++ b/lib/test/upper/rlc_um_test.cc @@ -43,17 +43,17 @@ class rlc_um_lte_test_context1 { public: rlc_um_lte_test_context1() : - log1("RLC_UM_1"), - log2("RLC_UM_2"), + logger1(srslog::fetch_basic_logger("RLC_UM_1", false)), + logger2(srslog::fetch_basic_logger("RLC_UM_2", false)), timers(16), - rlc1(log1, 3, &tester, &tester, &timers), - rlc2(log2, 3, &tester, &tester, &timers) + rlc1(logger1, 3, &tester, &tester, &timers), + rlc2(logger2, 3, &tester, &tester, &timers) { // setup logging - log1->set_level(srslte::LOG_LEVEL_DEBUG); - log2->set_level(srslte::LOG_LEVEL_DEBUG); - log1->set_hex_limit(-1); - log2->set_hex_limit(-1); + logger1.set_level(srslog::basic_levels::debug); + logger1.set_hex_dump_max_size(-1); + logger2.set_level(srslog::basic_levels::debug); + logger2.set_hex_dump_max_size(-1); // configure RLC entities rlc_config_t cnfg = rlc_config_t::default_rlc_um_config(10); @@ -67,7 +67,8 @@ public: tester.set_expected_sdu_len(1); } - srslte::log_ref log1, log2; + srslog::basic_logger& logger1; + srslog::basic_logger& logger2; srslte::timer_handler timers; rlc_um_tester tester; rlc_um_lte rlc1, rlc2; @@ -78,10 +79,9 @@ int meas_obj_test() rlc_um_lte_test_context1 ctxt; // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); *sdu_bufs[i]->msg = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte ctxt.rlc1.write_sdu(std::move(sdu_bufs[i])); @@ -119,10 +119,9 @@ int loss_test() rlc_um_lte_test_context1 ctxt; // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); sdu_bufs[i]->msg[0] = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte ctxt.rlc1.write_sdu(std::move(sdu_bufs[i])); @@ -165,10 +164,9 @@ int basic_mbsfn_test() ctxt.rlc2.configure(rlc_config_t::mch_config()); // Push 5 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[NBUFS * 2]; for (int i = 0; i < NBUFS; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); sdu_bufs[i]->msg[0] = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 1; // Give each buffer a size of 1 byte ctxt.rlc1.write_sdu(std::move(sdu_bufs[i])); @@ -228,10 +226,9 @@ int reassmble_test() const int n_sdu_first_batch = 17; - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[n_sdus]; for (int i = 0; i < n_sdu_first_batch; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int k = 0; k < sdu_len; ++k) { sdu_bufs[i]->msg[k] = i; } @@ -240,11 +237,11 @@ int reassmble_test() } // Read PDUs from RLC1 (use smaller grant for first PDU and large for the rest) - const int max_n_pdus = 100; - int n_pdus = 0; - byte_buffer_t* pdu_bufs[max_n_pdus]; + const int max_n_pdus = 100; + int n_pdus = 0; + std::unique_ptr pdu_bufs[max_n_pdus]; for (int i = 0; i < max_n_pdus; i++) { - pdu_bufs[i] = byte_buffer_pool::get_instance()->allocate(); + pdu_bufs[i] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[i]->msg, (i == 0) ? sdu_len * 3 / 4 : sdu_len * 1.25); pdu_bufs[i]->N_bytes = len; if (len) { @@ -259,7 +256,7 @@ int reassmble_test() // push second batch of SDUs for (int i = n_sdu_first_batch; i < n_sdus; ++i) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int k = 0; k < sdu_len; ++k) { sdu_bufs[i]->msg[k] = i; } @@ -269,7 +266,7 @@ int reassmble_test() // Read second batch of PDUs (use large grants) for (int i = n_pdus; i < max_n_pdus; i++) { - pdu_bufs[i] = byte_buffer_pool::get_instance()->allocate(); + pdu_bufs[i] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[i]->msg, sdu_len * 1.25); pdu_bufs[i]->N_bytes = len; if (len) { @@ -321,10 +318,9 @@ int reassmble_test2() ctxt.tester.set_expected_sdu_len(sdu_len); const int n_sdu_first_batch = 17; - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[n_sdus]; for (int i = 0; i < n_sdu_first_batch; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int k = 0; k < sdu_len; ++k) { sdu_bufs[i]->msg[k] = i; } @@ -332,11 +328,11 @@ int reassmble_test2() ctxt.rlc1.write_sdu(std::move(sdu_bufs[i])); } - const int max_n_pdus = 100; - int n_pdus = 0; - byte_buffer_t* pdu_bufs[max_n_pdus]; + const int max_n_pdus = 100; + int n_pdus = 0; + srslte::unique_byte_buffer_t pdu_bufs[max_n_pdus]; for (int i = 0; i < max_n_pdus; i++) { - pdu_bufs[i] = byte_buffer_pool::get_instance()->allocate(); + pdu_bufs[i] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[i]->msg, (i == 0) ? sdu_len * .75 : sdu_len * .25); pdu_bufs[i]->N_bytes = len; if (len) { @@ -351,7 +347,7 @@ int reassmble_test2() // push second batch of SDUs for (int i = n_sdu_first_batch; i < n_sdus; ++i) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); for (int k = 0; k < sdu_len; ++k) { sdu_bufs[i]->msg[k] = i; } @@ -361,7 +357,7 @@ int reassmble_test2() // Read second batch of PDUs for (int i = n_pdus; i < max_n_pdus; i++) { - pdu_bufs[i] = byte_buffer_pool::get_instance()->allocate(); + pdu_bufs[i] = srslte::make_byte_buffer(); int len = ctxt.rlc1.read_pdu(pdu_bufs[i]->msg, sdu_len * 1.25); pdu_bufs[i]->N_bytes = len; if (len) { @@ -401,10 +397,9 @@ int pdu_pack_no_space_test() const int32_t num_sdus = 2; // Push 2 SDUs into RLC1 - byte_buffer_pool* pool = byte_buffer_pool::get_instance(); unique_byte_buffer_t sdu_bufs[num_sdus]; for (int i = 0; i < num_sdus; i++) { - sdu_bufs[i] = srslte::allocate_unique_buffer(*pool, true); + sdu_bufs[i] = srslte::make_byte_buffer(); *sdu_bufs[i]->msg = i; // Write the index into the buffer sdu_bufs[i]->N_bytes = 10; // Give each buffer a size of 1 byte ctxt.rlc1.write_sdu(std::move(sdu_bufs[i])); @@ -441,31 +436,27 @@ int pdu_pack_no_space_test() int main(int argc, char** argv) { + srslog::init(); + if (meas_obj_test()) { return -1; } - byte_buffer_pool::get_instance()->cleanup(); if (loss_test()) { return -1; } - byte_buffer_pool::get_instance()->cleanup(); if (basic_mbsfn_test()) { return -1; } - byte_buffer_pool::get_instance()->cleanup(); if (reassmble_test()) { return -1; } - byte_buffer_pool::get_instance()->cleanup(); if (reassmble_test2()) { return -1; } - byte_buffer_pool::get_instance()->cleanup(); TESTASSERT(pdu_pack_no_space_test() == 0); - byte_buffer_pool::get_instance()->cleanup(); } diff --git a/srsenb/drb.conf.example b/srsenb/drb.conf.example index 32b6e9376..55a1a1491 100644 --- a/srsenb/drb.conf.example +++ b/srsenb/drb.conf.example @@ -6,7 +6,7 @@ qci_config = ( { qci=7; pdcp_config = { - discard_timer = 100; + discard_timer = -1; pdcp_sn_size = 12; } rlc_config = { @@ -28,7 +28,7 @@ qci_config = ( { qci=9; pdcp_config = { - discard_timer = -1; + discard_timer = 150; status_report_required = true; } rlc_config = { diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 2e8e011d7..8840862f3 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -50,6 +50,7 @@ #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -120,7 +121,7 @@ struct rrc_cfg_t; class enb : public enb_metrics_interface, enb_command_interface { public: - enb(); + enb(srslog::sink& log_sink); virtual ~enb(); @@ -143,12 +144,9 @@ private: int parse_args(const all_args_t& args_, rrc_cfg_t& rrc_cfg); - srslte::logger* logger = nullptr; - srslte::log_ref log; // Own logger for eNB - - srslte::log_filter pool_log; - - srslte::byte_buffer_pool* pool = nullptr; + srslte::logger* logger = nullptr; + srslog::sink& log_sink; + srslog::basic_logger& enb_log; all_args_t args = {}; bool started = false; diff --git a/srsenb/hdr/phy/lte/cc_worker.h b/srsenb/hdr/phy/lte/cc_worker.h index 55dd4f46e..19a2e5f4f 100644 --- a/srsenb/hdr/phy/lte/cc_worker.h +++ b/srsenb/hdr/phy/lte/cc_worker.h @@ -25,6 +25,7 @@ #include #include "../phy_common.h" +#include "srslte/srslog/srslog.h" #define LOG_EXECTIME @@ -34,9 +35,9 @@ namespace lte { class cc_worker { public: - cc_worker(); + cc_worker(srslog::basic_logger& logger); ~cc_worker(); - void init(phy_common* phy, srslte::log* log_h, uint32_t cc_idx); + void init(phy_common* phy, uint32_t cc_idx); void reset(); cf_t* get_buffer_rx(uint32_t antenna_idx); @@ -79,9 +80,9 @@ private: int decode_pucch(); /* Common objects */ - srslte::log* log_h = nullptr; - phy_common* phy = nullptr; - bool initiated = false; + srslog::basic_logger& logger; + phy_common* phy = nullptr; + bool initiated = false; cf_t* signal_buffer_rx[SRSLTE_MAX_PORTS] = {}; cf_t* signal_buffer_tx[SRSLTE_MAX_PORTS] = {}; diff --git a/srsenb/hdr/phy/lte/sf_worker.h b/srsenb/hdr/phy/lte/sf_worker.h index 3beaa31b7..9535967d5 100644 --- a/srsenb/hdr/phy/lte/sf_worker.h +++ b/srsenb/hdr/phy/lte/sf_worker.h @@ -27,6 +27,7 @@ #include "../phy_common.h" #include "cc_worker.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" namespace srsenb { @@ -35,9 +36,9 @@ namespace lte { class sf_worker : public srslte::thread_pool::worker { public: - sf_worker() = default; + sf_worker(srslog::basic_logger& logger) : logger(logger) {} ~sf_worker(); - void init(phy_common* phy, srslte::log* log_h); + void init(phy_common* phy); cf_t* get_buffer_rx(uint32_t cc_idx, uint32_t antenna_idx); void set_time(uint32_t tti_, uint32_t tx_worker_cnt_, const srslte::rf_timestamp_t& tx_time_); @@ -62,11 +63,11 @@ private: void work_imp() final; /* Common objects */ - srslte::log* log_h = nullptr; - phy_common* phy = nullptr; - bool initiated = false; - bool running = false; - std::mutex work_mutex; + srslog::basic_logger& logger; + phy_common* phy = nullptr; + bool initiated = false; + bool running = false; + std::mutex work_mutex; uint32_t tti_rx = 0, tti_tx_dl = 0, tti_tx_ul = 0; uint32_t t_rx = 0, t_tx_dl = 0, t_tx_ul = 0; diff --git a/srsenb/hdr/phy/lte/worker_pool.h b/srsenb/hdr/phy/lte/worker_pool.h index b7940c98a..de93114d0 100644 --- a/srsenb/hdr/phy/lte/worker_pool.h +++ b/srsenb/hdr/phy/lte/worker_pool.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -30,10 +21,6 @@ namespace lte { class worker_pool { - -private: - std::vector > log_vec; - srslte::thread_pool pool; std::vector > workers; @@ -42,7 +29,7 @@ public: uint32_t get_nof_workers() { return (uint32_t)workers.size(); } worker_pool(uint32_t max_workers); - bool init(const phy_args_t& args, phy_common* common, srslte::logger* logger, int prio); + bool init(const phy_args_t& args, phy_common* common, srslog::sink& log_sink, int prio); sf_worker* wait_worker(uint32_t tti); sf_worker* wait_worker_id(uint32_t id); void start_worker(sf_worker* w); diff --git a/srsenb/hdr/phy/nr/cc_worker.h b/srsenb/hdr/phy/nr/cc_worker.h index 19b8bdb09..64f7a9543 100644 --- a/srsenb/hdr/phy/nr/cc_worker.h +++ b/srsenb/hdr/phy/nr/cc_worker.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -25,6 +16,7 @@ #include "srslte/common/log.h" #include "srslte/interfaces/gnb_interfaces.h" #include "srslte/phy/enb/enb_dl_nr.h" +#include "srslte/srslog/srslog.h" #include #include @@ -37,7 +29,7 @@ typedef struct { } phy_nr_args_t; typedef struct { - srslte_sch_cfg_nr_t pdsch; + srslte_sch_hl_cfg_nr_t pdsch; } phy_nr_cfg_t; class phy_nr_state @@ -61,7 +53,7 @@ public: class cc_worker { public: - cc_worker(uint32_t cc_idx, srslte::log* log, phy_nr_state* phy_state_); + cc_worker(uint32_t cc_idx, srslog::basic_logger& logger, phy_nr_state* phy_state_); ~cc_worker(); bool set_carrier(const srslte_carrier_nr_t* carrier); @@ -71,20 +63,20 @@ public: cf_t* get_rx_buffer(uint32_t antenna_idx); uint32_t get_buffer_len(); - bool work_dl(const srslte_dl_slot_cfg_t& dl_slot_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants); + bool work_dl(const srslte_slot_cfg_t& dl_slot_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants); private: int encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants); int encode_pdcch_dl(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants); - srslte_dl_slot_cfg_t dl_slot_cfg = {}; + srslte_slot_cfg_t dl_slot_cfg = {}; uint32_t cc_idx = 0; std::array tx_buffer = {}; std::array rx_buffer = {}; uint32_t buffer_sz = 0; phy_nr_state* phy_state; srslte_enb_dl_nr_t enb_dl = {}; - srslte::log* log_h = nullptr; + srslog::basic_logger& logger; }; } // namespace nr diff --git a/srsenb/hdr/phy/nr/sf_worker.h b/srsenb/hdr/phy/nr/sf_worker.h index b4a3d3eef..a56d038f4 100644 --- a/srsenb/hdr/phy/nr/sf_worker.h +++ b/srsenb/hdr/phy/nr/sf_worker.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -25,6 +16,7 @@ #include "cc_worker.h" #include "srsenb/hdr/phy/phy_common.h" #include "srslte/common/thread_pool.h" +#include "srslte/srslog/srslog.h" namespace srsenb { namespace nr { @@ -40,7 +32,7 @@ namespace nr { class sf_worker final : public srslte::thread_pool::worker { public: - sf_worker(phy_common* phy_, phy_nr_state* phy_state_, srslte::log* log); + sf_worker(phy_common* phy_, phy_nr_state* phy_state_, srslog::basic_logger& logger); ~sf_worker(); bool set_carrier_unlocked(uint32_t cc_idx, const srslte_carrier_nr_t* carrier_); @@ -57,9 +49,9 @@ private: std::vector > cc_workers; - phy_common* phy = nullptr; - phy_nr_state* phy_state = nullptr; - srslte::log* log_h = nullptr; + phy_common* phy = nullptr; + phy_nr_state* phy_state = nullptr; + srslog::basic_logger& logger; // Temporal attributes srslte_softbuffer_tx_t softbuffer_tx = {}; diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index 4d619ae64..3cfbfbcb2 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -30,10 +21,6 @@ namespace nr { class worker_pool { - -private: - std::vector > log_vec; - srslte::thread_pool pool; std::vector > workers; phy_nr_state phy_state; @@ -42,7 +29,7 @@ public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } worker_pool(uint32_t max_workers); - bool init(const phy_args_t& args, phy_common* common, srslte::logger* logger, int prio); + bool init(const phy_args_t& args, phy_common* common, srslog::sink& log_sink, int prio); sf_worker* wait_worker(uint32_t tti); sf_worker* wait_worker_id(uint32_t id); void start_worker(sf_worker* w); diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index 00dce2c17..711f9de46 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -22,16 +22,16 @@ #ifndef SRSENB_PHY_H #define SRSENB_PHY_H -#include "phy_common.h" #include "lte/sf_worker.h" +#include "phy_common.h" #include "srsenb/hdr/phy/enb_phy_base.h" #include "srslte/common/log.h" #include "srslte/common/log_filter.h" #include "srslte/common/trace.h" -#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "txrx.h" namespace srsenb { @@ -39,7 +39,7 @@ namespace srsenb { class phy final : public enb_phy_base, public phy_interface_stack_lte, public srslte::phy_interface_radio { public: - phy(srslte::logger* logger_); + phy(srslog::sink& log_sink); ~phy(); int init(const phy_args_t& args, @@ -75,7 +75,7 @@ public: private: srslte::phy_cfg_mbsfn_t mbsfn_config = {}; - uint32_t nof_workers = 0; + uint32_t nof_workers = 0; const static int MAX_WORKERS = 4; @@ -85,9 +85,9 @@ private: srslte::radio_interface_phy* radio = nullptr; - srslte::logger* logger = nullptr; - std::unique_ptr log_h = nullptr; - std::unique_ptr log_phy_lib_h = nullptr; + srslog::sink& log_sink; + srslog::basic_logger& phy_log; + srslog::basic_logger& phy_lib_log; lte::worker_pool lte_workers; nr::worker_pool nr_workers; diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 876884100..f9c46c734 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -29,7 +29,6 @@ #include "srslte/common/log.h" #include "srslte/common/thread_pool.h" #include "srslte/common/threads.h" -#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/radio_interfaces.h" #include "srslte/phy/channel/channel.h" @@ -240,19 +239,19 @@ private: phy_cell_cfg_list_t cell_list_lte; phy_cell_cfg_list_nr_t cell_list_nr; - bool have_mtch_stop = false; - pthread_mutex_t mtch_mutex = {}; - pthread_cond_t mtch_cvar = {}; - srslte::phy_cfg_mbsfn_t mbsfn = {}; - bool sib13_configured = false; - bool mcch_configured = false; - uint8_t mch_table[40] = {}; - uint8_t mcch_table[10] = {}; - uint32_t mch_period_stop = 0; - bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); - bool is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); - srslte::rf_buffer_t nr_tx_buffer; - bool nr_tx_buffer_ready = false; + bool have_mtch_stop = false; + pthread_mutex_t mtch_mutex = {}; + pthread_cond_t mtch_cvar = {}; + srslte::phy_cfg_mbsfn_t mbsfn = {}; + bool sib13_configured = false; + bool mcch_configured = false; + uint8_t mch_table[40] = {}; + uint8_t mcch_table[10] = {}; + uint32_t mch_period_stop = 0; + bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); + bool is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); + srslte::rf_buffer_t nr_tx_buffer; + bool nr_tx_buffer_ready = false; }; } // namespace srsenb diff --git a/srsenb/hdr/phy/phy_ue_db.h b/srsenb/hdr/phy/phy_ue_db.h index c67de27dc..ce19aad8a 100644 --- a/srsenb/hdr/phy/phy_ue_db.h +++ b/srsenb/hdr/phy/phy_ue_db.h @@ -23,10 +23,11 @@ #define SRSENB_PHY_UE_DB_H_ #include "phy_interfaces.h" +#include "srslte/interfaces/enb_mac_interfaces.h" +#include "srslte/interfaces/enb_phy_interfaces.h" #include #include #include -#include #include namespace srsenb { @@ -84,14 +85,14 @@ private: * Cell information for the UE database */ typedef struct { - cell_state_t state = cell_state_none; ///< Configuration state - uint32_t enb_cc_idx = 0; ///< Corresponding eNb cell/carrier index - uint8_t last_ri = 0; ///< Last reported rank indicator + cell_state_t state = cell_state_none; ///< Configuration state + uint32_t enb_cc_idx = 0; ///< Corresponding eNb cell/carrier index + uint8_t last_ri = 0; ///< Last reported rank indicator srslte::circular_array last_tb = - {}; ///< Stores last PUSCH Resource allocation - bool stash_use_tbs_index_alt = false; - srslte::phy_cfg_t phy_cfg; ///< Configuration, it has a default constructor - srslte::circular_array is_grant_available; ///< Indicates whether there is an available grant + {}; ///< Stores last PUSCH Resource allocation + bool stash_use_tbs_index_alt = false; + srslte::phy_cfg_t phy_cfg; ///< Configuration, it has a default constructor + srslte::circular_array is_grant_available; ///< Indicates whether there is an available grant } cell_info_t; /** diff --git a/srsenb/hdr/phy/prach_worker.h b/srsenb/hdr/phy/prach_worker.h index a443a33fc..30977d1f8 100644 --- a/srsenb/hdr/phy/prach_worker.h +++ b/srsenb/hdr/phy/prach_worker.h @@ -26,7 +26,8 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/threads.h" -#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_phy_interfaces.h" +#include "srslte/srslog/srslog.h" // Setting ENABLE_PRACH_GUI to non zero enables a GUI showing signal received in the PRACH window. #define ENABLE_PRACH_GUI 0 @@ -37,15 +38,19 @@ namespace srsenb { +class stack_interface_phy_lte; + class prach_worker : srslte::thread { public: - prach_worker(uint32_t cc_idx_) : buffer_pool(8), thread("PRACH_WORKER") { cc_idx = cc_idx_; } + prach_worker(uint32_t cc_idx_, srslog::basic_logger& logger) : buffer_pool(8), thread("PRACH_WORKER"), logger(logger) + { + cc_idx = cc_idx_; + } int init(const srslte_cell_t& cell_, const srslte_prach_cfg_t& prach_cfg_, stack_interface_phy_lte* mac, - srslte::log* log_h, int priority, uint32_t nof_workers); int new_tti(uint32_t tti, cf_t* buffer); @@ -53,7 +58,7 @@ public: void stop(); private: - uint32_t cc_idx = 0; + uint32_t cc_idx = 0; uint32_t prach_indices[165] = {}; float prach_offsets[165] = {}; @@ -88,8 +93,8 @@ private: srslte::buffer_pool buffer_pool; srslte::block_queue pending_buffers; + srslog::basic_logger& logger; sf_buffer* current_buffer = nullptr; - srslte::log* log_h = nullptr; stack_interface_phy_lte* stack = nullptr; float max_prach_offset_us = 0.0f; bool initiated = false; @@ -115,16 +120,16 @@ public: const srslte_cell_t& cell_, const srslte_prach_cfg_t& prach_cfg_, stack_interface_phy_lte* mac, - srslte::log* log_h, + srslog::basic_logger& logger, int priority, uint32_t nof_workers_x_cc) { // Create PRACH worker if required while (cc_idx >= prach_vec.size()) { - prach_vec.push_back(std::unique_ptr(new prach_worker(prach_vec.size()))); + prach_vec.push_back(std::unique_ptr(new prach_worker(prach_vec.size(), logger))); } - prach_vec[cc_idx]->init(cell_, prach_cfg_, mac, log_h, priority, nof_workers_x_cc); + prach_vec[cc_idx]->init(cell_, prach_cfg_, mac, priority, nof_workers_x_cc); } void set_max_prach_offset_us(float delay_us) diff --git a/srsenb/hdr/phy/txrx.h b/srsenb/hdr/phy/txrx.h index bb1ff949a..2c667b5b8 100644 --- a/srsenb/hdr/phy/txrx.h +++ b/srsenb/hdr/phy/txrx.h @@ -36,23 +36,22 @@ namespace srsenb { class txrx final : public srslte::thread { public: - txrx(); + txrx(srslog::basic_logger& logger); bool init(stack_interface_phy_lte* stack_, srslte::radio_interface_phy* radio_handler, lte::worker_pool* lte_workers_, nr::worker_pool* nr_workers_, phy_common* worker_com, prach_worker_pool* prach_, - srslte::log* log_h, uint32_t prio); void stop(); private: void run_thread() override; - stack_interface_phy_lte* stack = nullptr; - srslte::radio_interface_phy* radio_h = nullptr; - srslte::log* log_h = nullptr; + stack_interface_phy_lte* stack = nullptr; + srslte::radio_interface_phy* radio_h = nullptr; + srslog::basic_logger& logger; lte::worker_pool* lte_workers = nullptr; nr::worker_pool* nr_workers = nullptr; prach_worker_pool* prach = nullptr; diff --git a/srsenb/hdr/phy/vnf_phy_nr.h b/srsenb/hdr/phy/vnf_phy_nr.h index e681a496b..325f3c053 100644 --- a/srsenb/hdr/phy/vnf_phy_nr.h +++ b/srsenb/hdr/phy/vnf_phy_nr.h @@ -40,7 +40,7 @@ struct nr_phy_cfg_t { class vnf_phy_nr : public srsenb::enb_phy_base, public srsenb::phy_interface_stack_nr { public: - vnf_phy_nr(srslte::logger* logger_); + vnf_phy_nr() = default; ~vnf_phy_nr(); int init(const srsenb::phy_args_t& args, const nr_phy_cfg_t& cfg, srsenb::stack_interface_phy_nr* stack_); @@ -62,8 +62,6 @@ public: } private: - srslte::logger* logger = nullptr; - std::unique_ptr vnf = nullptr; bool initialized = false; diff --git a/srsenb/hdr/stack/enb_stack_base.h b/srsenb/hdr/stack/enb_stack_base.h index 0372d2fa9..7db3b69cf 100644 --- a/srsenb/hdr/stack/enb_stack_base.h +++ b/srsenb/hdr/stack/enb_stack_base.h @@ -23,6 +23,8 @@ #define SRSLTE_ENB_STACK_BASE_H #include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_mac_interfaces.h" +#include "srslte/interfaces/enb_s1ap_interfaces.h" #include "srsue/hdr/stack/upper/gw.h" #include diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 88cd64911..4fc8586f6 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -37,7 +37,7 @@ #include "enb_stack_base.h" #include "srslte/interfaces/enb_interfaces.h" -#include "srslte/interfaces/enb_rrc_interface_types.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -48,7 +48,7 @@ class enb_stack_lte final : public enb_stack_base, public srslte::thread { public: - enb_stack_lte(srslte::logger* logger_); + enb_stack_lte(srslte::logger* logger_, srslog::sink& log_sink); ~enb_stack_lte() final; // eNB stack base interface @@ -126,6 +126,14 @@ private: stack_args_t args = {}; rrc_cfg_t rrc_cfg = {}; + srslog::basic_logger& mac_logger; + srslog::basic_logger& rlc_logger; + srslog::basic_logger& pdcp_logger; + srslog::basic_logger& rrc_logger; + srslog::basic_logger& s1ap_logger; + srslog::basic_logger& gtpu_logger; + srslog::basic_logger& stack_logger; + // task handling srslte::task_scheduler task_sched; srslte::task_queue_handle enb_task_queue, gtpu_task_queue, mme_task_queue, sync_task_queue; @@ -142,8 +150,7 @@ private: srsenb::s1ap s1ap; srslte::s1ap_pcap s1ap_pcap; - srslte::logger* logger = nullptr; - srslte::byte_buffer_pool* pool = nullptr; + srslte::logger* logger = nullptr; // Radio and PHY log are in enb.cc srslte::log_ref mac_log{"MAC"}; diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index 8aeaaa484..d9e3ed5f9 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -66,8 +66,8 @@ public: bool get_metrics(srsenb::stack_metrics_t* metrics) final; // GW srsue stack_interface_gw dummy interface - bool is_registered(){return true;}; - bool start_service_request(){return true;}; + bool is_registered() { return true; }; + bool start_service_request() { return true; }; // PHY->MAC interface int sf_indication(const uint32_t tti); diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 64585bb18..b155e35fc 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -29,10 +29,11 @@ #include "srslte/common/task_scheduler.h" #include "srslte/common/threads.h" #include "srslte/common/tti_sync_cv.h" -#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_mac_interfaces.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/interfaces/enb_rrc_interface_types.h" #include "srslte/interfaces/sched_interface.h" +#include "srslte/srslog/srslog.h" #include "ta.h" #include "ue.h" #include @@ -42,7 +43,7 @@ namespace srsenb { class mac final : public mac_interface_phy_lte, public mac_interface_rlc, public mac_interface_rrc { public: - mac(srslte::ext_task_sched_handle task_sched_); + mac(srslte::ext_task_sched_handle task_sched_, srslog::basic_logger& logger); ~mac(); bool init(const mac_args_t& args_, const cell_list_t& cells_, @@ -115,6 +116,8 @@ private: std::mutex rnti_mutex; + srslog::basic_logger& logger; + // We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since // access for different TTIs pthread_rwlock_t rwlock = {}; @@ -154,7 +157,7 @@ private: uint32_t pdu_len, uint32_t tti); - const static int rar_payload_len = 128; + const static int rar_payload_len = 128; std::array rar_pdu_msg; srslte::byte_buffer_t rar_payload[SRSLTE_MAX_CARRIERS][sched_interface::MAX_RAR_LIST]; diff --git a/srsenb/hdr/stack/mac/mac_nr.h b/srsenb/hdr/stack/mac/mac_nr.h index 973e68965..e6a0e3858 100644 --- a/srsenb/hdr/stack/mac/mac_nr.h +++ b/srsenb/hdr/stack/mac/mac_nr.h @@ -24,8 +24,8 @@ #include "srslte/common/block_queue.h" #include "srslte/common/logmap.h" -#include "srslte/common/mac_nr_pcap.h" -#include "srslte/mac/mac_nr_pdu.h" +#include "srslte/common/mac_pcap.h" +#include "srslte/mac/mac_sch_pdu_nr.h" #include "srsenb/hdr/stack/enb_stack_base.h" #include "srslte/interfaces/enb_metrics_interface.h" @@ -90,10 +90,9 @@ private: rlc_interface_mac_nr* rlc_h = nullptr; rrc_interface_mac_nr* rrc_h = nullptr; - std::unique_ptr pcap = nullptr; - srslte::log_ref log_h; - srslte::byte_buffer_pool* pool = nullptr; - mac_nr_args_t args = {}; + std::unique_ptr pcap = nullptr; + srslte::log_ref log_h; + mac_nr_args_t args = {}; bool started = false; @@ -109,14 +108,14 @@ private: srslte::unique_byte_buffer_t bcch_bch_payload = nullptr; // UE-specific buffer - srslte::mac_nr_sch_pdu ue_tx_pdu; + srslte::mac_sch_pdu_nr ue_tx_pdu; std::vector ue_tx_buffer; srslte::block_queue ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) srslte::unique_byte_buffer_t ue_rlc_buffer; - srslte::mac_nr_sch_pdu ue_rx_pdu; + srslte::mac_sch_pdu_nr ue_rx_pdu; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index b38a93239..b28efe6f8 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -25,15 +25,16 @@ #include "sched_grid.h" #include "sched_ue.h" #include "srslte/common/log.h" -#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/sched_interface.h" +#include #include #include -#include #include namespace srsenb { +class rrc_interface_mac; + class sched : public sched_interface { public: @@ -46,9 +47,8 @@ public: sched(); ~sched() override; - void init(rrc_interface_mac* rrc); + void init(rrc_interface_mac* rrc, const sched_args_t& sched_cfg); int cell_cfg(const std::vector& cell_cfg) override; - void set_sched_cfg(sched_args_t* sched_cfg); int reset() final; int ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) final; @@ -94,15 +94,14 @@ protected: bool is_generated(srslte::tti_point, uint32_t enb_cc_idx) const; // Helper methods template - int ue_db_access(uint16_t rnti, Func, const char* func_name = nullptr); + int ue_db_access_locked(uint16_t rnti, Func&& f, const char* func_name = nullptr); // args - srslte::log_ref log_h; rrc_interface_mac* rrc = nullptr; sched_args_t sched_cfg = {}; std::vector sched_cell_params; - std::map ue_db; + std::map > ue_db; // independent schedulers for each carrier std::vector > carrier_schedulers; @@ -112,7 +111,7 @@ protected: srslte::tti_point last_tti; std::mutex sched_mutex; - bool configured = false; + std::atomic configured; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/sched_carrier.h b/srsenb/hdr/stack/mac/sched_carrier.h index f43ff2425..757a4059c 100644 --- a/srsenb/hdr/stack/mac/sched_carrier.h +++ b/srsenb/hdr/stack/mac/sched_carrier.h @@ -24,6 +24,7 @@ #include "sched.h" #include "schedulers/sched_base.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -33,10 +34,10 @@ class ra_sched; class sched::carrier_sched { public: - explicit carrier_sched(rrc_interface_mac* rrc_, - std::map* ue_db_, - uint32_t enb_cc_idx_, - sched_result_list* sched_results_); + explicit carrier_sched(rrc_interface_mac* rrc_, + std::map >* ue_db_, + uint32_t enb_cc_idx_, + sched_result_list* sched_results_); ~carrier_sched(); void reset(); void carrier_cfg(const sched_cell_params_t& sched_params_); @@ -58,11 +59,11 @@ private: sf_sched* get_sf_sched(srslte::tti_point tti_rx); // args - const sched_cell_params_t* cc_cfg = nullptr; - srslte::log_ref log_h; - rrc_interface_mac* rrc = nullptr; - std::map* ue_db = nullptr; - const uint32_t enb_cc_idx; + const sched_cell_params_t* cc_cfg = nullptr; + srslog::basic_logger& logger; + rrc_interface_mac* rrc = nullptr; + std::map >* ue_db = nullptr; + const uint32_t enb_cc_idx; // Subframe scheduling logic std::array sf_scheds; @@ -115,7 +116,7 @@ public: using dl_sched_rar_t = sched_interface::dl_sched_rar_t; using dl_sched_rar_grant_t = sched_interface::dl_sched_rar_grant_t; - explicit ra_sched(const sched_cell_params_t& cfg_, std::map& ue_db_); + explicit ra_sched(const sched_cell_params_t& cfg_, sched_ue_list& ue_db_); void dl_sched(sf_sched* tti_sched); void ul_sched(sf_sched* sf_dl_sched, sf_sched* sf_msg3_sched); int dl_rach_info(dl_sched_rar_info_t rar_info); @@ -123,9 +124,9 @@ public: private: // args - srslte::log_ref log_h; - const sched_cell_params_t* cc_cfg = nullptr; - std::map* ue_db = nullptr; + srslog::basic_logger& logger; + const sched_cell_params_t* cc_cfg = nullptr; + sched_ue_list* ue_db = nullptr; std::deque pending_rars; uint32_t rar_aggr_level = 2; diff --git a/srsenb/hdr/stack/mac/sched_common.h b/srsenb/hdr/stack/mac/sched_common.h index edee30b8d..b58a0cdb1 100644 --- a/srsenb/hdr/stack/mac/sched_common.h +++ b/srsenb/hdr/stack/mac/sched_common.h @@ -32,17 +32,24 @@ namespace srsenb { * Constants **********************/ -constexpr float tti_duration_ms = 1; +constexpr float tti_duration_ms = 1; +constexpr uint32_t NOF_AGGR_LEVEL = 4; /*********************** * Helper Types **********************/ -//! Struct used to store possible CCE locations. -struct sched_dci_cce_t { - uint32_t cce_start[4][6]; ///< Stores starting CCE for each aggr level index and CCE location index - uint32_t nof_loc[4]; ///< Number of possible CCE locations for each aggregation level index -}; +/// List of CCE start positions in PDCCH +using cce_position_list = srslte::bounded_vector; + +/// Map {L} -> list of CCE positions +using cce_cfi_position_table = std::array; + +/// Map {cfi, L} -> list of CCE positions +using cce_sf_position_table = std::array, SRSLTE_NOF_CFI>; + +/// Map {sf, cfi, L} -> list of CCE positions +using cce_frame_position_table = std::array; /// structs to bundle together all the sched arguments, and share them with all the sched sub-components class sched_cell_params_t @@ -61,15 +68,15 @@ public: uint32_t get_dl_lb_nof_re(tti_point tti_tx_dl, uint32_t nof_prbs_alloc) const; uint32_t get_dl_nof_res(srslte::tti_point tti_tx_dl, const srslte_dci_dl_t& dci, uint32_t cfi) const; - uint32_t enb_cc_idx = 0; - sched_interface::cell_cfg_t cfg = {}; - const sched_interface::sched_args_t* sched_cfg = nullptr; - std::unique_ptr regs; - std::array common_locations = {}; - std::array, 3> rar_locations = {}; - std::array nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH - uint32_t P = 0; - uint32_t nof_rbgs = 0; + uint32_t enb_cc_idx = 0; + sched_interface::cell_cfg_t cfg = {}; + const sched_interface::sched_args_t* sched_cfg = nullptr; + std::unique_ptr regs; + cce_sf_position_table common_locations = {}; + cce_frame_position_table rar_locations = {}; + std::array nof_cce_table = {}; ///< map cfix -> nof cces in PDCCH + uint32_t P = 0; + uint32_t nof_rbgs = 0; using dl_nof_re_table = srslte::bounded_vector< std::array, SRSLTE_NOF_SLOTS_PER_SF>, SRSLTE_NOF_SF_X_FRAME>, @@ -82,8 +89,6 @@ public: dl_lb_nof_re_table nof_re_lb_table; }; -using ue_cce_locations_table = std::array, SRSLTE_NOF_CFI>; - //! Bitmask used for CCE allocations using pdcch_mask_t = srslte::bounded_bitset; @@ -100,14 +105,16 @@ struct rbg_interval : public srslte::interval { static rbg_interval rbgmask_to_rbgs(const rbgmask_t& mask); }; -//! Struct to express a {min,...,max} range of PRBs +/// Struct to express a {min,...,max} range of PRBs struct prb_interval : public srslte::interval { using interval::interval; - static prb_interval rbgs_to_prbs(const rbg_interval& rbgs, uint32_t cell_nof_prb); static prb_interval riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs = -1); }; +/// Type of Allocation stored in PDSCH/PUSCH +enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA }; + } // namespace srsenb #endif // SRSLTE_SCHED_COMMON_H diff --git a/srsenb/hdr/stack/mac/sched_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index 1e188b8c5..095197f9f 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -23,18 +23,17 @@ #define SRSLTE_SCHED_GRID_H #include "lib/include/srslte/interfaces/sched_interface.h" +#include "sched_phy_ch/sf_cch_allocator.h" #include "sched_ue.h" #include "srslte/adt/bounded_bitset.h" #include "srslte/common/log.h" +#include "srslte/srslog/srslog.h" #include #include namespace srsenb { -//! Type of Allocation -enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA }; - -//! Result of alloc attempt +/// Error code of alloc attempt struct alloc_outcome_t { enum result_enum { SUCCESS, @@ -44,7 +43,10 @@ struct alloc_outcome_t { NOF_RB_INVALID, PUCCH_COLLISION, MEASGAP_COLLISION, - ALREADY_ALLOC + ALREADY_ALLOC, + NO_DATA, + INVALID_PRBMASK, + INVALID_CARRIER }; result_enum result = ERROR; alloc_outcome_t() = default; @@ -95,77 +97,7 @@ private: std::array results; }; -//! Class responsible for managing a PDCCH CCE grid, namely cce allocs, and avoid collisions. -class pdcch_grid_t -{ -public: - const static uint32_t MAX_CFI = 3; - struct alloc_t { - uint16_t rnti = 0; - srslte_dci_location_t dci_pos = {0, 0}; - pdcch_mask_t current_mask; ///< this PDCCH alloc mask - pdcch_mask_t total_mask; ///< Accumulation of all PDCCH masks for the current solution (tree route) - }; - using alloc_result_t = std::vector; - - void init(const sched_cell_params_t& cell_params_); - void new_tti(tti_point tti_rx_); - bool alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user = nullptr); - bool set_cfi(uint32_t cfi); - - // getters - uint32_t get_cfi() const { return current_cfix + 1; } - void get_allocs(alloc_result_t* vec = nullptr, pdcch_mask_t* tot_mask = nullptr, size_t idx = 0) const; - uint32_t nof_cces() const { return cc_cfg->nof_cce_table[current_cfix]; } - size_t nof_allocs() const { return dci_record_list.size(); } - size_t nof_alloc_combinations() const { return get_alloc_tree().nof_leaves(); } - std::string result_to_string(bool verbose = false) const; - -private: - struct alloc_tree_t { - struct node_t { - int parent_idx; - alloc_t node; - node_t(int i, const alloc_t& a) : parent_idx(i), node(a) {} - }; - // state - size_t nof_cces; - std::vector dci_alloc_tree; - size_t prev_start = 0, prev_end = 0; - - explicit alloc_tree_t(size_t nof_cces_) : nof_cces(nof_cces_) {} - size_t nof_leaves() const { return prev_end - prev_start; } - void reset(); - }; - struct alloc_record_t { - sched_ue* user; - uint32_t aggr_idx; - alloc_type_t alloc_type; - }; - - const alloc_tree_t& get_alloc_tree() const { return alloc_trees[current_cfix]; } - const sched_dci_cce_t* get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const; - - // PDCCH allocation algorithm - bool alloc_dci_record(const alloc_record_t& record, uint32_t cfix); - static bool add_tree_node_leaves(alloc_tree_t& tree, - int node_idx, - const alloc_record_t& dci_record, - const sched_dci_cce_t& dci_locs, - tti_point tti_tx_dl); - - // consts - const sched_cell_params_t* cc_cfg = nullptr; - srslte::log_ref log_h; - - // tti vars - tti_point tti_rx; - uint32_t current_cfix = 0; - std::vector alloc_trees; ///< List of PDCCH alloc trees, where index is the cfi index - std::vector dci_record_list; ///< Keeps a record of all the PDCCH allocations done so far -}; - -//! manages a subframe grid resources, namely CCE and DL/UL RB allocations +/// manages a subframe grid resources, namely CCE and DL/UL RB allocations class sf_grid_t { public: @@ -174,6 +106,8 @@ public: rbg_interval rbg_range; }; + sf_grid_t() : logger(srslog::fetch_basic_logger("MAC")) {} + void init(const sched_cell_params_t& cell_params_); void new_tti(tti_point tti_rx); dl_ctrl_alloc_t alloc_dl_ctrl(uint32_t aggr_lvl, alloc_type_t alloc_type); @@ -184,22 +118,22 @@ public: bool find_ul_alloc(uint32_t L, prb_interval* alloc) const; // getters - const rbgmask_t& get_dl_mask() const { return dl_mask; } - const prbmask_t& get_ul_mask() const { return ul_mask; } - uint32_t get_cfi() const { return pdcch_alloc.get_cfi(); } - const pdcch_grid_t& get_pdcch_grid() const { return pdcch_alloc; } + const rbgmask_t& get_dl_mask() const { return dl_mask; } + const prbmask_t& get_ul_mask() const { return ul_mask; } + uint32_t get_cfi() const { return pdcch_alloc.get_cfi(); } + const sf_cch_allocator& get_pdcch_grid() const { return pdcch_alloc; } private: alloc_outcome_t alloc_dl(uint32_t aggr_lvl, alloc_type_t alloc_type, rbgmask_t alloc_mask, sched_ue* user = nullptr); // consts const sched_cell_params_t* cc_cfg = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger; uint32_t nof_rbgs = 0; uint32_t si_n_rbg = 0, rar_n_rbg = 0; // derived - pdcch_grid_t pdcch_alloc = {}; + sf_cch_allocator pdcch_alloc = {}; // internal state tti_point tti_rx; @@ -303,18 +237,20 @@ public: private: ctrl_code_t alloc_dl_ctrl(uint32_t aggr_lvl, uint32_t tbs_bytes, uint16_t rnti); int generate_format1a(prb_interval prb_range, uint32_t tbs, uint32_t rv, uint16_t rnti, srslte_dci_dl_t* dci); - void set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, sched_interface::dl_sched_res_t* dl_result); - void set_rar_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, sched_interface::dl_sched_res_t* dl_result); - void set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, - sched_interface::dl_sched_res_t* dl_result, - sched_ue_list& ue_list); - void set_ul_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, - sched_interface::ul_sched_res_t* ul_result, - sched_ue_list& ue_list); + void set_bc_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::dl_sched_res_t* dl_result); + void set_rar_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::dl_sched_res_t* dl_result); + void set_dl_data_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::dl_sched_res_t* dl_result, + sched_ue_list& ue_list); + void set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::ul_sched_res_t* ul_result, + sched_ue_list& ue_list); // consts const sched_cell_params_t* cc_cfg = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger; sf_sched_result* cc_results; ///< Results of other CCs for the same Subframe prbmask_t pucch_mask; diff --git a/srsenb/hdr/stack/mac/sched_helpers.h b/srsenb/hdr/stack/mac/sched_helpers.h index 448ff5838..c8b78df0a 100644 --- a/srsenb/hdr/stack/mac/sched_helpers.h +++ b/srsenb/hdr/stack/mac/sched_helpers.h @@ -25,6 +25,7 @@ #include "srsenb/hdr/stack/mac/sched_common.h" #include "srslte/common/logmap.h" #include "srslte/interfaces/sched_interface.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -115,7 +116,7 @@ inline uint32_t count_prb_per_tb_approx(uint32_t nof_rbgs, uint32_t cell_nof_prb return std::min(nof_rbgs * P, cell_nof_prb); } -ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg); +cce_frame_position_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg); /** * Generate possible CCE locations a user can use to allocate DCIs @@ -125,11 +126,11 @@ ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_ce * @param sf_idx subframe index specific to the tx TTI (relevant only for data and RAR transmissions) * @param rnti identity of the user (invalid RNTI for RAR and BC transmissions) */ -void generate_cce_location(srslte_regs_t* regs, - sched_dci_cce_t* location, - uint32_t cfi, - uint32_t sf_idx = 0, - uint16_t rnti = SRSLTE_INVALID_RNTI); +void generate_cce_location(srslte_regs_t* regs, + cce_cfi_position_table& locations, + uint32_t cfi, + uint32_t sf_idx = 0, + uint16_t rnti = SRSLTE_INVALID_RNTI); /// Obtains TB size *in bytes* for a given MCS and nof allocated prbs inline uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool use_tbs_index_alt, bool is_ul) @@ -150,6 +151,12 @@ uint32_t get_aggr_level(uint32_t nof_bits, uint32_t cell_nof_prb, bool use_tbs_index_alt); +/******************************************************* + * RB mask helper functions + *******************************************************/ + +bool is_contiguous(const rbgmask_t& mask); + /******************************************************* * sched_interface helper functions *******************************************************/ @@ -163,10 +170,14 @@ inline bool operator==(const sched_interface::ue_cfg_t::cc_cfg_t& lhs, const sch int check_ue_cfg_correctness(const sched_interface::ue_cfg_t& ue_cfg); /// Logs DL MAC PDU contents -void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result); +void log_dl_cc_results(srslog::basic_logger& logger, + uint32_t enb_cc_idx, + const sched_interface::dl_sched_res_t& result); /// Logs PHICH contents -void log_phich_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::ul_sched_res_t& result); +void log_phich_cc_results(srslog::basic_logger& logger, + uint32_t enb_cc_idx, + const sched_interface::ul_sched_res_t& result); const char* to_string(sched_interface::ue_bearer_cfg_t::direction_t dir); diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h b/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h new file mode 100644 index 000000000..e9310d62a --- /dev/null +++ b/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h @@ -0,0 +1,96 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "../sched_common.h" + +#ifndef SRSLTE_PDCCH_SCHED_H +#define SRSLTE_PDCCH_SCHED_H + +namespace srsenb { + +class sched_ue; + +/// Class responsible for managing a PDCCH CCE grid, namely CCE allocs, and avoid collisions. +class sf_cch_allocator +{ +public: + const static uint32_t MAX_CFI = 3; + struct alloc_t { + uint16_t rnti = 0; + srslte_dci_location_t dci_pos = {0, 0}; + pdcch_mask_t current_mask; ///< this PDCCH alloc mask + pdcch_mask_t total_mask; ///< Accumulation of all PDCCH masks for the current solution (tree route) + }; + using alloc_result_t = std::vector; + + sf_cch_allocator() : logger(srslog::fetch_basic_logger("MAC")) {} + + void init(const sched_cell_params_t& cell_params_); + void new_tti(tti_point tti_rx_); + bool alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user = nullptr); + bool set_cfi(uint32_t cfi); + + // getters + uint32_t get_cfi() const { return current_cfix + 1; } + void get_allocs(alloc_result_t* vec = nullptr, pdcch_mask_t* tot_mask = nullptr, size_t idx = 0) const; + uint32_t nof_cces() const { return cc_cfg->nof_cce_table[current_cfix]; } + size_t nof_allocs() const { return dci_record_list.size(); } + size_t nof_alloc_combinations() const { return get_alloc_tree().nof_leaves(); } + std::string result_to_string(bool verbose = false) const; + +private: + struct alloc_tree_t { + struct node_t { + int parent_idx; + alloc_t node; + node_t(int i, const alloc_t& a) : parent_idx(i), node(a) {} + }; + // state + size_t nof_cces; + std::vector dci_alloc_tree; + size_t prev_start = 0, prev_end = 0; + + explicit alloc_tree_t(size_t nof_cces_) : nof_cces(nof_cces_) {} + size_t nof_leaves() const { return prev_end - prev_start; } + void reset(); + }; + struct alloc_record_t { + sched_ue* user; + uint32_t aggr_idx; + alloc_type_t alloc_type; + }; + + const alloc_tree_t& get_alloc_tree() const { return alloc_trees[current_cfix]; } + const cce_cfi_position_table* get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const; + + // PDCCH allocation algorithm + bool alloc_dci_record(const alloc_record_t& record, uint32_t cfix); + static bool add_tree_node_leaves(alloc_tree_t& tree, + int node_idx, + const alloc_record_t& dci_record, + const cce_cfi_position_table& dci_locs, + tti_point tti_tx_dl); + + // consts + const sched_cell_params_t* cc_cfg = nullptr; + srslog::basic_logger& logger; + + // tti vars + tti_point tti_rx; + uint32_t current_cfix = 0; + std::vector alloc_trees; ///< List of PDCCH alloc trees, where index is the cfi index + std::vector dci_record_list; ///< Keeps a record of all the PDCCH allocations done so far +}; + +} // namespace srsenb + +#endif // SRSLTE_PDCCH_SCHED_H diff --git a/srsenb/hdr/stack/mac/sched_ue.h b/srsenb/hdr/stack/mac/sched_ue.h index 1de701f08..a97c196d5 100644 --- a/srsenb/hdr/stack/mac/sched_ue.h +++ b/srsenb/hdr/stack/mac/sched_ue.h @@ -24,6 +24,7 @@ #include "sched_common.h" #include "srslte/common/log.h" +#include "srslte/srslog/srslog.h" #include #include @@ -46,8 +47,7 @@ class sched_ue using bearer_cfg_t = sched_interface::ue_bearer_cfg_t; public: - sched_ue(); - void init(uint16_t rnti, const std::vector& cell_list_params_); + sched_ue(uint16_t rnti, const std::vector& cell_list_params_, const ue_cfg_t& cfg); void new_subframe(tti_point tti_rx, uint32_t enb_cc_idx); /************************************************************* @@ -134,8 +134,8 @@ public: int explicit_mcs = -1, uci_pusch_t uci_type = UCI_PUSCH_NONE); - srslte_dci_format_t get_dci_format(); - const sched_dci_cce_t* get_locations(uint32_t enb_cc_idx, uint32_t current_cfi, uint32_t sf_idx) const; + srslte_dci_format_t get_dci_format(); + const cce_cfi_position_table* get_locations(uint32_t enb_cc_idx, uint32_t current_cfi, uint32_t sf_idx) const; sched_ue_cell* find_ue_carrier(uint32_t enb_cc_idx); size_t nof_carriers_configured() const { return cfg.supported_cc_list.size(); } @@ -173,6 +173,12 @@ private: uint32_t enb_cc_idx, uint32_t cfi, const rbgmask_t& user_mask); + int generate_format1a(uint32_t pid, + sched_interface::dl_sched_data_t* data, + tti_point tti_tx_dl, + uint32_t enb_cc_idx, + uint32_t cfi, + const rbgmask_t& user_mask); int generate_format2a(uint32_t pid, sched_interface::dl_sched_data_t* data, tti_point tti_tx_dl, @@ -189,7 +195,7 @@ private: /* Args */ ue_cfg_t cfg = {}; srslte_cell_t cell = {}; - mutable srslte::log_ref log_h; + srslog::basic_logger& logger; const sched_cell_params_t* main_cc_params = nullptr; /* Buffer states */ @@ -206,7 +212,7 @@ private: std::vector cells; ///< List of eNB cells that may be configured/activated/deactivated for the UE }; -using sched_ue_list = std::map; +using sched_ue_list = std::map >; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h index 28c48b967..5a27f8c37 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h @@ -26,6 +26,7 @@ #include "srslte/common/log.h" #include "srslte/common/tti_point.h" #include "srslte/interfaces/sched_interface.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -63,8 +64,6 @@ protected: srslte::tti_point tti; int last_mcs[SRSLTE_MAX_TB]; int last_tbs[SRSLTE_MAX_TB]; - - srslte::log_ref log_h; }; class dl_harq_proc : public harq_proc @@ -79,7 +78,7 @@ public: uint32_t n_cce_, uint32_t max_retx); void new_retx(const rbgmask_t& new_mask, uint32_t tb_idx, tti_point tti_tx_dl, int* mcs, int* tbs, uint32_t n_cce_); - int set_ack(uint32_t tb_idx, bool ack); + int set_ack(uint32_t tb_idx, bool ack); rbgmask_t get_rbgmask() const; bool has_pending_retx(uint32_t tb_idx, tti_point tti_tx_dl) const; bool has_pending_retx(tti_point tti_tx_dl) const; @@ -120,6 +119,7 @@ public: static const bool is_async = ASYNC_DL_SCHED; harq_entity(size_t nof_dl_harqs, size_t nof_ul_harqs); + void reset(); void new_tti(tti_point tti_rx); @@ -165,7 +165,6 @@ public: private: dl_harq_proc* get_oldest_dl_harq(tti_point tti_tx_dl); - srslte::log_ref log_h; std::array last_ttis; std::vector dl_harqs; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h index 9568dc567..4885b034a 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -25,6 +25,7 @@ #include "srslte/common/logmap.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/mac/pdu.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -34,6 +35,7 @@ class lch_ue_manager constexpr static uint32_t MAX_LC = sched_interface::MAX_LC; public: + lch_ue_manager() : logger(srslog::fetch_basic_logger("MAC")) {} void set_cfg(const sched_interface::ue_cfg_t& cfg_); void new_tti(); @@ -81,7 +83,7 @@ private: int alloc_tx_bytes(uint8_t lcid, int rem_bytes); size_t prio_idx = 0; - srslte::log_ref log_h{"MAC"}; + srslog::basic_logger& logger; std::array lch = {}; std::array lcg_bsr = {}; }; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index 9273f2e8c..35d849464 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h @@ -61,7 +61,7 @@ struct sched_ue_cell { const sched_cell_params_t* cell_cfg = nullptr; /// Allowed DCI locations per per CFI and per subframe - const ue_cce_locations_table dci_locations; + const cce_frame_position_table dci_locations; /// Cell HARQ Entity harq_entity harq_ent; @@ -87,7 +87,7 @@ struct sched_ue_cell { private: void enter_idle_st(); - srslte::log_ref log_h{"MAC"}; + srslog::basic_logger& logger; const sched_interface::ue_cfg_t* ue_cfg = nullptr; tti_point cfg_tti; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h index f85c17920..14504eb20 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h @@ -25,6 +25,7 @@ #include "srslte/adt/accumulators.h" #include "srslte/common/common.h" #include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -133,7 +134,7 @@ private: case 3: return 3; default: - srslte::logmap::get("MAC")->warning("Invalid TPC delta value=%d\n", delta); + srslog::fetch_basic_logger("MAC").warning("Invalid TPC delta value=%d", delta); return 1; } } diff --git a/srsenb/hdr/stack/mac/schedulers/sched_base.h b/srsenb/hdr/stack/mac/schedulers/sched_base.h index acd81725d..c7212dc51 100644 --- a/srsenb/hdr/stack/mac/schedulers/sched_base.h +++ b/srsenb/hdr/stack/mac/schedulers/sched_base.h @@ -34,22 +34,23 @@ class sched_base public: virtual ~sched_base() = default; - virtual void sched_dl_users(std::map& ue_db, sf_sched* tti_sched) = 0; - virtual void sched_ul_users(std::map& ue_db, sf_sched* tti_sched) = 0; + virtual void sched_dl_users(sched_ue_list& ue_db, sf_sched* tti_sched) = 0; + virtual void sched_ul_users(sched_ue_list& ue_db, sf_sched* tti_sched) = 0; protected: - srslte::log_ref log_h = srslte::logmap::get("MAC"); + srslog::basic_logger& logger = srslog::fetch_basic_logger("MAC"); }; /**************** Helper methods ****************/ /** - * Finds a bitmask of available RBG resources - * @param L Size of the requested DL RBGs - * @param current_mask input RBG bitmask where to search for available RBGs - * @return bitmask of found RBGs + * Finds a bitmask of available RBG resources for a given UE in a greedy fashion + * @param ue UE being allocated + * @param enb_cc_idx carrier index + * @param current_mask bitmask of occupied RBGs, where to search for available RBGs + * @return bitmask of found RBGs. If a valid mask wasn't found, bitmask::size() == 0 */ -rbgmask_t find_available_dl_rbgs(uint32_t L, const rbgmask_t& current_mask); +rbgmask_t compute_user_rbgmask_greedy(sched_ue& ue, uint32_t enb_cc_idx, const rbgmask_t& current_mask); /** * Finds a range of L contiguous PRBs that are empty @@ -66,6 +67,8 @@ const ul_harq_proc* get_ul_newtx_harq(sched_ue& user, sf_sched* tti_sched); /// Helper methods to allocate resources in subframe alloc_outcome_t try_dl_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const dl_harq_proc& h); +alloc_outcome_t + try_dl_newtx_alloc_greedy(sf_sched& tti_sched, sched_ue& ue, const dl_harq_proc& h, rbgmask_t* result_mask = nullptr); alloc_outcome_t try_ul_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const ul_harq_proc& h); } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h b/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h index 039e86160..3f40e49fa 100644 --- a/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h +++ b/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h @@ -29,15 +29,15 @@ namespace srsenb { class sched_time_pf final : public sched_base { - using ue_cit_t = std::map::const_iterator; + using ue_cit_t = sched_ue_list::const_iterator; public: sched_time_pf(const sched_cell_params_t& cell_params_, const sched_interface::sched_args_t& sched_args); - void sched_dl_users(std::map& ue_db, sf_sched* tti_sched) override; - void sched_ul_users(std::map& ue_db, sf_sched* tti_sched) override; + void sched_dl_users(sched_ue_list& ue_db, sf_sched* tti_sched) override; + void sched_ul_users(sched_ue_list& ue_db, sf_sched* tti_sched) override; private: - void new_tti(std::map& ue_db, sf_sched* tti_sched); + void new_tti(sched_ue_list& ue_db, sf_sched* tti_sched); const sched_cell_params_t* cc_cfg = nullptr; float fairness_coeff = 1; diff --git a/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h b/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h index d26f865d6..b89a70095 100644 --- a/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h +++ b/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h @@ -32,14 +32,14 @@ class sched_time_rr final : public sched_base public: sched_time_rr(const sched_cell_params_t& cell_params_, const sched_interface::sched_args_t& sched_args); - void sched_dl_users(std::map& ue_db, sf_sched* tti_sched) override; - void sched_ul_users(std::map& ue_db, sf_sched* tti_sched) override; + void sched_dl_users(sched_ue_list& ue_db, sf_sched* tti_sched) override; + void sched_ul_users(sched_ue_list& ue_db, sf_sched* tti_sched) override; private: - void sched_dl_retxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx); - void sched_dl_newtxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx); - void sched_ul_retxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx); - void sched_ul_newtxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx); + void sched_dl_retxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx); + void sched_dl_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx); + void sched_ul_retxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx); + void sched_ul_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx); const sched_cell_params_t* cc_cfg = nullptr; }; diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 4ecbb3502..f5be2f378 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -23,20 +23,24 @@ #define SRSENB_UE_H #include "mac_metrics.h" -#include "srslte/common/block_queue.h" #include "srslte/adt/circular_array.h" +#include "srslte/common/block_queue.h" #include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" -#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/mac/pdu.h" #include "srslte/mac/pdu_queue.h" +#include "srslte/srslog/srslog.h" #include "ta.h" #include #include namespace srsenb { +class rrc_interface_mac; +class rlc_interface_mac; +class phy_interface_stack_lte; + class ue : public srslte::read_pdu_interface, public srslte::pdu_queue::process_callback, public mac_ta_ue_interface { public: @@ -47,6 +51,7 @@ public: rlc_interface_mac* rlc, phy_interface_stack_lte* phy_, srslte::log_ref log_, + srslog::basic_logger& logger, uint32_t nof_cells_, uint32_t nof_rx_harq_proc = SRSLTE_FDD_NOF_HARQ, uint32_t nof_tx_harq_proc = SRSLTE_FDD_NOF_HARQ * SRSLTE_MAX_TB); @@ -148,6 +153,7 @@ private: rrc_interface_mac* rrc = nullptr; phy_interface_stack_lte* phy = nullptr; srslte::log_ref log_h; + srslog::basic_logger& logger; sched_interface* sched = nullptr; // Mutexes diff --git a/srsenb/hdr/stack/rrc/mac_controller.h b/srsenb/hdr/stack/rrc/mac_controller.h index a031830d3..6e8104bc6 100644 --- a/srsenb/hdr/stack/rrc/mac_controller.h +++ b/srsenb/hdr/stack/rrc/mac_controller.h @@ -24,11 +24,14 @@ #include "rrc_bearer_cfg.h" #include "rrc_cell_cfg.h" +#include "srslte/interfaces/rrc_interface_types.h" #include "srslte/interfaces/sched_interface.h" #include namespace srsenb { +class mac_interface_rrc; + class mac_controller { using ue_cfg_t = sched_interface::ue_cfg_t; @@ -73,7 +76,7 @@ private: int apply_basic_conn_cfg(const asn1::rrc::rr_cfg_ded_s& rr_cfg); void apply_current_bearers_cfg(); - srslte::log_ref log_h; + srslog::basic_logger& logger; uint16_t rnti; const ue_cell_ded_list& ue_cell_list; const bearer_cfg_handler& bearer_list; diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 219940609..ea8f92adc 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -34,12 +34,19 @@ #include "srslte/common/stack_procedure.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/timeout.h" -#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include namespace srsenb { +class s1ap_interface_rrc; +class pdcp_interface_rrc; +class rlc_interface_rrc; +class mac_interface_rrc; +class phy_interface_rrc_lte; + static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", "WAIT FOR CON SETUP COMPLETE", "WAIT FOR SECURITY MODE COMPLETE", @@ -54,7 +61,7 @@ class rrc final : public rrc_interface_pdcp, public rrc_interface_s1ap { public: - rrc(srslte::task_sched_handle task_sched_); + explicit rrc(srslte::task_sched_handle task_sched_); ~rrc(); void init(const rrc_cfg_t& cfg_, @@ -100,7 +107,10 @@ public: std::vector* erabs_released, std::vector* erabs_failed_to_release) override; void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& UEPagingID) override; - void ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique_byte_buffer_t rrc_container) override; + void ho_preparation_complete(uint16_t rnti, + bool is_success, + const asn1::s1ap::ho_cmd_s& msg, + srslte::unique_byte_buffer_t rrc_container) override; uint16_t start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg, const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container) override; @@ -130,14 +140,14 @@ public: const std::string& msg_type) { static const char* dir_str[] = {"Rx", "Tx", "S1AP Tx", "S1AP Rx"}; - if (rrc_log->get_level() == srslte::LOG_LEVEL_INFO) { - rrc_log->info("%s - %s %s (%zd B)\n", source.c_str(), dir_str[dir], msg_type.c_str(), pdu.size()); - } else if (rrc_log->get_level() >= srslte::LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { asn1::json_writer json_writer; msg.to_json(json_writer); - rrc_log->debug_hex( - pdu.data(), pdu.size(), "%s - %s %s (%zd B)\n", source.c_str(), dir_str[dir], msg_type.c_str(), pdu.size()); - rrc_log->debug_long("Content:\n%s\n", json_writer.to_string().c_str()); + logger.debug( + pdu.data(), pdu.size(), "%s - %s %s (%zd B)", source.c_str(), dir_str[dir], msg_type.c_str(), pdu.size()); + logger.debug("Content:\n%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info("%s - %s %s (%zd B)", source.c_str(), dir_str[dir], msg_type.c_str(), pdu.size()); } } @@ -145,14 +155,13 @@ private: class ue; // args srslte::task_sched_handle task_sched; - srslte::byte_buffer_pool* pool = nullptr; phy_interface_rrc_lte* phy = nullptr; mac_interface_rrc* mac = nullptr; rlc_interface_rrc* rlc = nullptr; pdcp_interface_rrc* pdcp = nullptr; gtpu_interface_rrc* gtpu = nullptr; s1ap_interface_rrc* s1ap = nullptr; - srslte::log_ref rrc_log; + srslog::basic_logger& logger; // derived params std::unique_ptr cell_common_list; diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index 355145ee5..1099bea1f 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -25,15 +25,27 @@ #include "srsenb/hdr/stack/rrc/rrc_config.h" #include "srslte/asn1/s1ap.h" #include "srslte/common/logmap.h" +#include "srslte/interfaces/enb_gtpu_interfaces.h" #include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_rrc_interface_types.h" +#include "srslte/srslog/srslog.h" namespace srsenb { class security_cfg_handler { public: - explicit security_cfg_handler(const rrc_cfg_t& cfg_) : cfg(&cfg_) {} + explicit security_cfg_handler(const rrc_cfg_t& cfg_) : cfg(&cfg_), logger(srslog::fetch_basic_logger("RRC")) {} + security_cfg_handler& operator=(const security_cfg_handler& other) + { + cfg = other.cfg; + k_enb_present = other.k_enb_present; + security_capabilities = other.security_capabilities; + std::copy(other.k_enb, other.k_enb + 32, k_enb); + sec_cfg = other.sec_cfg; + ncc = other.ncc; + return *this; + } bool set_security_capabilities(const asn1::s1ap::ue_security_cap_s& caps); void set_security_key(const asn1::fixed_bitstring<256, false, true>& key); @@ -49,7 +61,7 @@ public: private: void generate_as_keys(); - srslte::log_ref log_h{"RRC"}; + srslog::basic_logger& logger; const rrc_cfg_t* cfg = nullptr; bool k_enb_present = false; asn1::s1ap::ue_security_cap_s security_capabilities = {}; @@ -62,14 +74,20 @@ class bearer_cfg_handler { public: struct erab_t { + struct gtpu_tunnel { + uint32_t teid_out = 0; + uint32_t teid_in = 0; + uint32_t addr = 0; + }; uint8_t id = 0; asn1::s1ap::erab_level_qos_params_s qos_params; asn1::bounded_bitstring<1, 160, true, true> address; uint32_t teid_out = 0; uint32_t teid_in = 0; + std::vector tunnels; }; - bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_); + bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_); int add_erab(uint8_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos, @@ -83,8 +101,13 @@ public: const asn1::unbounded_octstring* nas_pdu); // Methods to apply bearer updates - void add_gtpu_bearer(gtpu_interface_rrc* gtpu, uint32_t erab_id); - void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg); + void add_gtpu_bearer(uint32_t erab_id); + uint32_t add_gtpu_bearer(uint32_t erab_id, + uint32_t teid_out, + uint32_t addr, + const gtpu_interface_rrc::bearer_props* props = nullptr); + void rem_gtpu_bearer(uint32_t erab_id); + void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg); const std::map& get_erabs() const { return erabs; } const asn1::rrc::drb_to_add_mod_list_l& get_established_drbs() const { return current_drbs; } @@ -93,9 +116,10 @@ public: std::map erabs; private: - srslte::log_ref log_h{"RRC"}; - uint16_t rnti = 0; - const rrc_cfg_t* cfg = nullptr; + srslog::basic_logger& logger; + uint16_t rnti = 0; + const rrc_cfg_t* cfg = nullptr; + gtpu_interface_rrc* gtpu = nullptr; // last cfg asn1::rrc::drb_to_add_mod_list_l current_drbs; diff --git a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h index ec0dd39f1..6f857cbfc 100644 --- a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h @@ -24,6 +24,7 @@ #include "rrc_config.h" #include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" namespace srsenb { @@ -178,7 +179,7 @@ private: bool alloc_pucch_cs_resources(); bool dealloc_pucch_cs_resources(); - srslte::log_ref log_h{"RRC"}; + srslog::basic_logger& logger; const rrc_cfg_t& cfg; const enb_cell_common_list& common_list; freq_res_common_list& cell_res_list; diff --git a/srsenb/hdr/stack/rrc/rrc_config.h b/srsenb/hdr/stack/rrc/rrc_config.h index 8230cf77b..1884464c8 100644 --- a/srsenb/hdr/stack/rrc/rrc_config.h +++ b/srsenb/hdr/stack/rrc/rrc_config.h @@ -39,14 +39,12 @@ struct rrc_cfg_sr_t { uint32_t nof_subframes; }; -typedef struct { +struct rrc_cfg_qci_t { bool configured = false; asn1::rrc::lc_ch_cfg_s::ul_specific_params_s_ lc_cfg; asn1::rrc::pdcp_cfg_s pdcp_cfg; asn1::rrc::rlc_cfg_c rlc_cfg; -} rrc_cfg_qci_t; - -#define MAX_NOF_QCI 10 +}; struct rrc_cfg_t { uint32_t enb_id; ///< Required to pack SIB1 @@ -60,7 +58,7 @@ struct rrc_cfg_t { asn1::rrc::pdsch_cfg_ded_s::p_a_e_ pdsch_cfg; rrc_cfg_sr_t sr_cfg; rrc_cfg_cqi_t cqi_cfg; - rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI]; + std::map qci_cfg; bool enable_mbsfn; uint16_t mbms_mcs; uint32_t inactivity_timeout_ms; diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 203e496d4..62670671f 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -42,11 +42,13 @@ public: }; struct ho_cancel_ev {}; - explicit rrc_mobility(srsenb::rrc::ue* outer_ue); + rrc_mobility(srsenb::rrc::ue* outer_ue); bool fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg); - void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg); - void handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container); + void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg, srslte::unique_byte_buffer_t pdu); + void handle_ho_preparation_complete(bool is_success, + const asn1::s1ap::ho_cmd_s& msg, + srslte::unique_byte_buffer_t container); bool is_ho_running() const { return not is_in_state(); } // S1-Handover @@ -59,25 +61,23 @@ public: private: // helper methods - bool update_ue_var_meas_cfg(uint32_t src_earfcn, + bool update_ue_var_meas_cfg(uint32_t src_earfcn, const enb_cell_common& target_pcell, - asn1::rrc::meas_cfg_s* diff_meas_cfg); + asn1::rrc::meas_cfg_s* diff_meas_cfg); // Handover from source cell bool start_ho_preparation(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available); - bool start_enb_status_transfer(); // Handover to target cell void fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s& msg, - const enb_cell_common& target_cell, + const enb_cell_common& target_cell, uint32_t src_dl_earfcn, uint32_t src_pci); bool apply_ho_prep_cfg(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep, const asn1::s1ap::ho_request_s& ho_req_msg); - rrc::ue* rrc_ue = nullptr; - rrc* rrc_enb = nullptr; - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref rrc_log; + rrc::ue* rrc_ue = nullptr; + rrc* rrc_enb = nullptr; + srslog::basic_logger& logger; // vars asn1::rrc::meas_cfg_s current_meas_cfg; @@ -101,39 +101,47 @@ private: struct intraenb_ho_st { const enb_cell_common* target_cell = nullptr; const enb_cell_common* source_cell = nullptr; - uint16_t last_temp_crnti = SRSLTE_INVALID_RNTI; + uint16_t last_temp_crnti = SRSLTE_INVALID_RNTI; void enter(rrc_mobility* f, const ho_meas_report_ev& meas_report); }; - struct s1_target_ho_st {}; + struct s1_target_ho_st { + std::vector pending_tunnels; + }; struct wait_recfg_comp {}; struct s1_source_ho_st : public subfsm_t { + struct ho_cmd_msg { + const asn1::s1ap::ho_cmd_s* s1ap_ho_cmd; + const asn1::rrc::ho_cmd_r8_ies_s* ho_cmd; + }; ho_meas_report_ev report; - using ho_cmd_msg = asn1::rrc::ho_cmd_r8_ies_s; - struct wait_ho_req_ack_st { - void enter(s1_source_ho_st* f, const ho_meas_report_ev& ev); - }; - struct status_transfer_st { - void enter(s1_source_ho_st* f); - }; + void enter(rrc_mobility* f, const ho_meas_report_ev& ev); - explicit s1_source_ho_st(rrc_mobility* parent_) : base_t(parent_) {} + struct wait_ho_cmd {}; + struct status_transfer_st {}; + + explicit s1_source_ho_st(rrc_mobility* parent_); private: - void send_ho_cmd(wait_ho_req_ack_st& s, const ho_cmd_msg& ho_cmd); + void handle_ho_cmd(wait_ho_cmd& s, const ho_cmd_msg& ho_cmd); void handle_ho_cancel(const ho_cancel_ev& ev); + bool start_enb_status_transfer(const asn1::s1ap::ho_cmd_s& s1ap_ho_cmd); + + rrc* rrc_enb; + rrc::ue* rrc_ue; + srslog::basic_logger& logger; protected: using fsm = s1_source_ho_st; - state_list states{this}; + state_list states{this}; // clang-format off using transitions = transition_table< // Start Target Event Action Guard // +-------------------+------------------+---------------------+-----------------------+---------------------+ to_state< idle_st, srslte::failure_ev >, to_state< idle_st, ho_cancel_ev, &fsm::handle_ho_cancel >, - row< wait_ho_req_ack_st, status_transfer_st, ho_cmd_msg, &fsm::send_ho_cmd > + row< wait_ho_cmd, status_transfer_st, ho_cmd_msg, &fsm::handle_ho_cmd > // +-------------------+------------------+---------------------+-----------------------+---------------------+ >; // clang-format on @@ -146,7 +154,7 @@ private: // FSM transition handlers void handle_crnti_ce(intraenb_ho_st& s, const user_crnti_upd_ev& ev); void handle_recfg_complete(intraenb_ho_st& s, const recfg_complete_ev& ev); - void handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req); + void handle_ho_requested(idle_st& s, const ho_req_rx_ev& ho_req); void handle_status_transfer(s1_target_ho_st& s, const status_transfer_ev& ev); void defer_recfg_complete(s1_target_ho_st& s, const recfg_complete_ev& ev); void handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev); @@ -168,7 +176,7 @@ protected: // +----------------+-------------------+---------------------+----------------------------+-------------------------+ row< idle_st, s1_source_ho_st, ho_meas_report_ev, nullptr, &fsm::needs_s1_ho >, row< idle_st, intraenb_ho_st, ho_meas_report_ev, nullptr, &fsm::needs_intraenb_ho >, - row< idle_st, s1_target_ho_st, ho_req_rx_ev, &fsm::handle_ho_req >, + row< idle_st, s1_target_ho_st, ho_req_rx_ev, &fsm::handle_ho_requested >, // +----------------+-------------------+---------------------+----------------------------+-------------------------+ upd< intraenb_ho_st, user_crnti_upd_ev, &fsm::handle_crnti_ce >, row< intraenb_ho_st, idle_st, recfg_complete_ev, &fsm::handle_recfg_complete >, diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 0d1ffdcd4..0a7448620 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -115,9 +115,8 @@ public: // setters private: - srslte::byte_buffer_pool* pool = nullptr; - rrc_nr* parent; - uint16_t rnti; + rrc_nr* parent; + uint16_t rnti; // state rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE; @@ -137,9 +136,8 @@ private: ngap_interface_rrc_nr* ngap = nullptr; // args - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref m_log; - srslte::timer_handler* timers = nullptr; + srslte::log_ref m_log; + srslte::timer_handler* timers = nullptr; // derived uint32_t slot_dur_ms = 0; diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index f12f30164..3ad2a1a09 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -24,6 +24,8 @@ #include "mac_controller.h" #include "rrc.h" +#include "srslte/interfaces/enb_phy_interfaces.h" +#include "srslte/interfaces/pdcp_interface_types.h" namespace srsenb { @@ -51,18 +53,29 @@ public: rrc_state_t get_state(); void get_metrics(rrc_ue_metrics_t& ue_metrics) const; + ///< Helper to access a cell cfg based on ue_cc_idx + enb_cell_common* get_ue_cc_cfg(uint32_t ue_cc_idx); + void send_connection_setup(); void send_connection_reest(uint8_t ncc); void send_connection_reject(); void send_connection_release(); void send_connection_reest_rej(); - void send_connection_reconf(srslte::unique_byte_buffer_t sdu = {}, bool phy_cfg_updated = true); + void send_connection_reconf(srslte::unique_byte_buffer_t sdu = {}, + bool phy_cfg_updated = true, + const asn1::unbounded_octstring* nas_pdu = nullptr); void send_security_mode_command(); void send_ue_cap_enquiry(); void send_ue_info_req(); void parse_ul_dcch(uint32_t lcid, srslte::unique_byte_buffer_t pdu); + /// List of results for a connection request. + enum class conn_request_result_t { success, error_mme_not_connected, error_unknown_rnti }; + + /// Possible causes for the RRC to transition to the idle state. + enum class rrc_idle_transition_cause { release, timeout }; + void handle_rrc_con_req(asn1::rrc::rrc_conn_request_s* msg); void handle_rrc_con_setup_complete(asn1::rrc::rrc_conn_setup_complete_s* msg, srslte::unique_byte_buffer_t pdu); void handle_rrc_con_reest_req(asn1::rrc::rrc_conn_reest_request_s* msg); @@ -73,7 +86,7 @@ public: bool handle_ue_cap_info(asn1::rrc::ue_cap_info_s* msg); void handle_ue_init_ctxt_setup_req(const asn1::s1ap::init_context_setup_request_s& msg); bool handle_ue_ctxt_mod_req(const asn1::s1ap::ue_context_mod_request_s& msg); - void handle_ue_info_resp(const asn1::rrc::ue_info_resp_r9_s& msg); + void handle_ue_info_resp(const asn1::rrc::ue_info_resp_r9_s& msg, srslte::unique_byte_buffer_t pdu); void set_bitrates(const asn1::s1ap::ue_aggregate_maximum_bitrate_s& rates); @@ -85,9 +98,6 @@ public: const asn1::s1ap::erab_level_qos_params_s& qos_params, const asn1::unbounded_octstring* nas_pdu); - // handover - void handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container); - void notify_s1ap_ue_ctxt_setup_complete(); void notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e); @@ -100,6 +110,8 @@ public: bool send_dl_dcch(const asn1::rrc::dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffer_t pdu = srslte::unique_byte_buffer_t()); + void save_ul_message(srslte::unique_byte_buffer_t pdu) { last_ul_msg = std::move(pdu); } + uint16_t rnti = 0; rrc* parent = nullptr; @@ -115,7 +127,6 @@ public: private: // args - srslte::byte_buffer_pool* pool = nullptr; srslte::timer_handler::unique_timer activity_timer; /// cached ASN1 fields for RRC config update checking, and ease of context transfer during HO @@ -147,12 +158,12 @@ private: bearer_cfg_handler bearer_list; security_cfg_handler ue_security_cfg; + /// Cached message of the last uplinl message. + srslte::unique_byte_buffer_t last_ul_msg; + // controllers mac_controller mac_ctrl; - ///< Helper to access a cell cfg based on ue_cc_idx - enb_cell_common* get_ue_cc_cfg(uint32_t ue_cc_idx); - /// Helper to fill cell_ded_list with SCells provided in the eNB config void update_scells(); diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 42efdcd0e..bae7f12da 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -26,7 +26,8 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/logmap.h" #include "srslte/common/threads.h" -#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_gtpu_interfaces.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #ifndef SRSENB_GTPU_H @@ -34,10 +35,13 @@ namespace srsenb { +class pdcp_interface_gtpu; +class stack_interface_gtpu_lte; + class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp { public: - gtpu(); + explicit gtpu(srslog::basic_logger& logger); int init(std::string gtp_bind_addr_, std::string mme_addr_, @@ -49,7 +53,12 @@ public: void stop(); // gtpu_interface_rrc - uint32_t add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) override; + uint32_t add_bearer(uint16_t rnti, + uint32_t lcid, + uint32_t addr, + uint32_t teid_out, + const bearer_props* props = nullptr) override; + void set_tunnel_status(uint32_t teidin, bool dl_active) override; void rem_bearer(uint16_t rnti, uint32_t lcid) override; void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) override; void rem_user(uint16_t rnti) override; @@ -64,20 +73,21 @@ public: private: static const int GTPU_PORT = 2152; - srslte::byte_buffer_pool* pool = nullptr; + void rem_tunnel(uint32_t teidin); + stack_interface_gtpu_lte* stack = nullptr; bool enable_mbsfn = false; std::string gtp_bind_addr; std::string mme_addr; srsenb::pdcp_interface_gtpu* pdcp = nullptr; - srslte::log_ref gtpu_log; + srslog::basic_logger& logger; // Class to create class m1u_handler { public: - explicit m1u_handler(gtpu* gtpu_) : parent(gtpu_) {} + explicit m1u_handler(gtpu* gtpu_) : parent(gtpu_), logger(parent->logger) {} ~m1u_handler(); m1u_handler(const m1u_handler&) = delete; m1u_handler(m1u_handler&&) = delete; @@ -87,11 +97,11 @@ private: void handle_rx_packet(srslte::unique_byte_buffer_t pdu, const sockaddr_in& addr); private: - gtpu* parent = nullptr; - pdcp_interface_gtpu* pdcp = nullptr; - srslte::log_ref gtpu_log; - std::string m1u_multiaddr; - std::string m1u_if_addr; + gtpu* parent = nullptr; + pdcp_interface_gtpu* pdcp = nullptr; + srslog::basic_logger& logger; + std::string m1u_multiaddr; + std::string m1u_if_addr; bool initiated = false; int m1u_sd = -1; @@ -99,18 +109,22 @@ private: }; m1u_handler m1u; - typedef struct { - uint32_t teids_in[SRSENB_N_RADIO_BEARERS]; - uint32_t teids_out[SRSENB_N_RADIO_BEARERS]; - uint32_t spgw_addrs[SRSENB_N_RADIO_BEARERS]; - } bearer_map; - std::map rnti_bearers; - - typedef struct { - uint16_t rnti; - uint16_t lcid; - } rnti_lcid_t; - std::map teidin_to_rntilcid_map; + const uint32_t undefined_pdcp_sn = std::numeric_limits::max(); + struct tunnel { + bool dl_enabled = true; + bool fwd_teid_in_present = false; + bool prior_teid_in_present = false; + uint16_t rnti = SRSLTE_INVALID_RNTI; + uint32_t lcid = SRSENB_N_RADIO_BEARERS; + uint32_t teid_in = 0; + uint32_t teid_out = 0; + uint32_t spgw_addr = 0; + uint32_t fwd_teid_in = 0; ///< forward Rx SDUs to this TEID + uint32_t prior_teid_in = 0; ///< buffer bearer SDUs until this TEID receives an End Marker + std::multimap buffer; + }; + std::unordered_map tunnels; + std::map, SRSENB_N_RADIO_BEARERS> > ue_teidin_db; // Tx sequence number for signaling messages uint32_t tx_seq = 0; @@ -118,18 +132,23 @@ private: // Socket file descriptor int fd = -1; + void send_pdu_to_tunnel(tunnel& tx_tun, srslte::unique_byte_buffer_t pdu, int pdcp_sn = -1); + void echo_response(in_addr_t addr, in_port_t port, uint16_t seq); void error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid); + void end_marker(uint32_t teidin); + + int create_dl_fwd_tunnel(uint32_t rx_teid_in, uint32_t tx_teid_in); /**************************************************************************** * TEID to RNIT/LCID helper functions ***************************************************************************/ - uint32_t next_teid_in = 0; - uint32_t allocate_teidin(uint16_t rnti, uint16_t lcid); - void free_teidin(uint16_t rnti, uint16_t lcid); - void free_teidin(uint16_t rnti); - rnti_lcid_t teidin_to_rntilcid(uint32_t teidin); - uint32_t rntilcid_to_teidin(uint16_t rnti, uint16_t lcid); + uint32_t next_teid_in = 0; + + tunnel* get_tunnel(uint32_t teidin); + srslte::span get_lcid_teids(uint16_t rnti, uint32_t lcid); + + void log_message(tunnel& tun, bool is_rx, srslte::span pdu, int pdcp_sn = -1); }; } // namespace srsenb diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 02eeaeb04..55fcda413 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -20,8 +20,10 @@ */ #include "srslte/common/timers.h" -#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_metrics_interface.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include "srslte/upper/pdcp.h" #include @@ -30,23 +32,29 @@ namespace srsenb { +class rrc_interface_pdcp; +class rlc_interface_pdcp; +class gtpu_interface_pdcp; + class pdcp : public pdcp_interface_rlc, public pdcp_interface_gtpu, public pdcp_interface_rrc { public: - pdcp(srslte::task_sched_handle task_sched_, const char* logname); + pdcp(srslte::task_sched_handle task_sched_, srslog::basic_logger& logger); virtual ~pdcp() {} void init(rlc_interface_pdcp* rlc_, rrc_interface_pdcp* rrc_, gtpu_interface_pdcp* gtpu_); void stop(); // pdcp_interface_rlc void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override; + void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sn) override; + void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sn) override; void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} // pdcp_interface_rrc void reset(uint16_t rnti) override; void add_user(uint16_t rnti) override; void rem_user(uint16_t rnti) override; - void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override; + void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn = -1) override; void add_bearer(uint16_t rnti, uint32_t lcid, srslte::pdcp_config_t cnfg) override; void del_bearer(uint16_t rnti, uint32_t lcid) override; void config_security(uint16_t rnti, uint32_t lcid, srslte::as_security_config_t cfg_sec) override; @@ -54,8 +62,16 @@ public: void enable_encryption(uint16_t rnti, uint32_t lcid) override; bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) override; bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) override; + void send_status_report(uint16_t rnti) override; + void send_status_report(uint16_t rnti, uint32_t lcid) override; void reestablish(uint16_t rnti) override; + // pdcp_interface_gtpu + std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) override; + + // Metrics + void get_metrics(pdcp_metrics_t& m, const uint32_t nof_tti); + private: class user_interface_rlc : public srsue::rlc_interface_pdcp { @@ -110,8 +126,7 @@ private: rrc_interface_pdcp* rrc; gtpu_interface_pdcp* gtpu; srslte::task_sched_handle task_sched; - srslte::log_ref log_h; - srslte::byte_buffer_pool* pool; + srslog::basic_logger& logger; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/upper/pdcp_nr.h b/srsenb/hdr/stack/upper/pdcp_nr.h index 157aaa1bf..4a03c959e 100644 --- a/srsenb/hdr/stack/upper/pdcp_nr.h +++ b/srsenb/hdr/stack/upper/pdcp_nr.h @@ -49,6 +49,8 @@ public: // pdcp_interface_rlc_nr void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu); + void notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& tx_count); + void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& tx_count); void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} // pdcp_interface_rrc_nr @@ -108,12 +110,11 @@ private: }; // args - pdcp_nr_args_t m_args = {}; - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref m_log; - rlc_interface_pdcp_nr* m_rlc = nullptr; - rrc_interface_pdcp_nr* m_rrc = nullptr; - sdap_interface_pdcp_nr* m_sdap = nullptr; + pdcp_nr_args_t m_args = {}; + srslte::log_ref m_log; + rlc_interface_pdcp_nr* m_rlc = nullptr; + rrc_interface_pdcp_nr* m_rrc = nullptr; + sdap_interface_pdcp_nr* m_sdap = nullptr; std::map users; @@ -122,4 +123,4 @@ private: } // namespace srsenb -#endif // SRSENB_PDCP_NR_H \ No newline at end of file +#endif // SRSENB_PDCP_NR_H diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index aae2260c3..27b1e9c54 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -19,9 +19,10 @@ * */ -#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_metrics_interface.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include "srslte/upper/rlc.h" #include @@ -37,14 +38,16 @@ typedef struct { namespace srsenb { +class rrc_interface_rlc; +class pdcp_interface_rlc; +class mac_interface_rlc; + class rlc : public rlc_interface_mac, public rlc_interface_rrc, public rlc_interface_pdcp { public: - void init(pdcp_interface_rlc* pdcp_, - rrc_interface_rlc* rrc_, - mac_interface_rlc* mac_, - srslte::timer_handler* timers_, - srslte::log_ref log_h); + explicit rlc(srslog::basic_logger& logger) : logger(logger) {} + void + init(pdcp_interface_rlc* pdcp_, rrc_interface_rlc* rrc_, mac_interface_rlc* mac_, srslte::timer_handler* timers_); void stop(); void get_metrics(rlc_metrics_t& m, const uint32_t nof_tti); @@ -77,6 +80,8 @@ private: { public: void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu); + void notify_delivery(uint32_t lcid, const std::vector& tx_count); + void notify_failure(uint32_t lcid, const std::vector& tx_count); void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu); void write_pdu_pcch(srslte::unique_byte_buffer_t sdu); @@ -98,12 +103,11 @@ private: std::map users; std::vector mch_services; - mac_interface_rlc* mac; - pdcp_interface_rlc* pdcp; - rrc_interface_rlc* rrc; - srslte::log_ref log_h; - srslte::byte_buffer_pool* pool; - srslte::timer_handler* timers; + mac_interface_rlc* mac; + pdcp_interface_rlc* pdcp; + rrc_interface_rlc* rrc; + srslog::basic_logger& logger; + srslte::timer_handler* timers; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/upper/rlc_nr.h b/srsenb/hdr/stack/upper/rlc_nr.h index 5b87dd3fa..99fa0be1f 100644 --- a/srsenb/hdr/stack/upper/rlc_nr.h +++ b/srsenb/hdr/stack/upper/rlc_nr.h @@ -72,6 +72,8 @@ private: { public: void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu); + void notify_delivery(uint32_t lcid, const std::vector& pdcp_sns); + void notify_failure(uint32_t lcid, const std::vector& pdcp_sns); void write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu); void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu); void write_pdu_pcch(srslte::unique_byte_buffer_t sdu); @@ -87,12 +89,11 @@ private: }; // args - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref m_log; - srslte::timer_handler* timers = nullptr; - mac_interface_rlc_nr* m_mac = nullptr; - pdcp_interface_rlc_nr* m_pdcp = nullptr; - rrc_interface_rlc_nr* m_rrc = nullptr; + srslte::log_ref m_log; + srslte::timer_handler* timers = nullptr; + mac_interface_rlc_nr* m_mac = nullptr; + pdcp_interface_rlc_nr* m_pdcp = nullptr; + rrc_interface_rlc_nr* m_rrc = nullptr; // state std::map users; @@ -101,4 +102,4 @@ private: } // namespace srsenb -#endif // SRSENB_RLC_NR_H \ No newline at end of file +#endif // SRSENB_RLC_NR_H diff --git a/srsenb/hdr/stack/upper/s1ap.h b/srsenb/hdr/stack/upper/s1ap.h index 743105336..41af0f977 100644 --- a/srsenb/hdr/stack/upper/s1ap.h +++ b/srsenb/hdr/stack/upper/s1ap.h @@ -31,16 +31,20 @@ #include "srslte/common/s1ap_pcap.h" #include "srslte/common/threads.h" #include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_s1ap_interfaces.h" #include "s1ap_metrics.h" #include "srslte/asn1/s1ap.h" #include "srslte/common/network_utils.h" #include "srslte/common/stack_procedure.h" #include "srslte/common/task_scheduler.h" +#include "srslte/srslog/srslog.h" #include namespace srsenb { +class rrc_interface_s1ap; + struct ue_ctxt_t { static const uint32_t invalid_enb_id = std::numeric_limits::max(); @@ -48,6 +52,7 @@ struct ue_ctxt_t { uint16_t rnti = SRSLTE_INVALID_RNTI; uint32_t enb_ue_s1ap_id = invalid_enb_id; uint32_t mme_ue_s1ap_id = 0; + uint32_t enb_cc_idx = 0; struct timeval init_timestamp = {}; }; @@ -57,15 +62,18 @@ public: static const uint32_t ts1_reloc_prep_timeout_ms = 10000; static const uint32_t ts1_reloc_overall_timeout_ms = 10000; - s1ap(srslte::task_sched_handle task_sched_); + s1ap(srslte::task_sched_handle task_sched_, srslog::basic_logger& logger); int init(s1ap_args_t args_, rrc_interface_s1ap* rrc_, srsenb::stack_interface_s1ap_lte* stack_); void stop(); void get_metrics(s1ap_metrics_t& m); // RRC interface - void - initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) override; void initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, + asn1::s1ap::rrc_establishment_cause_e cause, + srslte::unique_byte_buffer_t pdu) override; + void initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu, uint32_t m_tmsi, @@ -80,20 +88,24 @@ public: bool send_ho_required(uint16_t rnti, uint32_t target_eci, srslte::plmn_id_t target_plmn, + srslte::span fwd_erabs, srslte::unique_byte_buffer_t rrc_container) override; bool send_enb_status_transfer_proc(uint16_t rnti, std::vector& bearer_status_list) override; bool send_ho_failure(uint32_t mme_ue_s1ap_id); - bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, - uint16_t rnti, - srslte::unique_byte_buffer_t ho_cmd, - srslte::span > admitted_bearers) override; + bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, + uint16_t rnti, + uint32_t enb_cc_idx, + srslte::unique_byte_buffer_t ho_cmd, + srslte::span admitted_bearers) override; void send_ho_notify(uint16_t rnti, uint64_t target_eci) override; void send_ho_cancel(uint16_t rnti) override; - // void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps); + bool release_erabs(uint16_t rnti, const std::vector& erabs_successfully_released) override; + bool send_error_indication(uint16_t rnti, const asn1::s1ap::cause_c& cause); + bool send_ue_cap_info_indication(uint16_t rnti, srslte::unique_byte_buffer_t ue_radio_cap) override; // Stack interface bool - handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); void start_pcap(srslte::s1ap_pcap* pcap_); private: @@ -107,8 +119,7 @@ private: // args rrc_interface_s1ap* rrc = nullptr; s1ap_args_t args; - srslte::log_ref s1ap_log; - srslte::byte_buffer_pool* pool = nullptr; + srslog::basic_logger& logger; srsenb::stack_interface_s1ap_lte* stack = nullptr; srslte::task_sched_handle task_sched; @@ -151,11 +162,39 @@ private: bool handle_erabmodifyrequest(const asn1::s1ap::erab_modify_request_s& msg); bool handle_uecontextmodifyrequest(const asn1::s1ap::ue_context_mod_request_s& msg); - // bool send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) // handover - bool handle_hopreparationfailure(const asn1::s1ap::ho_prep_fail_s& msg); - bool handle_s1hocommand(const asn1::s1ap::ho_cmd_s& msg); - bool handle_ho_request(const asn1::s1ap::ho_request_s& msg); + /** + * Source eNB Handler for S1AP "HANDOVER PREPARATION FAILURE" Message + * MME ---> Source eNB + * @remark TS 36.413, 8.4.1.3 - S1AP Procedures | Handover Signalling | Handover Preparation | Unsuccessful Operation + * @param msg HANDOVER COMMAND S1AP PDU + * @return true if the HANDOVER COMMAND content is valid. False otherwise + */ + bool handle_handover_preparation_failure(const asn1::s1ap::ho_prep_fail_s& msg); + /** + * Source eNB Handler for S1AP "HANDOVER COMMAND" Message + * MME ---> Source eNB + * @remark TS 36.413, 8.4.1.2 - S1AP Procedures | Handover Signalling | Handover Preparation | Successful Operation + * @param msg HANDOVER COMMAND S1AP PDU + * @return true if the HANDOVER COMMAND content is valid. False otherwise + */ + bool handle_handover_command(const asn1::s1ap::ho_cmd_s& msg); + + /** + * Target eNB Handler for S1AP "HANDOVER REQUEST" Message + * MME ---> Target eNB + * @remark TS 36.413, 8.4.7.2 - S1AP Procedures | Handover Signalling | Handover Resource Allocation + * @param msg HANDOVER REQUEST S1AP PDU + * @return true if the new user resources were successfully allocated + */ + bool handle_handover_request(const asn1::s1ap::ho_request_s& msg); + /** + * Target eNB Handler for S1AP "MME STATUS TRANSFER" Message + * MME ---> Target eNB + * @remark TS 36.413, 8.4.7.2 - S1AP Procedures | Handover Signalling | MME Status Transfer | Successful Operation + * @param msg MME STATUS TRANSFER S1AP PDU + * @return true if the msg content is valid. False otherwise + */ bool handle_mme_status_transfer(const asn1::s1ap::mme_status_transfer_s& msg); // UE-specific data and procedures @@ -166,8 +205,10 @@ private: public: struct ts1_reloc_prep_expired {}; ho_prep_proc_t(s1ap::ue* ue_); - srslte::proc_outcome_t - init(uint32_t target_eci_, srslte::plmn_id_t target_plmn_, srslte::unique_byte_buffer_t rrc_container); + srslte::proc_outcome_t init(uint32_t target_eci_, + srslte::plmn_id_t target_plmn_, + srslte::span fwd_erabs, + srslte::unique_byte_buffer_t rrc_container); srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; } srslte::proc_outcome_t react(ts1_reloc_prep_expired e); srslte::proc_outcome_t react(const asn1::s1ap::ho_prep_fail_s& msg); @@ -182,6 +223,7 @@ private: uint32_t target_eci = 0; srslte::plmn_id_t target_plmn; srslte::unique_byte_buffer_t rrc_container; + const asn1::s1ap::ho_cmd_s* ho_cmd_msg = nullptr; }; explicit ue(s1ap* s1ap_ptr_); @@ -204,19 +246,24 @@ private: const std::vector& erabs_failed_to_release); bool send_erab_modify_response(const std::vector& erabs_successfully_released, const std::vector& erabs_failed_to_release); + bool send_erab_release_indication(const std::vector& erabs_successfully_released); + bool send_ue_cap_info_indication(srslte::unique_byte_buffer_t ue_radio_cap); + bool was_uectxtrelease_requested() const { return release_requested; } ue_ctxt_t ctxt = {}; uint16_t stream_id = 1; private: - bool - send_ho_required(uint32_t target_eci_, srslte::plmn_id_t target_plmn_, srslte::unique_byte_buffer_t rrc_container); + bool send_ho_required(uint32_t target_eci_, + srslte::plmn_id_t target_plmn_, + srslte::span fwd_erabs, + srslte::unique_byte_buffer_t rrc_container); //! TS 36.413, Section 8.4.6 - eNB Status Transfer procedure // args - s1ap* s1ap_ptr; - srslte::log_ref s1ap_log; + s1ap* s1ap_ptr; + srslog::basic_logger& logger; // state bool release_requested = false; @@ -276,6 +323,7 @@ private: ue* find_s1apmsg_user(uint32_t enb_id, uint32_t mme_id); std::string get_cause(const asn1::s1ap::cause_c& c); + void log_s1ap_msg(const asn1::s1ap::s1ap_pdu_c& msg, srslte::const_span sdu, bool is_rx); srslte::proc_t s1setup_proc; }; diff --git a/srsenb/hdr/stack/upper/sdap.h b/srsenb/hdr/stack/upper/sdap.h index 6eb982258..3e8b09967 100644 --- a/srsenb/hdr/stack/upper/sdap.h +++ b/srsenb/hdr/stack/upper/sdap.h @@ -44,7 +44,6 @@ public: void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) final; private: - srslte::log_ref m_log{"SDAP"}; gtpu_interface_sdap_nr* m_gtpu = nullptr; pdcp_interface_sdap_nr* m_pdcp = nullptr; srsue::gw_interface_pdcp* m_gw = nullptr; diff --git a/srsenb/src/CMakeLists.txt b/srsenb/src/CMakeLists.txt index 325f390c7..d8c7b24a7 100644 --- a/srsenb/src/CMakeLists.txt +++ b/srsenb/src/CMakeLists.txt @@ -40,10 +40,8 @@ add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_js set(SRSENB_SOURCES srsenb_phy srsenb_stack srsenb_upper srsenb_mac srsenb_rrc srslog) set(SRSLTE_SOURCES srslte_common srslte_mac srslte_phy srslte_upper srslte_radio rrc_asn1 s1ap_asn1 enb_cfg_parser srslog) -if(ENABLE_5GNR) - set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_phy srsgnb_stack srsgnb_upper srsgnb_mac srsgnb_rrc) - set(SRSLTE_SOURCES ${SRSLTE_SOURCES} rrc_nr_asn1 ngap_nr_asn1) -endif() +set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_phy srsgnb_stack srsgnb_upper srsgnb_mac srsgnb_rrc) +set(SRSLTE_SOURCES ${SRSLTE_SOURCES} rrc_nr_asn1 ngap_nr_asn1) target_link_libraries(srsenb ${SRSENB_SOURCES} ${SRSLTE_SOURCES} diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index cbc88136a..879ddd407 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -25,18 +25,17 @@ #include "srslte/build_info.h" #include "srslte/common/enb_events.h" #include "srslte/radio/radio_null.h" -#ifdef HAVE_5GNR #include "srsenb/hdr/phy/vnf_phy_nr.h" #include "srsenb/hdr/stack/gnb_stack_nr.h" -#endif #include namespace srsenb { -enb::enb() : started(false), pool(srslte::byte_buffer_pool::get_instance(ENB_POOL_SIZE)) +enb::enb(srslog::sink& log_sink) : + started(false), log_sink(log_sink), enb_log(srslog::fetch_basic_logger("ENB", log_sink, false)) { // print build info - std::cout << std::endl << get_build_string() << std::endl; + std::cout << std::endl << get_build_string() << std::endl << std::endl; } enb::~enb() @@ -51,9 +50,8 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_) // Init eNB log srslte::logmap::set_default_logger(logger); - log = srslte::logmap::get("ENB"); - log->set_level(srslte::LOG_LEVEL_INFO); - log->info("%s", get_build_string().c_str()); + enb_log.set_level(srslog::basic_levels::info); + enb_log.info("%s", get_build_string().c_str()); // Validate arguments if (parse_args(args_, rrc_cfg)) { @@ -61,25 +59,23 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_) return SRSLTE_ERROR; } - pool_log.init("POOL", logger); - pool_log.set_level(srslte::LOG_LEVEL_ERROR); - pool->set_log(&pool_log); + srslte::byte_buffer_pool::get_instance()->enable_logger(true); // Create layers if (args.stack.type == "lte") { - std::unique_ptr lte_stack(new enb_stack_lte(logger)); + std::unique_ptr lte_stack(new enb_stack_lte(logger, log_sink)); if (!lte_stack) { srslte::console("Error creating eNB stack.\n"); return SRSLTE_ERROR; } - std::unique_ptr lte_radio = std::unique_ptr(new srslte::radio(logger)); + std::unique_ptr lte_radio = std::unique_ptr(new srslte::radio); if (!lte_radio) { srslte::console("Error creating radio multi instance.\n"); return SRSLTE_ERROR; } - std::unique_ptr lte_phy = std::unique_ptr(new srsenb::phy(logger)); + std::unique_ptr lte_phy = std::unique_ptr(new srsenb::phy(log_sink)); if (!lte_phy) { srslte::console("Error creating LTE PHY instance.\n"); return SRSLTE_ERROR; @@ -101,7 +97,7 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_) // Only init Stack if both radio and PHY could be initialized if (ret == SRSLTE_SUCCESS) { - if (lte_stack->init(args.stack, rrc_cfg, lte_phy.get())) { + if (lte_stack->init(args.stack, rrc_cfg, lte_phy.get()) != SRSLTE_SUCCESS) { srslte::console("Error initializing stack.\n"); ret = SRSLTE_ERROR; } @@ -112,10 +108,9 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_) radio = std::move(lte_radio); } else if (args.stack.type == "nr") { -#ifdef HAVE_5GNR std::unique_ptr nr_stack(new srsenb::gnb_stack_nr(logger)); - std::unique_ptr nr_radio(new srslte::radio_null(logger)); - std::unique_ptr nr_phy(new srsenb::vnf_phy_nr(logger)); + std::unique_ptr nr_radio(new srslte::radio_null); + std::unique_ptr nr_phy(new srsenb::vnf_phy_nr); // Init layers if (nr_radio->init(args.rf, nullptr)) { @@ -146,10 +141,6 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_) stack = std::move(nr_stack); phy = std::move(nr_phy); radio = std::move(nr_radio); -#else - srslte::console("ERROR: 5G NR stack not compiled. Please, activate CMAKE HAVE_5GNR flag.\n"); - log->error("5G NR stack not compiled. Please, activate CMAKE HAVE_5GNR flag.\n"); -#endif } started = true; // set to true in any case to allow stopping the eNB if an error happened @@ -260,7 +251,7 @@ std::string enb::get_build_info() std::string enb::get_build_string() { std::stringstream ss; - ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; + ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "."; return ss.str(); } diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 0589a9145..9a4bee553 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -136,11 +136,10 @@ int field_carrier_freqs_info_list::parse(libconfig::Setting& root) data->carrier_freqs_info_list.resize((uint32_t)root.getLength()); data->carrier_freqs_info_list_present = data->carrier_freqs_info_list.size() > 0; if (data->carrier_freqs_info_list.size() > ASN1_RRC_MAX_GNFG) { - ERROR("CarrierFreqsInfoGERAN cannot have more than %d entries\n", ASN1_RRC_MAX_GNFG); + ERROR("CarrierFreqsInfoGERAN cannot have more than %d entries", ASN1_RRC_MAX_GNFG); return -1; } for (uint32_t i = 0; i < data->carrier_freqs_info_list.size(); i++) { - int cell_resel_prio; if (root[i].lookupValue("cell_resel_prio", cell_resel_prio)) { data->carrier_freqs_info_list[i].common_info.cell_resel_prio_present = true; @@ -156,27 +155,27 @@ int field_carrier_freqs_info_list::parse(libconfig::Setting& root) field_asn1_bitstring_number, uint8_t> ncc_permitted( "ncc_permitted", &data->carrier_freqs_info_list[i].common_info.ncc_permitted); if (ncc_permitted.parse(root[i])) { - ERROR("Error parsing `ncc_permitted` in carrier_freqs_info_lsit=%d\n", i); + ERROR("Error parsing `ncc_permitted` in carrier_freqs_info_lsit=%d", i); return -1; } int q_rx_lev_min = 0; if (!root[i].lookupValue("q_rx_lev_min", q_rx_lev_min)) { - ERROR("Missing field `q_rx_lev_min` in carrier_freqs_info_list=%d\n", i); + ERROR("Missing field `q_rx_lev_min` in carrier_freqs_info_list=%d", i); return -1; } data->carrier_freqs_info_list[i].common_info.q_rx_lev_min = q_rx_lev_min; int thresh_x_high = 0; if (!root[i].lookupValue("thresh_x_high", thresh_x_high)) { - ERROR("Missing field `thresh_x_high` in carrier_freqs_info_list=%d\n", i); + ERROR("Missing field `thresh_x_high` in carrier_freqs_info_list=%d", i); return -1; } data->carrier_freqs_info_list[i].common_info.thresh_x_high = thresh_x_high; int thresh_x_low = 0; if (!root[i].lookupValue("thresh_x_low", thresh_x_low)) { - ERROR("Missing field `thresh_x_low` in carrier_freqs_info_list=%d\n", i); + ERROR("Missing field `thresh_x_low` in carrier_freqs_info_list=%d", i); return -1; } data->carrier_freqs_info_list[i].common_info.thresh_x_low = thresh_x_low; @@ -189,7 +188,7 @@ int field_carrier_freqs_info_list::parse(libconfig::Setting& root) field_asn1_enum_str band_ind("band_ind", &data->carrier_freqs_info_list[i].carrier_freqs.band_ind); if (band_ind.parse(root[i])) { - ERROR("Error parsing `band_ind` in carrier_freqs_info_list=%d\n", i); + ERROR("Error parsing `band_ind` in carrier_freqs_info_list=%d", i); return -1; } @@ -405,20 +404,22 @@ int field_qci::parse(libconfig::Setting& root) return -1; } + rrc_cfg_qci_t qcicfg; + field_asn1_enum_number discard_timer( - "discard_timer", &cfg[qci].pdcp_cfg.discard_timer, &cfg[qci].pdcp_cfg.discard_timer_present); + "discard_timer", &qcicfg.pdcp_cfg.discard_timer, &qcicfg.pdcp_cfg.discard_timer_present); discard_timer.parse(q["pdcp_config"]); field_asn1_enum_number pdcp_sn_size( - "pdcp_sn_size", &cfg[qci].pdcp_cfg.rlc_um.pdcp_sn_size, &cfg[qci].pdcp_cfg.rlc_um_present); + "pdcp_sn_size", &qcicfg.pdcp_cfg.rlc_um.pdcp_sn_size, &qcicfg.pdcp_cfg.rlc_um_present); pdcp_sn_size.parse(q["pdcp_config"]); - cfg[qci].pdcp_cfg.rlc_am_present = - q["pdcp_config"].lookupValue("status_report_required", cfg[qci].pdcp_cfg.rlc_am.status_report_required); - cfg[qci].pdcp_cfg.hdr_compress.set(pdcp_cfg_s::hdr_compress_c_::types::not_used); + qcicfg.pdcp_cfg.rlc_am_present = + q["pdcp_config"].lookupValue("status_report_required", qcicfg.pdcp_cfg.rlc_am.status_report_required); + qcicfg.pdcp_cfg.hdr_compress.set(pdcp_cfg_s::hdr_compress_c_::types::not_used); // Parse RLC section - rlc_cfg_c* rlc_cfg = &cfg[qci].rlc_cfg; + rlc_cfg_c* rlc_cfg = &qcicfg.rlc_cfg; if (q["rlc_config"].exists("ul_am")) { rlc_cfg->set_am(); } else if (q["rlc_config"].exists("ul_um") && q["rlc_config"].exists("dl_um")) { @@ -434,7 +435,6 @@ int field_qci::parse(libconfig::Setting& root) // Parse RLC-UM section if (q["rlc_config"].exists("ul_um")) { - ul_um_rlc_s* um_rlc; if (rlc_cfg->type() == rlc_cfg_c::types::um_uni_dir_ul) { um_rlc = &rlc_cfg->um_uni_dir_ul().ul_um_rlc; @@ -444,12 +444,11 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number sn_field_len("sn_field_length", &um_rlc->sn_field_len); if (sn_field_len.parse(q["rlc_config"]["ul_um"])) { - ERROR("Error can't find sn_field_length in section ul_um\n"); + ERROR("Error can't find sn_field_length in section ul_um"); } } if (q["rlc_config"].exists("dl_um")) { - dl_um_rlc_s* um_rlc; if (rlc_cfg->type() == rlc_cfg_c::types::um_uni_dir_dl) { um_rlc = &rlc_cfg->um_uni_dir_dl().dl_um_rlc; @@ -459,12 +458,12 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number sn_field_len("sn_field_length", &um_rlc->sn_field_len); if (sn_field_len.parse(q["rlc_config"]["dl_um"])) { - ERROR("Error can't find sn_field_length in section dl_um\n"); + ERROR("Error can't find sn_field_length in section dl_um"); } field_asn1_enum_number t_reordering("t_reordering", &um_rlc->t_reordering); if (t_reordering.parse(q["rlc_config"]["dl_um"])) { - ERROR("Error can't find t_reordering in section dl_um\n"); + ERROR("Error can't find t_reordering in section dl_um"); } } @@ -474,23 +473,23 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number t_poll_retx("t_poll_retx", &am_rlc->t_poll_retx); if (t_poll_retx.parse(q["rlc_config"]["ul_am"])) { - ERROR("Error can't find t_poll_retx in section ul_am\n"); + ERROR("Error can't find t_poll_retx in section ul_am"); } field_asn1_enum_number poll_pdu("poll_pdu", &am_rlc->poll_pdu); if (poll_pdu.parse(q["rlc_config"]["ul_am"])) { - ERROR("Error can't find poll_pdu in section ul_am\n"); + ERROR("Error can't find poll_pdu in section ul_am"); } field_asn1_enum_number poll_byte("poll_byte", &am_rlc->poll_byte); if (poll_byte.parse(q["rlc_config"]["ul_am"])) { - ERROR("Error can't find poll_byte in section ul_am\n"); + ERROR("Error can't find poll_byte in section ul_am"); } field_asn1_enum_number max_retx_thresh("max_retx_thresh", &am_rlc->max_retx_thres); if (max_retx_thresh.parse(q["rlc_config"]["ul_am"])) { - ERROR("Error can't find max_retx_thresh in section ul_am\n"); + ERROR("Error can't find max_retx_thresh in section ul_am"); } } @@ -499,12 +498,12 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number t_reordering("t_reordering", &am_rlc->t_reordering); if (t_reordering.parse(q["rlc_config"]["dl_am"])) { - ERROR("Error can't find t_reordering in section dl_am\n"); + ERROR("Error can't find t_reordering in section dl_am"); } field_asn1_enum_number t_status_prohibit("t_status_prohibit", &am_rlc->t_status_prohibit); if (t_status_prohibit.parse(q["rlc_config"]["dl_am"])) { - ERROR("Error can't find t_status_prohibit in section dl_am\n"); + ERROR("Error can't find t_status_prohibit in section dl_am"); } } @@ -514,11 +513,11 @@ int field_qci::parse(libconfig::Setting& root) return -1; } - lc_ch_cfg_s::ul_specific_params_s_* lc_cfg = &cfg[qci].lc_cfg; + lc_ch_cfg_s::ul_specific_params_s_* lc_cfg = &qcicfg.lc_cfg; parser::field priority("priority", &lc_cfg->prio); if (priority.parse(q["logical_channel_config"])) { - ERROR("Error can't find logical_channel_config in section priority\n"); + ERROR("Error can't find logical_channel_config in section priority"); } field_asn1_enum_number prioritised_bit_rate( @@ -530,12 +529,13 @@ int field_qci::parse(libconfig::Setting& root) field_asn1_enum_number bucket_size_duration( "bucket_size_duration", &lc_cfg->bucket_size_dur); if (bucket_size_duration.parse(q["logical_channel_config"])) { - ERROR("Error can't find bucket_size_duration in section logical_channel_config\n"); + ERROR("Error can't find bucket_size_duration in section logical_channel_config"); } parser::field log_chan_group("log_chan_group", &lc_cfg->lc_ch_group); lc_cfg->lc_ch_group_present = not log_chan_group.parse(q["logical_channel_config"]); - cfg[qci].configured = true; + qcicfg.configured = true; + cfg.insert(std::make_pair(qci, qcicfg)); } return 0; @@ -547,15 +547,15 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) { /* Transmission mode config section */ if (args_->enb.transmission_mode < 1 || args_->enb.transmission_mode > 4) { - ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.\n", args_->enb.transmission_mode); + ERROR("Invalid transmission mode (%d). Only indexes 1-4 are implemented.", args_->enb.transmission_mode); return SRSLTE_ERROR; } else if (args_->enb.transmission_mode == 1 && args_->enb.nof_ports > 1) { - ERROR("Invalid number of ports (%d) for transmission mode (%d). Only one antenna port is allowed.\n", + ERROR("Invalid number of ports (%d) for transmission mode (%d). Only one antenna port is allowed.", args_->enb.nof_ports, args_->enb.transmission_mode); return SRSLTE_ERROR; } else if (args_->enb.transmission_mode > 1 && args_->enb.nof_ports != 2) { - ERROR("The selected number of ports (%d) are insufficient for the selected transmission mode (%d).\n", + ERROR("The selected number of ports (%d) are insufficient for the selected transmission mode (%d).", args_->enb.nof_ports, args_->enb.transmission_mode); return SRSLTE_ERROR; @@ -585,7 +585,7 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) rrc_cfg_->antenna_info.codebook_subset_restrict.n2_tx_ant_tm4().from_number(0b111111); break; default: - ERROR("Unsupported transmission mode %d\n", rrc_cfg_->antenna_info.tx_mode.to_number()); + ERROR("Unsupported transmission mode %d", rrc_cfg_->antenna_info.tx_mode.to_number()); return SRSLTE_ERROR; } @@ -767,12 +767,12 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) for (auto it2 = it + 1; it2 != rrc_cfg->cell_list.end(); it2++) { // Check RF port is not repeated if (it->rf_port == it2->rf_port) { - ERROR("Repeated RF port for multiple cells\n"); + ERROR("Repeated RF port for multiple cells"); } // Check cell ID is not repeated if (it->cell_id == it2->cell_id) { - ERROR("Repeated Cell identifier\n"); + ERROR("Repeated Cell identifier"); } } } @@ -895,20 +895,20 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ auto& cfg = rrc_cfg_->cell_list.at(0); if (args_->enb.dl_earfcn > 0) { cfg.dl_earfcn = args_->enb.dl_earfcn; - ERROR("Force DL EARFCN for cell PCI=%d to %d\n", cfg.pci, cfg.dl_earfcn); + ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn); } if (args_->rf.dl_freq > 0) { cfg.dl_freq_hz = args_->rf.dl_freq; - ERROR("Force DL freq for cell PCI=%d to %f MHz\n", cfg.pci, cfg.dl_freq_hz / 1e6f); + ERROR("Force DL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.dl_freq_hz / 1e6f); } if (args_->rf.ul_freq > 0) { cfg.ul_freq_hz = args_->rf.ul_freq; - ERROR("Force UL freq for cell PCI=%d to %f MHz\n", cfg.pci, cfg.ul_freq_hz / 1e6f); + ERROR("Force UL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.ul_freq_hz / 1e6f); } } else { // If more than one cell is defined, single EARFCN or DL freq will be ignored if (args_->enb.dl_earfcn > 0 || args_->rf.dl_freq > 0) { - INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config.\n"); + INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config."); } } @@ -952,10 +952,10 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ rrc_cfg_->cell_list.end(), [scell_it](const cell_cfg_t& c) { return scell_it->cell_id == c.cell_id; }); if (cell_it == rrc_cfg_->cell_list.end()) { - ERROR("Scell with cell_id=0x%x is not present in rr.conf. Ignoring it.\n", scell_it->cell_id); + ERROR("Scell with cell_id=0x%x is not present in rr.conf. Ignoring it.", scell_it->cell_id); scell_it = cfg.scell_list.erase(scell_it); } else if (cell_it->cell_id == cfg.cell_id) { - ERROR("A cell cannot have an scell with the same cell_id=0x%x\n", cfg.cell_id); + ERROR("A cell cannot have an scell with the same cell_id=0x%x", cfg.cell_id); return SRSLTE_ERROR; } else { scell_it++; @@ -969,7 +969,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ auto collision_it = std::find_if(it + 1, rrc_cfg_->cell_list.end(), is_pss_collision); if (collision_it != rrc_cfg_->cell_list.end()) { ERROR("The cells pci1=%d and pci2=%d will have the same PSS. Consider changing one of the cells' PCI values, " - "otherwise a UE may fail to correctly detect and distinguish them\n", + "otherwise a UE may fail to correctly detect and distinguish them", it->pci, collision_it->pci); } @@ -1022,7 +1022,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ uint32_t n310 = rrc_cfg_->sibs[1].sib2().ue_timers_and_consts.n310.to_number(); uint32_t min_rrc_inactivity_timer = t310 + t311 + n310 + 50; if (args_->general.rrc_inactivity_timer < min_rrc_inactivity_timer) { - ERROR("rrc_inactivity_timer=%d is too low. Consider setting it to a value equal or above %d\n", + ERROR("rrc_inactivity_timer=%d is too low. Consider setting it to a value equal or above %d", args_->general.rrc_inactivity_timer, min_rrc_inactivity_timer); } @@ -1031,7 +1031,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ // Check number of control symbols if (args_->stack.mac.sched.min_nof_ctrl_symbols > args_->stack.mac.sched.max_nof_ctrl_symbols) { - ERROR("Invalid minimum number of control symbols %d. Setting it to 1.\n", + ERROR("Invalid minimum number of control symbols %d. Setting it to 1.", args_->stack.mac.sched.min_nof_ctrl_symbols); args_->stack.mac.sched.min_nof_ctrl_symbols = 1; } @@ -1547,7 +1547,7 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co cell_access->plmn_id_list.resize(1); srslte::plmn_id_t plmn; if (plmn.from_string(mcc_str + mnc_str) == SRSLTE_ERROR) { - ERROR("Could not convert %s to a plmn_id\n", (mcc_str + mnc_str).c_str()); + ERROR("Could not convert %s to a plmn_id", (mcc_str + mnc_str).c_str()); return -1; } srslte::to_asn1(&cell_access->plmn_id_list[0].plmn_id, plmn); diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index 412fb6da2..7f8face9b 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -158,13 +158,13 @@ private: class field_qci final : public parser::field_itf { public: - explicit field_qci(rrc_cfg_qci_t* cfg_) { cfg = cfg_; } + explicit field_qci(std::map& cfg_) : cfg(cfg_) {} const char* get_name() override { return "field_cqi"; } int parse(Setting& root) override; private: - rrc_cfg_qci_t* cfg; + std::map& cfg; }; // ASN1 parsers @@ -183,7 +183,6 @@ public: int parse(Setting& root) override { if (root.exists(name)) { - if (enabled_value) { *enabled_value = true; } @@ -212,10 +211,8 @@ class field_asn1_seqof_size : public field_asn1 public: field_asn1_seqof_size(const char* name_, ListType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_) + {} int parse_value(Setting& root) override { @@ -242,10 +239,8 @@ class field_asn1_choice_type_number : public field_asn1 public: field_asn1_choice_type_number(const char* name_, ChoiceType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_) + {} int parse_value(Setting& root) override { @@ -347,10 +342,8 @@ class field_asn1_enum_number : public field_asn1 public: field_asn1_enum_number(const char* name_, EnumType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_) + {} int parse_value(Setting& root) override { @@ -373,10 +366,8 @@ class field_asn1_enum_str : public field_asn1 public: field_asn1_enum_str(const char* name_, EnumType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_) + {} int parse_value(Setting& root) override { @@ -398,10 +389,8 @@ class field_asn1_enum_number_str : public field_asn1 public: field_asn1_enum_number_str(const char* name_, EnumType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_) + {} int parse_value(Setting& root) override { @@ -427,12 +416,8 @@ public: func_ptr f_, ChoiceType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_), - choicetypename(choicetypename_), - f(f_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_), choicetypename(choicetypename_), f(f_) + {} int parse_value(Setting& root) override { @@ -474,12 +459,8 @@ public: func_ptr f_, ChoiceType* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_), - choicetypename(choicetypename_), - f(f_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_), choicetypename(choicetypename_), f(f_) + {} int parse_value(Setting& root) override { @@ -508,10 +489,8 @@ class field_asn1_bitstring_number : public field_asn1 public: field_asn1_bitstring_number(const char* name_, BitString* store_ptr_, bool* enabled_value_ = nullptr) : - field_asn1(name_, enabled_value_), - store_ptr(store_ptr_) - { - } + field_asn1(name_, enabled_value_), store_ptr(store_ptr_) + {} int parse_value(Setting& root) override { @@ -552,10 +531,8 @@ class mbsfn_sf_cfg_list_parser : public parser::field_itf { public: mbsfn_sf_cfg_list_parser(asn1::rrc::mbsfn_sf_cfg_list_l* mbsfn_list_, bool* enabled_) : - mbsfn_list(mbsfn_list_), - enabled(enabled_) - { - } + mbsfn_list(mbsfn_list_), enabled(enabled_) + {} int parse(Setting& root) override; const char* get_name() override { return "mbsfnSubframeConfigList"; } @@ -568,10 +545,8 @@ class mbsfn_area_info_list_parser final : public parser::field_itf { public: mbsfn_area_info_list_parser(asn1::rrc::mbsfn_area_info_list_r9_l* mbsfn_list_, bool* enabled_) : - mbsfn_list(mbsfn_list_), - enabled(enabled_) - { - } + mbsfn_list(mbsfn_list_), enabled(enabled_) + {} int parse(Setting& root) override; const char* get_name() override { return "mbsfn_area_info_list"; } diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 8fff8ede2..1ab6dd31d 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -489,19 +489,13 @@ int main(int argc, char* argv[]) srslte_debug_handle_crash(argc, argv); parse_args(&args, argc, argv); - // Setup logging. - log_sink = (args.log.filename == "stdout") - ? srslog::create_stdout_sink() - : srslog::create_file_sink(args.log.filename, fixup_log_file_maxsize(args.log.file_max_size)); - if (!log_sink) { - return SRSLTE_ERROR; - } + // Setup the default log sink. + srslog::set_default_sink( + (args.log.filename == "stdout") + ? srslog::fetch_stdout_sink() + : srslog::fetch_file_sink(args.log.filename, fixup_log_file_maxsize(args.log.file_max_size))); - srslog::log_channel* chan = srslog::create_log_channel("main_channel", *log_sink); - if (!chan) { - return SRSLTE_ERROR; - } - srslte::srslog_wrapper log_wrapper(*chan); + srslte::srslog_wrapper log_wrapper(srslog::fetch_log_channel("main_channel")); // Alarms log channel creation. srslog::sink& alarm_sink = srslog::fetch_file_sink(args.general.alarms_filename); @@ -529,7 +523,7 @@ int main(int argc, char* argv[]) } // Create eNB - unique_ptr enb{new srsenb::enb}; + unique_ptr enb{new srsenb::enb(srslog::get_default_sink())}; if (enb->init(args, &log_wrapper) != SRSLTE_SUCCESS) { enb->stop(); return SRSLTE_ERROR; diff --git a/srsenb/src/metrics_json.cc b/srsenb/src/metrics_json.cc index fee102055..270c08846 100644 --- a/srsenb/src/metrics_json.cc +++ b/srsenb/src/metrics_json.cc @@ -62,7 +62,7 @@ DECLARE_METRIC("ul_mcs", metric_ul_mcs, float, ""); DECLARE_METRIC("ul_bitrate", metric_ul_bitrate, float, ""); DECLARE_METRIC("ul_bler", metric_ul_bler, float, ""); DECLARE_METRIC("ul_phr", metric_ul_phr, float, ""); -DECLARE_METRIC("bsr", metric_bsr, int, ""); +DECLARE_METRIC("ul_bsr", metric_bsr, uint32_t, ""); DECLARE_METRIC_LIST("bearer_list", mlist_bearers, std::vector); DECLARE_METRIC_SET("ue_container", mset_ue_container, @@ -87,10 +87,11 @@ DECLARE_METRIC_SET("sector_container", mset_sector_container, metric_sector_id, /// Metrics root object. DECLARE_METRIC("type", metric_type_tag, std::string, ""); +DECLARE_METRIC("timestamp", metric_timestamp_tag, double, ""); DECLARE_METRIC_LIST("sector_list", mlist_sector, std::vector); /// Metrics context. -using metric_context_t = srslog::build_context_type; +using metric_context_t = srslog::build_context_type; } // namespace @@ -136,14 +137,24 @@ static void fill_ue_metrics(mset_ue_container& ue, const enb_metrics_t& m, unsig if (drb.first >= SRSLTE_N_RADIO_BEARERS) { continue; } - const auto& rlc_bearer = m.stack.rlc.ues[i].bearer; - bearer_container.write(rlc_bearer[drb.first].num_tx_sdu_bytes); - bearer_container.write(rlc_bearer[drb.first].num_rx_sdu_bytes); + const auto& rlc_bearer = m.stack.rlc.ues[i].bearer; + const auto& pdcp_bearer = m.stack.pdcp.ues[i].bearer; + bearer_container.write(pdcp_bearer[drb.first].num_tx_acked_bytes); + bearer_container.write(pdcp_bearer[drb.first].num_rx_pdu_bytes); + bearer_container.write(pdcp_bearer[drb.first].tx_notification_latency_ms / 1e3); bearer_container.write(rlc_bearer[drb.first].rx_latency_ms / 1e3); + bearer_container.write(pdcp_bearer[drb.first].num_tx_buffered_pdus_bytes); bearer_container.write(rlc_bearer[drb.first].rx_buffered_bytes); } } +/// Returns the current time in seconds with ms precision since UNIX epoch. +static double get_time_stamp() +{ + auto tp = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(tp).count() * 1e-3; +} + /// Returns false if the input index is out of bounds in the metrics struct. static bool has_valid_metric_ranges(const enb_metrics_t& m, unsigned index) { @@ -156,6 +167,9 @@ static bool has_valid_metric_ranges(const enb_metrics_t& m, unsigned index) if (index >= m.stack.rlc.ues.size()) { return false; } + if (index >= m.stack.pdcp.ues.size()) { + return false; + } return true; } @@ -198,5 +212,6 @@ void metrics_json::set_metrics(const enb_metrics_t& m, const uint32_t period_use } // Log the context. + ctx.write(get_time_stamp()); log_c(ctx); } diff --git a/srsenb/src/phy/CMakeLists.txt b/srsenb/src/phy/CMakeLists.txt index d7bcd0f3f..f7191a81b 100644 --- a/srsenb/src/phy/CMakeLists.txt +++ b/srsenb/src/phy/CMakeLists.txt @@ -32,10 +32,8 @@ set(SOURCES txrx.cc) add_library(srsenb_phy STATIC ${SOURCES}) +add_library(srsgnb_phy STATIC vnf_phy_nr.cc) + if(ENABLE_GUI AND SRSGUI_FOUND) target_link_libraries(srsenb_phy ${SRSGUI_LIBRARIES}) endif(ENABLE_GUI AND SRSGUI_FOUND) - -if(ENABLE_5GNR) - add_library(srsgnb_phy STATIC vnf_phy_nr.cc) -endif() \ No newline at end of file diff --git a/srsenb/src/phy/lte/cc_worker.cc b/srsenb/src/phy/lte/cc_worker.cc index 15f602b86..95acb0f5b 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -27,16 +27,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) using namespace std; @@ -55,7 +55,7 @@ using namespace asn1::rrc; namespace srsenb { namespace lte { -cc_worker::cc_worker() +cc_worker::cc_worker(srslog::basic_logger& logger) : logger(logger) { reset(); } @@ -85,10 +85,9 @@ cc_worker::~cc_worker() FILE* f; #endif -void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_) +void cc_worker::init(phy_common* phy_, uint32_t cc_idx_) { phy = phy_; - log_h = log_h_; cc_idx = cc_idx_; srslte_cell_t cell = phy_->get_cell(cc_idx); uint32_t nof_prb = phy_->get_nof_prb(cc_idx); @@ -98,32 +97,32 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_) for (uint32_t p = 0; p < phy->get_nof_ports(cc_idx); p++) { signal_buffer_rx[p] = srslte_vec_cf_malloc(2 * sf_len); if (!signal_buffer_rx[p]) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return; } srslte_vec_cf_zero(signal_buffer_rx[p], 2 * sf_len); signal_buffer_tx[p] = srslte_vec_cf_malloc(2 * sf_len); if (!signal_buffer_tx[p]) { - ERROR("Error allocating memory\n"); + ERROR("Error allocating memory"); return; } srslte_vec_cf_zero(signal_buffer_tx[p], 2 * sf_len); } if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, nof_prb)) { - ERROR("Error initiating ENB DL (cc=%d)\n", cc_idx); + ERROR("Error initiating ENB DL (cc=%d)", cc_idx); return; } if (srslte_enb_dl_set_cell(&enb_dl, cell)) { - ERROR("Error initiating ENB DL (cc=%d)\n", cc_idx); + ERROR("Error initiating ENB DL (cc=%d)", cc_idx); return; } if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx[0], nof_prb)) { - ERROR("Error initiating ENB UL\n"); + ERROR("Error initiating ENB UL"); return; } if (srslte_enb_ul_set_cell(&enb_ul, cell, &phy->dmrs_pusch_cfg, nullptr)) { - ERROR("Error initiating ENB UL\n"); + ERROR("Error initiating ENB UL"); return; } @@ -139,13 +138,13 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_) } if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, nof_prb)) { - ERROR("Error initiating soft buffer\n"); + ERROR("Error initiating soft buffer"); exit(-1); } srslte_softbuffer_tx_reset(&temp_mbsfn_softbuffer); - Info("Component Carrier Worker %d configured cell %d PRB\n", cc_idx, nof_prb); + Info("Component Carrier Worker %d configured cell %d PRB", cc_idx, nof_prb); if (phy->params.pusch_8bit_decoder) { enb_ul.pusch.llr_is_8bit = true; @@ -226,7 +225,7 @@ void cc_worker::work_ul(const srslte_ul_sf_cfg_t& ul_sf_cfg, stack_interface_phy { std::lock_guard lock(mutex); ul_sf = ul_sf_cfg; - log_h->step(ul_sf.tti); + logger.set_context(ul_sf.tti); // Process UL signal srslte_enb_ul_fft(&enb_ul); @@ -305,33 +304,31 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ // Compute UL grant srslte_pusch_grant_t& grant = ul_cfg.pusch.grant; if (srslte_ra_ul_dci_to_grant(&enb_ul.cell, &ul_sf, &ul_cfg.hopping, &ul_grant.dci, &grant)) { - Error("Computing PUSCH dci for RNTI %x\n", rnti); + Error("Computing PUSCH dci for RNTI %x", rnti); return; } - uint32_t ul_pid = TTI_RX(ul_sf.tti) % SRSLTE_FDD_NOF_HARQ; - // Handle Format0 adaptive retx // Use last TBS for this TB in case of mcs>28 if (ul_grant.dci.tb.mcs_idx > 28) { int rv_idx = grant.tb.rv; - grant.tb = phy->ue_db.get_last_ul_tb(rnti, cc_idx, ul_pid); + grant.tb = phy->ue_db.get_last_ul_tb(rnti, cc_idx, ul_grant.pid); grant.tb.rv = rv_idx; - Info("Adaptive retx: rnti=0x%x, pid=%d, rv_idx=%d, mcs=%d, old_tbs=%d\n", + Info("Adaptive retx: rnti=0x%x, pid=%d, rv_idx=%d, mcs=%d, old_tbs=%d", rnti, - ul_pid, + ul_grant.pid, grant.tb.rv, ul_grant.dci.tb.mcs_idx, grant.tb.tbs / 8); } - phy->ue_db.set_last_ul_tb(rnti, cc_idx, ul_pid, grant.tb); + phy->ue_db.set_last_ul_tb(rnti, cc_idx, ul_grant.pid, grant.tb); // Run PUSCH decoder ul_cfg.pusch.softbuffers.rx = ul_grant.softbuffer_rx; pusch_res.data = ul_grant.data; if (pusch_res.data) { if (srslte_enb_ul_get_pusch(&enb_ul, &ul_sf, &ul_cfg.pusch, &pusch_res)) { - Error("Decoding PUSCH for RNTI %x\n", rnti); + Error("Decoding PUSCH for RNTI %x", rnti); return; } } @@ -385,10 +382,10 @@ void cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, // Push PDU buffer phy->stack->push_pdu(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc); // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_pusch_rx_info(&ul_cfg.pusch, &pusch_res, &enb_ul.chest_res, str, sizeof(str)); - log_h->info("PUSCH: cc=%d, %s\n", cc_idx, str); + logger.info("PUSCH: cc=%d, %s", cc_idx, str); } } } @@ -409,7 +406,7 @@ int cc_worker::decode_pucch() if (phy->ue_db.fill_uci_cfg(tti_rx, cc_idx, rnti, false, false, ul_cfg.pucch.uci_cfg)) { // Decode PUCCH if (srslte_enb_ul_get_pucch(&enb_ul, &ul_sf, &ul_cfg.pucch, &pucch_res)) { - ERROR("Error getting PUCCH\n"); + ERROR("Error getting PUCCH"); return SRSLTE_ERROR; } @@ -422,10 +419,10 @@ int cc_worker::decode_pucch() } // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_pucch_rx_info(&ul_cfg.pucch, &pucch_res, str, sizeof(str)); - log_h->info("PUCCH: cc=%d; %s\n", cc_idx, str); + logger.info("PUCCH: cc=%d; %s", cc_idx, str); } // Save metrics @@ -442,7 +439,7 @@ int cc_worker::encode_phich(stack_interface_phy_lte::ul_sched_ack_t* acks, uint3 if (acks[i].rnti && ue_db.count(acks[i].rnti)) { srslte_enb_dl_put_phich(&enb_dl, &ue_db[acks[i].rnti]->phich_grant, acks[i].ack); - Info("PHICH: rnti=0x%x, hi=%d, I_lowest=%d, n_dmrs=%d, tti_tx_dl=%d\n", + Info("PHICH: rnti=0x%x, hi=%d, I_lowest=%d, n_dmrs=%d, tti_tx_dl=%d", acks[i].rnti, acks[i].ack, ue_db[acks[i].rnti]->phich_grant.n_prb_lowest, @@ -468,15 +465,15 @@ int cc_worker::encode_pdcch_ul(stack_interface_phy_lte::ul_sched_grant_t* grants } if (srslte_enb_dl_put_pdcch_ul(&enb_dl, &dci_cfg, &grants[i].dci)) { - ERROR("Error putting PUSCH %d\n", i); + ERROR("Error putting PUSCH %d", i); return SRSLTE_ERROR; } // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_dci_ul_info(&grants[i].dci, str, 512); - log_h->info("PDCCH: cc=%d, %s, tti_tx_dl=%d\n", cc_idx, str, tti_tx_dl); + logger.info("PDCCH: cc=%d, %s, tti_tx_dl=%d", cc_idx, str, tti_tx_dl); } } } @@ -498,15 +495,15 @@ int cc_worker::encode_pdcch_dl(stack_interface_phy_lte::dl_sched_grant_t* grants } if (srslte_enb_dl_put_pdcch_dl(&enb_dl, &dci_cfg, &grants[i].dci)) { - ERROR("Error putting PDCCH %d\n", i); + ERROR("Error putting PDCCH %d", i); return SRSLTE_ERROR; } - if (LOG_THIS(rnti) and log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (LOG_THIS(rnti) and logger.info.enabled()) { // Logging char str[512]; srslte_dci_dl_info(&grants[i].dci, str, 512); - log_h->info("PDCCH: cc=%d, %s, tti_tx_dl=%d\n", cc_idx, str, tti_tx_dl); + logger.info("PDCCH: cc=%d, %s, tti_tx_dl=%d", cc_idx, str, tti_tx_dl); } } } @@ -525,15 +522,15 @@ int cc_worker::encode_pmch(stack_interface_phy_lte::dl_sched_grant_t* grant, srs // Encode PMCH if (srslte_enb_dl_put_pmch(&enb_dl, &pmch_cfg, grant->data[0])) { - Error("Error putting PMCH\n"); + Error("Error putting PMCH"); return SRSLTE_ERROR; } // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_pdsch_tx_info(&pmch_cfg.pdsch_cfg, str, 512); - log_h->info("PMCH: %s\n", str); + logger.info("PMCH: %s", str); } // Save metrics stats @@ -557,7 +554,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, u // Compute DL grant if (srslte_ra_dl_dci_to_grant( &enb_dl.cell, &dl_sf, dl_cfg.tm, dl_cfg.pdsch.use_tbs_index_alt, &grants[i].dci, &dl_cfg.pdsch.grant)) { - Error("Computing DL grant\n"); + Error("Computing DL grant"); } // Set soft buffer @@ -567,7 +564,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, u // Encode PDSCH if (srslte_enb_dl_put_pdsch(&enb_dl, &dl_cfg.pdsch, grants[i].data)) { - Error("Error putting PDSCH %d\n", i); + Error("Error putting PDSCH %d", i); return SRSLTE_ERROR; } @@ -577,17 +574,17 @@ int cc_worker::encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, u phy->ue_db.set_ack_pending(tti_tx_ul, cc_idx, grants[i].dci); } - if (LOG_THIS(rnti) and log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (LOG_THIS(rnti) and logger.info.enabled()) { // Logging char str[512]; srslte_pdsch_tx_info(&dl_cfg.pdsch, str, 512); - log_h->info("PDSCH: cc=%d, %s, tti_tx_dl=%d\n", cc_idx, str, tti_tx_dl); + logger.info("PDSCH: cc=%d, %s, tti_tx_dl=%d", cc_idx, str, tti_tx_dl); } // Save metrics stats ue_db[rnti]->metrics_dl(grants[i].dci.tb[0].mcs_idx); } else { - Error("User rnti=0x%x not found in cc_worker=%d\n", rnti, cc_idx); + Error("User rnti=0x%x not found in cc_worker=%d", rnti, cc_idx); } } diff --git a/srsenb/src/phy/lte/sf_worker.cc b/srsenb/src/phy/lte/sf_worker.cc index 0ab31a892..71db441ab 100644 --- a/srsenb/src/phy/lte/sf_worker.cc +++ b/srsenb/src/phy/lte/sf_worker.cc @@ -27,16 +27,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) using namespace std; @@ -73,31 +73,30 @@ namespace lte { FILE* f; #endif -void sf_worker::init(phy_common* phy_, srslte::log* log_h_) +void sf_worker::init(phy_common* phy_) { - phy = phy_; - log_h = log_h_; + phy = phy_; // Initialise each component carrier workers for (uint32_t i = 0; i < phy->get_nof_carriers_lte(); i++) { // Create pointer - auto q = new cc_worker(); + auto q = new cc_worker(logger); // Initialise - q->init(phy, log_h, i); + q->init(phy, i); // Create unique pointer cc_workers.push_back(std::unique_ptr(q)); } if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, phy->get_nof_prb(0))) { - ERROR("Error initiating soft buffer\n"); + ERROR("Error initiating soft buffer"); exit(-1); } srslte_softbuffer_tx_reset(&temp_mbsfn_softbuffer); - Info("Worker %d configured cell %d PRB\n", get_id(), phy->get_nof_prb(0)); + Info("Worker %d configured cell %d PRB", get_id(), phy->get_nof_prb(0)); initiated = true; running = true; @@ -197,9 +196,9 @@ void sf_worker::work_imp() stack_interface_phy_lte* stack = phy->stack; - log_h->step(tti_rx); + logger.set_context(tti_rx); - Debug("Worker %d running\n", get_id()); + Debug("Worker %d running", get_id()); // Configure UL subframe ul_sf.tti = tti_rx; @@ -215,14 +214,14 @@ void sf_worker::work_imp() // Get DL scheduling for the TX TTI from MAC if (sf_type == SRSLTE_SF_NORM) { if (stack->get_dl_sched(tti_tx_dl, dl_grants) < 0) { - Error("Getting DL scheduling from MAC\n"); + Error("Getting DL scheduling from MAC"); phy->worker_end(this, tx_buffer, tx_time); return; } } else { dl_grants[0].cfi = mbsfn_cfg.non_mbsfn_region_length; if (stack->get_mch_sched(tti_tx_dl, mbsfn_cfg.is_mcch, dl_grants)) { - Error("Getting MCH packets from MAC\n"); + Error("Getting MCH packets from MAC"); phy->worker_end(this, tx_buffer, tx_time); return; } @@ -234,7 +233,7 @@ void sf_worker::work_imp() // Get UL scheduling for the TX TTI from MAC if (stack->get_ul_sched(tti_tx_ul, ul_grants_tx) < 0) { - Error("Getting UL scheduling from MAC\n"); + Error("Getting UL scheduling from MAC"); phy->worker_end(this, tx_buffer, tx_time); return; } @@ -257,7 +256,7 @@ void sf_worker::work_imp() phy->set_ul_grants(t_tx_ul, ul_grants_tx); phy->set_ul_grants(t_rx, ul_grants); - Debug("Sending to radio\n"); + Debug("Sending to radio"); tx_buffer.set_nof_samples(SRSLTE_SF_LEN_PRB(phy->get_nof_prb(0))); phy->worker_end(this, tx_buffer, tx_time); diff --git a/srsenb/src/phy/lte/worker_pool.cc b/srsenb/src/phy/lte/worker_pool.cc index 87a16c510..4e1458641 100644 --- a/srsenb/src/phy/lte/worker_pool.cc +++ b/srsenb/src/phy/lte/worker_pool.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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 "srsenb/hdr/phy/lte/worker_pool.h" @@ -25,24 +16,17 @@ namespace lte { worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {} -bool worker_pool::init(const phy_args_t& args, phy_common* common, srslte::logger* logger, int prio) +bool worker_pool::init(const phy_args_t& args, phy_common* common, srslog::sink& log_sink, int prio) { - // Create logs - // Create array of pointers to phy_logs + // Add workers to workers pool and start threads. + srslog::basic_levels log_level = srslog::str_to_basic_level(args.log.phy_level); for (uint32_t i = 0; i < args.nof_phy_threads; i++) { - auto* mylog = new srslte::log_filter; - char tmp[16]; - sprintf(tmp, "PHY%d", i); - mylog->init(tmp, logger, true); - mylog->set_level(args.log.phy_level); - mylog->set_hex_limit(args.log.phy_hex_limit); - log_vec.push_back(std::unique_ptr(mylog)); - } + auto& log = srslog::fetch_basic_logger(fmt::format("PHY{}", i), log_sink); + log.set_level(log_level); + log.set_hex_dump_max_size(args.log.phy_hex_limit); - // Add workers to workers pool and start threads - for (uint32_t i = 0; i < args.nof_phy_threads; i++) { - auto w = std::unique_ptr(new sf_worker()); - w->init(common, (srslte::log*)log_vec[i].get()); + auto w = std::unique_ptr(new sf_worker(log)); + w->init(common); pool.init_worker(i, w.get(), prio); workers.push_back(std::move(w)); } diff --git a/srsenb/src/phy/nr/cc_worker.cc b/srsenb/src/phy/nr/cc_worker.cc index 3309e560e..6e2d5a154 100644 --- a/srsenb/src/phy/nr/cc_worker.cc +++ b/srsenb/src/phy/nr/cc_worker.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -24,8 +15,8 @@ namespace srsenb { namespace nr { -cc_worker::cc_worker(uint32_t cc_idx_, srslte::log* log, phy_nr_state* phy_state_) : - cc_idx(cc_idx_), phy_state(phy_state_), log_h(log) +cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, phy_nr_state* phy_state_) : + cc_idx(cc_idx_), phy_state(phy_state_), logger(log) { cf_t* buffer_c[SRSLTE_MAX_PORTS] = {}; @@ -38,7 +29,7 @@ cc_worker::cc_worker(uint32_t cc_idx_, srslte::log* log, phy_nr_state* phy_state } if (srslte_enb_dl_nr_init(&enb_dl, buffer_c, &phy_state_->args.dl)) { - ERROR("Error initiating UE DL NR\n"); + ERROR("Error initiating UE DL NR"); return; } } @@ -61,7 +52,7 @@ cc_worker::~cc_worker() bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier) { if (srslte_enb_dl_nr_set_carrier(&enb_dl, carrier) < SRSLTE_SUCCESS) { - ERROR("Error setting carrier\n"); + ERROR("Error setting carrier"); return false; } @@ -70,7 +61,7 @@ bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier) coreset.duration = 2; if (srslte_enb_dl_nr_set_coreset(&enb_dl, &coreset) < SRSLTE_SUCCESS) { - ERROR("Error setting coreset\n"); + ERROR("Error setting coreset"); return false; } @@ -108,18 +99,17 @@ uint32_t cc_worker::get_buffer_len() int cc_worker::encode_pdcch_dl(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants) { for (uint32_t i = 0; i < nof_grants; i++) { - // Get PHY config for UE // ... // Put actual DCI if (srslte_enb_dl_nr_pdcch_put(&enb_dl, &dl_slot_cfg, &grants[i].dci) < SRSLTE_SUCCESS) { - ERROR("Error putting PDCCH\n"); + ERROR("Error putting PDCCH"); return SRSLTE_ERROR; } - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { - log_h->info("PDCCH: cc=%d, ...\n", cc_idx); + if (logger.info.enabled()) { + logger.info("PDCCH: cc=%d, ...", cc_idx); } } @@ -129,14 +119,14 @@ int cc_worker::encode_pdcch_dl(stack_interface_phy_nr::dl_sched_grant_t* grants, int cc_worker::encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants) { for (uint32_t i = 0; i < nof_grants; i++) { - // Get PHY config for UE // ... - srslte_sch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; + srslte_sch_hl_cfg_nr_t pdsch_hl_cfg = {}; + srslte_sch_cfg_nr_t pdsch_cfg = {}; // Compute DL grant - if (srslte_ra_dl_dci_to_grant_nr(&enb_dl.carrier, &pdsch_cfg, &grants[i].dci, &pdsch_cfg.grant)) { - ERROR("Computing DL grant\n"); + if (srslte_ra_dl_dci_to_grant_nr(&enb_dl.carrier, &pdsch_hl_cfg, &grants[i].dci, &pdsch_cfg, &pdsch_cfg.grant)) { + ERROR("Computing DL grant"); } // Set soft buffer @@ -145,26 +135,26 @@ int cc_worker::encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, ui } if (srslte_enb_dl_nr_pdsch_put(&enb_dl, &dl_slot_cfg, &pdsch_cfg, grants[i].data) < SRSLTE_SUCCESS) { - ERROR("Error putting PDSCH\n"); + ERROR("Error putting PDSCH"); return false; } // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_enb_dl_nr_pdsch_info(&enb_dl, &pdsch_cfg, str, sizeof(str)); - log_h->info("PDSCH: cc=%d, %s\n", cc_idx, str); + logger.info("PDSCH: cc=%d, %s", cc_idx, str); } } return SRSLTE_SUCCESS; } -bool cc_worker::work_dl(const srslte_dl_slot_cfg_t& dl_sf_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants) +bool cc_worker::work_dl(const srslte_slot_cfg_t& dl_sf_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants) { // Reset resource grid if (srslte_enb_dl_nr_base_zero(&enb_dl) < SRSLTE_SUCCESS) { - ERROR("Error setting base to zero\n"); + ERROR("Error setting base to zero"); return SRSLTE_ERROR; } diff --git a/srsenb/src/phy/nr/sf_worker.cc b/srsenb/src/phy/nr/sf_worker.cc index de12d10d8..8a7b85cb8 100644 --- a/srsenb/src/phy/nr/sf_worker.cc +++ b/srsenb/src/phy/nr/sf_worker.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -23,17 +14,17 @@ namespace srsenb { namespace nr { -sf_worker::sf_worker(phy_common* phy_, phy_nr_state* phy_state_, srslte::log* log) : - phy(phy_), phy_state(phy_state_), log_h(log) +sf_worker::sf_worker(phy_common* phy_, phy_nr_state* phy_state_, srslog::basic_logger& logger) : + phy(phy_), phy_state(phy_state_), logger(logger) { for (uint32_t i = 0; i < phy_state->args.nof_carriers; i++) { - cc_worker* w = new cc_worker(i, log, phy_state); + cc_worker* w = new cc_worker(i, logger, phy_state); cc_workers.push_back(std::unique_ptr(w)); } if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); return; } data.resize(SRSLTE_SCH_NR_MAX_NOF_CB_LDPC * SRSLTE_LDPC_MAX_LEN_ENCODED_CB / 8); @@ -80,7 +71,7 @@ uint32_t sf_worker::get_buffer_len() void sf_worker::set_tti(uint32_t tti) { - log_h->step(tti); + logger.set_context(tti); for (auto& w : cc_workers) { w->set_tti(tti); } @@ -98,11 +89,10 @@ void sf_worker::work_imp() } // Configure user - phy_state->cfg.pdsch.rbg_size_cfg_1 = false; - phy_state->cfg.pdsch.pdsch_time_is_default = true; + phy_state->cfg.pdsch.rbg_size_cfg_1 = false; // Fill grant (this comes from the scheduler) - srslte_dl_slot_cfg_t dl_cfg = {}; + srslte_slot_cfg_t dl_cfg = {}; stack_interface_phy_nr::dl_sched_t grants = {}; grants.nof_grants = 1; @@ -117,10 +107,8 @@ void sf_worker::work_imp() grants.pdsch[0].dci.time_domain_assigment = 0; grants.pdsch[0].dci.mcs = 27; - grants.pdsch[0].dci.search_space.type = srslte_search_space_type_ue; - for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - grants.pdsch[0].dci.search_space.nof_candidates[L] = 1; - } + grants.pdsch[0].dci.search_space = srslte_search_space_type_ue; + grants.pdsch[0].dci.coreset_id = 1; grants.pdsch[0].dci.location.L = 0; grants.pdsch[0].dci.location.ncce = 0; diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index 6d68b3930..771560d36 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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 "srsenb/hdr/phy/nr/worker_pool.h" @@ -25,23 +16,16 @@ namespace nr { worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {} -bool worker_pool::init(const phy_args_t& args, phy_common* common, srslte::logger* logger, int prio) +bool worker_pool::init(const phy_args_t& args, phy_common* common, srslog::sink& log_sink, int prio) { - // Create logs - // Create array of pointers to phy_logs - for (uint32_t i = 0; i < args.nof_phy_threads; i++) { - auto* mylog = new srslte::log_filter; - char tmp[16]; - sprintf(tmp, "PHY%d", i); - mylog->init(tmp, logger, true); - mylog->set_level(args.log.phy_level); - mylog->set_hex_limit(args.log.phy_hex_limit); - log_vec.push_back(std::unique_ptr(mylog)); - } - // Add workers to workers pool and start threads + srslog::basic_levels log_level = srslog::str_to_basic_level(args.log.phy_level); for (uint32_t i = 0; i < args.nof_phy_threads; i++) { - auto w = new sf_worker(common, &phy_state, (srslte::log*)log_vec[i].get()); + auto& log = srslog::fetch_basic_logger(fmt::format("PHY{}", i), log_sink); + log.set_level(log_level); + log.set_hex_dump_max_size(args.log.phy_hex_limit); + + auto w = new sf_worker(common, &phy_state, log); pool.init_worker(i, w, prio); workers.push_back(std::unique_ptr(w)); diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index ea5c20d97..0aa025a62 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -33,16 +33,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + phy_log.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + phy_log.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + phy_log.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + phy_log.debug(fmt, ##__VA_ARGS__) using namespace std; using namespace asn1::rrc; @@ -57,27 +57,30 @@ static void srslte_phy_handler(phy_logger_level_t log_level, void* ctx, char* st void phy::srslte_phy_logger(phy_logger_level_t log_level, char* str) { - if (log_phy_lib_h) { - switch (log_level) { - case LOG_LEVEL_INFO_S: - log_phy_lib_h->info(" %s", str); - break; - case LOG_LEVEL_DEBUG_S: - log_phy_lib_h->debug(" %s", str); - break; - case LOG_LEVEL_ERROR_S: - log_phy_lib_h->error(" %s", str); - break; - default: - break; - } - } else { - printf("[PHY_LIB]: %s\n", str); + switch (log_level) { + case LOG_LEVEL_INFO_S: + phy_lib_log.info(" %s", str); + break; + case LOG_LEVEL_DEBUG_S: + phy_lib_log.debug(" %s", str); + break; + case LOG_LEVEL_ERROR_S: + phy_lib_log.error(" %s", str); + break; + default: + break; } } -phy::phy(srslte::logger* logger_) : - logger(logger_), lte_workers(MAX_WORKERS), nr_workers(MAX_WORKERS), workers_common(), nof_workers(0) +phy::phy(srslog::sink& log_sink) : + log_sink(log_sink), + phy_log(srslog::fetch_basic_logger("PHY", log_sink)), + phy_lib_log(srslog::fetch_basic_logger("PHY_LIB", log_sink)), + lte_workers(MAX_WORKERS), + nr_workers(MAX_WORKERS), + workers_common(), + nof_workers(0), + tx_rx(phy_log) {} phy::~phy() @@ -108,22 +111,18 @@ int phy::init(const phy_args_t& args, { mlockall((uint32_t)MCL_CURRENT | (uint32_t)MCL_FUTURE); - // Add PHY lib log - if (srslte::log::get_level_from_string(args.log.phy_lib_level) != srslte::LOG_LEVEL_NONE) { - log_phy_lib_h = std::unique_ptr(new srslte::log_filter); - log_phy_lib_h->init("PHY_LIB", logger, true); - log_phy_lib_h->set_level(args.log.phy_lib_level); - log_phy_lib_h->set_hex_limit(args.log.phy_hex_limit); + // Add PHY lib log. + srslog::basic_levels log_lvl = srslog::str_to_basic_level(args.log.phy_lib_level); + + phy_lib_log.set_level(log_lvl); + phy_lib_log.set_hex_dump_max_size(args.log.phy_hex_limit); + if (log_lvl != srslog::basic_levels::none) { srslte_phy_log_register_handler(this, srslte_phy_handler); } - // Create default log - { - log_h = std::unique_ptr(new srslte::log_filter); - log_h->init("PHY", logger, true); - log_h->set_level(args.log.phy_level); - log_h->set_hex_limit(args.log.phy_hex_limit); - } + // Create default log. + phy_log.set_level(log_lvl); + phy_log.set_hex_dump_max_size(args.log.phy_hex_limit); radio = radio_; nof_workers = args.nof_phy_threads; @@ -135,24 +134,19 @@ int phy::init(const phy_args_t& args, parse_common_config(cfg); // Add workers to workers pool and start threads - lte_workers.init(args, &workers_common, logger, WORKERS_THREAD_PRIO); - nr_workers.init(args, &workers_common, logger, WORKERS_THREAD_PRIO); + lte_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO); + nr_workers.init(args, &workers_common, log_sink, WORKERS_THREAD_PRIO); // For each carrier, initialise PRACH worker for (uint32_t cc = 0; cc < cfg.phy_cell_cfg.size(); cc++) { prach_cfg.root_seq_idx = cfg.phy_cell_cfg[cc].root_seq_idx; - prach.init(cc, - cfg.phy_cell_cfg[cc].cell, - prach_cfg, - stack_, - log_h.get(), - PRACH_WORKER_THREAD_PRIO, - args.nof_prach_threads); + prach.init( + cc, cfg.phy_cell_cfg[cc].cell, prach_cfg, stack_, phy_log, PRACH_WORKER_THREAD_PRIO, args.nof_prach_threads); } prach.set_max_prach_offset_us(args.max_prach_offset_us); // Warning this must be initialized after all workers have been added to the pool - tx_rx.init(stack_, radio, <e_workers, &nr_workers, &workers_common, &prach, log_h.get(), SF_RECV_THREAD_PRIO); + tx_rx.init(stack_, radio, <e_workers, &nr_workers, &workers_common, &prach, SF_RECV_THREAD_PRIO); initialized = true; @@ -246,7 +240,7 @@ void phy::get_metrics(std::vector& metrics) void phy::cmd_cell_gain(uint32_t cell_id, float gain_db) { - Info("set_cell_gain: cell_id=%d, gain_db=%.2f\n", cell_id, gain_db); + Info("set_cell_gain: cell_id=%d, gain_db=%.2f", cell_id, gain_db); workers_common.set_cell_gain(cell_id, gain_db); } @@ -281,10 +275,10 @@ void phy::configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, con { if (sib2->mbsfn_sf_cfg_list_present) { if (sib2->nof_mbsfn_sf_cfg == 0) { - Warning("SIB2 does not have any MBSFN config although it was set as present\n"); + Warning("SIB2 does not have any MBSFN config although it was set as present"); } else { if (sib2->nof_mbsfn_sf_cfg > 1) { - Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", sib2->nof_mbsfn_sf_cfg); + Warning("SIB2 has %d MBSFN subframe configs - only 1 supported", sib2->nof_mbsfn_sf_cfg); } mbsfn_config.mbsfn_subfr_cnfg = sib2->mbsfn_sf_cfg_list[0]; } @@ -296,7 +290,7 @@ void phy::configure_mbsfn(srslte::sib2_mbms_t* sib2, srslte::sib13_t* sib13, con mbsfn_config.mbsfn_notification_cnfg = sib13->notif_cfg; if (sib13->nof_mbsfn_area_info > 0) { if (sib13->nof_mbsfn_area_info > 1) { - Warning("SIB13 has %d MBSFN area info elements - only 1 supported\n", sib13->nof_mbsfn_area_info); + Warning("SIB13 has %d MBSFN area info elements - only 1 supported", sib13->nof_mbsfn_area_info); } mbsfn_config.mbsfn_area_info = sib13->mbsfn_area_info_list[0]; } diff --git a/srsenb/src/phy/phy_common.cc b/srsenb/src/phy/phy_common.cc index e33e34804..7ceda9809 100644 --- a/srsenb/src/phy/phy_common.cc +++ b/srsenb/src/phy/phy_common.cc @@ -26,19 +26,6 @@ #include -#define Error(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) - using namespace std; using namespace asn1::rrc; @@ -68,7 +55,8 @@ bool phy_common::init(const phy_cell_cfg_list_t& cell_list_, // Instantiate DL channel emulator if (params.dl_channel_args.enable) { - dl_channel = srslte::channel_ptr(new srslte::channel(params.dl_channel_args, get_nof_rf_channels())); + dl_channel = srslte::channel_ptr( + new srslte::channel(params.dl_channel_args, get_nof_rf_channels(), srslog::fetch_basic_logger("PHY"))); dl_channel->set_srate((uint32_t)srslte_sampling_freq_hz(cell_list_lte[0].cell.nof_prb)); dl_channel->set_signal_power_dBfs(srslte_enb_dl_get_maximum_signal_power_dBfs(cell_list_lte[0].cell.nof_prb)); } diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index a2c0a8767..69736d52b 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -138,7 +138,7 @@ uint32_t phy_ue_db::_get_uci_enb_cc_idx(uint32_t tti, uint16_t rnti) const inline int phy_ue_db::_assert_rnti(uint16_t rnti) const { if (not ue_db.count(rnti)) { - ERROR("Trying to access RNTI 0x%X, it does not exist.\n", rnti); + ERROR("Trying to access RNTI 0x%X, it does not exist.", rnti); return SRSLTE_ERROR; } @@ -242,7 +242,7 @@ inline srslte::phy_cfg_t phy_ue_db::_get_rnti_config(uint16_t rnti, uint32_t enb // Make sure the C-RNTI exists and the cell/carrier is configured if (_assert_enb_cc(rnti, enb_cc_idx) != SRSLTE_SUCCESS) { - ERROR("Trying to access cell/carrier %d in RNTI 0x%X. It is not active.\n", enb_cc_idx, rnti); + ERROR("Trying to access cell/carrier %d in RNTI 0x%X. It is not active.", enb_cc_idx, rnti); return default_cfg; } @@ -392,7 +392,7 @@ void phy_ue_db::activate_deactivate_scell(uint16_t rnti, uint32_t ue_cc_idx, boo // If scell is default only complain if (activate and cell_info.state == cell_state_none) { - ERROR("RNTI 0x%X SCell %d has received an activation MAC command but it was not configured\n", rnti, ue_cc_idx); + ERROR("RNTI 0x%X SCell %d has received an activation MAC command but it was not configured", rnti, ue_cc_idx); return; } // Set scell state @@ -668,7 +668,7 @@ void phy_ue_db::send_uci_data(uint32_t tti, pmi_value = uci_value.cqi.subband_hl.pmi; break; default: - ERROR("CQI type=%d not implemented for PMI\n", uci_cfg.cqi.type); + ERROR("CQI type=%d not implemented for PMI", uci_cfg.cqi.type); break; } stack->pmi_info(tti, rnti, cqi_cc_idx, pmi_value); diff --git a/srsenb/src/phy/prach_worker.cc b/srsenb/src/phy/prach_worker.cc index 8dd39ecce..d17df0070 100644 --- a/srsenb/src/phy/prach_worker.cc +++ b/srsenb/src/phy/prach_worker.cc @@ -20,6 +20,7 @@ */ #include "srsenb/hdr/phy/prach_worker.h" +#include "srslte/interfaces/enb_mac_interfaces.h" #include "srslte/srslte.h" namespace srsenb { @@ -27,11 +28,9 @@ namespace srsenb { int prach_worker::init(const srslte_cell_t& cell_, const srslte_prach_cfg_t& prach_cfg_, stack_interface_phy_lte* stack_, - srslte::log* log_h_, int priority, uint32_t nof_workers_) { - log_h = log_h_; stack = stack_; prach_cfg = prach_cfg_; cell = cell_; @@ -44,7 +43,7 @@ int prach_worker::init(const srslte_cell_t& cell_, } if (srslte_prach_set_cfg(&prach, &prach_cfg, cell.nof_prb)) { - ERROR("Error initiating PRACH\n"); + ERROR("Error initiating PRACH"); return -1; } @@ -100,12 +99,12 @@ int prach_worker::new_tti(uint32_t tti_rx, cf_t* buffer_rx) if (sf_cnt == 0) { current_buffer = buffer_pool.allocate(); if (!current_buffer) { - log_h->warning("PRACH skipping tti=%d due to lack of available buffers\n", tti_rx); + logger.warning("PRACH skipping tti=%d due to lack of available buffers", tti_rx); return 0; } } if (!current_buffer) { - log_h->error("PRACH: Expected available current_buffer\n"); + logger.error("PRACH: Expected available current_buffer"); return -1; } if (current_buffer->nof_samples + SRSLTE_SF_LEN_PRB(cell.nof_prb) < sf_buffer_sz) { @@ -117,7 +116,7 @@ int prach_worker::new_tti(uint32_t tti_rx, cf_t* buffer_rx) current_buffer->tti = tti_rx; } } else { - log_h->error("PRACH: Not enough space in current_buffer\n"); + logger.error("PRACH: Not enough space in current_buffer"); return -1; } sf_cnt++; @@ -148,13 +147,13 @@ int prach_worker::run_tti(sf_buffer* b) prach_offsets, prach_p2avg, &prach_nof_det)) { - log_h->error("Error detecting PRACH\n"); + logger.error("Error detecting PRACH"); return SRSLTE_ERROR; } if (prach_nof_det) { for (uint32_t i = 0; i < prach_nof_det; i++) { - log_h->info("PRACH: cc=%d, %d/%d, preamble=%d, offset=%.1f us, peak2avg=%.1f, max_offset=%.1f us\n", + logger.info("PRACH: cc=%d, %d/%d, preamble=%d, offset=%.1f us, peak2avg=%.1f, max_offset=%.1f us", cc_idx, i, prach_nof_det, diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index 3085e84cd..4e98a1e28 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -29,22 +29,22 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) using namespace std; namespace srsenb { -txrx::txrx() : thread("TXRX") +txrx::txrx(srslog::basic_logger& logger) : thread("TXRX"), logger(logger) { /* Do nothing */ } @@ -55,12 +55,10 @@ bool txrx::init(stack_interface_phy_lte* stack_, nr::worker_pool* nr_workers_, phy_common* worker_com_, prach_worker_pool* prach_, - srslte::log* log_h_, uint32_t prio_) { stack = stack_; radio_h = radio_h_; - log_h = log_h_; lte_workers = lte_workers_; nr_workers = nr_workers_; worker_com = worker_com_; @@ -72,8 +70,8 @@ bool txrx::init(stack_interface_phy_lte* stack_, // Instantiate UL channel emulator if (worker_com->params.ul_channel_args.enable) { - ul_channel = - srslte::channel_ptr(new srslte::channel(worker_com->params.ul_channel_args, worker_com->get_nof_rf_channels())); + ul_channel = srslte::channel_ptr( + new srslte::channel(worker_com->params.ul_channel_args, worker_com->get_nof_rf_channels(), logger)); } start(prio_); @@ -119,7 +117,7 @@ void txrx::run_thread() ul_channel->set_srate(static_cast(samp_rate)); } - log_h->info("Starting RX/TX thread nof_prb=%d, sf_len=%d\n", worker_com->get_nof_prb(0), sf_len); + logger.info("Starting RX/TX thread nof_prb=%d, sf_len=%d", worker_com->get_nof_prb(0), sf_len); // Set TTI so that first TX is at tti=0 tti = TTI_SUB(0, FDD_HARQ_DELAY_UL_MS + 1); @@ -127,10 +125,7 @@ void txrx::run_thread() // Main loop while (running) { tti = TTI_ADD(tti, 1); - - if (log_h) { - log_h->step(tti); - } + logger.set_context(tti); lte::sf_worker* lte_worker = nullptr; if (worker_com->get_nof_carriers_lte() > 0) { @@ -182,7 +177,7 @@ void txrx::run_thread() // Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time timestamp.add(FDD_HARQ_DELAY_UL_MS * 1e-3); - Debug("Setting TTI=%d, tx_mutex=%d, tx_time=%ld:%f to worker %d\n", + Debug("Setting TTI=%d, tx_mutex=%d, tx_time=%ld:%f to worker %d", tti, tx_worker_cnt, timestamp.get(0).full_secs, diff --git a/srsenb/src/phy/vnf_phy_nr.cc b/srsenb/src/phy/vnf_phy_nr.cc index 3ec6a8a38..b5a5cfa07 100644 --- a/srsenb/src/phy/vnf_phy_nr.cc +++ b/srsenb/src/phy/vnf_phy_nr.cc @@ -37,8 +37,6 @@ using namespace std; namespace srsenb { -vnf_phy_nr::vnf_phy_nr(srslte::logger* logger_) : logger(logger_) {} - vnf_phy_nr::~vnf_phy_nr() { stop(); @@ -51,7 +49,7 @@ int vnf_phy_nr::init(const srsenb::phy_args_t& args, const nr_phy_cfg_t& cfg, sr mlockall(MCL_CURRENT | MCL_FUTURE); // create VNF - vnf = std::unique_ptr(new srslte::srslte_basic_vnf(args.vnf_args, logger, stack_)); + vnf = std::unique_ptr(new srslte::srslte_basic_vnf(args.vnf_args, stack_)); initialized = true; diff --git a/srsenb/src/stack/CMakeLists.txt b/srsenb/src/stack/CMakeLists.txt index cad351fb0..2315009a1 100644 --- a/srsenb/src/stack/CMakeLists.txt +++ b/srsenb/src/stack/CMakeLists.txt @@ -27,7 +27,5 @@ set(SOURCES enb_stack_lte.cc) add_library(srsenb_stack STATIC ${SOURCES}) target_link_libraries(srsenb_stack) -if(ENABLE_5GNR) - add_library(srsgnb_stack STATIC gnb_stack_nr.cc) - target_link_libraries(srsgnb_stack srsue_upper) -endif() +add_library(srsgnb_stack STATIC gnb_stack_nr.cc) +target_link_libraries(srsgnb_stack srsue_upper) diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 1c83392ee..4357a548b 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -29,21 +29,29 @@ using namespace srslte; namespace srsenb { -enb_stack_lte::enb_stack_lte(srslte::logger* logger_) : - task_sched(512, 0, 128), - logger(logger_), - pdcp(&task_sched, "PDCP"), +enb_stack_lte::enb_stack_lte(srslte::logger* logger_, srslog::sink& log_sink) : thread("STACK"), - mac(&task_sched), - s1ap(&task_sched), - rrc(&task_sched) + mac_logger(srslog::fetch_basic_logger("MAC", log_sink)), + rlc_logger(srslog::fetch_basic_logger("RLC", log_sink, false)), + pdcp_logger(srslog::fetch_basic_logger("PDCP", log_sink, false)), + rrc_logger(srslog::fetch_basic_logger("RRC", log_sink, false)), + s1ap_logger(srslog::fetch_basic_logger("S1AP", log_sink, false)), + gtpu_logger(srslog::fetch_basic_logger("GTPU", log_sink, false)), + stack_logger(srslog::fetch_basic_logger("STCK", log_sink, false)), + task_sched(512, 0, 128), + pdcp(&task_sched, pdcp_logger), + mac(&task_sched, mac_logger), + rlc(rlc_logger), + gtpu(gtpu_logger), + s1ap(&task_sched, s1ap_logger), + rrc(&task_sched), + logger(logger_), + mac_pcap(srslte_rat_t::lte) { enb_task_queue = task_sched.make_task_queue(); mme_task_queue = task_sched.make_task_queue(); gtpu_task_queue = task_sched.make_task_queue(); // sync_queue is added in init() - - pool = byte_buffer_pool::get_instance(); } enb_stack_lte::~enb_stack_lte() @@ -75,21 +83,35 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) srslte::logmap::register_log(std::unique_ptr{new log_filter{"MAC ", logger, true}}); mac_log->set_level(args.log.mac_level); mac_log->set_hex_limit(args.log.mac_hex_limit); + mac_logger.set_level(srslog::str_to_basic_level(args.log.mac_level)); + mac_logger.set_hex_dump_max_size(args.log.mac_hex_limit); // Init logs rlc_log->set_level(args.log.rlc_level); + rlc_logger.set_level(srslog::str_to_basic_level(args.log.rlc_level)); pdcp_log->set_level(args.log.pdcp_level); + pdcp_logger.set_level(srslog::str_to_basic_level(args.log.pdcp_level)); rrc_log->set_level(args.log.rrc_level); + rrc_logger.set_level(srslog::str_to_basic_level(args.log.rrc_level)); gtpu_log->set_level(args.log.gtpu_level); + gtpu_logger.set_level(srslog::str_to_basic_level(args.log.gtpu_level)); s1ap_log->set_level(args.log.s1ap_level); + s1ap_logger.set_level(srslog::str_to_basic_level(args.log.s1ap_level)); stack_log->set_level(args.log.stack_level); + stack_logger.set_level(srslog::str_to_basic_level(args.log.stack_level)); rlc_log->set_hex_limit(args.log.rlc_hex_limit); + rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); pdcp_log->set_hex_limit(args.log.pdcp_hex_limit); + pdcp_logger.set_hex_dump_max_size(args.log.pdcp_hex_limit); rrc_log->set_hex_limit(args.log.rrc_hex_limit); + rrc_logger.set_hex_dump_max_size(args.log.rrc_hex_limit); gtpu_log->set_hex_limit(args.log.gtpu_hex_limit); + gtpu_logger.set_hex_dump_max_size(args.log.gtpu_hex_limit); s1ap_log->set_hex_limit(args.log.s1ap_hex_limit); + s1ap_logger.set_hex_dump_max_size(args.log.s1ap_hex_limit); stack_log->set_hex_limit(args.log.stack_hex_limit); + stack_logger.set_hex_dump_max_size(args.log.stack_hex_limit); // Set up pcap and trace if (args.mac_pcap.enable) { @@ -102,18 +124,21 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) } // Init Rx socket handler - rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", stack_log)); + rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", stack_logger)); // add sync queue sync_task_queue = task_sched.make_task_queue(args.sync_queue_size); // Init all layers - mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc, mac_log); - rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler(), rlc_log); + if (!mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc, mac_log)) { + stack_logger.error("Couldn't initialize MAC"); + return SRSLTE_ERROR; + } + rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler()); pdcp.init(&rlc, &rrc, >pu); rrc.init(rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, >pu); if (s1ap.init(args.s1ap, &rrc, this) != SRSLTE_SUCCESS) { - stack_log->error("Couldn't initialize S1AP\n"); + stack_logger.error("Couldn't initialize S1AP"); return SRSLTE_ERROR; } if (gtpu.init(args.s1ap.gtp_bind_addr, @@ -123,7 +148,7 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) &pdcp, this, args.embms.enable)) { - stack_log->error("Couldn't initialize GTPU\n"); + stack_logger.error("Couldn't initialize GTPU"); return SRSLTE_ERROR; } @@ -183,6 +208,7 @@ bool enb_stack_lte::get_metrics(stack_metrics_t* metrics) mac.get_metrics(metrics.mac); if (not metrics.mac.ues.empty()) { rlc.get_metrics(metrics.rlc, metrics.mac.ues[0].nof_tti); + pdcp.get_metrics(metrics.pdcp, metrics.mac.ues[0].nof_tti); } rrc.get_metrics(metrics.rrc); s1ap.get_metrics(metrics.s1ap); diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index 6b1ccea33..aeac6f5ec 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -77,7 +77,6 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, const rrc_nr_cfg_t& rr mac_args.sched = args.mac.sched; mac_args.tb_size = args.mac.nr_tb_size; mac_args.rnti = args.coreless.rnti; - mac_args.drb_lcid = args.coreless.drb_lcid; m_mac->init(mac_args, phy, this, m_rlc.get(), m_rrc.get()); srslte::logmap::get("RLC")->set_level(args.log.rlc_level); @@ -95,7 +94,8 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, const rrc_nr_cfg_t& rr m_gw->init(args.coreless.gw_args, logger, this); char* err_str = nullptr; - if (m_gw->setup_if_addr(args.coreless.drb_lcid, + if (m_gw->setup_if_addr(5, + args.coreless.drb_lcid, LIBLTE_MME_PDN_TYPE_IPV4, htonl(inet_addr(args.coreless.ip_addr.c_str())), nullptr, diff --git a/srsenb/src/stack/mac/CMakeLists.txt b/srsenb/src/stack/mac/CMakeLists.txt index 6fd59883f..90a46c042 100644 --- a/srsenb/src/stack/mac/CMakeLists.txt +++ b/srsenb/src/stack/mac/CMakeLists.txt @@ -21,10 +21,8 @@ add_subdirectory(schedulers) set(SOURCES mac.cc ue.cc sched.cc sched_carrier.cc sched_grid.cc sched_ue_ctrl/sched_harq.cc sched_ue.cc - sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_helpers.cc) + sched_ue_ctrl/sched_lch.cc sched_ue_ctrl/sched_ue_cell.cc sched_phy_ch/sf_cch_allocator.cc sched_helpers.cc) add_library(srsenb_mac STATIC ${SOURCES} $) -if(ENABLE_5GNR) - set(SOURCES mac_nr.cc) - add_library(srsgnb_mac STATIC ${SOURCES}) -endif() +set(SOURCES mac_nr.cc) +add_library(srsgnb_mac STATIC ${SOURCES}) diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index ae19d4306..287e495fc 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -20,26 +20,23 @@ */ #include -#include #include -#include -#include #include "srsenb/hdr/stack/mac/mac.h" #include "srslte/common/log.h" -#include "srslte/common/log_helper.h" #include "srslte/common/rwlock_guard.h" #include "srslte/common/time_prof.h" +#include "srslte/interfaces/enb_phy_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" //#define WRITE_SIB_PCAP using namespace asn1::rrc; namespace srsenb { -mac::mac(srslte::ext_task_sched_handle task_sched_) : - rar_payload(), - common_buffers(SRSLTE_MAX_CARRIERS), - task_sched(task_sched_) +mac::mac(srslte::ext_task_sched_handle task_sched_, srslog::basic_logger& logger) : + logger(logger), rar_payload(), common_buffers(SRSLTE_MAX_CARRIERS), task_sched(task_sched_) { pthread_rwlock_init(&rwlock, nullptr); } @@ -70,10 +67,7 @@ bool mac::init(const mac_args_t& args_, stack_task_queue = task_sched.make_task_queue(); - scheduler.init(rrc); - - // Set default scheduler configuration - scheduler.set_sched_cfg(&args.sched); + scheduler.init(rrc, args.sched); // Init softbuffer for SI messages common_buffers.resize(cells.size()); @@ -120,7 +114,7 @@ void mac::stop() // Implement Section 5.9 void mac::reset() { - Info("Resetting MAC\n"); + logger.info("Resetting MAC"); last_rnti = 70; @@ -158,7 +152,7 @@ int mac::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint ret = 0; } } else { - Error("User rnti=0x%x not found\n", rnti); + logger.error("User rnti=0x%x not found", rnti); } return ret; } @@ -170,7 +164,7 @@ int mac::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer if (ue_db.count(rnti)) { ret = scheduler.bearer_ue_cfg(rnti, lc_id, *cfg); } else { - Error("User rnti=0x%x not found\n", rnti); + logger.error("User rnti=0x%x not found", rnti); } return ret; } @@ -182,7 +176,7 @@ int mac::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) if (ue_db.count(rnti)) { ret = scheduler.bearer_ue_rem(rnti, lc_id); } else { - Error("User rnti=0x%x not found\n", rnti); + logger.error("User rnti=0x%x not found", rnti); } return ret; } @@ -200,7 +194,7 @@ int mac::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg) auto it = ue_db.find(rnti); ue* ue_ptr = nullptr; if (it == ue_db.end()) { - Error("User rnti=0x%x not found\n", rnti); + logger.error("User rnti=0x%x not found", rnti); return SRSLTE_ERROR; } ue_ptr = it->second.get(); @@ -210,18 +204,18 @@ int mac::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg) // Add RNTI to the PHY (pregenerate signals) now instead of after PRACH if (not ue_ptr->is_phy_added) { - Info("Registering RNTI=0x%X to PHY...\n", rnti); + logger.info("Registering RNTI=0x%X to PHY...", rnti); // Register new user in PHY with first CC index if (phy_h->pregen_sequences(rnti) == SRSLTE_ERROR) { - Error("Generating sequences for UE RNTI=0x%X\n", rnti); + logger.error("Generating sequences for UE RNTI=0x%X", rnti); } - Info("Done registering RNTI=0x%X to PHY...\n", rnti); + logger.info("Done registering RNTI=0x%X to PHY...", rnti); ue_ptr->is_phy_added = true; } // Update Scheduler configuration if (cfg != nullptr and scheduler.ue_cfg(rnti, *cfg) == SRSLTE_ERROR) { - Error("Registering new UE rnti=0x%x to SCHED\n", rnti); + logger.error("Registering new UE rnti=0x%x to SCHED", rnti); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -237,7 +231,7 @@ int mac::ue_rem(uint16_t rnti) ues_to_rem[rnti] = std::move(ue_db[rnti]); ue_db.erase(rnti); } else { - Error("User rnti=0x%x not found\n", rnti); + logger.error("User rnti=0x%x not found", rnti); return SRSLTE_ERROR; } } @@ -248,7 +242,7 @@ int mac::ue_rem(uint16_t rnti) task_sched.defer_callback(FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS, [this, rnti]() { phy_h->rem_rnti(rnti); ues_to_rem.erase(rnti); - Info("User rnti=0x%x removed from MAC/PHY\n", rnti); + logger.info("User rnti=0x%x removed from MAC/PHY", rnti); }); return SRSLTE_SUCCESS; } @@ -297,6 +291,7 @@ void mac::get_metrics(mac_metrics_t& metrics) int mac::ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) { + logger.set_context(tti_rx); log_h->step(tti_rx); srslte::rwlock_read_guard lock(rwlock); @@ -310,7 +305,7 @@ int mac::ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t if (ack) { if (nof_bytes > 64) { // do not count RLC status messages only rrc_h->set_activity_user(rnti); - log_h->info("DL activity rnti=0x%x, n_bytes=%d\n", rnti, nof_bytes); + logger.info("DL activity rnti=0x%x, n_bytes=%d", rnti, nof_bytes); } } return SRSLTE_SUCCESS; @@ -318,6 +313,7 @@ int mac::ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc) { + logger.set_context(tti_rx); log_h->step(tti_rx); srslte::rwlock_read_guard lock(rwlock); @@ -342,18 +338,18 @@ int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t std::array enb_ue_cc_map = scheduler.get_enb_ue_cc_map(rnti); if (enb_ue_cc_map[enb_cc_idx] < 0) { - Error("User rnti=0x%x is not activated for carrier %d\n", rnti, enb_cc_idx); + logger.error("User rnti=0x%x is not activated for carrier %d", rnti, enb_cc_idx); return SRSLTE_ERROR; } uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx]; // push the pdu through the queue if received correctly if (crc) { - Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); + logger.info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d", rnti, tti_rx, nof_bytes); ue_db[rnti]->push_pdu(tti_rx, ue_cc_idx, nof_bytes); stack_task_queue.push([this]() { process_pdus(); }); } else { - Debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); + logger.debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d", rnti, tti_rx, nof_bytes); ue_db[rnti]->deallocate_pdu(tti_rx, ue_cc_idx); } return SRSLTE_SUCCESS; @@ -361,6 +357,7 @@ int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) { + logger.set_context(tti); log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); @@ -376,6 +373,7 @@ int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_v int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) { + logger.set_context(tti); log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); @@ -391,6 +389,7 @@ int mac::pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) { + logger.set_context(tti); log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); @@ -406,6 +405,7 @@ int mac::cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi int mac::snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, float snr, ul_channel_t ch) { + logger.set_context(tti_rx); log_h->step(tti_rx); srslte::rwlock_read_guard lock(rwlock); @@ -433,6 +433,7 @@ int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us) int mac::sr_detected(uint32_t tti, uint16_t rnti) { + logger.set_context(tti); log_h->step(tti); srslte::rwlock_read_guard lock(rwlock); @@ -461,14 +462,14 @@ uint16_t mac::allocate_ue() { srslte::rwlock_read_guard lock(rwlock); if (ue_db.size() >= args.max_nof_ues) { - Warning("Maximum number of connected UEs %d reached. Ignoring PRACH\n", args.max_nof_ues); + logger.warning("Maximum number of connected UEs %d reached. Ignoring PRACH", args.max_nof_ues); return SRSLTE_INVALID_RNTI; } } // Get pre-allocated UE object if (ue_pool.empty()) { - Error("Ignoring RACH attempt. UE pool empty.\n"); + logger.error("Ignoring RACH attempt. UE pool empty."); return SRSLTE_INVALID_RNTI; } std::unique_ptr ue_ptr = ue_pool.wait_pop(); @@ -501,7 +502,7 @@ uint16_t mac::reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) // Add new user to the scheduler so that it can RX/TX SRB0 if (scheduler.ue_cfg(rnti, ue_cfg) != SRSLTE_SUCCESS) { - Error("Registering new user rnti=0x%x to SCHED\n", rnti); + logger.error("Registering new user rnti=0x%x to SCHED", rnti); return SRSLTE_INVALID_RNTI; } @@ -511,6 +512,7 @@ uint16_t mac::reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx, uint32_t time_adv) { static srslte::mutexed_tprof rach_tprof("rach_tprof", "MAC", 1); + logger.set_context(tti); log_h->step(tti); auto rach_tprof_meas = rach_tprof.start(); @@ -540,7 +542,7 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx ue_cfg.ue_bearers[0].direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH; ue_cfg.supported_cc_list[0].dl_cfg.tm = SRSLTE_TM1; if (scheduler.ue_cfg(rnti, ue_cfg) != SRSLTE_SUCCESS) { - Error("Registering new user rnti=0x%x to SCHED\n", rnti); + logger.error("Registering new user rnti=0x%x to SCHED", rnti); ue_rem(rnti); return; } @@ -554,12 +556,8 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx // Trigger scheduler RACH scheduler.dl_rach_info(enb_cc_idx, rar_info); - log_h->info("RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", - tti, - enb_cc_idx, - preamble_idx, - time_adv, - rnti); + logger.info( + "RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", tti, enb_cc_idx, preamble_idx, time_adv, rnti); srslte::console("RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", tti, enb_cc_idx, @@ -576,7 +574,7 @@ void mac::prealloc_ue(uint32_t nof_ue) { for (uint32_t i = 0; i < nof_ue; i++) { std::unique_ptr ptr = std::unique_ptr( - new ue(allocate_rnti(), args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, cells.size())); + new ue(allocate_rnti(), args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, logger, cells.size())); ue_pool.push(std::move(ptr)); } } @@ -587,13 +585,14 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) return 0; } + logger.set_context(TTI_SUB(tti_tx_dl, FDD_HARQ_DELAY_UL_MS)); log_h->step(TTI_SUB(tti_tx_dl, FDD_HARQ_DELAY_UL_MS)); for (uint32_t enb_cc_idx = 0; enb_cc_idx < cell_config.size(); enb_cc_idx++) { // Run scheduler with current info sched_interface::dl_sched_res_t sched_result = {}; if (scheduler.dl_sched(tti_tx_dl, enb_cc_idx, sched_result) < 0) { - Error("Running scheduler\n"); + logger.error("Running scheduler"); return SRSLTE_ERROR; } @@ -633,7 +632,7 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) sched_result.data[i].tbs[tb]); if (!dl_sched_res->pdsch[n].data[tb]) { - Error("Error! PDU was not generated (rnti=0x%04x, tb=%d)\n", rnti, tb); + logger.error("Error! PDU was not generated (rnti=0x%04x, tb=%d)", rnti, tb); } if (pcap) { @@ -653,7 +652,7 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) n++; } } else { - Warning("Invalid DL scheduling result. User 0x%x does not exist\n", rnti); + logger.warning("Invalid DL scheduling result. User 0x%x does not exist", rnti); } } @@ -769,6 +768,7 @@ void mac::build_mch_sched(uint32_t tbs) int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res_list) { dl_sched_t* dl_sched_res = &dl_sched_res_list[0]; + logger.set_context(tti); log_h->step(tti); srslte_ra_tb_t mcs = {}; srslte_ra_tb_t mcs_data = {}; @@ -780,10 +780,10 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res build_mch_sched(mcs_data.tbs); mch.mcch_payload = mcch_payload_buffer; mch.current_sf_allocation_num = 1; - Info("MCH Sched Info: LCID: %d, Stop: %d, tti is %d \n", - mch.mtch_sched[0].lcid, - mch.mtch_sched[mch.num_mtch_sched - 1].stop, - tti); + logger.info("MCH Sched Info: LCID: %d, Stop: %d, tti is %d ", + mch.mtch_sched[0].lcid, + mch.mtch_sched[mch.num_mtch_sched - 1].stop, + tti); phy_h->set_mch_period_stop(mch.mtch_sched[mch.num_mtch_sched - 1].stop); for (uint32_t i = 0; i < mch.num_mtch_sched; i++) { mch.pdu[i].lcid = (uint32_t)srslte::mch_lcid::MCH_SCHED_INFO; @@ -865,11 +865,11 @@ uint8_t* mac::assemble_rar(sched_interface::dl_sched_rar_grant_t* grants, } } - Error("Assembling RAR: rar_idx=%d, pdu_len=%d, rar_payload_len=%d, nof_grants=%d\n", - rar_idx, - pdu_len, - rar_payload_len, - nof_grants); + logger.error("Assembling RAR: rar_idx=%d, pdu_len=%d, rar_payload_len=%d, nof_grants=%d", + rar_idx, + pdu_len, + int(rar_payload_len), + nof_grants); return nullptr; } @@ -879,6 +879,7 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) return SRSLTE_SUCCESS; } + logger.set_context(TTI_SUB(tti_tx_ul, FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS)); log_h->step(TTI_SUB(tti_tx_ul, FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS)); // Execute UE FSMs (e.g. TA) @@ -892,7 +893,7 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) // Run scheduler with current info sched_interface::ul_sched_res_t sched_result = {}; if (scheduler.ul_sched(tti_tx_ul, enb_cc_idx, sched_result) < 0) { - Error("Running scheduler\n"); + logger.error("Running scheduler"); return SRSLTE_ERROR; } @@ -903,7 +904,6 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) phy_ul_sched_res->nof_grants = 0; int n = 0; for (uint32_t i = 0; i < sched_result.nof_dci_elems; i++) { - if (sched_result.pusch[i].tbs > 0) { // Get UE uint16_t rnti = sched_result.pusch[i].dci.rnti; @@ -911,6 +911,7 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) if (ue_db.count(rnti)) { // Copy grant info phy_ul_sched_res->pusch[n].current_tx_nb = sched_result.pusch[i].current_tx_nb; + phy_ul_sched_res->pusch[n].pid = TTI_RX(tti_tx_ul) % SRSLTE_FDD_NOF_HARQ; phy_ul_sched_res->pusch[n].needs_pdcch = sched_result.pusch[i].needs_pdcch; phy_ul_sched_res->pusch[n].dci = sched_result.pusch[i].dci; phy_ul_sched_res->pusch[n].softbuffer_rx = @@ -929,15 +930,15 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) if (phy_ul_sched_res->pusch[n].data) { phy_ul_sched_res->nof_grants++; } else { - Error("Grant for rnti=0x%x could not be allocated due to lack of buffers\n", rnti); + logger.error("Grant for rnti=0x%x could not be allocated due to lack of buffers", rnti); } n++; } else { - Warning("Invalid UL scheduling result. User 0x%x does not exist\n", rnti); + logger.warning("Invalid UL scheduling result. User 0x%x does not exist", rnti); } } else { - Warning("Grant %d for rnti=0x%x has zero TBS\n", i, sched_result.pusch[i].dci.rnti); + logger.warning("Grant %d for rnti=0x%x has zero TBS", i, sched_result.pusch[i].dci.rnti); } } @@ -983,8 +984,8 @@ void mac::write_mcch(const srslte::sib2_mbms_t* sib2_, sib13 = *sib13_; memcpy(mcch_payload_buffer, mcch_payload, mcch_payload_length * sizeof(uint8_t)); current_mcch_length = mcch_payload_length; - ue_db[SRSLTE_MRNTI] = - std::unique_ptr{new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, cells.size())}; + ue_db[SRSLTE_MRNTI] = std::unique_ptr{ + new ue(SRSLTE_MRNTI, args.nof_prb, &scheduler, rrc_h, rlc_h, phy_h, log_h, logger, cells.size())}; rrc_h->add_user(SRSLTE_MRNTI, {}); } @@ -993,7 +994,7 @@ bool mac::check_ue_exists(uint16_t rnti) { if (not ue_db.count(rnti)) { if (not ues_to_rem.count(rnti)) { - Error("User rnti=0x%x not found\n", rnti); + logger.error("User rnti=0x%x not found", rnti); } return false; } diff --git a/srsenb/src/stack/mac/mac_nr.cc b/srsenb/src/stack/mac/mac_nr.cc index 926ca9acb..b2419949c 100644 --- a/srsenb/src/stack/mac/mac_nr.cc +++ b/srsenb/src/stack/mac/mac_nr.cc @@ -29,16 +29,16 @@ namespace srsenb { -mac_nr::mac_nr() : pool(srslte::byte_buffer_pool::get_instance()), log_h("MAC") +mac_nr::mac_nr() : log_h("MAC") { - bcch_bch_payload = srslte::allocate_unique_buffer(*pool); + bcch_bch_payload = srslte::make_byte_buffer(); // allocate 8 tx buffers for UE (TODO: as we don't handle softbuffers why do we need so many buffers) for (int i = 0; i < SRSLTE_FDD_NOF_HARQ; i++) { - ue_tx_buffer.emplace_back(srslte::allocate_unique_buffer(*pool)); + ue_tx_buffer.emplace_back(srslte::make_byte_buffer()); } - ue_rlc_buffer = srslte::allocate_unique_buffer(*pool); + ue_rlc_buffer = srslte::make_byte_buffer(); } mac_nr::~mac_nr() @@ -63,7 +63,7 @@ int mac_nr::init(const mac_nr_args_t& args_, log_h->set_hex_limit(args.log_hex_limit); if (args.pcap.enable) { - pcap = std::unique_ptr(new srslte::mac_nr_pcap()); + pcap = std::unique_ptr(new srslte::mac_pcap(srslte::srslte_rat_t::nr)); pcap->open(args.pcap.filename); } @@ -122,7 +122,7 @@ void mac_nr::get_dl_config(const uint32_t tti, tx_request.pdus[tx_request.nof_pdus].index = tx_request.nof_pdus; if (pcap) { - pcap->write_dl_si_rnti(sib.payload->msg, sib.payload->N_bytes, 0xffff, 0, tti); + pcap->write_dl_si_rnti_nr(sib.payload->msg, sib.payload->N_bytes, 0xffff, 0, tti); } tx_request.nof_pdus++; @@ -161,11 +161,11 @@ void mac_nr::get_dl_config(const uint32_t tti, tx_request.pdus[tx_request.nof_pdus].index = tx_request.nof_pdus; if (pcap) { - pcap->write_dl_crnti(tx_request.pdus[tx_request.nof_pdus].data[0], - tx_request.pdus[tx_request.nof_pdus].length, - args.rnti, - buffer_index, - tti); + pcap->write_dl_crnti_nr(tx_request.pdus[tx_request.nof_pdus].data[0], + tx_request.pdus[tx_request.nof_pdus].length, + args.rnti, + buffer_index, + tti); } tx_request.nof_pdus++; @@ -200,7 +200,7 @@ int mac_nr::rx_data_indication(stack_interface_phy_nr::rx_data_ind_t& rx_data) // push received PDU on queue if (rx_data.tb != nullptr) { if (pcap) { - pcap->write_ul_crnti(rx_data.tb->msg, rx_data.tb->N_bytes, rx_data.rnti, true, rx_data.tti); + pcap->write_ul_crnti_nr(rx_data.tb->msg, rx_data.tb->N_bytes, rx_data.rnti, true, rx_data.tti); } ue_rx_pdu_queue.push(std::move(rx_data.tb)); } @@ -231,16 +231,14 @@ int mac_nr::handle_pdu(srslte::unique_byte_buffer_t pdu) ue_rx_pdu.unpack(pdu->msg, pdu->N_bytes); for (uint32_t i = 0; i < ue_rx_pdu.get_num_subpdus(); ++i) { - srslte::mac_nr_sch_subpdu subpdu = ue_rx_pdu.get_subpdu(i); + srslte::mac_sch_subpdu_nr subpdu = ue_rx_pdu.get_subpdu(i); log_h->info("Handling subPDU %d/%d: lcid=%d, sdu_len=%d\n", i, ue_rx_pdu.get_num_subpdus(), subpdu.get_lcid(), subpdu.get_sdu_length()); - if (subpdu.get_lcid() == args.drb_lcid) { - rlc_h->write_pdu(args.rnti, subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); - } + // rlc_h->write_pdu(args.rnti, subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); } return SRSLTE_SUCCESS; } @@ -255,7 +253,7 @@ int mac_nr::cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) sib_info_t sib = {}; sib.index = i; sib.periodicity = cell_cfg->sibs->period_rf; - sib.payload = srslte::allocate_unique_buffer(*pool); + sib.payload = srslte::make_byte_buffer(); if (rrc_h->read_pdu_bcch_dlsch(sib.index, sib.payload) != SRSLTE_SUCCESS) { log_h->error("Couldn't read SIB %d from RRC\n", sib.index); } diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index 384e43e88..39e3ef31c 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -26,10 +26,11 @@ #include "srsenb/hdr/stack/mac/sched_carrier.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" #include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #define Console(fmt, ...) srslte::console(fmt, ##__VA_ARGS__) -#define Error(fmt, ...) srslte::logmap::get("MAC ")->error(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) srslog::fetch_basic_logger("MAC").error(fmt, ##__VA_ARGS__) using srslte::tti_point; @@ -41,13 +42,14 @@ namespace srsenb { * *******************************************************/ -sched::sched() : log_h(srslte::logmap::get("MAC")) {} +sched::sched() {} sched::~sched() {} -void sched::init(rrc_interface_mac* rrc_) +void sched::init(rrc_interface_mac* rrc_, const sched_args_t& sched_cfg_) { - rrc = rrc_; + rrc = rrc_; + sched_cfg = sched_cfg_; // Initialize first carrier scheduler carrier_schedulers.emplace_back(new carrier_sched{rrc, &ue_db, 0, &sched_results}); @@ -58,7 +60,6 @@ void sched::init(rrc_interface_mac* rrc_) int sched::reset() { std::lock_guard lock(sched_mutex); - configured = false; for (std::unique_ptr& c : carrier_schedulers) { c->reset(); } @@ -66,14 +67,7 @@ int sched::reset() return 0; } -void sched::set_sched_cfg(sched_interface::sched_args_t* sched_cfg_) -{ - std::lock_guard lock(sched_mutex); - if (sched_cfg_ != nullptr) { - sched_cfg = *sched_cfg_; - } -} - +/// Called by rrc::init int sched::cell_cfg(const std::vector& cell_cfg) { std::lock_guard lock(sched_mutex); @@ -97,8 +91,7 @@ int sched::cell_cfg(const std::vector& cell_cfg) carrier_schedulers[i]->carrier_cfg(sched_cell_params[i]); } - configured = true; - + configured.store(true, std::memory_order_release); return 0; } @@ -110,16 +103,20 @@ int sched::cell_cfg(const std::vector& cell_cfg) int sched::ue_cfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg) { - std::lock_guard lock(sched_mutex); - // Add or config user - auto it = ue_db.find(rnti); - if (it == ue_db.end()) { - // create new user - ue_db[rnti].init(rnti, sched_cell_params); - it = ue_db.find(rnti); + { + // config existing user + std::lock_guard lock(sched_mutex); + auto it = ue_db.find(rnti); + if (it != ue_db.end()) { + it->second->set_cfg(ue_cfg); + return SRSLTE_SUCCESS; + } } - it->second.set_cfg(ue_cfg); + // Add new user case + std::unique_ptr ue{new sched_ue(rnti, sched_cell_params, ue_cfg)}; + std::lock_guard lock(sched_mutex); + ue_db.insert(std::make_pair(rnti, std::move(ue))); return SRSLTE_SUCCESS; } @@ -129,7 +126,7 @@ int sched::ue_rem(uint16_t rnti) if (ue_db.count(rnti) > 0) { ue_db.erase(rnti); } else { - Error("User rnti=0x%x not found\n", rnti); + Error("User rnti=0x%x not found", rnti); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; @@ -137,30 +134,30 @@ int sched::ue_rem(uint16_t rnti) bool sched::ue_exists(uint16_t rnti) { - return ue_db_access(rnti, [](sched_ue& ue) {}) >= 0; + return ue_db_access_locked(rnti, [](sched_ue& ue) {}) >= 0; } void sched::phy_config_enabled(uint16_t rnti, bool enabled) { // TODO: Check if correct use of last_tti - ue_db_access( + ue_db_access_locked( rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(last_tti, enabled); }, __PRETTY_FUNCTION__); } int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg_) { - return ue_db_access(rnti, [lc_id, cfg_](sched_ue& ue) { ue.set_bearer_cfg(lc_id, cfg_); }); + return ue_db_access_locked(rnti, [lc_id, cfg_](sched_ue& ue) { ue.set_bearer_cfg(lc_id, cfg_); }); } int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) { - return ue_db_access(rnti, [lc_id](sched_ue& ue) { ue.rem_bearer(lc_id); }); + return ue_db_access_locked(rnti, [lc_id](sched_ue& ue) { ue.rem_bearer(lc_id); }); } uint32_t sched::get_dl_buffer(uint16_t rnti) { uint32_t ret = SRSLTE_ERROR; - ue_db_access( + ue_db_access_locked( rnti, [&ret](sched_ue& ue) { ret = ue.get_pending_dl_rlc_data(); }, __PRETTY_FUNCTION__); return ret; } @@ -169,7 +166,7 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) { // TODO: Check if correct use of last_tti uint32_t ret = SRSLTE_ERROR; - ue_db_access( + ue_db_access_locked( rnti, [this, &ret](sched_ue& ue) { ret = ue.get_pending_ul_new_data(to_tx_ul(last_tti), -1); }, __PRETTY_FUNCTION__); @@ -178,18 +175,18 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { - return ue_db_access(rnti, [&](sched_ue& ue) { ue.dl_buffer_state(lc_id, tx_queue, retx_queue); }); + return ue_db_access_locked(rnti, [&](sched_ue& ue) { ue.dl_buffer_state(lc_id, tx_queue, retx_queue); }); } int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code, uint32_t nof_cmds) { - return ue_db_access(rnti, [ce_code, nof_cmds](sched_ue& ue) { ue.mac_buffer_state(ce_code, nof_cmds); }); + return ue_db_access_locked(rnti, [ce_code, nof_cmds](sched_ue& ue) { ue.mac_buffer_state(ce_code, nof_cmds); }); } int sched::dl_ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) { int ret = -1; - ue_db_access( + ue_db_access_locked( rnti, [&](sched_ue& ue) { ret = ue.set_ack_info(tti_point{tti_rx}, enb_cc_idx, tb_idx, ack); }, __PRETTY_FUNCTION__); @@ -198,25 +195,25 @@ int sched::dl_ack_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint int sched::ul_crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, bool crc) { - return ue_db_access(rnti, - [tti_rx, enb_cc_idx, crc](sched_ue& ue) { ue.set_ul_crc(tti_point{tti_rx}, enb_cc_idx, crc); }); + return ue_db_access_locked( + rnti, [tti_rx, enb_cc_idx, crc](sched_ue& ue) { ue.set_ul_crc(tti_point{tti_rx}, enb_cc_idx, crc); }); } int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) { - return ue_db_access( + return ue_db_access_locked( rnti, [tti, enb_cc_idx, ri_value](sched_ue& ue) { ue.set_dl_ri(tti_point{tti}, enb_cc_idx, ri_value); }); } int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) { - return ue_db_access( + return ue_db_access_locked( rnti, [tti, enb_cc_idx, pmi_value](sched_ue& ue) { ue.set_dl_pmi(tti_point{tti}, enb_cc_idx, pmi_value); }); } int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) { - return ue_db_access( + return ue_db_access_locked( rnti, [tti, enb_cc_idx, cqi_value](sched_ue& ue) { ue.set_dl_cqi(tti_point{tti}, enb_cc_idx, cqi_value); }); } @@ -228,28 +225,29 @@ int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info) int sched::ul_snr_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, float snr, uint32_t ul_ch_code) { - return ue_db_access(rnti, [&](sched_ue& ue) { ue.set_ul_snr(tti_point{tti_rx}, enb_cc_idx, snr, ul_ch_code); }); + return ue_db_access_locked(rnti, + [&](sched_ue& ue) { ue.set_ul_snr(tti_point{tti_rx}, enb_cc_idx, snr, ul_ch_code); }); } int sched::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) { - return ue_db_access(rnti, [lcg_id, bsr](sched_ue& ue) { ue.ul_buffer_state(lcg_id, bsr); }); + return ue_db_access_locked(rnti, [lcg_id, bsr](sched_ue& ue) { ue.ul_buffer_state(lcg_id, bsr); }); } int sched::ul_buffer_add(uint16_t rnti, uint32_t lcid, uint32_t bytes) { - return ue_db_access(rnti, [lcid, bytes](sched_ue& ue) { ue.ul_buffer_add(lcid, bytes); }); + return ue_db_access_locked(rnti, [lcid, bytes](sched_ue& ue) { ue.ul_buffer_add(lcid, bytes); }); } int sched::ul_phr(uint16_t rnti, int phr) { - return ue_db_access( + return ue_db_access_locked( rnti, [phr](sched_ue& ue) { ue.ul_phr(phr); }, __PRETTY_FUNCTION__); } int sched::ul_sr_info(uint32_t tti, uint16_t rnti) { - return ue_db_access( + return ue_db_access_locked( rnti, [](sched_ue& ue) { ue.set_sr(); }, __PRETTY_FUNCTION__); } @@ -263,7 +261,7 @@ std::array sched::get_enb_ue_cc_map(uint16_t rnti) { std::array ret{}; ret.fill(-1); // -1 for inactive & non-existent carriers - ue_db_access( + ue_db_access_locked( rnti, [this, &ret](sched_ue& ue) { for (size_t enb_cc_idx = 0; enb_cc_idx < carrier_schedulers.size(); ++enb_cc_idx) { @@ -300,7 +298,7 @@ std::array sched::get_scell_activation_mask(uint16_t // Downlink Scheduler API int sched::dl_sched(uint32_t tti_tx_dl, uint32_t enb_cc_idx, sched_interface::dl_sched_res_t& sched_result) { - if (!configured) { + if (not configured.load(std::memory_order_acquire)) { return 0; } @@ -321,7 +319,7 @@ int sched::dl_sched(uint32_t tti_tx_dl, uint32_t enb_cc_idx, sched_interface::dl // Uplink Scheduler API int sched::ul_sched(uint32_t tti, uint32_t enb_cc_idx, srsenb::sched_interface::ul_sched_res_t& sched_result) { - if (!configured) { + if (not configured.load(std::memory_order_acquire)) { return 0; } @@ -366,17 +364,17 @@ bool sched::is_generated(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const // Common way to access ue_db elements in a read locking way template -int sched::ue_db_access(uint16_t rnti, Func f, const char* func_name) +int sched::ue_db_access_locked(uint16_t rnti, Func&& f, const char* func_name) { std::lock_guard lock(sched_mutex); auto it = ue_db.find(rnti); if (it != ue_db.end()) { - f(it->second); + f(*it->second); } else { if (func_name != nullptr) { - Error("User rnti=0x%x not found. Failed to call %s.\n", rnti, func_name); + Error("User rnti=0x%x not found. Failed to call %s.", rnti, func_name); } else { - Error("User rnti=0x%x not found.\n", rnti); + Error("User rnti=0x%x not found.", rnti); } return SRSLTE_ERROR; } diff --git a/srsenb/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index a1d4449bd..57340da7f 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -24,6 +24,7 @@ #include "srsenb/hdr/stack/mac/schedulers/sched_time_pf.h" #include "srsenb/hdr/stack/mac/schedulers/sched_time_rr.h" #include "srslte/common/logmap.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { @@ -138,8 +139,8 @@ void bc_sched::reset() * RAR scheduling *******************************************************/ -ra_sched::ra_sched(const sched_cell_params_t& cfg_, std::map& ue_db_) : - cc_cfg(&cfg_), log_h(srslte::logmap::get("MAC")), ue_db(&ue_db_) +ra_sched::ra_sched(const sched_cell_params_t& cfg_, sched_ue_list& ue_db_) : + cc_cfg(&cfg_), logger(srslog::fetch_basic_logger("MAC")), ue_db(&ue_db_) {} // Schedules RAR @@ -161,13 +162,13 @@ void ra_sched::dl_sched(sf_sched* tti_sched) char error_msg[128]; int len = snprintf(error_msg, sizeof(error_msg), - "SCHED: Could not transmit RAR within the window (RA=%d, Window=%s, RAR=%d)\n", + "SCHED: Could not transmit RAR within the window (RA=%d, Window=%s, RAR=%d)", rar.prach_tti.to_uint(), rar_window.to_string().c_str(), tti_tx_dl.to_uint()); error_msg[len] = '\0'; - srslte::console("%s", error_msg); - log_h->error("%s", error_msg); + srslte::console("%s\n", error_msg); + logger.error("%s", error_msg); // Remove from pending queue and get next one if window has passed already pending_rars.pop_front(); continue; @@ -201,7 +202,7 @@ void ra_sched::dl_sched(sf_sched* tti_sched) int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) { - log_h->info("SCHED: New PRACH tti=%d, preamble=%d, temp_crnti=0x%x, ta_cmd=%d, msg3_size=%d\n", + logger.info("SCHED: New PRACH tti=%d, preamble=%d, temp_crnti=0x%x, ta_cmd=%d, msg3_size=%d", rar_info.prach_tti, rar_info.preamble_idx, rar_info.temp_crnti, @@ -216,7 +217,7 @@ int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) for (sf_sched::pending_rar_t& r : pending_rars) { if (r.prach_tti.to_uint() == rar_info.prach_tti and ra_rnti == r.ra_rnti) { if (r.nof_grants >= sched_interface::MAX_RAR_LIST) { - log_h->warning("PRACH ignored, as the the maximum number of RAR grants per tti has been reached\n"); + logger.warning("PRACH ignored, as the the maximum number of RAR grants per tti has been reached"); return SRSLTE_ERROR; } r.msg3_grant[r.nof_grants] = rar_info; @@ -243,15 +244,13 @@ void ra_sched::ul_sched(sf_sched* sf_dl_sched, sf_sched* sf_msg3_sched) for (const auto& rar : alloc_rars) { for (const auto& msg3grant : rar.rar_grant.msg3_grant) { - uint16_t crnti = msg3grant.data.temp_crnti; auto user_it = ue_db->find(crnti); - if (user_it != ue_db->end() and sf_msg3_sched->alloc_msg3(&user_it->second, msg3grant)) { - log_h->debug("SCHED: Queueing Msg3 for rnti=0x%x at tti=%d\n", crnti, sf_msg3_sched->get_tti_tx_ul().to_uint()); + if (user_it != ue_db->end() and sf_msg3_sched->alloc_msg3(user_it->second.get(), msg3grant)) { + logger.debug("SCHED: Queueing Msg3 for rnti=0x%x at tti=%d", crnti, sf_msg3_sched->get_tti_tx_ul().to_uint()); } else { - log_h->error("SCHED: Failed to allocate Msg3 for rnti=0x%x at tti=%d\n", - crnti, - sf_msg3_sched->get_tti_tx_ul().to_uint()); + logger.error( + "SCHED: Failed to allocate Msg3 for rnti=0x%x at tti=%d", crnti, sf_msg3_sched->get_tti_tx_ul().to_uint()); } } } @@ -266,13 +265,13 @@ void ra_sched::reset() * Carrier scheduling *******************************************************/ -sched::carrier_sched::carrier_sched(rrc_interface_mac* rrc_, - std::map* ue_db_, - uint32_t enb_cc_idx_, - sched_result_list* sched_results_) : +sched::carrier_sched::carrier_sched(rrc_interface_mac* rrc_, + sched_ue_list* ue_db_, + uint32_t enb_cc_idx_, + sched_result_list* sched_results_) : rrc(rrc_), ue_db(ue_db_), - log_h(srslte::logmap::get("MAC ")), + logger(srslog::fetch_basic_logger("MAC")), enb_cc_idx(enb_cc_idx_), prev_sched_results(sched_results_) { @@ -299,10 +298,10 @@ void sched::carrier_sched::carrier_cfg(const sched_cell_params_t& cell_params_) // Setup data scheduling algorithms if (cell_params_.sched_cfg->sched_policy == "time_rr") { sched_algo.reset(new sched_time_rr{*cc_cfg, *cell_params_.sched_cfg}); - log_h->info("Using time-domain RR scheduling policy for cc=%d\n", cc_cfg->enb_cc_idx); + logger.info("Using time-domain RR scheduling policy for cc=%d", cc_cfg->enb_cc_idx); } else { sched_algo.reset(new sched_time_pf{*cc_cfg, *cell_params_.sched_cfg}); - log_h->info("Using time-domain PF scheduling policy for cc=%d\n", cc_cfg->enb_cc_idx); + logger.info("Using time-domain PF scheduling policy for cc=%d", cc_cfg->enb_cc_idx); } // Initiate the tti_scheduler for each TTI @@ -326,7 +325,7 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r /* Refresh UE internal buffers and subframe vars */ for (auto& user : *ue_db) { - user.second.new_subframe(tti_rx, enb_cc_idx); + user.second->new_subframe(tti_rx, enb_cc_idx); } /* Schedule PHICH */ @@ -334,7 +333,7 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r if (cc_result->ul_sched_result.nof_phich_elems >= MAX_PHICH_LIST) { break; } - tti_sched->alloc_phich(&ue_pair.second, &cc_result->ul_sched_result); + tti_sched->alloc_phich(ue_pair.second.get(), &cc_result->ul_sched_result); } /* Schedule DL control data */ @@ -367,11 +366,11 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r /* Reset ue harq pending ack state, clean-up blocked pids */ for (auto& user : *ue_db) { - user.second.finish_tti(tti_rx, enb_cc_idx); + user.second->finish_tti(tti_rx, enb_cc_idx); } - log_dl_cc_results(log_h, enb_cc_idx, cc_result->dl_sched_result); - log_phich_cc_results(log_h, enb_cc_idx, cc_result->ul_sched_result); + log_dl_cc_results(logger, enb_cc_idx, cc_result->dl_sched_result); + log_phich_cc_results(logger, enb_cc_idx, cc_result->ul_sched_result); return *cc_result; } diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index 5558c9a5c..1a76d8035 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -21,7 +21,6 @@ #include "srsenb/hdr/stack/mac/sched_grid.h" #include "srsenb/hdr/stack/mac/sched_helpers.h" -#include "srslte/common/log_helper.h" #include "srslte/common/logmap.h" using srslte::tti_point; @@ -47,6 +46,14 @@ const char* alloc_outcome_t::to_string() const return "measgap_collision"; case ALREADY_ALLOC: return "already allocated"; + case NO_DATA: + return "no pending data to allocate"; + case INVALID_PRBMASK: + return "invalid rbg mask"; + case INVALID_CARRIER: + return "invalid eNB carrier"; + default: + break; } return "unknown error"; } @@ -118,269 +125,6 @@ cc_sched_result* sched_result_list::get_cc(srslte::tti_point tti_rx, uint32_t en * PDCCH Allocation Methods *******************************************************/ -void pdcch_grid_t::alloc_tree_t::reset() -{ - prev_start = 0; - prev_end = 0; - dci_alloc_tree.clear(); -} - -void pdcch_grid_t::init(const sched_cell_params_t& cell_params_) -{ - cc_cfg = &cell_params_; - log_h = srslte::logmap::get("MAC "); - - // init alloc trees - alloc_trees.reserve(cc_cfg->sched_cfg->max_nof_ctrl_symbols); - for (uint32_t i = 0; i < cc_cfg->sched_cfg->max_nof_ctrl_symbols; ++i) { - alloc_trees.emplace_back(cc_cfg->nof_cce_table[i]); - } -} - -void pdcch_grid_t::new_tti(tti_point tti_rx_) -{ - tti_rx = tti_rx_; - - // Reset back all CFIs - for (auto& t : alloc_trees) { - t.reset(); - } - dci_record_list.clear(); - current_cfix = cc_cfg->sched_cfg->min_nof_ctrl_symbols - 1; -} - -const sched_dci_cce_t* pdcch_grid_t::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const -{ - switch (alloc_type) { - case alloc_type_t::DL_BC: - return &cc_cfg->common_locations[cfix]; - case alloc_type_t::DL_PCCH: - return &cc_cfg->common_locations[cfix]; - case alloc_type_t::DL_RAR: - return &cc_cfg->rar_locations[cfix][to_tx_dl(tti_rx).sf_idx()]; - case alloc_type_t::DL_DATA: - return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx()); - case alloc_type_t::UL_DATA: - return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx()); - default: - break; - } - return nullptr; -} - -bool pdcch_grid_t::alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user) -{ - // TODO: Make the alloc tree update lazy - alloc_record_t record{.user = user, .aggr_idx = aggr_idx, .alloc_type = alloc_type}; - - // Try to allocate user in PDCCH for given CFI. If it fails, increment CFI. - uint32_t first_cfi = get_cfi(); - bool success; - do { - success = alloc_dci_record(record, get_cfi() - 1); - } while (not success and get_cfi() < cc_cfg->sched_cfg->max_nof_ctrl_symbols and set_cfi(get_cfi() + 1)); - - if (not success) { - // DCI allocation failed. go back to original CFI - if (get_cfi() != first_cfi and not set_cfi(first_cfi)) { - log_h->error("SCHED: Failed to return back to original PDCCH state\n"); - } - return false; - } - - // DCI record allocation successful - dci_record_list.push_back(record); - return true; -} - -bool pdcch_grid_t::alloc_dci_record(const alloc_record_t& record, uint32_t cfix) -{ - bool ret = false; - auto& tree = alloc_trees[cfix]; - - // Get DCI Location Table - const sched_dci_cce_t* dci_locs = get_cce_loc_table(record.alloc_type, record.user, cfix); - if (dci_locs == nullptr or dci_locs->nof_loc[record.aggr_idx] == 0) { - return ret; - } - - if (tree.prev_end > 0) { - for (size_t j = tree.prev_start; j < tree.prev_end; ++j) { - ret |= add_tree_node_leaves(tree, (int)j, record, *dci_locs, to_tx_dl(tti_rx)); - } - } else { - ret = add_tree_node_leaves(tree, -1, record, *dci_locs, to_tx_dl(tti_rx)); - } - - if (ret) { - tree.prev_start = tree.prev_end; - tree.prev_end = tree.dci_alloc_tree.size(); - } - - return ret; -} - -//! Algorithm to compute a valid PDCCH allocation -bool pdcch_grid_t::add_tree_node_leaves(alloc_tree_t& tree, - int parent_node_idx, - const alloc_record_t& dci_record, - const sched_dci_cce_t& dci_locs, - tti_point tti_tx_dl) -{ - bool ret = false; - - alloc_t alloc; - alloc.rnti = (dci_record.user != nullptr) ? dci_record.user->get_rnti() : (uint16_t)0u; - alloc.dci_pos.L = dci_record.aggr_idx; - - // get cumulative pdcch mask - pdcch_mask_t cum_mask; - if (parent_node_idx >= 0) { - cum_mask = tree.dci_alloc_tree[parent_node_idx].node.total_mask; - } else { - cum_mask.resize(tree.nof_cces); - } - - uint32_t nof_locs = dci_locs.nof_loc[dci_record.aggr_idx]; - for (uint32_t i = 0; i < nof_locs; ++i) { - uint32_t startpos = dci_locs.cce_start[dci_record.aggr_idx][i]; - - if (dci_record.alloc_type == alloc_type_t::DL_DATA and dci_record.user->pucch_sr_collision(tti_tx_dl, startpos)) { - // will cause a collision in the PUCCH - continue; - } - - pdcch_mask_t alloc_mask(tree.nof_cces); - alloc_mask.fill(startpos, startpos + (1u << dci_record.aggr_idx)); - if ((cum_mask & alloc_mask).any()) { - // there is collision. Try another mask - continue; - } - - // Allocation successful - alloc.current_mask = alloc_mask; - alloc.total_mask = cum_mask | alloc_mask; - alloc.dci_pos.ncce = startpos; - - // Prune if repetition - uint32_t j = tree.prev_end; - for (; j < tree.dci_alloc_tree.size(); ++j) { - if (tree.dci_alloc_tree[j].node.total_mask == alloc.total_mask) { - break; - } - } - if (j < tree.dci_alloc_tree.size()) { - continue; - } - - // Register allocation - tree.dci_alloc_tree.emplace_back(parent_node_idx, alloc); - ret = true; - } - - return ret; -} - -bool pdcch_grid_t::set_cfi(uint32_t cfi) -{ - if (cfi < cc_cfg->sched_cfg->min_nof_ctrl_symbols or cfi > cc_cfg->sched_cfg->max_nof_ctrl_symbols) { - srslte::logmap::get("MAC")->error("Invalid CFI value. Defaulting to current CFI.\n"); - return false; - } - - uint32_t new_cfix = cfi - 1; - if (new_cfix == current_cfix) { - return true; - } - - // setup new PDCCH alloc tree - auto& new_tree = alloc_trees[new_cfix]; - new_tree.reset(); - - if (not dci_record_list.empty()) { - // there are already PDCCH allocations - - // Rebuild Allocation Tree - bool ret = true; - for (const auto& old_record : dci_record_list) { - ret &= alloc_dci_record(old_record, new_cfix); - } - - if (not ret) { - // Fail to rebuild allocation tree. Go back to previous CFI - return false; - } - } - - current_cfix = new_cfix; - // TODO: The estimation of the number of required prbs in metric depends on CFI. Analyse the consequences - return true; -} - -void pdcch_grid_t::get_allocs(alloc_result_t* vec, pdcch_mask_t* tot_mask, size_t idx) const -{ - auto& tree = alloc_trees[current_cfix]; - // if alloc tree is empty - if (tree.prev_start == tree.prev_end) { - if (vec != nullptr) { - vec->clear(); - } - if (tot_mask != nullptr) { - tot_mask->resize(nof_cces()); - tot_mask->reset(); - } - return; - } - - // set vector of allocations - if (vec != nullptr) { - vec->clear(); - size_t i = tree.prev_start + idx; - while (tree.dci_alloc_tree[i].parent_idx >= 0) { - vec->push_back(&tree.dci_alloc_tree[i].node); - i = (size_t)tree.dci_alloc_tree[i].parent_idx; - } - vec->push_back(&tree.dci_alloc_tree[i].node); - std::reverse(vec->begin(), vec->end()); - } - - // set final cce mask - if (tot_mask != nullptr) { - *tot_mask = tree.dci_alloc_tree[tree.prev_start + idx].node.total_mask; - } -} - -std::string pdcch_grid_t::result_to_string(bool verbose) const -{ - auto& tree = alloc_trees[current_cfix]; - std::stringstream ss; - ss << "cfi=" << get_cfi() << ", mask_size=" << nof_cces() << ", " << tree.prev_end - tree.prev_start - << " DCI allocation combinations:\n"; - // get all the possible combinations of DCI allocations - uint32_t count = 0; - for (size_t i = tree.prev_start; i < tree.prev_end; ++i) { - alloc_result_t vec; - pdcch_mask_t tot_mask; - get_allocs(&vec, &tot_mask, i - tree.prev_start); - - ss << " combination " << count << ": mask=0x" << tot_mask.to_hex().c_str(); - if (verbose) { - ss << ", DCI allocs:\n"; - for (const auto& dci_alloc : vec) { - char hex[5]; - sprintf(hex, "%x", dci_alloc->rnti); - ss << " > rnti=0x" << hex << ": " << dci_alloc->current_mask.to_hex().c_str() << " / " - << dci_alloc->total_mask.to_hex().c_str() << "\n"; - } - } else { - ss << "\n"; - } - count++; - } - - return ss.str(); -} - /******************************************************* * TTI resource Scheduling Methods *******************************************************/ @@ -388,7 +132,6 @@ std::string pdcch_grid_t::result_to_string(bool verbose) const void sf_grid_t::init(const sched_cell_params_t& cell_params_) { cc_cfg = &cell_params_; - log_h = srslte::logmap::get("MAC "); nof_rbgs = cc_cfg->nof_rbgs; si_n_rbg = srslte::ceil_div(4, cc_cfg->P); rar_n_rbg = srslte::ceil_div(3, cc_cfg->P); @@ -422,8 +165,8 @@ alloc_outcome_t sf_grid_t::alloc_dl(uint32_t aggr_idx, alloc_type_t alloc_type, // Allocate DCI in PDCCH if (not pdcch_alloc.alloc_dci(alloc_type, aggr_idx, user)) { if (user != nullptr) { - if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) { - log_h->debug("No space in PDCCH for rnti=0x%x DL tx. Current PDCCH allocation: %s\n", + if (logger.debug.enabled()) { + logger.debug("No space in PDCCH for rnti=0x%x DL tx. Current PDCCH allocation: %s", user->get_rnti(), pdcch_alloc.result_to_string(true).c_str()); } @@ -446,7 +189,7 @@ sf_grid_t::dl_ctrl_alloc_t sf_grid_t::alloc_dl_ctrl(uint32_t aggr_idx, alloc_typ if (alloc_type != alloc_type_t::DL_RAR and alloc_type != alloc_type_t::DL_BC and alloc_type != alloc_type_t::DL_PCCH) { - log_h->error("SCHED: DL control allocations must be RAR/BC/PDCCH\n"); + logger.error("SCHED: DL control allocations must be RAR/BC/PDCCH"); return {alloc_outcome_t::ERROR, range}; } // Setup range starting from left @@ -488,8 +231,8 @@ alloc_outcome_t sf_grid_t::alloc_ul_data(sched_ue* user, prb_interval alloc, boo uint32_t nof_bits = srslte_dci_format_sizeof(&cc_cfg->cfg.cell, nullptr, nullptr, SRSLTE_DCI_FORMAT0); uint32_t aggr_idx = user->get_aggr_level(cc_cfg->enb_cc_idx, nof_bits); if (not pdcch_alloc.alloc_dci(alloc_type_t::UL_DATA, aggr_idx, user)) { - if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) { - log_h->debug("No space in PDCCH for rnti=0x%x UL tx. Current PDCCH allocation: %s\n", + if (logger.debug.enabled()) { + logger.debug("No space in PDCCH for rnti=0x%x UL tx. Current PDCCH allocation: %s", user->get_rnti(), pdcch_alloc.result_to_string(true).c_str()); } @@ -512,7 +255,7 @@ bool sf_grid_t::reserve_ul_prbs(const prbmask_t& prbmask, bool strict) { bool ret = true; if (strict and (ul_mask & prbmask).any()) { - log_h->error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s\n", + logger.error("There was a collision in UL channel. current mask=0x%s, new alloc mask=0x%s", ul_mask.to_hex().c_str(), prbmask.to_hex().c_str()); ret = false; @@ -560,7 +303,7 @@ bool sf_grid_t::find_ul_alloc(uint32_t L, prb_interval* alloc) const * TTI resource Scheduling Methods *******************************************************/ -sf_sched::sf_sched() : log_h(srslte::logmap::get("MAC")) {} +sf_sched::sf_sched() : logger(srslog::fetch_basic_logger("MAC")) {} void sf_sched::init(const sched_cell_params_t& cell_params_) { @@ -595,7 +338,7 @@ void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_) prbmask_t prach_mask{cc_cfg->nof_prb()}; prach_mask.fill(cc_cfg->cfg.prach_freq_offset, cc_cfg->cfg.prach_freq_offset + 6); reserve_ul_prbs(prach_mask, cc_cfg->nof_prb() != 6); - log_h->debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s\n", + logger.debug("SCHED: Allocated PRACH RBs for tti_tx_ul=%d. Mask: 0x%s", to_tx_ul(tti_rx).to_uint(), prach_mask.to_hex().c_str()); } @@ -662,11 +405,11 @@ alloc_outcome_t sf_sched::alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t uint32_t rv = get_rvidx(sib_ntx); ctrl_code_t ret = alloc_dl_ctrl(aggr_lvl, sib_len, SRSLTE_SIRNTI); if (not ret.first) { - Warning("SCHED: Could not allocate SIB=%d, L=%d, len=%d, cause=%s\n", - sib_idx + 1, - aggr_lvl, - sib_len, - ret.first.to_string()); + logger.warning("SCHED: Could not allocate SIB=%d, L=%d, len=%d, cause=%s", + sib_idx + 1, + aggr_lvl, + sib_len, + ret.first.to_string()); return ret.first; } @@ -682,13 +425,13 @@ alloc_outcome_t sf_sched::alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t alloc_outcome_t sf_sched::alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload) { if (bc_allocs.size() >= sched_interface::MAX_BC_LIST) { - Warning("SCHED: Maximum number of Broadcast allocations reached\n"); + logger.warning("SCHED: Maximum number of Broadcast allocations reached"); return alloc_outcome_t::ERROR; } ctrl_code_t ret = alloc_dl_ctrl(aggr_lvl, paging_payload, SRSLTE_PRNTI); if (not ret.first) { - Warning( - "SCHED: Could not allocate Paging with payload length=%d, cause=%s\n", paging_payload, ret.first.to_string()); + logger.warning( + "SCHED: Could not allocate Paging with payload length=%d, cause=%s", paging_payload, ret.first.to_string()); return ret.first; } @@ -704,7 +447,7 @@ std::pair sf_sched::alloc_rar(uint32_t aggr_lvl, cons const uint32_t msg3_grant_size = 3; std::pair ret = {alloc_outcome_t::ERROR, 0}; if (rar_allocs.size() >= sched_interface::MAX_RAR_LIST) { - Warning("SCHED: Maximum number of RAR allocations per TTI reached.\n"); + logger.warning("SCHED: Maximum number of RAR allocations per TTI reached."); return ret; } @@ -729,7 +472,7 @@ std::pair sf_sched::alloc_rar(uint32_t aggr_lvl, cons } // if any other error, return if (ret.first != alloc_outcome_t::SUCCESS) { - log_h->warning("SCHED: Could not allocate RAR for L=%d, cause=%s\n", aggr_lvl, ret.first.to_string()); + logger.warning("SCHED: Could not allocate RAR for L=%d, cause=%s", aggr_lvl, ret.first.to_string()); return ret; } @@ -750,7 +493,7 @@ std::pair sf_sched::alloc_rar(uint32_t aggr_lvl, cons break; } if (ret.first != alloc_outcome_t::SUCCESS) { - log_h->info("SCHED: Failed to allocate RAR due to lack of RBs\n"); + logger.info("SCHED: Failed to allocate RAR due to lack of RBs"); } return ret; } @@ -770,18 +513,18 @@ bool is_periodic_cqi_expected(const sched_interface::ue_cfg_t& ue_cfg, tti_point alloc_outcome_t sf_sched::alloc_dl_user(sched_ue* user, const rbgmask_t& user_mask, uint32_t pid) { if (data_allocs.size() >= sched_interface::MAX_DATA_LIST) { - Warning("SCHED: Maximum number of DL allocations reached\n"); + logger.warning("SCHED: Maximum number of DL allocations reached"); return alloc_outcome_t::ERROR; } if (is_dl_alloc(user->get_rnti())) { - Warning("SCHED: Attempt to assign multiple harq pids to the same user rnti=0x%x\n", user->get_rnti()); + logger.warning("SCHED: Attempt to assign multiple harq pids to the same user rnti=0x%x", user->get_rnti()); return alloc_outcome_t::ALREADY_ALLOC; } auto* cc = user->find_ue_carrier(cc_cfg->enb_cc_idx); if (cc == nullptr or cc->cc_state() != cc_st::active) { - return alloc_outcome_t::ERROR; + return alloc_outcome_t::INVALID_CARRIER; } if (not user->pdsch_enabled(srslte::tti_point{get_tti_rx()}, cc_cfg->enb_cc_idx)) { return alloc_outcome_t::MEASGAP_COLLISION; @@ -793,11 +536,17 @@ alloc_outcome_t sf_sched::alloc_dl_user(sched_ue* user, const rbgmask_t& user_ma // It is newTx rbg_interval r = user->get_required_dl_rbgs(cc_cfg->enb_cc_idx); if (r.start() > user_mask.count()) { - log_h->warning("The number of RBGs allocated to rnti=0x%x will force segmentation\n", user->get_rnti()); + logger.warning("SCHED: The number of RBGs allocated to rnti=0x%x will force segmentation", user->get_rnti()); return alloc_outcome_t::NOF_RB_INVALID; } } + srslte_dci_format_t dci_format = user->get_dci_format(); + if (dci_format == SRSLTE_DCI_FORMAT1A and not is_contiguous(user_mask)) { + logger.warning("SCHED: Can't use distributed RBGs for DCI format 1A"); + return alloc_outcome_t::INVALID_PRBMASK; + } + // Check if there is space in the PUCCH for HARQ ACKs const sched_interface::ue_cfg_t& ue_cfg = user->get_ue_cfg(); std::bitset scells = user->scell_activation_mask(); @@ -838,13 +587,13 @@ alloc_outcome_t sf_sched::alloc_dl_user(sched_ue* user, const rbgmask_t& user_ma alloc_outcome_t sf_sched::alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, int msg3_mcs) { if (ul_data_allocs.size() >= sched_interface::MAX_DATA_LIST) { - Warning("SCHED: Maximum number of UL allocations reached\n"); + logger.warning("SCHED: Maximum number of UL allocations reached"); return alloc_outcome_t::ERROR; } // Check whether user was already allocated if (is_ul_alloc(user->get_rnti())) { - log_h->warning("SCHED: Attempt to assign multiple ul_harq_proc to the same user rnti=0x%x\n", user->get_rnti()); + logger.warning("SCHED: Attempt to assign multiple ul_harq_proc to the same user rnti=0x%x", user->get_rnti()); return alloc_outcome_t::ALREADY_ALLOC; } @@ -893,7 +642,7 @@ alloc_outcome_t sf_sched::alloc_ul_user(sched_ue* user, prb_interval alloc) bool sf_sched::alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_sf_result) { if (ul_sf_result->nof_phich_elems >= sched_interface::MAX_PHICH_LIST) { - Warning("SCHED: Maximum number of PHICH allocations has been reached\n"); + logger.warning("SCHED: Maximum number of PHICH allocations has been reached"); return false; } using phich_t = sched_interface::ul_sched_phich_t; @@ -917,8 +666,8 @@ bool sf_sched::alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_s return false; } -void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, - sched_interface::dl_sched_res_t* dl_result) +void sf_sched::set_bc_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::dl_sched_res_t* dl_result) { for (const auto& bc_alloc : bc_allocs) { sched_interface::dl_sched_bc_t* bc = &dl_result->bc[dl_result->nof_bc_elems]; @@ -933,7 +682,7 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul // Setup BC/Paging processes if (bc_alloc.alloc_type == alloc_type_t::DL_BC) { if (tbs <= (int)bc_alloc.req_bytes) { - log_h->warning("SCHED: Error SIB%d, rbgs=(%d,%d), dci=(%d,%d), len=%d\n", + logger.warning("SCHED: Error SIB%d, rbgs=(%d,%d), dci=(%d,%d), len=%d", bc_alloc.sib_idx + 1, bc_alloc.rbg_range.start(), bc_alloc.rbg_range.stop(), @@ -948,7 +697,7 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul bc->type = sched_interface::dl_sched_bc_t::BCCH; bc->tbs = (uint32_t)bc_alloc.req_bytes; - log_h->debug("SCHED: SIB%d, rbgs=(%d,%d), dci=(%d,%d), rv=%d, len=%d, period=%d, mcs=%d\n", + logger.debug("SCHED: SIB%d, rbgs=(%d,%d), dci=(%d,%d), rv=%d, len=%d, period=%d, mcs=%d", bc_alloc.sib_idx + 1, bc_alloc.rbg_range.start(), bc_alloc.rbg_range.stop(), @@ -961,7 +710,7 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul } else { // Paging if (tbs <= 0) { - log_h->warning("SCHED: Error Paging, rbgs=%s, dci=(%d,%d)\n", + logger.warning("SCHED: Error Paging, rbgs=%s, dci=(%d,%d)", bc_alloc.rbg_range.to_string().c_str(), bc->dci.location.L, bc->dci.location.ncce); @@ -972,7 +721,7 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul bc->type = sched_interface::dl_sched_bc_t::PCCH; bc->tbs = (uint32_t)tbs; - log_h->info("SCHED: PCH, rbgs=%s, dci=(%d,%d), tbs=%d, mcs=%d\n", + logger.info("SCHED: PCH, rbgs=%s, dci=(%d,%d), tbs=%d, mcs=%d", bc_alloc.rbg_range.to_string().c_str(), bc->dci.location.L, bc->dci.location.ncce, @@ -984,8 +733,8 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul } } -void sf_sched::set_rar_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, - sched_interface::dl_sched_res_t* dl_result) +void sf_sched::set_rar_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::dl_sched_res_t* dl_result) { for (const auto& rar_alloc : rar_allocs) { sched_interface::dl_sched_rar_t* rar = &dl_result->rar[dl_result->nof_rar_elems]; @@ -997,7 +746,7 @@ void sf_sched::set_rar_sched_result(const pdcch_grid_t::alloc_result_t& dci_resu prb_interval prb_range = prb_interval::rbgs_to_prbs(rar_alloc.alloc_data.rbg_range, cc_cfg->nof_prb()); int tbs = generate_format1a(prb_range, rar_alloc.alloc_data.req_bytes, 0, rar_alloc.alloc_data.rnti, &rar->dci); if (tbs <= 0) { - log_h->warning("SCHED: Error RAR, ra_rnti_idx=%d, rbgs=%s, dci=(%d,%d)\n", + logger.warning("SCHED: Error RAR, ra_rnti_idx=%d, rbgs=%s, dci=(%d,%d)", rar_alloc.alloc_data.rnti, rar_alloc.alloc_data.rbg_range.to_string().c_str(), rar->dci.location.L, @@ -1013,8 +762,8 @@ void sf_sched::set_rar_sched_result(const pdcch_grid_t::alloc_result_t& dci_resu for (uint32_t i = 0; i < rar->msg3_grant.size(); ++i) { const auto& msg3_grant = rar->msg3_grant[i]; uint16_t expected_rnti = msg3_grant.data.temp_crnti; - log_h->info("SCHED: RAR, temp_crnti=0x%x, ra-rnti=%d, rbgs=%s, dci=(%d,%d), rar_grant_rba=%d, " - "rar_grant_mcs=%d\n", + logger.info("SCHED: RAR, temp_crnti=0x%x, ra-rnti=%d, rbgs=%s, dci=(%d,%d), rar_grant_rba=%d, " + "rar_grant_mcs=%d", expected_rnti, rar_alloc.alloc_data.rnti, rar_alloc.alloc_data.rbg_range.to_string().c_str(), @@ -1028,9 +777,9 @@ void sf_sched::set_rar_sched_result(const pdcch_grid_t::alloc_result_t& dci_resu } } -void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, - sched_interface::dl_sched_res_t* dl_result, - sched_ue_list& ue_list) +void sf_sched::set_dl_data_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::dl_sched_res_t* dl_result, + sched_ue_list& ue_list) { for (const auto& data_alloc : data_allocs) { sched_interface::dl_sched_data_t* data = &dl_result->data[dl_result->nof_data_elems]; @@ -1043,7 +792,7 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_ if (ue_it == ue_list.end()) { continue; } - sched_ue* user = &ue_it->second; + sched_ue* user = ue_it->second.get(); uint32_t data_before = user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop(); const dl_harq_proc& dl_harq = user->get_dl_harq(data_alloc.pid, cc_cfg->enb_cc_idx); bool is_newtx = dl_harq.is_empty(); @@ -1052,7 +801,7 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_ data_alloc.pid, data, get_tti_tx_dl(), cc_cfg->enb_cc_idx, tti_alloc.get_cfi(), data_alloc.user_mask); if (tbs <= 0) { - log_h->warning("SCHED: DL %s failed rnti=0x%x, pid=%d, mask=%s, tbs=%d, buffer=%d\n", + logger.warning("SCHED: DL %s failed rnti=0x%x, pid=%d, mask=%s, tbs=%d, buffer=%d", is_newtx ? "tx" : "retx", user->get_rnti(), data_alloc.pid, @@ -1063,7 +812,7 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_ } // Print Resulting DL Allocation - log_h->info("SCHED: DL %s rnti=0x%x, cc=%d, pid=%d, mask=0x%s, dci=(%d,%d), n_rtx=%d, tbs=%d, buffer=%d/%d\n", + logger.info("SCHED: DL %s rnti=0x%x, cc=%d, pid=%d, mask=0x%s, dci=(%d,%d), n_rtx=%d, tbs=%d, buffer=%d/%d", !is_newtx ? "retx" : "tx", user->get_rnti(), cc_cfg->enb_cc_idx, @@ -1166,9 +915,9 @@ uci_pusch_t is_uci_included(const sf_sched* sf_sched, } } -void sf_sched::set_ul_sched_result(const pdcch_grid_t::alloc_result_t& dci_result, - sched_interface::ul_sched_res_t* ul_result, - sched_ue_list& ue_list) +void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_result, + sched_interface::ul_sched_res_t* ul_result, + sched_ue_list& ue_list) { /* Set UL data DCI locs and format */ for (const auto& ul_alloc : ul_data_allocs) { @@ -1178,7 +927,7 @@ void sf_sched::set_ul_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul if (ue_it == ue_list.end()) { continue; } - sched_ue* user = &ue_it->second; + sched_ue* user = ue_it->second.get(); srslte_dci_location_t cce_range = {0, 0}; if (ul_alloc.needs_pdcch()) { @@ -1203,7 +952,7 @@ void sf_sched::set_ul_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul uint32_t new_pending_bytes = user->get_pending_ul_new_data(get_tti_tx_ul(), cc_cfg->enb_cc_idx); // Allow TBS=0 in case of UCI-only PUSCH if (tbs < 0 || (tbs == 0 && pusch->dci.tb.mcs_idx != 29)) { - log_h->warning("SCHED: Error %s %s rnti=0x%x, pid=%d, dci=(%d,%d), prb=%s, bsr=%d\n", + logger.warning("SCHED: Error %s %s rnti=0x%x, pid=%d, dci=(%d,%d), prb=%s, bsr=%d", ul_alloc.type == ul_alloc_t::MSG3 ? "Msg3" : "UL", ul_alloc.is_retx() ? "retx" : "tx", user->get_rnti(), @@ -1217,7 +966,7 @@ void sf_sched::set_ul_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul // Print Resulting UL Allocation uint32_t old_pending_bytes = user->get_pending_ul_old_data(); - log_h->info("SCHED: %s %s rnti=0x%x, cc=%d, pid=%d, dci=(%d,%d), prb=%s, n_rtx=%d, tbs=%d, bsr=%d (%d-%d)\n", + logger.info("SCHED: %s %s rnti=0x%x, cc=%d, pid=%d, dci=(%d,%d), prb=%s, n_rtx=%d, tbs=%d, bsr=%d (%d-%d)", ul_alloc.is_msg3() ? "Msg3" : "UL", ul_alloc.is_retx() ? "retx" : "tx", user->get_rnti(), @@ -1245,7 +994,7 @@ alloc_outcome_t sf_sched::alloc_msg3(sched_ue* user, const sched_interface::dl_s alloc_outcome_t ret = alloc_ul(user, msg3_alloc, sf_sched::ul_alloc_t::MSG3, rargrant.grant.trunc_mcs); if (not ret) { - log_h->warning("SCHED: Could not allocate msg3 within %s\n", msg3_alloc.to_string().c_str()); + logger.warning("SCHED: Could not allocate msg3 within %s", msg3_alloc.to_string().c_str()); } return ret; } @@ -1260,18 +1009,18 @@ void sf_sched::generate_sched_results(sched_ue_list& ue_db) for (uint32_t i = 0; i < cc_result->ul_sched_result.nof_phich_elems; ++i) { auto& phich = phich_list[i]; if (phich.phich == phich_t::NACK) { - auto& ue = ue_db[phich.rnti]; + auto& ue = *ue_db[phich.rnti]; ul_harq_proc* h = ue.get_ul_harq(get_tti_tx_ul(), cc_cfg->enb_cc_idx); if (not is_ul_alloc(ue.get_rnti()) and h != nullptr and not h->is_empty()) { // There was a missed UL harq retx. Halt+Resume the HARQ phich.phich = phich_t::ACK; - log_h->debug("SCHED: rnti=0x%x UL harq pid=%d is being resumed\n", ue.get_rnti(), h->get_id()); + logger.debug("SCHED: rnti=0x%x UL harq pid=%d is being resumed", ue.get_rnti(), h->get_id()); } } } /* Pick one of the possible DCI masks */ - pdcch_grid_t::alloc_result_t dci_result; + sf_cch_allocator::alloc_result_t dci_result; // tti_alloc.get_pdcch_grid().result_to_string(); tti_alloc.get_pdcch_grid().get_allocs(&dci_result, &cc_result->pdcch_mask); @@ -1323,16 +1072,16 @@ int sf_sched::generate_format1a(prb_interval prb_range, } } if (i == 28) { - Error("Can't allocate Format 1A for TBS=%d\n", tbs); + logger.error("Can't allocate Format 1A for TBS=%d", tbs); return -1; } - Debug("ra_tbs=%d/%d, tbs_bytes=%d, tbs=%d, mcs=%d\n", - srslte_ra_tbs_from_idx(mcs, 2), - srslte_ra_tbs_from_idx(mcs, 3), - tbs_bytes, - tbs, - mcs); + logger.debug("ra_tbs=%d/%d, tbs_bytes=%d, tbs=%d, mcs=%d", + srslte_ra_tbs_from_idx(mcs, 2), + srslte_ra_tbs_from_idx(mcs, 3), + tbs_bytes, + tbs, + mcs); dci->alloc_type = SRSLTE_RA_ALLOC_TYPE2; dci->type2_alloc.mode = srslte_ra_type2_t::SRSLTE_RA_TYPE2_LOC; diff --git a/srsenb/src/stack/mac/sched_helpers.cc b/srsenb/src/stack/mac/sched_helpers.cc index 2fa1eb6c0..fc383abc1 100644 --- a/srsenb/src/stack/mac/sched_helpers.cc +++ b/srsenb/src/stack/mac/sched_helpers.cc @@ -24,10 +24,10 @@ #include "srslte/srslog/bundled/fmt/format.h" #include -#define Debug(fmt, ...) srslte::logmap::get("MAC")->debug(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) srslte::logmap::get("MAC")->info(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) srslte::logmap::get("MAC")->warning(fmt, ##__VA_ARGS__) -#define Error(fmt, ...) srslte::logmap::get("MAC")->error(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) srslog::fetch_basic_logger("MAC").debug(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) srslog::fetch_basic_logger("MAC").info(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) srslog::fetch_basic_logger("MAC").warning(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) srslog::fetch_basic_logger("MAC").error(fmt, ##__VA_ARGS__) namespace srsenb { @@ -107,36 +107,39 @@ void fill_dl_cc_result_debug(custom_mem_buffer& strbuf, const dl_sched_data_t& d } } } - fmt::format_to(strbuf, "]\n"); + fmt::format_to(strbuf, "]"); } -void log_dl_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result) +void log_dl_cc_results(srslog::basic_logger& logger, uint32_t enb_cc_idx, const sched_interface::dl_sched_res_t& result) { - if (log_h->get_level() < srslte::LOG_LEVEL_INFO) { + if (!logger.info.enabled() && !logger.debug.enabled()) { return; } + custom_mem_buffer strbuf; for (uint32_t i = 0; i < result.nof_data_elems; ++i) { const dl_sched_data_t& data = result.data[i]; - if (log_h->get_level() == srslte::LOG_LEVEL_INFO) { - fill_dl_cc_result_info(strbuf, data); - } else if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { fill_dl_cc_result_debug(strbuf, data); + } else { + fill_dl_cc_result_info(strbuf, data); } } if (strbuf.size() != 0) { - if (log_h->get_level() == srslte::LOG_LEVEL_DEBUG) { - log_h->debug("SCHED: DL MAC PDU payload cc=%d:\n%s", enb_cc_idx, fmt::to_string(strbuf).c_str()); + if (logger.debug.enabled()) { + logger.debug("SCHED: DL MAC PDU payload cc=%d:\n%s", enb_cc_idx, fmt::to_string(strbuf).c_str()); } else { - log_h->info("SCHED: DL MAC CEs cc=%d: %s", enb_cc_idx, fmt::to_string(strbuf).c_str()); + logger.info("SCHED: DL MAC CEs cc=%d: %s", enb_cc_idx, fmt::to_string(strbuf).c_str()); } } } -void log_phich_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sched_interface::ul_sched_res_t& result) +void log_phich_cc_results(srslog::basic_logger& logger, + uint32_t enb_cc_idx, + const sched_interface::ul_sched_res_t& result) { using phich_t = sched_interface::ul_sched_phich_t; - if (log_h->get_level() < srslte::LOG_LEVEL_INFO) { + if (!logger.info.enabled()) { return; } custom_mem_buffer strbuf; @@ -147,7 +150,7 @@ void log_phich_cc_results(srslte::log_ref log_h, uint32_t enb_cc_idx, const sche fmt::format_to(strbuf, "{}rnti=0x{:0x}, val={}", prefix, phich.rnti, val); } if (strbuf.size() != 0) { - log_h->debug("SCHED: Allocated PHICHs, cc=%d: [%s]", enb_cc_idx, fmt::to_string(strbuf).c_str()); + logger.debug("SCHED: Allocated PHICHs, cc=%d: [%s]", enb_cc_idx, fmt::to_string(strbuf).c_str()); } } @@ -188,6 +191,11 @@ prb_interval prb_interval::riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_ return {rb_start, rb_start + l_crb}; } +bool is_contiguous(const rbgmask_t& mask) +{ + return rbg_interval::rbgmask_to_rbgs(mask).length() == mask.count(); +} + /******************************************************* * Sched Params *******************************************************/ @@ -259,7 +267,7 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id // Basic cell config checks if (cfg.si_window_ms == 0) { - Error("SCHED: Invalid si-window length 0 ms\n"); + Error("SCHED: Invalid si-window length 0 ms"); return false; } @@ -279,7 +287,7 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id ((int)cfg.prach_freq_offset < cfg.nrb_pucch); } if (invalid_prach) { - Error("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset); + Error("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits", cfg.prach_freq_offset); srslte::console("Invalid PRACH configuration: frequency offset=%d outside bandwidth limits\n", cfg.prach_freq_offset); return false; @@ -290,16 +298,16 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id // init regs regs.reset(new srslte_regs_t{}); if (srslte_regs_init(regs.get(), cfg.cell) != SRSLTE_SUCCESS) { - Error("Getting DCI locations\n"); + Error("Getting DCI locations"); return false; } // Compute Common locations for DCI for each CFI for (uint32_t cfix = 0; cfix < SRSLTE_NOF_CFI; cfix++) { - generate_cce_location(regs.get(), &common_locations[cfix], cfix + 1); + generate_cce_location(regs.get(), common_locations[cfix], cfix + 1); } - if (common_locations[sched_cfg->max_nof_ctrl_symbols - 1].nof_loc[2] == 0) { - Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).\n", + if (common_locations[sched_cfg->max_nof_ctrl_symbols - 1][2].empty()) { + Error("SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).", sched_cfg->max_nof_ctrl_symbols); srslte::console( "SCHED: Current cfi=%d is not valid for broadcast (check scheduler.max_nof_ctrl_symbols in conf file).\n", @@ -308,9 +316,9 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id } // Compute UE locations for RA-RNTI - for (uint32_t cfi = 0; cfi < 3; cfi++) { - for (uint32_t sf_idx = 0; sf_idx < 10; sf_idx++) { - generate_cce_location(regs.get(), &rar_locations[cfi][sf_idx], cfi + 1, sf_idx); + for (uint32_t cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) { + for (uint32_t sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) { + generate_cce_location(regs.get(), rar_locations[sf_idx][cfi], cfi + 1, sf_idx); } } @@ -318,7 +326,7 @@ bool sched_cell_params_t::set_cfg(uint32_t enb_cc_id for (uint32_t cfix = 0; cfix < nof_cce_table.size(); ++cfix) { int ret = srslte_regs_pdcch_ncce(regs.get(), cfix + 1); if (ret < 0) { - Error("SCHED: Failed to calculate the number of CCEs in the PDCCH\n"); + Error("SCHED: Failed to calculate the number of CCEs in the PDCCH"); return false; } nof_cce_table[cfix] = (uint32_t)ret; @@ -370,25 +378,25 @@ sched_cell_params_t::get_dl_nof_res(srslte::tti_point tti_tx_dl, const srslte_dc return nof_re; } -ue_cce_locations_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg) +cce_frame_position_table generate_cce_location_table(uint16_t rnti, const sched_cell_params_t& cell_cfg) { - ue_cce_locations_table dci_locations; + cce_frame_position_table dci_locations = {}; // Generate allowed CCE locations for (int cfi = 0; cfi < SRSLTE_NOF_CFI; cfi++) { for (int sf_idx = 0; sf_idx < SRSLTE_NOF_SF_X_FRAME; sf_idx++) { - generate_cce_location(cell_cfg.regs.get(), &dci_locations[cfi][sf_idx], cfi + 1, sf_idx, rnti); + generate_cce_location(cell_cfg.regs.get(), dci_locations[sf_idx][cfi], cfi + 1, sf_idx, rnti); } } return dci_locations; } -void generate_cce_location(srslte_regs_t* regs_, - sched_dci_cce_t* location, - uint32_t cfi, - uint32_t sf_idx, - uint16_t rnti) +void generate_cce_location(srslte_regs_t* regs_, + cce_cfi_position_table& locations, + uint32_t cfi, + uint32_t sf_idx, + uint16_t rnti) { - *location = {}; + locations = {}; srslte_dci_location_t loc[64]; uint32_t nloc = 0; @@ -400,9 +408,8 @@ void generate_cce_location(srslte_regs_t* regs_, // Save to different format for (uint32_t i = 0; i < nloc; i++) { - uint32_t l = loc[i].L; - location->cce_start[l][location->nof_loc[l]] = loc[i].ncce; - location->nof_loc[l]++; + uint32_t l = loc[i].L; + locations[l].push_back(loc[i].ncce); } } @@ -413,8 +420,6 @@ void generate_cce_location(srslte_regs_t* regs_, uint32_t get_aggr_level(uint32_t nof_bits, uint32_t dl_cqi, uint32_t max_aggr_lvl, uint32_t cell_nof_prb, bool use_tbs_index_alt) { - static srslte::log_ref cached_log = srslte::logmap::get("MAC"); - uint32_t l = 0; float max_coderate = srslte_cqi_to_coderate(dl_cqi, use_tbs_index_alt); float coderate; @@ -431,12 +436,12 @@ get_aggr_level(uint32_t nof_bits, uint32_t dl_cqi, uint32_t max_aggr_lvl, uint32 l++; } while (l < l_max && factor * coderate > max_coderate); - cached_log->debug("SCHED: CQI=%d, l=%d, nof_bits=%d, coderate=%.2f, max_coderate=%.2f\n", - dl_cqi, - l, - nof_bits, - coderate, - max_coderate); + Debug("SCHED: CQI=%d, l=%d, nof_bits=%d, coderate=%.2f, max_coderate=%.2f", + dl_cqi, + l, + nof_bits, + coderate, + max_coderate); return l; } @@ -460,14 +465,13 @@ int check_ue_cfg_correctness(const sched_interface::ue_cfg_t& ue_cfg) continue; } if (not cc1.dl_cfg.cqi_report.periodic_configured and not cc1.dl_cfg.cqi_report.aperiodic_configured) { - Warning("SCHED: No CQI configuration was provided for UE scell index=%d \n", i); + Warning("SCHED: No CQI configuration was provided for UE scell index=%d", i); ret = SRSLTE_ERROR; } else if (cc1.dl_cfg.cqi_report.periodic_configured) { for (uint32_t j = i + 1; j < cc_list.size(); ++j) { if (cc_list[j].active and cc_list[j].dl_cfg.cqi_report.periodic_configured and cc_list[j].dl_cfg.cqi_report.pmi_idx == cc1.dl_cfg.cqi_report.pmi_idx) { - Warning( - "SCHED: The provided CQI configurations for UE scells %d and %d collide in time resources.\n", i, j); + Warning("SCHED: The provided CQI configurations for UE scells %d and %d collide in time resources.", i, j); ret = SRSLTE_ERROR; } } diff --git a/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc new file mode 100644 index 000000000..96a687dd1 --- /dev/null +++ b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc @@ -0,0 +1,280 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h" +#include "srsenb/hdr/stack/mac/sched_grid.h" + +namespace srsenb { + +void sf_cch_allocator::alloc_tree_t::reset() +{ + prev_start = 0; + prev_end = 0; + dci_alloc_tree.clear(); +} + +void sf_cch_allocator::init(const sched_cell_params_t& cell_params_) +{ + cc_cfg = &cell_params_; + + // init alloc trees + alloc_trees.reserve(cc_cfg->sched_cfg->max_nof_ctrl_symbols); + for (uint32_t i = 0; i < cc_cfg->sched_cfg->max_nof_ctrl_symbols; ++i) { + alloc_trees.emplace_back(cc_cfg->nof_cce_table[i]); + } +} + +void sf_cch_allocator::new_tti(tti_point tti_rx_) +{ + tti_rx = tti_rx_; + + // Reset back all CFIs + for (auto& t : alloc_trees) { + t.reset(); + } + dci_record_list.clear(); + current_cfix = cc_cfg->sched_cfg->min_nof_ctrl_symbols - 1; +} + +const cce_cfi_position_table* +sf_cch_allocator::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uint32_t cfix) const +{ + switch (alloc_type) { + case alloc_type_t::DL_BC: + return &cc_cfg->common_locations[cfix]; + case alloc_type_t::DL_PCCH: + return &cc_cfg->common_locations[cfix]; + case alloc_type_t::DL_RAR: + return &cc_cfg->rar_locations[to_tx_dl(tti_rx).sf_idx()][cfix]; + case alloc_type_t::DL_DATA: + return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx()); + case alloc_type_t::UL_DATA: + return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx()); + default: + break; + } + return nullptr; +} + +bool sf_cch_allocator::alloc_dci(alloc_type_t alloc_type, uint32_t aggr_idx, sched_ue* user) +{ + // TODO: Make the alloc tree update lazy + alloc_record_t record{.user = user, .aggr_idx = aggr_idx, .alloc_type = alloc_type}; + + // Try to allocate user in PDCCH for given CFI. If it fails, increment CFI. + uint32_t first_cfi = get_cfi(); + bool success; + do { + success = alloc_dci_record(record, get_cfi() - 1); + } while (not success and get_cfi() < cc_cfg->sched_cfg->max_nof_ctrl_symbols and set_cfi(get_cfi() + 1)); + + if (not success) { + // DCI allocation failed. go back to original CFI + if (get_cfi() != first_cfi and not set_cfi(first_cfi)) { + logger.error("SCHED: Failed to return back to original PDCCH state"); + } + return false; + } + + // DCI record allocation successful + dci_record_list.push_back(record); + return true; +} + +bool sf_cch_allocator::alloc_dci_record(const alloc_record_t& record, uint32_t cfix) +{ + bool ret = false; + auto& tree = alloc_trees[cfix]; + + // Get DCI Location Table + const cce_cfi_position_table* dci_locs = get_cce_loc_table(record.alloc_type, record.user, cfix); + if (dci_locs == nullptr or (*dci_locs)[record.aggr_idx].empty()) { + return ret; + } + + if (tree.prev_end > 0) { + for (size_t j = tree.prev_start; j < tree.prev_end; ++j) { + ret |= add_tree_node_leaves(tree, (int)j, record, *dci_locs, to_tx_dl(tti_rx)); + } + } else { + ret = add_tree_node_leaves(tree, -1, record, *dci_locs, to_tx_dl(tti_rx)); + } + + if (ret) { + tree.prev_start = tree.prev_end; + tree.prev_end = tree.dci_alloc_tree.size(); + } + + return ret; +} + +//! Algorithm to compute a valid PDCCH allocation +bool sf_cch_allocator::add_tree_node_leaves(alloc_tree_t& tree, + int parent_node_idx, + const alloc_record_t& dci_record, + const cce_cfi_position_table& dci_locs, + tti_point tti_tx_dl) +{ + bool ret = false; + + alloc_t alloc; + alloc.rnti = (dci_record.user != nullptr) ? dci_record.user->get_rnti() : (uint16_t)0u; + alloc.dci_pos.L = dci_record.aggr_idx; + + // get cumulative pdcch mask + pdcch_mask_t cum_mask; + if (parent_node_idx >= 0) { + cum_mask = tree.dci_alloc_tree[parent_node_idx].node.total_mask; + } else { + cum_mask.resize(tree.nof_cces); + } + + for (uint32_t i = 0; i < dci_locs[dci_record.aggr_idx].size(); ++i) { + uint32_t startpos = dci_locs[dci_record.aggr_idx][i]; + + if (dci_record.alloc_type == alloc_type_t::DL_DATA and dci_record.user->pucch_sr_collision(tti_tx_dl, startpos)) { + // will cause a collision in the PUCCH + continue; + } + + pdcch_mask_t alloc_mask(tree.nof_cces); + alloc_mask.fill(startpos, startpos + (1u << dci_record.aggr_idx)); + if ((cum_mask & alloc_mask).any()) { + // there is collision. Try another mask + continue; + } + + // Allocation successful + alloc.current_mask = alloc_mask; + alloc.total_mask = cum_mask | alloc_mask; + alloc.dci_pos.ncce = startpos; + + // Prune if repetition + uint32_t j = tree.prev_end; + for (; j < tree.dci_alloc_tree.size(); ++j) { + if (tree.dci_alloc_tree[j].node.total_mask == alloc.total_mask) { + break; + } + } + if (j < tree.dci_alloc_tree.size()) { + continue; + } + + // Register allocation + tree.dci_alloc_tree.emplace_back(parent_node_idx, alloc); + ret = true; + } + + return ret; +} + +bool sf_cch_allocator::set_cfi(uint32_t cfi) +{ + if (cfi < cc_cfg->sched_cfg->min_nof_ctrl_symbols or cfi > cc_cfg->sched_cfg->max_nof_ctrl_symbols) { + logger.error("Invalid CFI value. Defaulting to current CFI."); + return false; + } + + uint32_t new_cfix = cfi - 1; + if (new_cfix == current_cfix) { + return true; + } + + // setup new PDCCH alloc tree + auto& new_tree = alloc_trees[new_cfix]; + new_tree.reset(); + + if (not dci_record_list.empty()) { + // there are already PDCCH allocations + + // Rebuild Allocation Tree + bool ret = true; + for (const auto& old_record : dci_record_list) { + ret &= alloc_dci_record(old_record, new_cfix); + } + + if (not ret) { + // Fail to rebuild allocation tree. Go back to previous CFI + return false; + } + } + + current_cfix = new_cfix; + // TODO: The estimation of the number of required prbs in metric depends on CFI. Analyse the consequences + return true; +} + +void sf_cch_allocator::get_allocs(alloc_result_t* vec, pdcch_mask_t* tot_mask, size_t idx) const +{ + auto& tree = alloc_trees[current_cfix]; + // if alloc tree is empty + if (tree.prev_start == tree.prev_end) { + if (vec != nullptr) { + vec->clear(); + } + if (tot_mask != nullptr) { + tot_mask->resize(nof_cces()); + tot_mask->reset(); + } + return; + } + + // set vector of allocations + if (vec != nullptr) { + vec->clear(); + size_t i = tree.prev_start + idx; + while (tree.dci_alloc_tree[i].parent_idx >= 0) { + vec->push_back(&tree.dci_alloc_tree[i].node); + i = (size_t)tree.dci_alloc_tree[i].parent_idx; + } + vec->push_back(&tree.dci_alloc_tree[i].node); + std::reverse(vec->begin(), vec->end()); + } + + // set final cce mask + if (tot_mask != nullptr) { + *tot_mask = tree.dci_alloc_tree[tree.prev_start + idx].node.total_mask; + } +} + +std::string sf_cch_allocator::result_to_string(bool verbose) const +{ + auto& tree = alloc_trees[current_cfix]; + std::stringstream ss; + ss << "cfi=" << get_cfi() << ", mask_size=" << nof_cces() << ", " << tree.prev_end - tree.prev_start + << " DCI allocation combinations:\n"; + // get all the possible combinations of DCI allocations + uint32_t count = 0; + for (size_t i = tree.prev_start; i < tree.prev_end; ++i) { + alloc_result_t vec; + pdcch_mask_t tot_mask; + get_allocs(&vec, &tot_mask, i - tree.prev_start); + + ss << " combination " << count << ": mask=0x" << tot_mask.to_hex().c_str(); + if (verbose) { + ss << ", DCI allocs:\n"; + for (const auto& dci_alloc : vec) { + char hex[5]; + sprintf(hex, "%x", dci_alloc->rnti); + ss << " > rnti=0x" << hex << ": " << dci_alloc->current_mask.to_hex().c_str() << " / " + << dci_alloc->total_mask.to_hex().c_str() << "\n"; + } + } else { + ss << "\n"; + } + count++; + } + + return ss.str(); +} + +} // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index 6a1f58918..bdccc4f5e 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -44,16 +44,17 @@ namespace srsenb { * *******************************************************/ -sched_ue::sched_ue() : log_h(srslte::logmap::get("MAC")) {} - -void sched_ue::init(uint16_t rnti_, const std::vector& cell_list_params_) +sched_ue::sched_ue(uint16_t rnti_, const std::vector& cell_list_params_, const ue_cfg_t& cfg_) : + logger(srslog::fetch_basic_logger("MAC")) { rnti = rnti_; cells.reserve(cell_list_params_.size()); for (auto& c : cell_list_params_) { cells.emplace_back(rnti_, c, current_tti); } - Info("SCHED: Added user rnti=0x%x\n", rnti); + logger.info("SCHED: Added user rnti=0x%x", rnti); + + set_cfg(cfg_); } void sched_ue::set_cfg(const ue_cfg_t& cfg_) @@ -64,7 +65,7 @@ void sched_ue::set_cfg(const ue_cfg_t& cfg_) if (not cfg_.supported_cc_list.empty()) { primary_cc_idx = cfg_.supported_cc_list[0].enb_cc_idx; } else { - Warning("Primary cc idx not provided in scheduler ue_cfg. Defaulting to cc_idx=0\n"); + logger.warning("Primary cc idx not provided in scheduler ue_cfg. Defaulting to cc_idx=0"); } // setup primary cc main_cc_params = cells[primary_cc_idx].cell_cfg; @@ -87,11 +88,11 @@ void sched_ue::set_cfg(const ue_cfg_t& cfg_) c.is_scell() and (c.cc_state() == cc_st::activating or c.cc_state() == cc_st::deactivating); } if (prev_supported_cc_list.empty() or prev_supported_cc_list[0].enb_cc_idx != cfg.supported_cc_list[0].enb_cc_idx) { - log_h->info("SCHED: rnti=0x%x PCell is now enb_cc_idx=%d.\n", rnti, cfg.supported_cc_list[0].enb_cc_idx); + logger.info("SCHED: rnti=0x%x PCell is now enb_cc_idx=%d", rnti, cfg.supported_cc_list[0].enb_cc_idx); } if (scell_activation_state_changed) { lch_handler.pending_ces.emplace_back(srslte::dl_sch_lcid::SCELL_ACTIVATION); - log_h->info("SCHED: Enqueueing SCell Activation CMD for rnti=0x%x\n", rnti); + logger.info("SCHED: Enqueueing SCell Activation CMD for rnti=0x%x", rnti); } check_ue_cfg_correctness(cfg); @@ -172,7 +173,7 @@ void sched_ue::mac_buffer_state(uint32_t ce_code, uint32_t nof_cmds) lch_handler.pending_ces.push_back(cmd); } } - Info("SCHED: %s for rnti=0x%x needs to be scheduled\n", to_string(cmd), rnti); + logger.info("SCHED: %s for rnti=0x%x needs to be scheduled", to_string(cmd), rnti); } void sched_ue::set_sr() @@ -264,13 +265,13 @@ int sched_ue::set_ack_info(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t tb_id std::pair p2 = cells[enb_cc_idx].harq_ent.set_ack_info(tti_rx, tb_idx, ack); tbs_acked = p2.second; if (tbs_acked > 0) { - Debug( - "SCHED: Set DL ACK=%d for rnti=0x%x, pid=%d, tb=%d, tti=%d\n", ack, rnti, p2.first, tb_idx, tti_rx.to_uint()); + logger.debug( + "SCHED: Set DL ACK=%d for rnti=0x%x, pid=%d, tb=%d, tti=%d", ack, rnti, p2.first, tb_idx, tti_rx.to_uint()); } else { - Warning("SCHED: Received ACK info for unknown TTI=%d\n", tti_rx.to_uint()); + logger.warning("SCHED: Received ACK info for unknown TTI=%d", tti_rx.to_uint()); } } else { - log_h->warning("Received DL ACK for invalid cell index %d\n", enb_cc_idx); + logger.warning("Received DL ACK for invalid cell index %d", enb_cc_idx); } return tbs_acked; } @@ -280,10 +281,10 @@ void sched_ue::set_ul_crc(tti_point tti_rx, uint32_t enb_cc_idx, bool crc_res) if (cells[enb_cc_idx].cc_state() != cc_st::idle) { int ret = cells[enb_cc_idx].harq_ent.set_ul_crc(tti_rx, 0, crc_res); if (ret < 0) { - log_h->warning("Received UL CRC for invalid tti_rx=%d\n", (int)tti_rx.to_uint()); + logger.warning("Received UL CRC for invalid tti_rx=%d", (int)tti_rx.to_uint()); } } else { - log_h->warning("Received UL CRC for invalid cell index %d\n", enb_cc_idx); + logger.warning("Received UL CRC for invalid cell index %d", enb_cc_idx); } } @@ -293,7 +294,7 @@ void sched_ue::set_dl_ri(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t ri) cells[enb_cc_idx].dl_ri = ri; cells[enb_cc_idx].dl_ri_tti_rx = tti_rx; } else { - log_h->warning("Received DL RI for invalid cell index %d\n", enb_cc_idx); + logger.warning("Received DL RI for invalid cell index %d", enb_cc_idx); } } @@ -303,7 +304,7 @@ void sched_ue::set_dl_pmi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t pmi) cells[enb_cc_idx].dl_pmi = pmi; cells[enb_cc_idx].dl_pmi_tti_rx = tti_rx; } else { - log_h->warning("Received DL PMI for invalid cell index %d\n", enb_cc_idx); + logger.warning("Received DL PMI for invalid cell index %d", enb_cc_idx); } } @@ -312,7 +313,7 @@ void sched_ue::set_dl_cqi(tti_point tti_rx, uint32_t enb_cc_idx, uint32_t cqi) if (cells[enb_cc_idx].cc_state() != cc_st::idle) { cells[enb_cc_idx].set_dl_cqi(tti_rx, cqi); } else { - log_h->warning("Received DL CQI for invalid enb cell index %d\n", enb_cc_idx); + logger.warning("Received DL CQI for invalid enb cell index %d", enb_cc_idx); } } @@ -323,7 +324,7 @@ void sched_ue::set_ul_snr(tti_point tti_rx, uint32_t enb_cc_idx, float snr, uint cells[enb_cc_idx].ul_cqi = srslte_cqi_from_snr(snr); cells[enb_cc_idx].ul_cqi_tti_rx = tti_rx; } else { - log_h->warning("Received SNR info for invalid cell index %d\n", enb_cc_idx); + logger.warning("Received SNR info for invalid cell index %d", enb_cc_idx); } } @@ -365,13 +366,13 @@ tbs_info sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* data, // emptied by another allocated tb_idx. uint32_t pending_bytes = lch_handler.get_dl_tx_total(); if (pending_bytes > 0) { - Warning("SCHED: Failed to allocate DL TB with tb_idx=%d, tbs=%d, pid=%d. Pending DL buffer data=%d\n", - tb, - rem_tbs, - h->get_id(), - pending_bytes); + logger.warning("SCHED: Failed to allocate DL TB with tb_idx=%d, tbs=%d, pid=%d. Pending DL buffer data=%d", + tb, + rem_tbs, + h->get_id(), + pending_bytes); } else { - Info("SCHED: DL TB tb_idx=%d, tbs=%d, pid=%d did not get allocated.\n", tb, rem_tbs, h->get_id()); + logger.info("SCHED: DL TB tb_idx=%d, tbs=%d, pid=%d did not get allocated.", tb, rem_tbs, h->get_id()); } tb_info.tbs_bytes = 0; tb_info.mcs = 0; @@ -388,25 +389,64 @@ int sched_ue::generate_dl_dci_format(uint32_t pid, const rbgmask_t& user_mask) { srslte_dci_format_t dci_format = get_dci_format(); - int tbs = 0; + int tbs_bytes = 0; switch (dci_format) { + case SRSLTE_DCI_FORMAT1A: + tbs_bytes = generate_format1a(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); + break; case SRSLTE_DCI_FORMAT1: - tbs = generate_format1(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); + tbs_bytes = generate_format1(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); break; case SRSLTE_DCI_FORMAT2: - tbs = generate_format2(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); + tbs_bytes = generate_format2(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); break; case SRSLTE_DCI_FORMAT2A: - tbs = generate_format2a(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); + tbs_bytes = generate_format2a(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); break; default: - Error("DCI format (%d) not implemented\n", dci_format); + logger.error("DCI format (%d) not implemented", dci_format); } - return tbs; + + // Set common DCI fields + if (tbs_bytes > 0) { + srslte_dci_dl_t* dci = &data->dci; + dci->rnti = rnti; + dci->pid = pid; + dci->ue_cc_idx = cells[enb_cc_idx].get_ue_cc_idx(); + data->dci.format = dci_format; + dci->tpc_pucch = cells[enb_cc_idx].tpc_fsm.encode_pucch_tpc(); + } + + return tbs_bytes; +} + +int sched_ue::generate_format1a(uint32_t pid, + sched_interface::dl_sched_data_t* data, + tti_point tti_tx_dl, + uint32_t enb_cc_idx, + uint32_t cfi, + const rbgmask_t& user_mask) +{ + int tbs_bytes = generate_format1(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); + + srslte_dci_dl_t* dci = &data->dci; + + dci->alloc_type = SRSLTE_RA_ALLOC_TYPE2; + dci->type2_alloc.mode = srslte_ra_type2_t::SRSLTE_RA_TYPE2_LOC; + rbg_interval rbg_int = rbg_interval::rbgmask_to_rbgs(user_mask); + prb_interval prb_int = prb_interval::rbgs_to_prbs(rbg_int, cell.nof_prb); + uint32_t L_crb = prb_int.length(); + uint32_t RB_start = prb_int.start(); + dci->type2_alloc.riv = srslte_ra_type2_to_riv(L_crb, RB_start, cell.nof_prb); + if (L_crb != count_prb_per_tb(user_mask)) { + // This happens if Type0 was using distributed allocation + logger.warning("SCHED: Can't use distributed RA due to DCI size ambiguity"); + } + + return tbs_bytes; } -// Generates a Format1 dci // > return 0 if allocation is invalid int sched_ue::generate_format1(uint32_t pid, sched_interface::dl_sched_data_t* data, @@ -418,46 +458,24 @@ int sched_ue::generate_format1(uint32_t pid, dl_harq_proc* h = &cells[enb_cc_idx].harq_ent.dl_harq_procs()[pid]; srslte_dci_dl_t* dci = &data->dci; - // If the size of Format1 and Format1A is ambiguous in the common SS, use Format1A since the UE assumes - // Common SS when spaces collide - if (cell.nof_prb == 15 && cells.size() > 1) { - dci->alloc_type = SRSLTE_RA_ALLOC_TYPE2; - dci->type2_alloc.mode = srslte_ra_type2_t::SRSLTE_RA_TYPE2_LOC; - rbg_interval rbg_int = rbg_interval::rbgmask_to_rbgs(user_mask); - prb_interval prb_int = prb_interval::rbgs_to_prbs(rbg_int, cell.nof_prb); - uint32_t L_crb = prb_int.length(); - uint32_t RB_start = prb_int.start(); - dci->type2_alloc.riv = srslte_ra_type2_to_riv(L_crb, RB_start, cell.nof_prb); - dci->format = SRSLTE_DCI_FORMAT1A; - if (L_crb != count_prb_per_tb(user_mask)) { - // This happens if Type0 was using distributed allocation - Warning("SCHED: Can't use distributed RA due to DCI size ambiguity\n"); - } - } else { - dci->alloc_type = SRSLTE_RA_ALLOC_TYPE0; - dci->type0_alloc.rbg_bitmask = (uint32_t)user_mask.to_uint64(); - dci->format = SRSLTE_DCI_FORMAT1; - } + dci->alloc_type = SRSLTE_RA_ALLOC_TYPE0; + dci->type0_alloc.rbg_bitmask = (uint32_t)user_mask.to_uint64(); tbs_info tbinfo; if (h->is_empty(0)) { tbinfo = allocate_new_dl_mac_pdu(data, h, user_mask, tti_tx_dl, enb_cc_idx, cfi, 0); } else { h->new_retx(user_mask, 0, tti_tx_dl, &tbinfo.mcs, &tbinfo.tbs_bytes, data->dci.location.ncce); - Debug("SCHED: Alloc format1 previous mcs=%d, tbs=%d\n", tbinfo.mcs, tbinfo.tbs_bytes); + logger.debug("SCHED: Alloc format1 previous mcs=%d, tbs=%d", tbinfo.mcs, tbinfo.tbs_bytes); } if (tbinfo.tbs_bytes > 0) { - dci->rnti = rnti; - dci->pid = h->get_id(); - dci->ue_cc_idx = cells[enb_cc_idx].get_ue_cc_idx(); dci->tb[0].mcs_idx = (uint32_t)tbinfo.mcs; dci->tb[0].rv = get_rvidx(h->nof_retx(0)); dci->tb[0].ndi = h->get_ndi(0); - dci->tpc_pucch = cells[enb_cc_idx].tpc_fsm.encode_pucch_tpc(); - data->tbs[0] = (uint32_t)tbinfo.tbs_bytes; - data->tbs[1] = 0; + data->tbs[0] = (uint32_t)tbinfo.tbs_bytes; + data->tbs[1] = 0; } return tbinfo.tbs_bytes; } @@ -487,7 +505,7 @@ tbs_info sched_ue::compute_mcs_and_tbs(uint32_t enb_cc_idx, tbs_info tb = alloc_tbs_dl(cells[enb_cc_idx], nof_alloc_prbs, nof_re, req_bytes.stop()); if (tb.tbs_bytes > 0 and tb.tbs_bytes < (int)req_bytes.start()) { - log_h->info("SCHED: Could not get PRB allocation that avoids MAC CE or RLC SRB0 PDU segmentation\n"); + logger.info("SCHED: Could not get PRB allocation that avoids MAC CE or RLC SRB0 PDU segmentation"); // Note: This is not a warning, because the srb0 buffer can be updated after the ue sched decision } @@ -559,13 +577,6 @@ int sched_ue::generate_format2a(uint32_t pid, } } - /* Fill common fields */ - dci->format = SRSLTE_DCI_FORMAT2A; - dci->rnti = rnti; - dci->ue_cc_idx = cells[enb_cc_idx].get_ue_cc_idx(); - dci->pid = h->get_id(); - dci->tpc_pucch = cells[enb_cc_idx].tpc_fsm.encode_pucch_tpc(); - int ret = data->tbs[0] + data->tbs[1]; return ret; } @@ -582,7 +593,6 @@ int sched_ue::generate_format2(uint32_t pid, int ret = generate_format2a(pid, data, tti_tx_dl, enb_cc_idx, cfi, user_mask); /* Compute precoding information */ - data->dci.format = SRSLTE_DCI_FORMAT2; if ((SRSLTE_DCI_IS_TB_EN(data->dci.tb[0]) + SRSLTE_DCI_IS_TB_EN(data->dci.tb[1])) == 1) { data->dci.pinfo = (uint8_t)(cells[enb_cc_idx].dl_pmi + 1) % (uint8_t)5; } else { @@ -698,9 +708,9 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data, dci->tb.mcs_idx = tbinfo.mcs; } } else if (tbinfo.tbs_bytes == 0) { - log_h->warning("SCHED: No space for ULSCH while allocating format0. Discarding grant.\n"); + logger.warning("SCHED: No space for ULSCH while allocating format0. Discarding grant."); } else { - log_h->error("SCHED: Unkown error while allocating format0\n"); + logger.error("SCHED: Unkown error while allocating format0"); } } @@ -731,7 +741,7 @@ bool sched_ue::needs_cqi(uint32_t tti, uint32_t enb_cc_idx, bool will_send) if (will_send) { cqi_request_tti = tti; } - Debug("SCHED: Needs_cqi, last_sent=%d, will_be_sent=%d\n", cqi_request_tti, will_send); + logger.debug("SCHED: Needs_cqi, last_sent=%d, will_be_sent=%d", cqi_request_tti, will_send); ret = true; } } @@ -755,8 +765,8 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t enb_cc_idx) int pending_prbs = get_required_prb_dl(cells[enb_cc_idx], to_tx_dl(current_tti), req_bytes.start()); if (pending_prbs < 0) { // Cannot fit allocation in given PRBs - log_h->error("SCHED: DL CQI=%d does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. " - "Consider increasing initial CQI value.\n", + logger.error("SCHED: DL CQI=%d does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. " + "Consider increasing initial CQI value.", cells[enb_cc_idx].dl_cqi, req_bytes.start()); return {cellparams->nof_prb(), cellparams->nof_prb()}; @@ -791,7 +801,7 @@ srslte::interval sched_ue::get_requested_dl_bytes(uint32_t enb_cc_idx) // Ensure there is space for ConRes and RRC Setup // SRB0 is a special case due to being RLC TM (no segmentation possible) if (not lch_handler.is_bearer_dl(0)) { - log_h->error("SRB0 must always be activated for DL\n"); + logger.error("SRB0 must always be activated for DL"); return {}; } if (cells[enb_cc_idx].cc_state() != cc_st::active) { @@ -945,10 +955,10 @@ uint32_t sched_ue::get_pending_ul_new_data(tti_point tti_tx_ul, int this_enb_cc_ pending_data = (pending_data > pending_ul_data) ? pending_data - pending_ul_data : 0; if (pending_data > 0) { - Debug("SCHED: pending_data=%d, in_harq_data=%d, bsr=%s\n", - pending_data, - pending_ul_data, - lch_handler.get_bsr_text().c_str()); + logger.debug("SCHED: pending_data=%d, in_harq_data=%d, bsr=%s", + pending_data, + pending_ul_data, + lch_handler.get_bsr_text().c_str()); } return pending_data; } @@ -1015,14 +1025,18 @@ void sched_ue::finish_tti(tti_point tti_rx, uint32_t enb_cc_idx) srslte_dci_format_t sched_ue::get_dci_format() { - srslte_dci_format_t ret = SRSLTE_DCI_FORMAT1; + srslte_dci_format_t ret = SRSLTE_DCI_FORMAT1A; if (phy_config_dedicated_enabled) { /* TODO: Assumes UE-Specific Search Space (Not common) */ switch (cfg.dl_ant_info.tx_mode) { case sched_interface::ant_info_ded_t::tx_mode_t::tm1: case sched_interface::ant_info_ded_t::tx_mode_t::tm2: - ret = SRSLTE_DCI_FORMAT1; + // If the size of Format1 and Format1A is ambiguous in the common SS, use Format1A since the UE assumes + // Common SS when spaces collide + if (not(cell.nof_prb == 15 && cells.size() > 1)) { + ret = SRSLTE_DCI_FORMAT1; + } break; case sched_interface::ant_info_ded_t::tx_mode_t::tm3: ret = SRSLTE_DCI_FORMAT2A; @@ -1035,20 +1049,21 @@ srslte_dci_format_t sched_ue::get_dci_format() case sched_interface::ant_info_ded_t::tx_mode_t::tm7: case sched_interface::ant_info_ded_t::tx_mode_t::tm8_v920: default: - Warning("Incorrect transmission mode (rnti=%04x; tm=%d)\n", rnti, static_cast(cfg.dl_ant_info.tx_mode)); + logger.warning( + "Incorrect transmission mode (rnti=%04x; tm=%d)", rnti, static_cast(cfg.dl_ant_info.tx_mode)); } } return ret; } -const sched_dci_cce_t* sched_ue::get_locations(uint32_t enb_cc_idx, uint32_t cfi, uint32_t sf_idx) const +const cce_cfi_position_table* sched_ue::get_locations(uint32_t enb_cc_idx, uint32_t cfi, uint32_t sf_idx) const { if (cfi > 0 && cfi <= 3) { - return &cells[enb_cc_idx].dci_locations[cfi - 1][sf_idx]; + return &cells[enb_cc_idx].dci_locations[sf_idx][cfi - 1]; } else { - Error("SCHED: Invalid CFI=%d\n", cfi); - return &cells[enb_cc_idx].dci_locations[0][sf_idx]; + logger.error("SCHED: Invalid CFI=%d", cfi); + return &cells[enb_cc_idx].dci_locations[sf_idx][0]; } } diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc index 1aae8cd81..cff21188a 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -39,8 +39,7 @@ namespace srsenb { void harq_proc::init(uint32_t id_) { - log_h = srslte::logmap::get("MAC "); - id = id_; + id = id_; } void harq_proc::reset(uint32_t tb_idx) @@ -87,17 +86,19 @@ tti_point harq_proc::get_tti() const int harq_proc::set_ack_common(uint32_t tb_idx, bool ack_) { if (is_empty(tb_idx)) { - log_h->warning("Received ACK for inactive harq\n"); + srslog::fetch_basic_logger("MAC").warning("Received ACK for inactive harq"); return SRSLTE_ERROR; } ack_state[tb_idx] = ack_; - log_h->debug("ACK=%d received pid=%d, tb_idx=%d, n_rtx=%d, max_retx=%d\n", ack_, id, tb_idx, n_rtx[tb_idx], max_retx); + srslog::fetch_basic_logger("MAC").debug( + "ACK=%d received pid=%d, tb_idx=%d, n_rtx=%d, max_retx=%d", ack_, id, tb_idx, n_rtx[tb_idx], max_retx); if (!ack_ && (n_rtx[tb_idx] + 1 >= max_retx)) { - Info("SCHED: discarding TB=%d pid=%d, tti=%d, maximum number of retx exceeded (%d)\n", - tb_idx, - id, - tti.to_uint(), - max_retx); + srslog::fetch_basic_logger("MAC").info( + "SCHED: discarding TB=%d pid=%d, tti=%d, maximum number of retx exceeded (%d)", + tb_idx, + id, + tti.to_uint(), + max_retx); active[tb_idx] = false; } else if (ack_) { active[tb_idx] = false; @@ -303,8 +304,7 @@ uint32_t ul_harq_proc::get_pending_data() const * Harq Entity *******************/ -harq_entity::harq_entity(size_t nof_dl_harqs, size_t nof_ul_harqs) : - dl_harqs(nof_dl_harqs), ul_harqs(nof_ul_harqs), log_h(srslte::logmap::get("MAC ")) +harq_entity::harq_entity(size_t nof_dl_harqs, size_t nof_ul_harqs) : dl_harqs(nof_dl_harqs), ul_harqs(nof_ul_harqs) { for (uint32_t i = 0; i < dl_harqs.size(); ++i) { dl_harqs[i].init(i); diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index fbd5f44b9..8d88c3399 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -85,11 +85,11 @@ void lch_ue_manager::new_tti() void lch_ue_manager::config_lcid(uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& bearer_cfg) { if (lc_id >= sched_interface::MAX_LC) { - Warning("Adding bearer with invalid logical channel id=%d\n", lc_id); + logger.warning("Adding bearer with invalid logical channel id=%d", lc_id); return; } if (bearer_cfg.group >= sched_interface::MAX_LC_GROUP) { - Warning("Adding bearer with invalid logical channel group id=%d\n", bearer_cfg.group); + logger.warning("Adding bearer with invalid logical channel group id=%d", bearer_cfg.group); return; } @@ -105,42 +105,42 @@ void lch_ue_manager::config_lcid(uint32_t lc_id, const sched_interface::ue_beare lch[lc_id].bucket_size = lch[lc_id].cfg.bsd * lch[lc_id].cfg.pbr; lch[lc_id].Bj = 0; } - Info("SCHED: bearer configured: lc_id=%d, mode=%s, prio=%d\n", - lc_id, - to_string(lch[lc_id].cfg.direction), - lch[lc_id].cfg.priority); + logger.info("SCHED: bearer configured: lc_id=%d, mode=%s, prio=%d", + lc_id, + to_string(lch[lc_id].cfg.direction), + lch[lc_id].cfg.priority); } } void lch_ue_manager::ul_bsr(uint8_t lcg_id, uint32_t bsr) { if (lcg_id >= sched_interface::MAX_LC_GROUP) { - Warning("The provided logical channel group id=%d is not valid\n", lcg_id); + logger.warning("The provided logical channel group id=%d is not valid", lcg_id); return; } lcg_bsr[lcg_id] = bsr; - Debug("SCHED: bsr=%d, lcg_id=%d, bsr=%s\n", bsr, lcg_id, get_bsr_text().c_str()); + logger.debug("SCHED: bsr=%d, lcg_id=%d, bsr=%s", bsr, lcg_id, get_bsr_text().c_str()); } void lch_ue_manager::ul_buffer_add(uint8_t lcid, uint32_t bytes) { if (lcid >= sched_interface::MAX_LC) { - Warning("The provided lcid=%d is not valid\n", lcid); + logger.warning("The provided lcid=%d is not valid", lcid); return; } lcg_bsr[lch[lcid].cfg.group] += bytes; - Debug("SCHED: UL buffer update=%d, lcg_id=%d, bsr=%s\n", bytes, lch[lcid].cfg.group, get_bsr_text().c_str()); + logger.debug("SCHED: UL buffer update=%d, lcg_id=%d, bsr=%s", bytes, lch[lcid].cfg.group, get_bsr_text().c_str()); } void lch_ue_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue) { if (lcid >= sched_interface::MAX_LC) { - Warning("The provided lcid=%d is not valid\n", lcid); + logger.warning("The provided lcid=%d is not valid", lcid); return; } lch[lcid].buf_retx = retx_queue; lch[lcid].buf_tx = tx_queue; - Debug("SCHED: DL lcid=%d buffer_state=%d,%d\n", lcid, tx_queue, retx_queue); + logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue); } int lch_ue_manager::get_max_prio_lcid() const diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index 45fd97134..924e5d645 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc @@ -30,6 +30,7 @@ namespace srsenb { *******************************************************/ sched_ue_cell::sched_ue_cell(uint16_t rnti_, const sched_cell_params_t& cell_cfg_, tti_point current_tti_) : + logger(srslog::fetch_basic_logger("MAC")), rnti(rnti_), cell_cfg(&cell_cfg_), dci_locations(generate_cce_location_table(rnti_, cell_cfg_)), @@ -86,7 +87,7 @@ void sched_ue_cell::set_ue_cfg(const sched_interface::ue_cfg_t& ue_cfg_) case cc_st::active: if (ue_cc_idx < 0 or not ue_cfg->supported_cc_list[ue_cc_idx].active) { cc_state_ = cc_st::deactivating; - log_h->info("SCHED: Deactivating rnti=0x%x, SCellIndex=%d...\n", rnti, ue_cc_idx); + logger.info("SCHED: Deactivating rnti=0x%x, SCellIndex=%d...", rnti, ue_cc_idx); } break; case cc_st::deactivating: @@ -94,7 +95,7 @@ void sched_ue_cell::set_ue_cfg(const sched_interface::ue_cfg_t& ue_cfg_) if (ue_cc_idx > 0 and ue_cfg->supported_cc_list[ue_cc_idx].active) { cc_state_ = cc_st::activating; dl_cqi = 0; - log_h->info("SCHED: Activating rnti=0x%x, SCellIndex=%d...\n", rnti, ue_cc_idx); + logger.info("SCHED: Activating rnti=0x%x, SCellIndex=%d...", rnti, ue_cc_idx); } break; default: @@ -145,7 +146,7 @@ void sched_ue_cell::set_dl_cqi(tti_point tti_rx, uint32_t dl_cqi_) if (ue_cc_idx > 0 and cc_state_ == cc_st::activating and dl_cqi_rx) { // Wait for SCell to receive a positive CQI before activating it cc_state_ = cc_st::active; - log_h->info("SCHED: SCell index=%d is now active\n", ue_cc_idx); + logger.info("SCHED: SCell index=%d is now active", ue_cc_idx); } } @@ -174,7 +175,7 @@ std::tuple false_position_method(int x1, int x2, YType y0, const Callable& f, const ErrorDetect& is_error) { static_assert(std::is_same::value, - "The type of the final result and callable return do not match\n"); + "The type of the final result and callable return do not match"); YType y1 = f(x1); if (is_error(y1) or y1 >= y0) { return std::make_tuple(x1, y1, x1, y1); diff --git a/srsenb/src/stack/mac/schedulers/sched_base.cc b/srsenb/src/stack/mac/schedulers/sched_base.cc index f1d76b030..5e45b0a23 100644 --- a/srsenb/src/stack/mac/schedulers/sched_base.cc +++ b/srsenb/src/stack/mac/schedulers/sched_base.cc @@ -23,16 +23,44 @@ namespace srsenb { -rbgmask_t find_available_dl_rbgs(uint32_t max_rbgs, const rbgmask_t& current_mask) +/********************************* + * Common UL/DL Helper methods + ********************************/ + +template ::value, prb_interval, rbg_interval>::type> +RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size) { - if (max_rbgs == 0 or current_mask.all()) { - return rbgmask_t{}; + RBInterval interv, max_interv; + + for (uint32_t n = 0; n < in_mask.size() and interv.length() < max_size; n++) { + if (not in_mask.test(n) and interv.empty()) { + // new interval + interv.set(n, n + 1); + } else if (not in_mask.test(n)) { + // extend current interval + interv.resize_by(1); + } else if (not interv.empty()) { + // reset interval + max_interv = interv.length() > max_interv.length() ? interv : max_interv; + interv = {}; + } } - // 1's for free rbgs - rbgmask_t localmask = ~(current_mask); + return interv.length() > max_interv.length() ? interv : max_interv; +} + +/**************************** + * DL Helper methods + ***************************/ + +rbgmask_t find_available_rb_mask(const rbgmask_t& in_mask, uint32_t max_size) +{ + // 1's for free RBs + rbgmask_t localmask = ~(in_mask); uint32_t i = 0, nof_alloc = 0; - for (; i < localmask.size() and nof_alloc < max_rbgs; ++i) { + for (; i < localmask.size() and nof_alloc < max_size; ++i) { if (localmask.test(i)) { nof_alloc++; } @@ -41,42 +69,17 @@ rbgmask_t find_available_dl_rbgs(uint32_t max_rbgs, const rbgmask_t& current_mas return localmask; } -prb_interval find_contiguous_ul_prbs(uint32_t L, const prbmask_t& current_mask) +rbgmask_t compute_user_rbgmask_greedy(uint32_t max_nof_rbgs, bool is_contiguous, const rbgmask_t& current_mask) { - prb_interval prb_interv, prb_interv2; - for (uint32_t n = 0; n < current_mask.size() and prb_interv.length() < L; n++) { - if (not current_mask.test(n) and prb_interv.length() == 0) { - // new interval - prb_interv.set(n, n + 1); - } else if (not current_mask.test(n)) { - // extend current interval - prb_interv.resize_by(1); - } else if (prb_interv.length() > 0) { - // reset interval - prb_interv2 = prb_interv.length() > prb_interv2.length() ? prb_interv : prb_interv2; - prb_interv = {}; - } + // Allocate enough RBs that accommodate pending data + rbgmask_t newtx_mask(current_mask.size()); + if (is_contiguous) { + rbg_interval interv = find_contiguous_interval(current_mask, max_nof_rbgs); + newtx_mask.fill(interv.start(), interv.stop()); + } else { + newtx_mask = find_available_rb_mask(current_mask, max_nof_rbgs); } - prb_interv = prb_interv2.length() > prb_interv.length() ? prb_interv2 : prb_interv; - if (prb_interv.empty()) { - return prb_interv; - } - - // Make sure L is allowed by SC-FDMA modulation - prb_interv2 = prb_interv; - while (not srslte_dft_precoding_valid_prb(prb_interv.length()) and prb_interv.stop() < current_mask.size() and - not current_mask.test(prb_interv.stop())) { - prb_interv.resize_by(1); - } - if (not srslte_dft_precoding_valid_prb(prb_interv.length())) { - // if length increase failed, try to decrease - prb_interv = prb_interv2; - prb_interv.resize_by(-1); - while (not srslte_dft_precoding_valid_prb(prb_interv.length()) and not prb_interv.empty()) { - prb_interv.resize_by(-1); - } - } - return prb_interv; + return newtx_mask; } int get_ue_cc_idx_if_pdsch_enabled(const sched_ue& user, sf_sched* tti_sched) @@ -113,6 +116,87 @@ const dl_harq_proc* get_dl_newtx_harq(sched_ue& user, sf_sched* tti_sched) return user.get_empty_dl_harq(tti_sched->get_tti_tx_dl(), tti_sched->get_enb_cc_idx()); } +alloc_outcome_t try_dl_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const dl_harq_proc& h) +{ + // Try to reuse the same mask + rbgmask_t retx_mask = h.get_rbgmask(); + alloc_outcome_t code = tti_sched.alloc_dl_user(&ue, retx_mask, h.get_id()); + if (code == alloc_outcome_t::SUCCESS or code == alloc_outcome_t::DCI_COLLISION) { + return code; + } + + // If previous mask does not fit, find another with exact same number of rbgs + size_t nof_rbg = retx_mask.count(); + bool is_contiguous_alloc = ue.get_dci_format() == SRSLTE_DCI_FORMAT1A; + retx_mask = compute_user_rbgmask_greedy(nof_rbg, is_contiguous_alloc, tti_sched.get_dl_mask()); + if (retx_mask.count() == nof_rbg) { + return tti_sched.alloc_dl_user(&ue, retx_mask, h.get_id()); + } + return alloc_outcome_t::RB_COLLISION; +} + +alloc_outcome_t +try_dl_newtx_alloc_greedy(sf_sched& tti_sched, sched_ue& ue, const dl_harq_proc& h, rbgmask_t* result_mask) +{ + if (result_mask != nullptr) { + *result_mask = {}; + } + + // If all RBGs are occupied, the next steps can be shortcut + const rbgmask_t& current_mask = tti_sched.get_dl_mask(); + if (current_mask.all()) { + return alloc_outcome_t::RB_COLLISION; + } + + // If there is no data to transmit, no need to allocate + rbg_interval req_rbgs = ue.get_required_dl_rbgs(tti_sched.get_enb_cc_idx()); + if (req_rbgs.stop() == 0) { + return alloc_outcome_t::NO_DATA; + } + + // Find RBG mask that accommodates pending data + bool is_contiguous_alloc = ue.get_dci_format() == SRSLTE_DCI_FORMAT1A; + rbgmask_t newtxmask = compute_user_rbgmask_greedy(req_rbgs.stop(), is_contiguous_alloc, current_mask); + if (newtxmask.none() or newtxmask.count() < req_rbgs.start()) { + return alloc_outcome_t::RB_COLLISION; + } + + // empty RBGs were found. Attempt allocation + alloc_outcome_t ret = tti_sched.alloc_dl_user(&ue, newtxmask, h.get_id()); + if (ret == alloc_outcome_t::SUCCESS and result_mask != nullptr) { + *result_mask = newtxmask; + } + return ret; +} + +/***************** + * UL Helpers + ****************/ + +prb_interval find_contiguous_ul_prbs(uint32_t L, const prbmask_t& current_mask) +{ + prb_interval prb_interv = find_contiguous_interval(current_mask, L); + if (prb_interv.empty()) { + return prb_interv; + } + + // Make sure L is allowed by SC-FDMA modulation + prb_interval prb_interv2 = prb_interv; + while (not srslte_dft_precoding_valid_prb(prb_interv.length()) and prb_interv.stop() < current_mask.size() and + not current_mask.test(prb_interv.stop())) { + prb_interv.resize_by(1); + } + if (not srslte_dft_precoding_valid_prb(prb_interv.length())) { + // if length increase failed, try to decrease + prb_interv = prb_interv2; + prb_interv.resize_by(-1); + while (not srslte_dft_precoding_valid_prb(prb_interv.length()) and not prb_interv.empty()) { + prb_interv.resize_by(-1); + } + } + return prb_interv; +} + int get_ue_cc_idx_if_pusch_enabled(const sched_ue& user, sf_sched* tti_sched, bool needs_pdcch) { // Do not allocate a user multiple times in the same tti @@ -148,24 +232,6 @@ const ul_harq_proc* get_ul_newtx_harq(sched_ue& user, sf_sched* tti_sched) return h->is_empty() ? h : nullptr; } -alloc_outcome_t try_dl_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const dl_harq_proc& h) -{ - // Try to reuse the same mask - rbgmask_t retx_mask = h.get_rbgmask(); - alloc_outcome_t code = tti_sched.alloc_dl_user(&ue, retx_mask, h.get_id()); - if (code == alloc_outcome_t::SUCCESS or code == alloc_outcome_t::DCI_COLLISION) { - return code; - } - - // If previous mask does not fit, find another with exact same number of rbgs - size_t nof_rbg = retx_mask.count(); - retx_mask = find_available_dl_rbgs(nof_rbg, tti_sched.get_dl_mask()); - if (retx_mask.count() == nof_rbg) { - return tti_sched.alloc_dl_user(&ue, retx_mask, h.get_id()); - } - return alloc_outcome_t::RB_COLLISION; -} - alloc_outcome_t try_ul_retx_alloc(sf_sched& tti_sched, sched_ue& ue, const ul_harq_proc& h) { // If can schedule the same mask, do it diff --git a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc index 276d092d8..16d546bb6 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc @@ -33,7 +33,7 @@ sched_time_pf::sched_time_pf(const sched_cell_params_t& cell_params_, const sche } } -void sched_time_pf::new_tti(std::map& ue_db, sf_sched* tti_sched) +void sched_time_pf::new_tti(sched_ue_list& ue_db, sf_sched* tti_sched) { current_tti_rx = tti_point{tti_sched->get_tti_rx()}; // remove deleted users from history @@ -50,7 +50,7 @@ void sched_time_pf::new_tti(std::map& ue_db, sf_sched* tti_s if (it == ue_history_db.end()) { it = ue_history_db.insert(std::make_pair(u.first, ue_ctxt{u.first, fairness_coeff})).first; } - it->second.new_tti(*cc_cfg, u.second, tti_sched); + it->second.new_tti(*cc_cfg, *u.second, tti_sched); if (it->second.dl_newtx_h != nullptr or it->second.dl_retx_h != nullptr) { dl_queue.push(&it->second); } @@ -64,7 +64,7 @@ void sched_time_pf::new_tti(std::map& ue_db, sf_sched* tti_s * Dowlink *****************************************************************/ -void sched_time_pf::sched_dl_users(std::map& ue_db, sf_sched* tti_sched) +void sched_time_pf::sched_dl_users(sched_ue_list& ue_db, sf_sched* tti_sched) { srslte::tti_point tti_rx{tti_sched->get_tti_rx()}; if (current_tti_rx != tti_rx) { @@ -73,7 +73,7 @@ void sched_time_pf::sched_dl_users(std::map& ue_db, sf_sched while (not dl_queue.empty()) { ue_ctxt& ue = *dl_queue.top(); - ue.save_dl_alloc(try_dl_alloc(ue, ue_db[ue.rnti], tti_sched), 0.01); + ue.save_dl_alloc(try_dl_alloc(ue, *ue_db[ue.rnti], tti_sched), 0.01); dl_queue.pop(); } } @@ -87,24 +87,17 @@ uint32_t sched_time_pf::try_dl_alloc(ue_ctxt& ue_ctxt, sched_ue& ue, sf_sched* t return ue_ctxt.dl_retx_h->get_tbs(0) + ue_ctxt.dl_retx_h->get_tbs(1); } } + + // There is space in PDCCH and an available DL HARQ if (code != alloc_outcome_t::DCI_COLLISION and ue_ctxt.dl_newtx_h != nullptr) { - rbg_interval req_rbgs = ue.get_required_dl_rbgs(cc_cfg->enb_cc_idx); - // Check if there is an empty harq for the newtx - if (req_rbgs.stop() == 0) { - return 0; - } - // Allocate resources based on pending data - rbgmask_t newtx_mask = find_available_dl_rbgs(req_rbgs.stop(), tti_sched->get_dl_mask()); - if (newtx_mask.count() >= req_rbgs.start()) { - // empty RBGs were found - code = tti_sched->alloc_dl_user(&ue, newtx_mask, ue_ctxt.dl_newtx_h->get_id()); - if (code == alloc_outcome_t::SUCCESS) { - return ue.get_expected_dl_bitrate(cc_cfg->enb_cc_idx, newtx_mask.count()) * tti_duration_ms / 8; - } + rbgmask_t alloc_mask; + code = try_dl_newtx_alloc_greedy(*tti_sched, ue, *ue_ctxt.dl_newtx_h, &alloc_mask); + if (code == alloc_outcome_t::SUCCESS) { + return ue.get_expected_dl_bitrate(cc_cfg->enb_cc_idx, alloc_mask.count()) * tti_duration_ms / 8; } } if (code == alloc_outcome_t::DCI_COLLISION) { - log_h->info("SCHED: Couldn't find space in PDCCH for DL tx for rnti=0x%x\n", ue.get_rnti()); + logger.info("SCHED: Couldn't find space in PDCCH for DL tx for rnti=0x%x", ue.get_rnti()); } return 0; } @@ -113,7 +106,7 @@ uint32_t sched_time_pf::try_dl_alloc(ue_ctxt& ue_ctxt, sched_ue& ue, sf_sched* t * Uplink *****************************************************************/ -void sched_time_pf::sched_ul_users(std::map& ue_db, sf_sched* tti_sched) +void sched_time_pf::sched_ul_users(sched_ue_list& ue_db, sf_sched* tti_sched) { srslte::tti_point tti_rx{tti_sched->get_tti_rx()}; if (current_tti_rx != tti_rx) { @@ -122,7 +115,7 @@ void sched_time_pf::sched_ul_users(std::map& ue_db, sf_sched while (not ul_queue.empty()) { ue_ctxt& ue = *ul_queue.top(); - ue.save_ul_alloc(try_ul_alloc(ue, ue_db[ue.rnti], tti_sched), 0.01); + ue.save_ul_alloc(try_ul_alloc(ue, *ue_db[ue.rnti], tti_sched), 0.01); ul_queue.pop(); } } @@ -161,7 +154,7 @@ uint32_t sched_time_pf::try_ul_alloc(ue_ctxt& ue_ctxt, sched_ue& ue, sf_sched* t : 0; } if (code == alloc_outcome_t::DCI_COLLISION) { - log_h->info("SCHED: Couldn't find space in PDCCH for UL retx of rnti=0x%x\n", ue.get_rnti()); + logger.info("SCHED: Couldn't find space in PDCCH for UL retx of rnti=0x%x", ue.get_rnti()); } return estim_tbs_bytes; } diff --git a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc index 072352f28..702ea1e21 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc @@ -33,7 +33,7 @@ sched_time_rr::sched_time_rr(const sched_cell_params_t& cell_params_, const sche * Dowlink *****************************************************************/ -void sched_time_rr::sched_dl_users(std::map& ue_db, sf_sched* tti_sched) +void sched_time_rr::sched_dl_users(sched_ue_list& ue_db, sf_sched* tti_sched) { if (ue_db.empty()) { return; @@ -45,7 +45,7 @@ void sched_time_rr::sched_dl_users(std::map& ue_db, sf_sched sched_dl_newtxs(ue_db, tti_sched, priority_idx); } -void sched_time_rr::sched_dl_retxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx) +void sched_time_rr::sched_dl_retxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx) { auto iter = ue_db.begin(); std::advance(iter, prio_idx); @@ -53,7 +53,7 @@ void sched_time_rr::sched_dl_retxs(std::map& ue_db, sf_sched if (iter == ue_db.end()) { iter = ue_db.begin(); // wrap around } - sched_ue& user = iter->second; + sched_ue& user = *iter->second; const dl_harq_proc* h = get_dl_retx_harq(user, tti_sched); // Check if there is a pending retx if (h == nullptr) { @@ -61,12 +61,12 @@ void sched_time_rr::sched_dl_retxs(std::map& ue_db, sf_sched } alloc_outcome_t code = try_dl_retx_alloc(*tti_sched, user, *h); if (code == alloc_outcome_t::DCI_COLLISION) { - log_h->info("SCHED: Couldn't find space in PDCCH for DL retx for rnti=0x%x\n", user.get_rnti()); + logger.info("SCHED: Couldn't find space in PDCCH for DL retx for rnti=0x%x", user.get_rnti()); } } } -void sched_time_rr::sched_dl_newtxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx) +void sched_time_rr::sched_dl_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx) { auto iter = ue_db.begin(); std::advance(iter, prio_idx); @@ -74,24 +74,17 @@ void sched_time_rr::sched_dl_newtxs(std::map& ue_db, sf_sche if (iter == ue_db.end()) { iter = ue_db.begin(); // wrap around } - sched_ue& user = iter->second; + sched_ue& user = *iter->second; if (user.enb_to_ue_cc_idx(cc_cfg->enb_cc_idx) < 0) { continue; } - const dl_harq_proc* h = get_dl_newtx_harq(user, tti_sched); - rbg_interval req_rbgs = user.get_required_dl_rbgs(cc_cfg->enb_cc_idx); + const dl_harq_proc* h = get_dl_newtx_harq(user, tti_sched); // Check if there is an empty harq for the newtx - if (h == nullptr or req_rbgs.stop() == 0) { + if (h == nullptr) { continue; } - // Allocate resources based on pending data - rbgmask_t newtx_mask = find_available_dl_rbgs(req_rbgs.stop(), tti_sched->get_dl_mask()); - if (newtx_mask.count() >= req_rbgs.start()) { - // empty RBGs were found - alloc_outcome_t code = tti_sched->alloc_dl_user(&user, newtx_mask, h->get_id()); - if (code == alloc_outcome_t::DCI_COLLISION) { - log_h->info("SCHED: Couldn't find space in PDCCH for DL tx for rnti=0x%x\n", user.get_rnti()); - } + if (try_dl_newtx_alloc_greedy(*tti_sched, user, *h) == alloc_outcome_t::DCI_COLLISION) { + logger.info("SCHED: Couldn't find space in PDCCH for DL tx for rnti=0x%x", user.get_rnti()); } } } @@ -100,7 +93,7 @@ void sched_time_rr::sched_dl_newtxs(std::map& ue_db, sf_sche * Uplink *****************************************************************/ -void sched_time_rr::sched_ul_users(std::map& ue_db, sf_sched* tti_sched) +void sched_time_rr::sched_ul_users(sched_ue_list& ue_db, sf_sched* tti_sched) { if (ue_db.empty()) { return; @@ -111,7 +104,7 @@ void sched_time_rr::sched_ul_users(std::map& ue_db, sf_sched sched_ul_newtxs(ue_db, tti_sched, priority_idx); } -void sched_time_rr::sched_ul_retxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx) +void sched_time_rr::sched_ul_retxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx) { auto iter = ue_db.begin(); std::advance(iter, prio_idx); @@ -119,7 +112,7 @@ void sched_time_rr::sched_ul_retxs(std::map& ue_db, sf_sched if (iter == ue_db.end()) { iter = ue_db.begin(); // wrap around } - sched_ue& user = iter->second; + sched_ue& user = *iter->second; const ul_harq_proc* h = get_ul_retx_harq(user, tti_sched); // Check if there is a pending retx if (h == nullptr) { @@ -127,12 +120,12 @@ void sched_time_rr::sched_ul_retxs(std::map& ue_db, sf_sched } alloc_outcome_t code = try_ul_retx_alloc(*tti_sched, user, *h); if (code == alloc_outcome_t::DCI_COLLISION) { - log_h->info("SCHED: Couldn't find space in PDCCH for UL retx of rnti=0x%x\n", user.get_rnti()); + logger.info("SCHED: Couldn't find space in PDCCH for UL retx of rnti=0x%x", user.get_rnti()); } } } -void sched_time_rr::sched_ul_newtxs(std::map& ue_db, sf_sched* tti_sched, size_t prio_idx) +void sched_time_rr::sched_ul_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, size_t prio_idx) { auto iter = ue_db.begin(); std::advance(iter, prio_idx); @@ -140,7 +133,7 @@ void sched_time_rr::sched_ul_newtxs(std::map& ue_db, sf_sche if (iter == ue_db.end()) { iter = ue_db.begin(); // wrap around } - sched_ue& user = iter->second; + sched_ue& user = *iter->second; const ul_harq_proc* h = get_ul_newtx_harq(user, tti_sched); // Check if there is a empty harq if (h == nullptr) { @@ -158,7 +151,7 @@ void sched_time_rr::sched_ul_newtxs(std::map& ue_db, sf_sche } alloc_outcome_t ret = tti_sched->alloc_ul_user(&user, alloc); if (ret == alloc_outcome_t::DCI_COLLISION) { - log_h->info("SCHED: Couldn't find space in PDCCH for UL tx of rnti=0x%x\n", user.get_rnti()); + logger.info("SCHED: Couldn't find space in PDCCH for UL tx of rnti=0x%x", user.get_rnti()); } } } diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 6c320e3a3..eaa14c482 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -26,7 +26,9 @@ #include "srsenb/hdr/stack/mac/ue.h" #include "srslte/common/log_helper.h" -#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_phy_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { @@ -37,6 +39,7 @@ ue::ue(uint16_t rnti_, rlc_interface_mac* rlc_, phy_interface_stack_lte* phy_, srslte::log_ref log_, + srslog::basic_logger& logger, uint32_t nof_cells_, uint32_t nof_rx_harq_proc_, uint32_t nof_tx_harq_proc_) : @@ -47,26 +50,26 @@ ue::ue(uint16_t rnti_, rlc(rlc_), phy(phy_), log_h(log_), - mac_msg_dl(20, log_), - mch_mac_msg_dl(10, log_), - mac_msg_ul(20, log_), - pdus(128), + logger(logger), + mac_msg_dl(20, logger), + mch_mac_msg_dl(10, logger), + mac_msg_ul(20, logger), + pdus(logger, 128), nof_rx_harq_proc(nof_rx_harq_proc_), nof_tx_harq_proc(nof_tx_harq_proc_), rx_used_buffers(nof_cells_), ta_fsm(this) { - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); tx_payload_buffer.resize(nof_cells_); for (auto& carrier_buffers : tx_payload_buffer) { for (auto& harq_buffers : carrier_buffers) { for (srslte::unique_byte_buffer_t& tb_buffer : harq_buffers) { - tb_buffer = srslte::allocate_unique_buffer(*pool); + tb_buffer = srslte::make_byte_buffer(); } } } - pdus.init(this, log_h); + pdus.init(this); // Allocate buffer for PCell allocate_cc_buffers(); @@ -152,12 +155,12 @@ void ue::start_pcap(srslte::mac_pcap* pcap_) srslte_softbuffer_rx_t* ue::get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti) { if ((size_t)ue_cc_idx >= softbuffer_rx.size()) { - ERROR("UE CC Index (%d/%zd) out-of-range\n", ue_cc_idx, softbuffer_rx.size()); + ERROR("UE CC Index (%d/%zd) out-of-range", ue_cc_idx, softbuffer_rx.size()); return nullptr; } if ((size_t)nof_rx_harq_proc > softbuffer_rx.at(ue_cc_idx).size()) { - ERROR("HARQ process index (%d/%zd) out-of-range\n", nof_rx_harq_proc, softbuffer_rx.at(ue_cc_idx).size()); + ERROR("HARQ process index (%d/%zd) out-of-range", nof_rx_harq_proc, softbuffer_rx.at(ue_cc_idx).size()); return nullptr; } @@ -168,12 +171,12 @@ srslte_softbuffer_tx_t* ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, const uint32_t tb_idx) { if ((size_t)ue_cc_idx >= softbuffer_tx.size()) { - ERROR("UE CC Index (%d/%zd) out-of-range\n", ue_cc_idx, softbuffer_tx.size()); + ERROR("UE CC Index (%d/%zd) out-of-range", ue_cc_idx, softbuffer_tx.size()); return nullptr; } if ((size_t)nof_tx_harq_proc > softbuffer_tx.at(ue_cc_idx).size()) { - ERROR("HARQ process index (%d/%zd) out-of-range\n", harq_process, softbuffer_tx.at(ue_cc_idx).size()); + ERROR("HARQ process index (%d/%zd) out-of-range", harq_process, softbuffer_tx.at(ue_cc_idx).size()); return nullptr; } @@ -183,7 +186,7 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con uint8_t* ue::request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len) { std::unique_lock lock(rx_buffers_mutex); - uint8_t* pdu = nullptr; + uint8_t* pdu = nullptr; if (len > 0) { // Deallocate oldest buffer if we didn't deallocate it if (!rx_used_buffers.at(ue_cc_idx).count(tti)) { @@ -191,13 +194,13 @@ uint8_t* ue::request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len if (pdu) { rx_used_buffers.at(ue_cc_idx).emplace(tti, pdu); } else { - Error("UE buffers: Requesting buffer from pool\n"); + logger.error("UE buffers: Requesting buffer from pool"); } } else { - Error("UE buffers: buffer for tti=%d already allocated\n", tti); + logger.error("UE buffers: buffer for tti=%d already allocated", tti); } } else { - Error("UE buffers: Requesting buffer for zero bytes\n"); + logger.error("UE buffers: Requesting buffer for zero bytes"); } return pdu; } @@ -210,11 +213,11 @@ void ue::clear_old_buffers(uint32_t tti) for (auto& rx_buffer_cc : rx_used_buffers) { for (auto it = rx_buffer_cc.begin(); it != rx_buffer_cc.end();) { if (srslte_tti_interval(tti, it->first) > 20 && srslte_tti_interval(tti, it->first) < 500) { - Warning("UE buffers: Removing old buffer tti=%d, rnti=%d, now is %d, interval=%d\n", - it->first, - rnti, - tti, - srslte_tti_interval(tti, it->first)); + logger.warning("UE buffers: Removing old buffer tti=%d, rnti=%d, now is %d, interval=%d", + it->first, + rnti, + tti, + srslte_tti_interval(tti, it->first)); pdus.deallocate(it->second); it = rx_buffer_cc.erase(it); } else { @@ -245,7 +248,7 @@ uint32_t ue::set_ta(int ta_) uint32_t ta_cmd = (uint32_t)(ta_value + 31); pending_ta_commands.try_push(ta_cmd); nof_cmd++; - Info("Added TA CMD: rnti=0x%x, ta=%d, ta_value=%d, ta_cmd=%d\n", rnti, ta_, ta_value, ta_cmd); + logger.info("Added TA CMD: rnti=0x%x, ta=%d, ta_value=%d, ta_cmd=%d", rnti, ta_, ta_value, ta_cmd); } while (ta_value <= -31 || ta_value >= 32); return nof_cmd; } @@ -258,7 +261,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe mac_msg_ul.init_rx(nof_bytes, true); mac_msg_ul.parse_packet(pdu); - Info("0x%x %s\n", rnti, mac_msg_ul.to_string().c_str()); + logger.info("0x%x %s", rnti, mac_msg_ul.to_string().c_str()); if (pcap) { pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX); @@ -284,7 +287,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe } if (sum == 0) { route_pdu = false; - Debug("Received all zero PDU\n"); + logger.debug("Received all zero PDU"); } } @@ -301,7 +304,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe // Indicate RRC about successful activity if valid RLC message is received if (mac_msg_ul.get()->get_payload_size() > 64) { // do not count RLC status messages only rrc->set_activity_user(rnti); - log_h->debug("UL activity rnti=0x%x, n_bytes=%d\n", rnti, nof_bytes); + logger.debug("UL activity rnti=0x%x, n_bytes=%d", rnti, nof_bytes); } if ((int)mac_msg_ul.get()->get_payload_size() > most_data) { @@ -319,7 +322,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe ue_cri_ptr[nbytes - i - 1] = pkt_ptr[i]; } } else { - Error("Received CCCH UL message of invalid size=%d bytes\n", mac_msg_ul.get()->get_payload_size()); + logger.error("Received CCCH UL message of invalid size=%d bytes", mac_msg_ul.get()->get_payload_size()); } } } @@ -340,10 +343,10 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe if (!bsr_received && lcid_most_data > 2) { // Add BSR to the LCID for which most data was received sched->ul_buffer_add(rnti, lcid_most_data, 256); - Debug("BSR not received. Giving extra dci\n"); + logger.debug("BSR not received. Giving extra dci"); } - Debug("MAC PDU processed\n"); + logger.debug("MAC PDU processed"); } void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx) @@ -354,10 +357,10 @@ void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx) pdus.deallocate(rx_used_buffers.at(ue_cc_idx).at(tti)); rx_used_buffers.at(ue_cc_idx).erase(tti); } else { - Warning("UE buffers: Null RX PDU pointer in deallocate_pdu for rnti=0x%x pid=%d cc_idx=%d\n", - rnti, - tti % nof_rx_harq_proc, - ue_cc_idx); + logger.warning("UE buffers: Null RX PDU pointer in deallocate_pdu for rnti=0x%x pid=%d cc_idx=%d", + rnti, + tti % nof_rx_harq_proc, + ue_cc_idx); } } @@ -368,14 +371,14 @@ void ue::push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len) if (len > 0) { pdus.push(rx_used_buffers.at(ue_cc_idx).at(tti), len); } else { - Error("Error pushing PDU: null length\n"); + logger.error("Error pushing PDU: null length"); } rx_used_buffers.at(ue_cc_idx).erase(tti); } else { - Warning("UE buffers: Null RX PDU pointer in push_pdu for rnti=0x%x pid=%d cc_idx=%d\n", - rnti, - tti % nof_rx_harq_proc, - ue_cc_idx); + logger.warning("UE buffers: Null RX PDU pointer in push_pdu for rnti=0x%x pid=%d cc_idx=%d", + rnti, + tti % nof_rx_harq_proc, + ue_cc_idx); } } @@ -399,14 +402,14 @@ bool ue::process_ce(srslte::sch_subh* subh) rrc->upd_user(rnti, old_rnti); rnti = old_rnti; } else { - Error("Updating user C-RNTI: rnti=0x%x already released\n", old_rnti); + logger.error("Updating user C-RNTI: rnti=0x%x already released", old_rnti); } break; case srslte::ul_sch_lcid::TRUNC_BSR: case srslte::ul_sch_lcid::SHORT_BSR: idx = subh->get_bsr(buff_size_idx, buff_size_bytes); if (idx == -1) { - Error("Invalid Index Passed to lc groups\n"); + logger.error("Invalid Index Passed to lc groups"); break; } // Indicate BSR to scheduler @@ -423,7 +426,7 @@ bool ue::process_ce(srslte::sch_subh* subh) case srslte::ul_sch_lcid::PADDING: break; default: - Error("CE: Invalid lcid=0x%x\n", (int)subh->ul_sch_ce_type()); + logger.error("CE: Invalid lcid=0x%x", (int)subh->ul_sch_ce_type()); break; } return is_bsr; @@ -443,13 +446,13 @@ void ue::allocate_sdu(srslte::sch_pdu* pdu, uint32_t lcid, uint32_t total_sdu_le int n = 1; while (sdu_len >= min_sdu_len && n > 0) { // minimum size is a single RLC AM status PDU (2 Byte) if (pdu->new_subh()) { // there is space for a new subheader - log_h->debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d\n", lcid, sdu_len, sdu_space); + logger.debug("SDU: set_sdu(), lcid=%d, sdu_len=%d, sdu_space=%d", lcid, sdu_len, sdu_space); n = pdu->get()->set_sdu(lcid, sdu_len, this); if (n > 0) { // new SDU could be added sdu_len -= n; - log_h->debug("SDU: rnti=0x%x, lcid=%d, nbytes=%d, rem_len=%d\n", rnti, lcid, n, sdu_len); + logger.debug("SDU: rnti=0x%x, lcid=%d, nbytes=%d, rem_len=%d", rnti, lcid, n, sdu_len); } else { - Debug("Could not add SDU lcid=%d nbytes=%d, space=%d\n", lcid, sdu_len, sdu_space); + logger.debug("Could not add SDU lcid=%d nbytes=%d, space=%d", lcid, sdu_len, sdu_space); pdu->del_subh(); } } else { @@ -467,19 +470,19 @@ void ue::allocate_ce(srslte::sch_pdu* pdu, uint32_t lcid) uint32_t ta_cmd = 31; pending_ta_commands.try_pop(&ta_cmd); if (!pdu->get()->set_ta_cmd(ta_cmd)) { - Error("CE: Setting TA CMD CE\n"); + logger.error("CE: Setting TA CMD CE"); } } else { - Error("CE: Setting TA CMD CE. No space for a subheader\n"); + logger.error("CE: Setting TA CMD CE. No space for a subheader"); } break; case srslte::dl_sch_lcid::CON_RES_ID: if (pdu->new_subh()) { if (!pdu->get()->set_con_res_id(conres_id)) { - Error("CE: Setting Contention Resolution ID CE\n"); + logger.error("CE: Setting Contention Resolution ID CE"); } } else { - Error("CE: Setting Contention Resolution ID CE. No space for a subheader\n"); + logger.error("CE: Setting Contention Resolution ID CE. No space for a subheader"); } break; case srslte::dl_sch_lcid::SCELL_ACTIVATION: @@ -490,14 +493,14 @@ void ue::allocate_ce(srslte::sch_pdu* pdu, uint32_t lcid) // Allocate and initialize Rx/Tx softbuffers for new carriers (exclude PCell) allocate_cc_buffers(active_scell_list.size() - 1); } else { - Error("CE: Setting SCell Activation CE\n"); + logger.error("CE: Setting SCell Activation CE"); } } else { - Error("CE: Setting SCell Activation CE. No space for a subheader\n"); + logger.error("CE: Setting SCell Activation CE. No space for a subheader"); } break; default: - Error("CE: Allocating CE=0x%x. Not supported\n", lcid); + logger.error("CE: Allocating CE=0x%x. Not supported", lcid); break; } } @@ -522,11 +525,11 @@ uint8_t* ue::generate_pdu(uint32_t ue_cc_idx, allocate_ce(&mac_msg_dl, pdu[i].lcid); } } - ret = mac_msg_dl.write_packet(log_h); - Info("0x%x %s\n", rnti, mac_msg_dl.to_string().c_str()); + ret = mac_msg_dl.write_packet(logger); + logger.info("0x%x %s", rnti, mac_msg_dl.to_string().c_str()); } else { - log_h->error( - "Invalid parameters calling generate_pdu: cc_idx=%d, harq_pid=%d, tb_idx=%d\n", ue_cc_idx, harq_pid, tb_idx); + logger.error( + "Invalid parameters calling generate_pdu: cc_idx=%d, harq_pid=%d, tb_idx=%d", ue_cc_idx, harq_pid, tb_idx); } } else { std::cout << "Error ue not configured (must call config() first" << std::endl; @@ -557,7 +560,7 @@ uint8_t* ue::generate_mch_pdu(uint32_t harq_pid, } } - ret = mch_mac_msg_dl.write_packet(log_h); + ret = mch_mac_msg_dl.write_packet(logger); return ret; } diff --git a/srsenb/src/stack/rrc/CMakeLists.txt b/srsenb/src/stack/rrc/CMakeLists.txt index e41da982f..ba27042ec 100644 --- a/srsenb/src/stack/rrc/CMakeLists.txt +++ b/srsenb/src/stack/rrc/CMakeLists.txt @@ -21,7 +21,5 @@ set(SOURCES rrc.cc rrc_ue.cc rrc_mobility.cc rrc_cell_cfg.cc rrc_bearer_cfg.cc mac_controller.cc ue_rr_cfg.cc ue_meas_cfg.cc) add_library(srsenb_rrc STATIC ${SOURCES}) -if (ENABLE_5GNR) - set(SOURCES rrc_nr.cc) - add_library(srsgnb_rrc STATIC ${SOURCES}) -endif () +set(SOURCES rrc_nr.cc) +add_library(srsgnb_rrc STATIC ${SOURCES}) diff --git a/srsenb/src/stack/rrc/mac_controller.cc b/srsenb/src/stack/rrc/mac_controller.cc index eb29b6317..9bd865887 100644 --- a/srsenb/src/stack/rrc/mac_controller.cc +++ b/srsenb/src/stack/rrc/mac_controller.cc @@ -22,6 +22,7 @@ #include "srsenb/hdr/stack/rrc/mac_controller.h" #include "srsenb/hdr/stack/upper/common_enb.h" #include "srslte/asn1/rrc_utils.h" +#include "srslte/interfaces/enb_mac_interfaces.h" namespace srsenb { @@ -91,7 +92,7 @@ mac_controller::mac_controller(uint16_t rnti_, mac_interface_rrc* mac_, const enb_cell_common_list& cell_common_list_, const ue_cfg_t& sched_ue_cfg) : - log_h("RRC"), + logger(srslog::fetch_basic_logger("RRC")), rnti(rnti_), ue_cell_list(ue_cell_list_), bearer_list(bearer_list_), @@ -101,7 +102,7 @@ mac_controller::mac_controller(uint16_t rnti_, current_sched_ue_cfg(sched_ue_cfg) { if (current_sched_ue_cfg.supported_cc_list.empty() or not current_sched_ue_cfg.supported_cc_list[0].active) { - log_h->warning("No PCell set. Picking enb_cc_idx=0 as PCell\n"); + logger.warning("No PCell set. Picking enb_cc_idx=0 as PCell"); current_sched_ue_cfg.supported_cc_list.resize(1); current_sched_ue_cfg.supported_cc_list[0].active = true; current_sched_ue_cfg.supported_cc_list[0].enb_cc_idx = 0; @@ -360,7 +361,7 @@ void ue_cfg_apply_phy_cfg_ded(ue_cfg_t& ue_cfg, const asn1::rrc::phys_cfg_ded_s& if (phy_cfg.ant_info.type().value == phys_cfg_ded_s::ant_info_c_::types_opts::explicit_value) { ue_cfg.dl_ant_info = srslte::make_ant_info_ded(phy_cfg.ant_info.explicit_value()); } else { - srslte::logmap::get("RRC")->warning("No antenna configuration provided\n"); + srslog::fetch_basic_logger("RRC").warning("No antenna configuration provided"); pcell_cfg.dl_cfg.tm = SRSLTE_TM1; ue_cfg.dl_ant_info.tx_mode = sched_interface::ant_info_ded_t::tx_mode_t::tm1; } @@ -379,7 +380,7 @@ void ue_cfg_apply_srb_updates(ue_cfg_t& ue_cfg, const srb_to_add_mod_list_l& srb bcfg = get_bearer_default_srb2_config(); break; default: - srslte::logmap::get("RRC")->warning("Invalid SRB ID %d\n", (int)srb.srb_id); + srslog::fetch_basic_logger("RRC").warning("Invalid SRB ID %d", (int)srb.srb_id); bcfg = {}; } bcfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH; @@ -432,7 +433,6 @@ void ue_cfg_apply_reconf_complete_updates(ue_cfg_t& ue_cfg, conn_recfg.non_crit_ext.non_crit_ext.non_crit_ext_present and conn_recfg.non_crit_ext.non_crit_ext.non_crit_ext.scell_to_add_mod_list_r10_present) { for (const auto& scell : conn_recfg.non_crit_ext.non_crit_ext.non_crit_ext.scell_to_add_mod_list_r10) { - // Resize MAC SCell list if required if (scell.scell_idx_r10 >= ue_cfg.supported_cc_list.size()) { ue_cfg.supported_cc_list.resize(scell.scell_idx_r10 + 1); @@ -459,7 +459,7 @@ void ue_cfg_apply_reconf_complete_updates(ue_cfg_t& ue_cfg, ul_cfg.cqi_report_cfg_scell_r10.cqi_report_mode_aperiodic_r10_present; mac_scell.aperiodic_cqi_period = ul_cfg.cqi_report_cfg_scell_r10.cqi_report_mode_aperiodic_r10.to_number(); } else { - srslte::logmap::get("RRC")->warning("Invalid Scell index %d CQI configuration\n", scell.scell_idx_r10); + srslog::fetch_basic_logger("RRC").warning("Invalid Scell index %d CQI configuration", scell.scell_idx_r10); } } } @@ -485,7 +485,7 @@ void ue_cfg_apply_meas_cfg(ue_cfg_t& ue_cfg, const meas_cfg_s& meas_cfg, const r ue_cfg.measgap_offset = setup.gap_offset.gp1(); break; default: - srslte::logmap::get("RRC")->warning("Invalid measGap configuration\n"); + srslog::fetch_basic_logger("RRC").warning("Invalid measGap configuration"); ue_cfg.measgap_period = 0; ue_cfg.measgap_offset = 0; } diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 4ea32131e..e2ae401df 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -26,6 +26,9 @@ #include "srslte/asn1/rrc_utils.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/int_helpers.h" +#include "srslte/interfaces/enb_mac_interfaces.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/srslte.h" @@ -37,7 +40,7 @@ using namespace asn1::rrc; namespace srsenb { -rrc::rrc(srslte::task_sched_handle task_sched_) : rrc_log("RRC"), task_sched(task_sched_) +rrc::rrc(srslte::task_sched_handle task_sched_) : logger(srslog::fetch_basic_logger("RRC")), task_sched(task_sched_) { pending_paging.clear(); ue_pool.reserve(16); @@ -60,8 +63,6 @@ void rrc::init(const rrc_cfg_t& cfg_, gtpu = gtpu_; s1ap = s1ap_; - pool = srslte::byte_buffer_pool::get_instance(); - cfg = cfg_; if (cfg.sibs[12].type() == asn1::rrc::sys_info_r8_ies_s::sib_type_and_info_item_c_::types::sib13_v920 && @@ -81,14 +82,14 @@ void rrc::init(const rrc_cfg_t& cfg_, uint32_t t310 = cfg.sibs[1].sib2().ue_timers_and_consts.t310.to_number(); uint32_t t311 = cfg.sibs[1].sib2().ue_timers_and_consts.t311.to_number(); uint32_t n310 = cfg.sibs[1].sib2().ue_timers_and_consts.n310.to_number(); - rrc_log->info("T310 %d, T311 %d, N310 %d \n", t310, t311, n310); + logger.info("T310 %d, T311 %d, N310 %d", t310, t311, n310); if (cfg.inactivity_timeout_ms < t310 + t311 + n310) { srslte::console("\nWarning: Inactivity timeout is smaller than the sum of t310, t311 and n310.\n" "This may break the UE's re-establishment procedure.\n"); - rrc_log->warning("Inactivity timeout is smaller than the sum of t310, t311 and n310. This may break the UE's " - "re-establishment procedure.\n"); + logger.warning("Inactivity timeout is smaller than the sum of t310, t311 and n310. This may break the UE's " + "re-establishment procedure."); } - rrc_log->info("Inactivity timeout: %d ms\n", cfg.inactivity_timeout_ms); + logger.info("Inactivity timeout: %d ms", cfg.inactivity_timeout_ms); running = true; } @@ -161,7 +162,7 @@ int rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg) // only non-eMBMS RNTIs are present in user map std::unique_ptr u{new ue(this, rnti, sched_ue_cfg)}; if (u->init() != SRSLTE_SUCCESS) { - rrc_log->error("Adding user rnti=0x%x - Failed to allocate user resources\n", rnti); + logger.error("Adding user rnti=0x%x - Failed to allocate user resources", rnti); return SRSLTE_ERROR; } if (ue_pool.capacity() <= 4) { @@ -171,9 +172,9 @@ int rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg) } rlc->add_user(rnti); pdcp->add_user(rnti); - rrc_log->info("Added new user rnti=0x%x\n", rnti); + logger.info("Added new user rnti=0x%x", rnti); } else { - rrc_log->error("Adding user rnti=0x%x (already exists)\n", rnti); + logger.error("Adding user rnti=0x%x (already exists)", rnti); } if (rnti == SRSLTE_MRNTI) { @@ -247,7 +248,7 @@ void rrc::write_dl_info(uint16_t rnti, srslte::unique_byte_buffer_t sdu) user_it->second->send_dl_dcch(&dl_dcch_msg, std::move(sdu)); } else { - rrc_log->error("Rx SDU for unknown rnti=0x%x\n", rnti); + logger.error("Rx SDU for unknown rnti=0x%x", rnti); } } @@ -259,11 +260,11 @@ void rrc::release_complete(uint16_t rnti) bool rrc::setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) { - rrc_log->info("Adding initial context for 0x%x\n", rnti); + logger.info("Adding initial context for 0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return false; } @@ -273,11 +274,11 @@ bool rrc::setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_requ bool rrc::modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) { - rrc_log->info("Modifying context for 0x%x\n", rnti); + logger.info("Modifying context for 0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return false; } @@ -286,11 +287,11 @@ bool rrc::modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request bool rrc::setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) { - rrc_log->info("Setting up erab(s) for 0x%x\n", rnti); + logger.info("Setting up erab(s) for 0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return false; } @@ -307,11 +308,11 @@ bool rrc::setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& bool rrc::release_erabs(uint32_t rnti) { - rrc_log->info("Releasing E-RABs for 0x%x\n", rnti); + logger.info("Releasing E-RABs for 0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return false; } @@ -324,11 +325,11 @@ void rrc::release_erabs(uint32_t rnti, std::vector* erabs_released, std::vector* erabs_failed_to_release) { - rrc_log->info("Releasing E-RAB for 0x%x\n", rnti); + logger.info("Releasing E-RAB for 0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return; } @@ -342,6 +343,10 @@ void rrc::release_erabs(uint32_t rnti, erabs_failed_to_release->push_back(erab_to_release.erab_id); } } + const asn1::unbounded_octstring* nas_pdu = + msg.protocol_ies.nas_pdu_present ? &msg.protocol_ies.nas_pdu.value : nullptr; + user_it->second->send_connection_reconf(nullptr, false, nas_pdu); + return; } @@ -350,11 +355,11 @@ void rrc::modify_erabs(uint16_t rnti, std::vector* erabs_modified, std::vector* erabs_failed_to_modify) { - rrc_log->info("Modifying E-RABs for 0x%x\n", rnti); + logger.info("Modifying E-RABs for 0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return; } @@ -383,11 +388,11 @@ bool rrc::modify_ue_erab(uint16_t rnti, const asn1::s1ap::erab_level_qos_params_s& qos_params, const asn1::unbounded_octstring* nas_pdu) { - rrc_log->info("Modifying E-RAB for 0x%x. E-RAB Id %d\n", rnti, erab_id); + logger.info("Modifying E-RAB for 0x%x. E-RAB Id %d", rnti, erab_id); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->warning("Unrecognised rnti: 0x%x\n", rnti); + logger.warning("Unrecognised rnti: 0x%x", rnti); return false; } @@ -405,7 +410,7 @@ void rrc::add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_pagi { std::lock_guard lock(paging_mutex); if (pending_paging.count(ueid) > 0) { - rrc_log->warning("Received Paging for UEID=%d but not yet transmitted\n", ueid); + logger.warning("Received Paging for UEID=%d but not yet transmitted", ueid); return; } @@ -437,7 +442,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len) if (tti == paging_tti) { *payload_len = byte_buf_paging.N_bytes; - rrc_log->debug("Sending paging to extra carriers. Payload len=%d, TTI=%d\n", *payload_len, tti); + logger.debug("Sending paging to extra carriers. Payload len=%d, TTI=%d", *payload_len, tti); return true; } else { paging_tti = INVALID_TTI; @@ -479,7 +484,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len) int sf_idx = sf_pattern[i_s % 4][(Ns - 1) % 4]; if (sf_idx < 0) { - rrc_log->error("SF pattern is N/A for Ns=%d, i_s=%d, imsi_decimal=%d\n", Ns, i_s, ueid); + logger.error("SF pattern is N/A for Ns=%d, i_s=%d, imsi_decimal=%d", Ns, i_s, ueid); continue; } @@ -488,7 +493,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len) paging_rec->paging_record_list.push_back(u); ue_to_remove.push_back(ueid); n++; - rrc_log->info("Assembled paging for ue_id=%d, tti=%d\n", ueid, tti); + logger.info("Assembled paging for ue_id=%d, tti=%d", ueid, tti); } } @@ -501,7 +506,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len) byte_buf_paging.clear(); asn1::bit_ref bref(byte_buf_paging.msg, byte_buf_paging.get_tailroom()); if (pcch_msg.pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - rrc_log->error("Failed to pack PCCH\n"); + logger.error("Failed to pack PCCH"); return false; } byte_buf_paging.N_bytes = (uint32_t)bref.distance_bytes(); @@ -510,10 +515,10 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t* payload_len) if (payload_len) { *payload_len = byte_buf_paging.N_bytes; } - rrc_log->info("Assembling PCCH payload with %d UE identities, payload_len=%d bytes, nbits=%d\n", - paging_rec->paging_record_list.size(), - byte_buf_paging.N_bytes, - N_bits); + logger.info("Assembling PCCH payload with %d UE identities, payload_len=%d bytes, nbits=%d", + paging_rec->paging_record_list.size(), + byte_buf_paging.N_bytes, + N_bits); log_rrc_message("PCCH-Message", Tx, &byte_buf_paging, pcch_msg, pcch_msg.msg.c1().type().to_string()); paging_tti = tti; // Store paging tti for other carriers @@ -535,16 +540,19 @@ void rrc::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) Handover functions *******************************************************************************/ -void rrc::ho_preparation_complete(uint16_t rnti, bool is_success, srslte::unique_byte_buffer_t rrc_container) +void rrc::ho_preparation_complete(uint16_t rnti, + bool is_success, + const asn1::s1ap::ho_cmd_s& msg, + srslte::unique_byte_buffer_t rrc_container) { - users.at(rnti)->mobility_handler->handle_ho_preparation_complete(is_success, std::move(rrc_container)); + users.at(rnti)->mobility_handler->handle_ho_preparation_complete(is_success, msg, std::move(rrc_container)); } void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) { auto ue_it = users.find(rnti); if (ue_it == users.end()) { - rrc_log->warning("rnti=0x%x does not exist\n", rnti); + logger.warning("rnti=0x%x does not exist", rnti); return; } ue_it->second->mobility_handler->trigger(erabs); @@ -563,7 +571,7 @@ void rrc::parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu) asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (ul_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or ul_ccch_msg.msg.type().value != ul_ccch_msg_type_c::types_opts::c1) { - rrc_log->error("Failed to unpack UL-CCCH message\n"); + logger.error("Failed to unpack UL-CCCH message"); return; } @@ -573,20 +581,22 @@ void rrc::parse_ul_ccch(uint16_t rnti, srslte::unique_byte_buffer_t pdu) switch (ul_ccch_msg.msg.c1().type().value) { case ul_ccch_msg_type_c::c1_c_::types::rrc_conn_request: if (user_it != users.end()) { + user_it->second->save_ul_message(std::move(pdu)); user_it->second->handle_rrc_con_req(&ul_ccch_msg.msg.c1().rrc_conn_request()); } else { - rrc_log->error("Received ConnectionSetup for rnti=0x%x without context\n", rnti); + logger.error("Received ConnectionSetup for rnti=0x%x without context", rnti); } break; case ul_ccch_msg_type_c::c1_c_::types::rrc_conn_reest_request: if (user_it != users.end()) { + user_it->second->save_ul_message(std::move(pdu)); user_it->second->handle_rrc_con_reest_req(&ul_ccch_msg.msg.c1().rrc_conn_reest_request()); } else { - rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context.\n", rnti); + logger.error("Received ConnectionReestablishment for rnti=0x%x without context.", rnti); } break; default: - rrc_log->error("UL CCCH message not recognised\n"); + logger.error("UL CCCH message not recognised"); break; } } @@ -600,7 +610,7 @@ void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer if (user_it != users.end()) { user_it->second->parse_ul_dcch(lcid, std::move(pdu)); } else { - rrc_log->error("Processing %s: Unknown rnti=0x%x\n", srsenb::to_string((rb_id_t)lcid), rnti); + logger.error("Processing %s: Unknown rnti=0x%x", srsenb::to_string((rb_id_t)lcid), rnti); } } } @@ -608,10 +618,10 @@ void rrc::parse_ul_dcch(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer ///< User mutex must be hold by caller void rrc::process_release_complete(uint16_t rnti) { - rrc_log->info("Received Release Complete rnti=0x%x\n", rnti); + logger.info("Received Release Complete rnti=0x%x", rnti); auto user_it = users.find(rnti); if (user_it == users.end()) { - rrc_log->error("Received ReleaseComplete for unknown rnti=0x%x\n", rnti); + logger.error("Received ReleaseComplete for unknown rnti=0x%x", rnti); return; } ue* u = user_it->second.get(); @@ -631,7 +641,7 @@ void rrc::rem_user(uint16_t rnti) auto user_it = users.find(rnti); if (user_it != users.end()) { srslte::console("Disconnecting rnti=0x%x.\n", rnti); - rrc_log->info("Disconnecting rnti=0x%x.\n", rnti); + logger.info("Disconnecting rnti=0x%x.", rnti); /* First remove MAC and GTPU to stop processing DL/UL traffic for this user */ @@ -643,9 +653,9 @@ void rrc::rem_user(uint16_t rnti) pdcp->rem_user(rnti); users.erase(rnti); - rrc_log->info("Removed user rnti=0x%x\n", rnti); + logger.info("Removed user rnti=0x%x", rnti); } else { - rrc_log->error("Removing user rnti=0x%x (does not exist)\n", rnti); + logger.error("Removing user rnti=0x%x (does not exist)", rnti); } } @@ -682,7 +692,7 @@ void rrc::config_mac() item.enable_phr_handling = cfg.cell_list[ccidx].enable_phr_handling; item.nrb_pucch = SRSLTE_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb); - rrc_log->info("Allocating %d PRBs for PUCCH\n", item.nrb_pucch); + logger.info("Allocating %d PRBs for PUCCH", item.nrb_pucch); // Copy base cell configuration item.cell = cfg.cell; @@ -696,7 +706,7 @@ void rrc::config_mac() return e.cell_id == scellitem.cell_id; }); if (it == cfg.cell_list.end()) { - rrc_log->warning("Secondary cell 0x%x not configured\n", scellitem.cell_id); + logger.warning("Secondary cell 0x%x not configured", scellitem.cell_id); continue; } sched_interface::cell_cfg_t::scell_cfg_t scellcfg; @@ -761,10 +771,10 @@ uint32_t rrc::generate_sibs() // Pack payload for all messages for (uint32_t msg_index = 0; msg_index < nof_messages; msg_index++) { - srslte::unique_byte_buffer_t sib_buffer = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sib_buffer = srslte::make_byte_buffer(); asn1::bit_ref bref(sib_buffer->msg, sib_buffer->get_tailroom()); if (msg[msg_index].pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - rrc_log->error("Failed to pack SIB message %d\n", msg_index); + logger.error("Failed to pack SIB message %d", msg_index); } sib_buffer->N_bytes = bref.distance_bytes(); cell_ctxt->sib_buffer.push_back(std::move(sib_buffer)); @@ -854,9 +864,9 @@ void rrc::configure_mbsfn_sibs() uint16_t mbms_mcs = cfg.mbms_mcs; if (mbms_mcs > 28) { mbms_mcs = 28; // TS 36.213, Table 8.6.1-1 - rrc_log->warning("PMCH data MCS too high, setting it to 28\n"); + logger.warning("PMCH data MCS too high, setting it to 28"); } - rrc_log->debug("PMCH data MCS=%d\n", mbms_mcs); + logger.debug("PMCH data MCS=%d", mbms_mcs); pmch_item->data_mcs = mbms_mcs; pmch_item->mch_sched_period = srslte::pmch_info_t::mch_sched_period_t::rf64; pmch_item->sf_alloc_end = 64 * 6; @@ -866,7 +876,6 @@ void rrc::configure_mbsfn_sibs() int rrc::pack_mcch() { - mcch.msg.set_c1(); mbsfn_area_cfg_r9_s& area_cfg_r9 = mcch.msg.c1().mbsfn_area_cfg_r9(); area_cfg_r9.common_sf_alloc_period_r9 = mbsfn_area_cfg_r9_s::common_sf_alloc_period_r9_e_::rf64; @@ -905,10 +914,10 @@ int rrc::pack_mcch() uint16_t mbms_mcs = cfg.mbms_mcs; if (mbms_mcs > 28) { mbms_mcs = 28; // TS 36.213, Table 8.6.1-1 - rrc_log->warning("PMCH data MCS too high, setting it to 28\n"); + logger.warning("PMCH data MCS too high, setting it to 28"); } - rrc_log->debug("PMCH data MCS=%d\n", mbms_mcs); + logger.debug("PMCH data MCS=%d", mbms_mcs); pmch_item->pmch_cfg_r9.data_mcs_r9 = mbms_mcs; pmch_item->pmch_cfg_r9.mch_sched_period_r9 = pmch_cfg_r9_s::mch_sched_period_r9_e_::rf64; pmch_item->pmch_cfg_r9.sf_alloc_end_r9 = 64 * 6; @@ -932,13 +941,13 @@ void rrc::tti_clock() while (rx_pdu_queue.try_pop(&p)) { // print Rx PDU if (p.pdu != nullptr) { - rrc_log->info_hex(p.pdu->msg, p.pdu->N_bytes, "Rx %s PDU", to_string((rb_id_t)p.lcid)); + logger.info(p.pdu->msg, p.pdu->N_bytes, "Rx %s PDU", to_string((rb_id_t)p.lcid)); } // check if user exists auto user_it = users.find(p.rnti); if (user_it == users.end()) { - rrc_log->warning("Discarding PDU for removed rnti=0x%x\n", p.rnti); + logger.warning("Discarding PDU for removed rnti=0x%x", p.rnti); continue; } @@ -961,10 +970,10 @@ void rrc::tti_clock() user_it->second->set_activity(); break; case LCID_EXIT: - rrc_log->info("Exiting thread\n"); + logger.info("Exiting thread"); break; default: - rrc_log->error("Rx PDU with invalid bearer id: %d", p.lcid); + logger.error("Rx PDU with invalid bearer id: %d", p.lcid); break; } } diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 5216795e8..23628b6cd 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -64,17 +64,17 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi // just assume that EEA0 is always supported even this can not be explicity signaled by S1AP sec_cfg.cipher_algo = srslte::CIPHERING_ALGORITHM_ID_EEA0; enc_algo_found = true; - log_h->info("Selected EEA0 as RRC encryption algorithm\n"); + logger.info("Selected EEA0 as RRC encryption algorithm"); break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA1: // “first bit” – 128-EEA1, if (v.get(v.length() - srslte::CIPHERING_ALGORITHM_ID_128_EEA1)) { sec_cfg.cipher_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA1; enc_algo_found = true; - log_h->info("Selected EEA1 as RRC encryption algorithm\n"); + logger.info("Selected EEA1 as RRC encryption algorithm"); break; } else { - log_h->info("Failed to selected EEA1 as RRC encryption algorithm, due to unsupported algorithm\n"); + logger.info("Failed to selected EEA1 as RRC encryption algorithm, due to unsupported algorithm"); } break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA2: @@ -82,10 +82,10 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi if (v.get(v.length() - srslte::CIPHERING_ALGORITHM_ID_128_EEA2)) { sec_cfg.cipher_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA2; enc_algo_found = true; - log_h->info("Selected EEA2 as RRC encryption algorithm\n"); + logger.info("Selected EEA2 as RRC encryption algorithm"); break; } else { - log_h->info("Failed to selected EEA2 as RRC encryption algorithm, due to unsupported algorithm\n"); + logger.info("Failed to selected EEA2 as RRC encryption algorithm, due to unsupported algorithm"); } break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA3: @@ -93,10 +93,10 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi if (v.get(v.length() - srslte::CIPHERING_ALGORITHM_ID_128_EEA3)) { sec_cfg.cipher_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA3; enc_algo_found = true; - log_h->info("Selected EEA3 as RRC encryption algorithm\n"); + logger.info("Selected EEA3 as RRC encryption algorithm"); break; } else { - log_h->info("Failed to selected EEA2 as RRC encryption algorithm, due to unsupported algorithm\n"); + logger.info("Failed to selected EEA2 as RRC encryption algorithm, due to unsupported algorithm"); } break; default: @@ -113,16 +113,16 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi switch (eia_enum) { case srslte::INTEGRITY_ALGORITHM_ID_EIA0: // Null integrity is not supported - log_h->info("Skipping EIA0 as RRC integrity algorithm. Null integrity is not supported.\n"); + logger.info("Skipping EIA0 as RRC integrity algorithm. Null integrity is not supported."); break; case srslte::INTEGRITY_ALGORITHM_ID_128_EIA1: // “first bit” – 128-EIA1, if (v.get(v.length() - srslte::INTEGRITY_ALGORITHM_ID_128_EIA1)) { sec_cfg.integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA1; integ_algo_found = true; - log_h->info("Selected EIA1 as RRC integrity algorithm.\n"); + logger.info("Selected EIA1 as RRC integrity algorithm."); } else { - log_h->info("Failed to selected EIA1 as RRC encryption algorithm, due to unsupported algorithm\n"); + logger.info("Failed to selected EIA1 as RRC encryption algorithm, due to unsupported algorithm"); } break; case srslte::INTEGRITY_ALGORITHM_ID_128_EIA2: @@ -130,9 +130,9 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi if (v.get(v.length() - srslte::INTEGRITY_ALGORITHM_ID_128_EIA2)) { sec_cfg.integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA2; integ_algo_found = true; - log_h->info("Selected EIA2 as RRC integrity algorithm.\n"); + logger.info("Selected EIA2 as RRC integrity algorithm."); } else { - log_h->info("Failed to selected EIA2 as RRC encryption algorithm, due to unsupported algorithm\n"); + logger.info("Failed to selected EIA2 as RRC encryption algorithm, due to unsupported algorithm"); } break; case srslte::INTEGRITY_ALGORITHM_ID_128_EIA3: @@ -140,9 +140,9 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi if (v.get(v.length() - srslte::INTEGRITY_ALGORITHM_ID_128_EIA3)) { sec_cfg.integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA3; integ_algo_found = true; - log_h->info("Selected EIA3 as RRC integrity algorithm.\n"); + logger.info("Selected EIA3 as RRC integrity algorithm."); } else { - log_h->info("Failed to selected EIA3 as RRC encryption algorithm, due to unsupported algorithm\n"); + logger.info("Failed to selected EIA3 as RRC encryption algorithm, due to unsupported algorithm"); } break; default: @@ -158,7 +158,7 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi if (not integ_algo_found || not enc_algo_found) { // TODO: if no security algorithm found abort radio connection and issue // encryption-and-or-integrity-protection-algorithms-not-supported message - log_h->error("Did not find a matching integrity or encryption algorithm with the UE\n"); + logger.error("Did not find a matching integrity or encryption algorithm with the UE"); return false; } return true; @@ -170,7 +170,7 @@ void security_cfg_handler::set_security_key(const asn1::fixed_bitstring<256, fal for (uint32_t i = 0; i < key.nof_octets(); ++i) { k_enb[i] = key.data()[key.nof_octets() - 1 - i]; } - log_h->info_hex(k_enb, 32, "Key eNodeB (k_enb)"); + logger.info(k_enb, 32, "Key eNodeB (k_enb)"); generate_as_keys(); } @@ -185,16 +185,16 @@ void security_cfg_handler::generate_as_keys() security_generate_k_up( k_enb, sec_cfg.cipher_algo, sec_cfg.integ_algo, sec_cfg.k_up_enc.data(), sec_cfg.k_up_int.data()); - log_h->info_hex(k_enb, 32, "K_eNB (k_enb)"); - log_h->info_hex(sec_cfg.k_rrc_enc.data(), 32, "RRC Encryption Key (k_rrc_enc)"); - log_h->info_hex(sec_cfg.k_rrc_int.data(), 32, "RRC Integrity Key (k_rrc_int)"); - log_h->info_hex(sec_cfg.k_up_enc.data(), 32, "UP Encryption Key (k_up_enc)"); + logger.info(k_enb, 32, "K_eNB (k_enb)"); + logger.info(sec_cfg.k_rrc_enc.data(), 32, "RRC Encryption Key (k_rrc_enc)"); + logger.info(sec_cfg.k_rrc_int.data(), 32, "RRC Integrity Key (k_rrc_int)"); + logger.info(sec_cfg.k_up_enc.data(), 32, "UP Encryption Key (k_up_enc)"); } void security_cfg_handler::regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_earfcn) { - log_h->info("Regenerating KeNB with PCI=0x%02x, DL-EARFCN=%d\n", new_pci, new_dl_earfcn); - log_h->info_hex(k_enb, 32, "Old K_eNB (k_enb)"); + logger.info("Regenerating KeNB with PCI=0x%02x, DL-EARFCN=%d", new_pci, new_dl_earfcn); + logger.info(k_enb, 32, "Old K_eNB (k_enb)"); // Generate K_enb* uint8_t k_enb_star[32]; srslte::security_generate_k_enb_star(k_enb, new_pci, new_dl_earfcn, k_enb_star); @@ -209,7 +209,9 @@ void security_cfg_handler::regenerate_keys_handover(uint32_t new_pci, uint32_t n * Bearer Handler ****************************/ -bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_) : rnti(rnti_), cfg(&cfg_) {} +bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_) : + rnti(rnti_), cfg(&cfg_), gtpu(gtpu_), logger(srslog::fetch_basic_logger("RRC")) +{} int bearer_cfg_handler::add_erab(uint8_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos, @@ -218,24 +220,22 @@ int bearer_cfg_handler::add_erab(uint8_t const asn1::unbounded_octstring* nas_pdu) { if (erab_id < 5) { - log_h->error("ERAB id=%d is invalid\n", erab_id); + logger.error("ERAB id=%d is invalid", erab_id); return SRSLTE_ERROR; } uint8_t lcid = erab_id - 2; // Map e.g. E-RAB 5 to LCID 3 (==DRB1) uint8_t drbid = erab_id - 4; - if (qos.qci >= MAX_NOF_QCI) { - log_h->error("Invalid QCI=%d for ERAB_id=%d, DRB_id=%d\n", qos.qci, erab_id, drbid); - return SRSLTE_ERROR; - } - if (not cfg->qci_cfg[qos.qci].configured) { - log_h->error("QCI=%d not configured\n", qos.qci); + auto qci_it = cfg->qci_cfg.find(qos.qci); + if (qci_it == cfg->qci_cfg.end() or not qci_it->second.configured) { + logger.error("QCI=%d not configured", qos.qci); return SRSLTE_ERROR; } if (lcid < 3 or lcid > 10) { - log_h->error("DRB logical channel ids must be within 3 and 10\n"); + logger.error("DRB logical channel ids must be within 3 and 10"); return SRSLTE_ERROR; } + const rrc_cfg_qci_t& qci_cfg = qci_it->second; erabs[erab_id].id = erab_id; erabs[erab_id].qos_params = qos; @@ -243,13 +243,13 @@ int bearer_cfg_handler::add_erab(uint8_t erabs[erab_id].teid_out = teid_out; if (addr.length() > 32) { - log_h->error("Only addresses with length <= 32 are supported\n"); + logger.error("Only addresses with length <= 32 are supported"); return SRSLTE_ERROR; } if (nas_pdu != nullptr and nas_pdu->size() > 0) { erab_info_list[erab_id].assign(nas_pdu->data(), nas_pdu->data() + nas_pdu->size()); - log_h->info_hex( + logger.info( &erab_info_list[erab_id][0], erab_info_list[erab_id].size(), "setup_erab nas_pdu -> erab_info rnti 0x%x", rnti); } @@ -262,11 +262,11 @@ int bearer_cfg_handler::add_erab(uint8_t drb_it->lc_ch_cfg_present = true; drb_it->lc_ch_cfg.ul_specific_params_present = true; drb_it->lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; - drb_it->lc_ch_cfg.ul_specific_params = cfg->qci_cfg[qos.qci].lc_cfg; + drb_it->lc_ch_cfg.ul_specific_params = qci_cfg.lc_cfg; drb_it->pdcp_cfg_present = true; - drb_it->pdcp_cfg = cfg->qci_cfg[qos.qci].pdcp_cfg; + drb_it->pdcp_cfg = qci_cfg.pdcp_cfg; drb_it->rlc_cfg_present = true; - drb_it->rlc_cfg = cfg->qci_cfg[qos.qci].rlc_cfg; + drb_it->rlc_cfg = qci_cfg.rlc_cfg; return SRSLTE_SUCCESS; } @@ -275,7 +275,7 @@ bool bearer_cfg_handler::release_erab(uint8_t erab_id) { auto it = erabs.find(erab_id); if (it == erabs.end()) { - log_h->warning("The user rnti=0x%x does not contain ERAB-ID=%d\n", rnti, erab_id); + logger.warning("The user rnti=0x%x does not contain ERAB-ID=%d", rnti, erab_id); return false; } @@ -302,10 +302,10 @@ bool bearer_cfg_handler::modify_erab(uint8_t const asn1::s1ap::erab_level_qos_params_s& qos, const asn1::unbounded_octstring* nas_pdu) { - log_h->info("Modifying E-RAB %d\n", erab_id); + logger.info("Modifying E-RAB %d", erab_id); std::map::iterator erab_it = erabs.find(erab_id); if (erab_it == erabs.end()) { - log_h->error("Could not find E-RAB to modify\n"); + logger.error("Could not find E-RAB to modify"); return false; } auto address = erab_it->second.address; @@ -315,16 +315,45 @@ bool bearer_cfg_handler::modify_erab(uint8_t return true; } -void bearer_cfg_handler::add_gtpu_bearer(srsenb::gtpu_interface_rrc* gtpu, uint32_t erab_id) +void bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id) +{ + auto it = erabs.find(erab_id); + if (it == erabs.end()) { + logger.error("Adding erab_id=%d to GTPU", erab_id); + return; + } + it->second.teid_in = add_gtpu_bearer(erab_id, it->second.teid_out, it->second.address.to_number(), nullptr); +} + +uint32_t bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id, + uint32_t teid_out, + uint32_t addr, + const gtpu_interface_rrc::bearer_props* props) +{ + auto it = erabs.find(erab_id); + if (it == erabs.end()) { + logger.error("Adding erab_id=%d to GTPU", erab_id); + return 0; + } + + // Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf + erab_t& erab = it->second; + erab_t::gtpu_tunnel bearer; + bearer.teid_out = teid_out; + bearer.addr = addr; + bearer.teid_in = gtpu->add_bearer(rnti, erab.id - 2, addr, teid_out, props); + erab.tunnels.push_back(bearer); + return bearer.teid_in; +} + +void bearer_cfg_handler::rem_gtpu_bearer(uint32_t erab_id) { auto it = erabs.find(erab_id); if (it != erabs.end()) { - erab_t& erab = it->second; - // Initialize ERAB in GTPU right-away. DRBs are only created during RRC setup/reconf - uint32_t addr_ = erab.address.to_number(); - erab.teid_in = gtpu->add_bearer(rnti, erab.id - 2, addr_, erab.teid_out); + // Map e.g. E-RAB 5 to LCID 3 (==DRB1) + gtpu->rem_bearer(rnti, erab_id - 2); } else { - log_h->error("Adding erab_id=%d to GTPU\n", erab_id); + logger.error("Removing erab_id=%d to GTPU\n", erab_id); } } @@ -346,12 +375,12 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_ auto it = erab_info_list.find(erab_id); if (it != erab_info_list.end()) { const std::vector& erab_info = it->second; - log_h->info_hex(&erab_info[0], erab_info.size(), "connection_reconf erab_info -> nas_info rnti 0x%x\n", rnti); + logger.info(&erab_info[0], erab_info.size(), "connection_reconf erab_info -> nas_info rnti 0x%x", rnti); msg->ded_info_nas_list[idx].resize(erab_info.size()); memcpy(msg->ded_info_nas_list[idx].data(), &erab_info[0], erab_info.size()); erab_info_list.erase(it); } else { - log_h->debug("Not adding NAS message to connection reconfiguration. E-RAB id %d\n", erab_id); + logger.debug("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); } idx++; } diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index d17b67c79..93604117b 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -149,7 +149,7 @@ cell_res_common* freq_res_common_list::get_earfcn(uint32_t earfcn) ue_cell_ded_list::ue_cell_ded_list(const rrc_cfg_t& cfg_, freq_res_common_list& cell_res_list_, const enb_cell_common_list& enb_common_list) : - cfg(cfg_), cell_res_list(cell_res_list_), common_list(enb_common_list) + logger(srslog::fetch_basic_logger("RRC")), cfg(cfg_), cell_res_list(cell_res_list_), common_list(enb_common_list) { cell_list.reserve(common_list.nof_cells()); } @@ -183,12 +183,12 @@ ue_cell_ded* ue_cell_ded_list::add_cell(uint32_t enb_cc_idx) { const enb_cell_common* cell_common = common_list.get_cc_idx(enb_cc_idx); if (cell_common == nullptr) { - log_h->error("cell with enb_cc_idx=%d does not exist.\n", enb_cc_idx); + logger.error("cell with enb_cc_idx=%d does not exist.", enb_cc_idx); return nullptr; } ue_cell_ded* ret = get_enb_cc_idx(enb_cc_idx); if (ret != nullptr) { - log_h->error("UE already registered cell %d\n", enb_cc_idx); + logger.error("UE already registered cell %d", enb_cc_idx); return nullptr; } @@ -230,7 +230,7 @@ bool ue_cell_ded_list::alloc_cell_resources(uint32_t ue_cc_idx) // Allocate CQI, SR, and PUCCH CS resources. If failure, do not add new cell if (ue_cc_idx == UE_PCELL_CC_IDX) { if (not alloc_sr_resources(cfg.sr_cfg.period)) { - log_h->error("Failed to allocate SR resources for PCell\n"); + logger.error("Failed to allocate SR resources for PCell"); return false; } @@ -242,7 +242,7 @@ bool ue_cell_ded_list::alloc_cell_resources(uint32_t ue_cc_idx) if (ue_cc_idx == 1 and not n_pucch_cs_present) { // Allocate resources for Format1b CS (will be optional PUCCH3/CS) if (not alloc_pucch_cs_resources()) { - log_h->error("Error allocating PUCCH Format1b CS resource for SCell\n"); + logger.error("Error allocating PUCCH Format1b CS resource for SCell"); return false; } } else { @@ -251,7 +251,7 @@ bool ue_cell_ded_list::alloc_cell_resources(uint32_t ue_cc_idx) } } if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) { - log_h->error("Failed to allocate CQIresources for cell ue_cc_idx=%d\n", ue_cc_idx); + logger.error("Failed to allocate CQIresources for cell ue_cc_idx=%d", ue_cc_idx); return false; } @@ -302,7 +302,7 @@ bool ue_cell_ded_list::set_cells(const std::vector& enb_cc_idxs) uint32_t enb_cc_idx = enb_cc_idxs[ue_cc_idx]; const enb_cell_common* cell_common = common_list.get_cc_idx(enb_cc_idx); if (cell_common == nullptr) { - log_h->error("cell with enb_cc_idx=%d does not exist.\n", enb_cc_idx); + logger.error("cell with enb_cc_idx=%d does not exist.", enb_cc_idx); break; } auto* prev_cell_common = cell_list[ue_cc_idx].cell_common; @@ -314,7 +314,7 @@ bool ue_cell_ded_list::set_cells(const std::vector& enb_cc_idxs) dealloc_cqi_resources(ue_cc_idx); cell_list[ue_cc_idx] = ue_cell_ded{ue_cc_idx, *cell_common}; if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) { - log_h->error("Failed to allocate CQI resources for cell ue_cc_idx=%d\n", ue_cc_idx); + logger.error("Failed to allocate CQI resources for cell ue_cc_idx=%d", ue_cc_idx); break; } } @@ -333,11 +333,11 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) { ue_cell_ded* cell = get_ue_cc_idx(ue_cc_idx); if (cell == nullptr) { - log_h->error("The user cell ue_cc_idx=%d has not been allocated\n", ue_cc_idx); + logger.error("The user cell ue_cc_idx=%d has not been allocated", ue_cc_idx); return false; } if (cell->cqi_res_present) { - log_h->error("The user cqi resources for cell ue_cc_idx=%d are already allocated\n", ue_cc_idx); + logger.error("The user cqi resources for cell ue_cc_idx=%d are already allocated", ue_cc_idx); return false; } @@ -361,7 +361,7 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) } } if (pucch_res->cqi_sched.nof_users[i_min][j_min] > max_users) { - log_h->error("Not enough PUCCH resources to allocate Scheduling Request\n"); + logger.error("Not enough PUCCH resources to allocate Scheduling Request"); return false; } @@ -370,7 +370,7 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) // Compute I_sr if (period != 2 && period != 5 && period != 10 && period != 20 && period != 40 && period != 80 && period != 160 && period != 32 && period != 64 && period != 128) { - log_h->error("Invalid CQI Report period %d ms\n", period); + logger.error("Invalid CQI Report period %d ms", period); return false; } if (cfg.cqi_cfg.sf_mapping[j_min] < period) { @@ -390,7 +390,7 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) } } } else { - log_h->error("Allocating CQI: invalid sf_idx=%d for period=%d\n", cfg.cqi_cfg.sf_mapping[j_min], period); + logger.error("Allocating CQI: invalid sf_idx=%d for period=%d", cfg.cqi_cfg.sf_mapping[j_min], period); return false; } @@ -408,7 +408,7 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) pucch_res->cqi_sched.nof_users[i_min][j_min]++; - log_h->info("Allocated CQI resources for ue_cc_idx=%d, time-frequency slot (%d, %d), n_pucch_2=%d, pmi_cfg_idx=%d\n", + logger.info("Allocated CQI resources for ue_cc_idx=%d, time-frequency slot (%d, %d), n_pucch_2=%d, pmi_cfg_idx=%d", ue_cc_idx, i_min, j_min, @@ -426,10 +426,10 @@ bool ue_cell_ded_list::dealloc_cqi_resources(uint32_t ue_cc_idx) if (pucch_res->cqi_sched.nof_users[c->cqi_res.prb_idx][c->cqi_res.sf_idx] > 0) { pucch_res->cqi_sched.nof_users[c->cqi_res.prb_idx][c->cqi_res.sf_idx]--; - log_h->info("Deallocated CQI resources for time-frequency slot (%d, %d)\n", c->cqi_res.prb_idx, c->cqi_res.sf_idx); + logger.info("Deallocated CQI resources for time-frequency slot (%d, %d)", c->cqi_res.prb_idx, c->cqi_res.sf_idx); } else { - log_h->warning( - "Removing CQI resources: no users in time-frequency slot (%d, %d)\n", c->cqi_res.prb_idx, c->cqi_res.sf_idx); + logger.warning( + "Removing CQI resources: no users in time-frequency slot (%d, %d)", c->cqi_res.prb_idx, c->cqi_res.sf_idx); } c->cqi_res_present = false; return true; @@ -439,11 +439,11 @@ bool ue_cell_ded_list::alloc_sr_resources(uint32_t period) { ue_cell_ded* cell = get_ue_cc_idx(UE_PCELL_CC_IDX); if (cell == nullptr) { - log_h->error("The user cell pcell has not been allocated\n"); + logger.error("The user cell pcell has not been allocated"); return false; } if (sr_res_present) { - log_h->error("The user sr resources are already allocated\n"); + logger.error("The user sr resources are already allocated"); return false; } @@ -466,19 +466,19 @@ bool ue_cell_ded_list::alloc_sr_resources(uint32_t period) } if (pucch_res->sr_sched.nof_users[i_min][j_min] > max_users) { - log_h->error("Not enough PUCCH resources to allocate Scheduling Request\n"); + logger.error("Not enough PUCCH resources to allocate Scheduling Request"); return false; } // Compute I_sr if (period != 5 && period != 10 && period != 20 && period != 40 && period != 80) { - log_h->error("Invalid SchedulingRequest period %d ms\n", period); + logger.error("Invalid SchedulingRequest period %d ms", period); return false; } if (cfg.sr_cfg.sf_mapping[j_min] < period) { sr_res.sr_I = period - 5 + cfg.sr_cfg.sf_mapping[j_min]; } else { - log_h->error("Allocating SR: invalid sf_idx=%d for period=%d\n", cfg.sr_cfg.sf_mapping[j_min], period); + logger.error("Allocating SR: invalid sf_idx=%d for period=%d", cfg.sr_cfg.sf_mapping[j_min], period); return false; } @@ -494,7 +494,7 @@ bool ue_cell_ded_list::alloc_sr_resources(uint32_t period) sr_res.sr_sched_sf_idx = j_min; sr_res_present = true; - log_h->info("Allocated SR resources in time-freq slot (%d, %d), sf_cfg_idx=%d\n", + logger.info("Allocated SR resources in time-freq slot (%d, %d), sf_cfg_idx=%d", sr_res.sr_sched_sf_idx, sr_res.sr_sched_prb_idx, cfg.sr_cfg.sf_mapping[sr_res.sr_sched_sf_idx]); @@ -508,13 +508,13 @@ bool ue_cell_ded_list::dealloc_sr_resources() if (pucch_res->sr_sched.nof_users[sr_res.sr_sched_prb_idx][sr_res.sr_sched_sf_idx] > 0) { pucch_res->sr_sched.nof_users[sr_res.sr_sched_prb_idx][sr_res.sr_sched_sf_idx]--; } else { - log_h->warning("Removing SR resources: no users in time-frequency slot (%d, %d)\n", + logger.warning("Removing SR resources: no users in time-frequency slot (%d, %d)", sr_res.sr_sched_prb_idx, sr_res.sr_sched_sf_idx); } - log_h->info( - "Deallocated SR resources for time-frequency slot (%d, %d)\n", sr_res.sr_sched_prb_idx, sr_res.sr_sched_sf_idx); - log_h->debug("Remaining SR allocations for slot (%d, %d): %d\n", + logger.info( + "Deallocated SR resources for time-frequency slot (%d, %d)", sr_res.sr_sched_prb_idx, sr_res.sr_sched_sf_idx); + logger.debug("Remaining SR allocations for slot (%d, %d): %d", sr_res.sr_sched_prb_idx, sr_res.sr_sched_sf_idx, pucch_res->sr_sched.nof_users[sr_res.sr_sched_prb_idx][sr_res.sr_sched_sf_idx]); @@ -528,11 +528,11 @@ bool ue_cell_ded_list::alloc_pucch_cs_resources() { ue_cell_ded* cell = get_ue_cc_idx(UE_PCELL_CC_IDX); if (cell == nullptr) { - log_h->error("The user cell pcell has not been allocated\n"); + logger.error("The user cell pcell has not been allocated"); return false; } if (n_pucch_cs_present) { - log_h->error("The user sr resources are already allocated\n"); + logger.error("The user sr resources are already allocated"); return false; } @@ -545,11 +545,11 @@ bool ue_cell_ded_list::alloc_pucch_cs_resources() pucch_res->n_pucch_cs_used[i] = true; n_pucch_cs_idx = i; n_pucch_cs_present = true; - log_h->info("Allocated N_pucch_cs=%d\n", n_pucch_cs_idx); + logger.info("Allocated N_pucch_cs=%d", n_pucch_cs_idx); return true; } } - log_h->warning("Could not allocated N_pucch_cs\n"); + logger.warning("Could not allocated N_pucch_cs"); return false; } @@ -558,7 +558,7 @@ bool ue_cell_ded_list::dealloc_pucch_cs_resources() if (n_pucch_cs_present) { pucch_res->n_pucch_cs_used[n_pucch_cs_idx] = false; n_pucch_cs_present = false; - log_h->info("Deallocated N_pucch_cs=%d\n", n_pucch_cs_idx); + logger.info("Deallocated N_pucch_cs=%d", n_pucch_cs_idx); return true; } return false; diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index d20196598..1372158cb 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -27,7 +27,12 @@ #include "srslte/asn1/rrc_utils.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/common.h" +#include "srslte/common/enb_events.h" #include "srslte/common/int_helpers.h" +#include "srslte/interfaces/enb_mac_interfaces.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" +#include "srslte/interfaces/enb_s1ap_interfaces.h" #include "srslte/rrc/rrc_cfg_utils.h" #include #include @@ -35,14 +40,14 @@ namespace srsenb { -#define Info(fmt, ...) rrc_log->info("Mobility: " fmt, ##__VA_ARGS__) -#define Error(fmt, ...) rrc_log->error("Mobility: " fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) rrc_log->warning("Mobility: " fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) rrc_log->debug("Mobility: " fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info("Mobility: " fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error("Mobility: " fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning("Mobility: " fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug("Mobility: " fmt, ##__VA_ARGS__) -#define procInfo(fmt, ...) parent->rrc_log->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define procWarning(fmt, ...) parent->rrc_log->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define procError(fmt, ...) parent->rrc_log->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procInfo(fmt, ...) parent->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procWarning(fmt, ...) parent->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procError(fmt, ...) parent->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) using namespace asn1::rrc; @@ -80,11 +85,12 @@ uint16_t compute_mac_i(uint16_t crnti, asn1::bit_ref bref(varShortMAC_packed, sizeof(varShortMAC_packed)); if (var_short_mac.pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { // already zeroed, so no need to align - printf("Error packing varShortMAC\n"); + printf("Error packing varShortMAC"); } uint32_t N_bytes = bref.distance_bytes(); - printf("Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes)\n", cellid, pci, crnti, N_bytes); + srslte::logmap::get("RRC")->info( + "Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes)", cellid, pci, crnti, N_bytes); // Compute MAC-I switch (integ_algo) { @@ -107,7 +113,7 @@ uint16_t compute_mac_i(uint16_t crnti, mac_key); break; default: - printf("Unsupported integrity algorithm %d.\n", integ_algo); + printf("Unsupported integrity algorithm %d.", integ_algo); } uint16_t short_mac_i = (((uint16_t)mac_key[2] << 8u) | (uint16_t)mac_key[3]); @@ -144,10 +150,10 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& // TODO: Decision Making on whether the same QoS of the source eNB can be provided by target eNB /* Evaluate if cell exists */ - uint32_t target_eci = container.target_cell_id.cell_id.to_number(); + uint32_t target_eci = container.target_cell_id.cell_id.to_number(); const enb_cell_common* target_cell = cell_common_list->get_cell_id(rrc_details::eci_to_cellid(target_eci)); if (target_cell == nullptr) { - rrc_log->error("The S1-handover target cell_id=0x%x does not exist\n", rrc_details::eci_to_cellid(target_eci)); + logger.error("The S1-handover target cell_id=0x%x does not exist", rrc_details::eci_to_cellid(target_eci)); return SRSLTE_INVALID_RNTI; } @@ -162,7 +168,7 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& ue_cfg.supported_cc_list[0].dl_cfg.tm = SRSLTE_TM1; uint16_t rnti = mac->reserve_new_crnti(ue_cfg); if (rnti == SRSLTE_INVALID_RNTI) { - rrc_log->error("Failed to allocate C-RNTI resources\n"); + logger.error("Failed to allocate C-RNTI resources"); return SRSLTE_INVALID_RNTI; } @@ -175,11 +181,10 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& // /* Setup e-RABs & DRBs / establish an UL/DL S1 bearer to the S-GW */ // if (not setup_ue_erabs(rnti, msg)) { - // rrc_ptr->rrc_log->error("Failed to setup e-RABs for rnti=0x%x\n", ); + // rrc_ptr->logger.error("Failed to setup e-RABs for rnti=0x%x", ); // } // TODO: KeNB derivations - if (not ue_ptr->mobility_handler->start_s1_tenb_ho(msg, container)) { rem_user_thread(rnti); return SRSLTE_INVALID_RNTI; @@ -192,11 +197,7 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& ************************************************************************************************/ rrc::ue::rrc_mobility::rrc_mobility(rrc::ue* outer_ue) : - base_t(outer_ue->parent->rrc_log), - rrc_ue(outer_ue), - rrc_enb(outer_ue->parent), - pool(outer_ue->pool), - rrc_log(outer_ue->parent->rrc_log) + base_t(outer_ue->parent->logger), rrc_ue(outer_ue), rrc_enb(outer_ue->parent), logger(outer_ue->parent->logger) {} //! Method to add Mobility Info to a RRC Connection Reconfiguration Message @@ -215,28 +216,28 @@ bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_ } //! Method called whenever the eNB receives a MeasReport from the UE. In normal situations, an HO procedure is started -void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg) +void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srslte::unique_byte_buffer_t pdu) { if (not is_in_state()) { - Info("Received a MeasReport while UE is performing Handover. Ignoring...\n"); + Info("Received a MeasReport while UE is performing Handover. Ignoring..."); return; } // Check if meas_id is valid const meas_results_s& meas_res = msg.crit_exts.c1().meas_report_r8().meas_results; if (not meas_res.meas_result_neigh_cells_present) { - Info("Received a MeasReport, but the UE did not detect any cell.\n"); + Info("Received a MeasReport, but the UE did not detect any cell."); return; } if (meas_res.meas_result_neigh_cells.type().value != meas_results_s::meas_result_neigh_cells_c_::types::meas_result_list_eutra) { - Error("MeasReports regarding non-EUTRA are not supported!\n"); + Error("MeasReports regarding non-EUTRA are not supported!"); return; } const meas_id_list& measid_list = rrc_ue->current_ue_cfg.meas_cfg.meas_id_to_add_mod_list; const meas_obj_list& measobj_list = rrc_ue->current_ue_cfg.meas_cfg.meas_obj_to_add_mod_list; auto measid_it = srslte::find_rrc_obj_id(measid_list, meas_res.meas_id); if (measid_it == measid_list.end()) { - Warning("The measurement ID %d provided by the UE does not exist.\n", meas_res.meas_id); + Warning("The measurement ID %d provided by the UE does not exist.", meas_res.meas_id); return; } const meas_result_list_eutra_l& eutra_report_list = meas_res.meas_result_neigh_cells.meas_result_list_eutra(); @@ -248,17 +249,17 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg) // iterate from strongest to weakest cell const ue_cell_ded* pcell = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); - const auto& meas_list_cfg = pcell->cell_common->cell_cfg.meas_cfg.meas_cells; + const auto& meas_list_cfg = pcell->cell_common->cell_cfg.meas_cfg.meas_cells; for (const meas_result_eutra_s& e : eutra_report_list) { - auto same_pci = [&e](const meas_cell_cfg_t& c) { return c.pci == e.pci; }; - auto meas_it = std::find_if(meas_list_cfg.begin(), meas_list_cfg.end(), same_pci); + auto same_pci = [&e](const meas_cell_cfg_t& c) { return c.pci == e.pci; }; + auto meas_it = std::find_if(meas_list_cfg.begin(), meas_list_cfg.end(), same_pci); const enb_cell_common* c = rrc_enb->cell_common_list->get_pci(e.pci); if (meas_it != meas_list_cfg.end()) { meas_ev.target_eci = meas_it->eci; } else if (c != nullptr) { meas_ev.target_eci = (rrc_enb->cfg.enb_id << 8u) + c->cell_cfg.cell_id; } else { - rrc_log->warning("The PCI=%d inside the MeasReport is not recognized.\n", e.pci); + logger.warning("The PCI=%d inside the MeasReport is not recognized.", e.pci); continue; } @@ -268,6 +269,11 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg) break; } } + + event_logger::get().log_measurement_report( + rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + asn1::octstring_to_string(pdu->msg, pdu->N_bytes), + rrc_ue->rnti); } /** @@ -281,14 +287,14 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, bool fwd_direct_path_available) { if (fwd_direct_path_available) { - Error("Direct tunnels not supported supported\n"); + Error("Direct tunnels not supported supported"); return false; } srslte::plmn_id_t target_plmn = srslte::make_plmn_id_t(rrc_enb->cfg.sib1.cell_access_related_info.plmn_id_list[0].plmn_id); - const ue_cell_ded* src_cell_ded = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); - const enb_cell_common* src_cell_cfg = src_cell_ded->cell_common; + const ue_cell_ded* src_cell_ded = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); + const enb_cell_common* src_cell_cfg = src_cell_ded->cell_common; /*** Fill HO Preparation Info ***/ asn1::rrc::ho_prep_info_s hoprep; @@ -319,20 +325,20 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, uint8_t buffer[128]; asn1::bit_ref bref(&buffer[0], sizeof(buffer)); if (capitem.pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - rrc_log->error("Failed to pack UE EUTRA Capability\n"); + logger.error("Failed to pack UE EUTRA Capability"); } hoprep_r8.ue_radio_access_cap_info[0].ue_cap_rat_container.resize((uint32_t)bref.distance_bytes()); memcpy(&hoprep_r8.ue_radio_access_cap_info[0].ue_cap_rat_container[0], &buffer[0], bref.distance_bytes()); } - Debug("UE RA Category: %d\n", capitem.ue_category); + Debug("UE RA Category: %d", capitem.ue_category); } else { hoprep_r8.ue_radio_access_cap_info.resize(1); hoprep_r8.ue_radio_access_cap_info[0].rat_type = asn1::rrc::rat_type_e::eutra; - srslte::unique_byte_buffer_t buffer = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t buffer = srslte::make_byte_buffer(); asn1::bit_ref bref(buffer->msg, buffer->get_tailroom()); if (rrc_ue->eutra_capabilities.pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - rrc_log->error("Failed to pack UE EUTRA Capability\n"); + logger.error("Failed to pack UE EUTRA Capability"); return false; } hoprep_r8.ue_radio_access_cap_info[0].ue_cap_rat_container.resize(bref.distance_bytes()); @@ -368,17 +374,22 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, rrc_ue->ue_security_cfg.get_as_sec_cfg().k_rrc_int.data())); /*** pack HO Preparation Info into an RRC container buffer ***/ - srslte::unique_byte_buffer_t buffer = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t buffer = srslte::make_byte_buffer(); asn1::bit_ref bref(buffer->msg, buffer->get_tailroom()); if (hoprep.pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - Error("Failed to pack HO preparation msg\n"); + Error("Failed to pack HO preparation msg"); return false; } buffer->N_bytes = bref.distance_bytes(); - bool success = rrc_enb->s1ap->send_ho_required(rrc_ue->rnti, target_eci, target_plmn, std::move(buffer)); - Info("sent s1ap msg with HO Required\n"); - return success; + // Set list of E-RABs for DL forwarding + std::vector fwd_erabs; + fwd_erabs.reserve(rrc_ue->bearer_list.get_erabs().size()); + for (auto& erab_pair : rrc_ue->bearer_list.get_erabs()) { + fwd_erabs.push_back(erab_pair.first); + } + + return rrc_enb->s1ap->send_ho_required(rrc_ue->rnti, target_eci, target_plmn, fwd_erabs, std::move(buffer)); } /** @@ -389,10 +400,12 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, * @param is_success flag to whether an HandoverCommand or HandoverReject was received * @param container RRC container with HandoverCommand to send to UE */ -void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container) +void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success, + const asn1::s1ap::ho_cmd_s& msg, + srslte::unique_byte_buffer_t container) { if (not is_success) { - log_h->info("Received S1AP HandoverFailure. Aborting Handover...\n"); + logger.info("Received S1AP HandoverFailure. Aborting Handover..."); trigger(srslte::failure_ev{}); return; } @@ -401,20 +414,20 @@ void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success, srsl { asn1::cbit_ref bref(container->msg, container->N_bytes); if (rrchocmd.unpack(bref) != asn1::SRSASN_SUCCESS) { - get_log()->warning("Unpacking of RRC HOCommand was unsuccessful\n"); - get_log()->warning_hex(container->msg, container->N_bytes, "Received container:\n"); + get_logger().warning("Unpacking of RRC HOCommand was unsuccessful"); + get_logger().warning(container->msg, container->N_bytes, "Received container:"); trigger(ho_cancel_ev{}); return; } } if (rrchocmd.crit_exts.type().value != c1_or_crit_ext_opts::c1 or rrchocmd.crit_exts.c1().type().value != ho_cmd_s::crit_exts_c_::c1_c_::types_opts::ho_cmd_r8) { - get_log()->warning("Only handling r8 Handover Commands\n"); + get_logger().warning("Only handling r8 Handover Commands"); trigger(ho_cancel_ev{}); return; } - trigger(rrchocmd.crit_exts.c1().ho_cmd_r8()); + trigger(s1_source_ho_st::ho_cmd_msg{&msg, &rrchocmd.crit_exts.c1().ho_cmd_r8()}); } bool rrc::ue::rrc_mobility::start_s1_tenb_ho( @@ -438,7 +451,7 @@ bool rrc::ue::rrc_mobility::start_s1_tenb_ho( * @param target_cell */ void rrc::ue::rrc_mobility::fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s& msg, - const enb_cell_common& target_cell, + const enb_cell_common& target_cell, uint32_t src_dl_earfcn, uint32_t src_pci) { @@ -485,36 +498,6 @@ void rrc::ue::rrc_mobility::fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s true); } -/** - * TS 36.413, Section 8.4.6 - eNB Status Transfer - * Description: Send "eNBStatusTransfer" message from source eNB to MME - * - Pass bearers' DL/UL HFN and PDCP SN to be put inside a transparent container - */ -bool rrc::ue::rrc_mobility::start_enb_status_transfer() -{ - std::vector s1ap_bearers; - s1ap_bearers.reserve(rrc_ue->bearer_list.get_erabs().size()); - - for (const auto& erab_pair : rrc_ue->bearer_list.get_erabs()) { - s1ap_interface_rrc::bearer_status_info b = {}; - uint8_t lcid = erab_pair.second.id - 2u; - b.erab_id = erab_pair.second.id; - srslte::pdcp_lte_state_t pdcp_state = {}; - if (not rrc_enb->pdcp->get_bearer_state(rrc_ue->rnti, lcid, &pdcp_state)) { - Error("PDCP bearer lcid=%d for rnti=0x%x was not found\n", lcid, rrc_ue->rnti); - return false; - } - b.dl_hfn = pdcp_state.tx_hfn; - b.pdcp_dl_sn = pdcp_state.next_pdcp_tx_sn; - b.ul_hfn = pdcp_state.rx_hfn; - b.pdcp_ul_sn = pdcp_state.next_pdcp_rx_sn; - s1ap_bearers.push_back(b); - } - - Info("PDCP Bearer list sent to S1AP to initiate the eNB Status Transfer\n"); - return rrc_enb->s1ap->send_enb_status_transfer_proc(rrc_ue->rnti, s1ap_bearers); -} - /************************************* * rrc_mobility FSM methods *************************************/ @@ -543,78 +526,149 @@ bool rrc::ue::rrc_mobility::needs_intraenb_ho(idle_st& s, const ho_meas_report_e * s1_source_ho subFSM methods *************************************/ -void rrc::ue::rrc_mobility::s1_source_ho_st::wait_ho_req_ack_st::enter(s1_source_ho_st* f, const ho_meas_report_ev& ev) -{ - srslte::console("Starting S1 Handover of rnti=0x%x to cellid=0x%x.\n", f->parent_fsm()->rrc_ue->rnti, ev.target_eci); - f->get_log()->info( - "Starting S1 Handover of rnti=0x%x to cellid=0x%x.\n", f->parent_fsm()->rrc_ue->rnti, ev.target_eci); - f->report = ev; +rrc::ue::rrc_mobility::s1_source_ho_st::s1_source_ho_st(rrc_mobility* parent_) : + base_t(parent_), rrc_enb(parent_->rrc_enb), rrc_ue(parent_->rrc_ue), logger(parent_->logger) +{} - bool success = f->parent_fsm()->start_ho_preparation(f->report.target_eci, f->report.meas_obj->meas_obj_id, false); - if (not success) { - f->trigger(srslte::failure_ev{}); +/** + * TS 36.413, Section 8.4.6 - eNB Status Transfer + * @brief: Send "eNBStatusTransfer" message from source eNB to MME, and setup Forwarding GTPU tunnel + * - PDCP provides the bearers' DL/UL HFN and COUNT to be put inside a transparent container + * - The eNB sends eNBStatusTransfer to MME + * - A GTPU forwarding tunnel is opened to forward buffered PDCP PDUs and incoming GTPU PDUs + */ +bool rrc::ue::rrc_mobility::s1_source_ho_st::start_enb_status_transfer(const asn1::s1ap::ho_cmd_s& s1ap_ho_cmd) +{ + std::vector s1ap_bearers; + s1ap_bearers.reserve(rrc_ue->bearer_list.get_erabs().size()); + + for (const auto& erab_pair : rrc_ue->bearer_list.get_erabs()) { + s1ap_interface_rrc::bearer_status_info b = {}; + uint8_t lcid = erab_pair.second.id - 2u; + b.erab_id = erab_pair.second.id; + srslte::pdcp_lte_state_t pdcp_state = {}; + if (not rrc_enb->pdcp->get_bearer_state(rrc_ue->rnti, lcid, &pdcp_state)) { + Error("PDCP bearer lcid=%d for rnti=0x%x was not found", lcid, rrc_ue->rnti); + return false; + } + b.dl_hfn = pdcp_state.tx_hfn; + b.pdcp_dl_sn = pdcp_state.next_pdcp_tx_sn; + b.ul_hfn = pdcp_state.rx_hfn; + b.pdcp_ul_sn = pdcp_state.next_pdcp_rx_sn; + s1ap_bearers.push_back(b); + } + + Info("PDCP Bearer list sent to S1AP to initiate the eNB Status Transfer"); + if (not rrc_enb->s1ap->send_enb_status_transfer_proc(rrc_ue->rnti, s1ap_bearers)) { + return false; + } + + // Setup GTPU forwarding tunnel + if (s1ap_ho_cmd.protocol_ies.erab_subjectto_data_forwarding_list_present) { + const auto& fwd_erab_list = s1ap_ho_cmd.protocol_ies.erab_subjectto_data_forwarding_list.value; + const auto& erab_list = rrc_ue->bearer_list.get_erabs(); + for (const auto& e : fwd_erab_list) { + const auto& fwd_erab = e.value.erab_data_forwarding_item(); + auto it = erab_list.find(fwd_erab.erab_id); + if (it == erab_list.end()) { + Warning("E-RAB id=%d subject to forwarding not found\n", fwd_erab.erab_id); + continue; + } + const bearer_cfg_handler::erab_t& erab = it->second; + if (fwd_erab.dl_g_tp_teid_present and fwd_erab.dl_transport_layer_address_present) { + gtpu_interface_rrc::bearer_props props; + props.forward_from_teidin_present = true; + props.forward_from_teidin = erab.teid_in; + rrc_ue->bearer_list.add_gtpu_bearer(fwd_erab.erab_id, + fwd_erab.dl_g_tp_teid.to_number(), + fwd_erab.dl_transport_layer_address.to_number(), + &props); + } + } + } + + return true; +} + +void rrc::ue::rrc_mobility::s1_source_ho_st::enter(rrc_mobility* f, const ho_meas_report_ev& ev) +{ + srslte::console("Starting S1 Handover of rnti=0x%x to cellid=0x%x.\n", rrc_ue->rnti, ev.target_eci); + logger.info("Starting S1 Handover of rnti=0x%x to cellid=0x%x.", rrc_ue->rnti, ev.target_eci); + report = ev; + + if (not parent_fsm()->start_ho_preparation(report.target_eci, report.meas_obj->meas_obj_id, false)) { + trigger(srslte::failure_ev{}); } } -void rrc::ue::rrc_mobility::s1_source_ho_st::send_ho_cmd(wait_ho_req_ack_st& s, const ho_cmd_r8_ies_s& ho_cmd) +/** + * TS 36.413, Section 8.4.2 - Handover Resource Allocation + * @brief: Send "eNBStatusTransfer" message from source eNB to MME, and setup Forwarding GTPU tunnel + * - PDCP provides the bearers' DL/UL HFN and COUNT to be put inside a transparent container + * - The eNB sends eNBStatusTransfer to MME + * - A GTPU forwarding tunnel is opened to forward buffered PDCP PDUs and incoming GTPU PDUs + */ +void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cmd(wait_ho_cmd& s, const ho_cmd_msg& ho_cmd) { /* unpack DL-DCCH message containing the RRCRonnectionReconf (with MobilityInfo) to be sent to the UE */ asn1::rrc::dl_dcch_msg_s dl_dcch_msg; { - asn1::cbit_ref bref(&ho_cmd.ho_cmd_msg[0], ho_cmd.ho_cmd_msg.size()); + asn1::cbit_ref bref(&ho_cmd.ho_cmd->ho_cmd_msg[0], ho_cmd.ho_cmd->ho_cmd_msg.size()); if (dl_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS) { - get_log()->warning("Unpacking of RRC DL-DCCH message with HO Command was unsuccessful.\n"); + Warning("Unpacking of RRC DL-DCCH message with HO Command was unsuccessful."); trigger(ho_cancel_ev{}); return; } } if (dl_dcch_msg.msg.type().value != dl_dcch_msg_type_c::types_opts::c1 or dl_dcch_msg.msg.c1().type().value != dl_dcch_msg_type_c::c1_c_::types_opts::rrc_conn_recfg) { - get_log()->warning("HandoverCommand is expected to contain an RRC Connection Reconf message inside\n"); + Warning("HandoverCommand is expected to contain an RRC Connection Reconf message inside"); trigger(ho_cancel_ev{}); return; } asn1::rrc::rrc_conn_recfg_s& reconf = dl_dcch_msg.msg.c1().rrc_conn_recfg(); if (not reconf.crit_exts.c1().rrc_conn_recfg_r8().mob_ctrl_info_present) { - get_log()->warning("HandoverCommand is expected to have mobility control subfield\n"); + Warning("HandoverCommand is expected to have mobility control subfield"); trigger(ho_cancel_ev{}); return; } - // Disable DRBs - parent_fsm()->rrc_ue->mac_ctrl.set_drb_activation(false); - parent_fsm()->rrc_ue->mac_ctrl.update_mac(mac_controller::proc_stage_t::other); + /* Enter Handover Execution */ + // TODO: Do anything with MeasCfg info within the Msg (e.g. update ue_var_meas)? - /* Send HO Command to UE */ - if (not parent_fsm()->rrc_ue->send_dl_dcch(&dl_dcch_msg)) { + // Disable DRBs in the MAC, while Reconfiguration is taking place. + rrc_ue->mac_ctrl.set_drb_activation(false); + rrc_ue->mac_ctrl.update_mac(mac_controller::proc_stage_t::other); + + // Send HO Command to UE + if (not rrc_ue->send_dl_dcch(&dl_dcch_msg)) { trigger(ho_cancel_ev{}); return; } + + /* Start S1AP eNBStatusTransfer Procedure */ + if (not start_enb_status_transfer(*ho_cmd.s1ap_ho_cmd)) { + trigger(ho_cancel_ev{}); + } } //! Called in Source ENB during S1-Handover when there was a Reestablishment Request void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cancel(const ho_cancel_ev& ev) { - parent_fsm()->rrc_enb->s1ap->send_ho_cancel(parent_fsm()->rrc_ue->rnti); -} - -void rrc::ue::rrc_mobility::s1_source_ho_st::status_transfer_st::enter(s1_source_ho_st* f) -{ - f->get_log()->info("HandoverCommand of rnti=0x%x handled successfully.\n", f->parent_fsm()->rrc_ue->rnti); - - // TODO: Do anything with MeasCfg info within the Msg (e.g. update ue_var_meas)? - - /* Start S1AP eNBStatusTransfer Procedure */ - if (not f->parent_fsm()->start_enb_status_transfer()) { - f->trigger(srslte::failure_ev{}); - } + rrc_enb->s1ap->send_ho_cancel(rrc_ue->rnti); } /************************************* * s1_target_ho state methods *************************************/ -void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req) +/** + * @brief handle S1AP "HO Requested" message from the MME + * - MME --> TeNB + * @param s initial state + * @param ho_req event with received message + */ +void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& ho_req) { const auto& rrc_container = ho_req.transparent_container->rrc_container; @@ -622,13 +676,13 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req asn1::cbit_ref bref{rrc_container.data(), rrc_container.size()}; asn1::rrc::ho_prep_info_s hoprep; if (hoprep.unpack(bref) != asn1::SRSASN_SUCCESS) { - rrc_enb->rrc_log->error("Failed to decode HandoverPreparationinformation in S1AP SourceENBToTargetENBContainer\n"); + rrc_enb->logger.error("Failed to decode HandoverPreparationinformation in S1AP SourceENBToTargetENBContainer"); trigger(srslte::failure_ev{}); return; } if (hoprep.crit_exts.type().value != c1_or_crit_ext_opts::c1 or hoprep.crit_exts.c1().type().value != ho_prep_info_s::crit_exts_c_::c1_c_::types_opts::ho_prep_info_r8) { - rrc_enb->rrc_log->error("Only release 8 supported\n"); + rrc_enb->logger.error("Only release 8 supported"); trigger(srslte::failure_ev{}); return; } @@ -641,7 +695,7 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req } /* Prepare Handover Request Acknowledgment - Handover Command */ - dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg_s dl_dcch_msg; const ue_cell_ded* target_cell = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); // Fill fields common to all types of handover (e.g. new CQI/SR configuration, mobControlInfo) @@ -663,10 +717,10 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req ho_req.ho_req_msg->protocol_ies.security_context.value.next_hop_chaining_count; /* Prepare Handover Command to be sent via S1AP */ - srslte::unique_byte_buffer_t ho_cmd_pdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t ho_cmd_pdu = srslte::make_byte_buffer(); asn1::bit_ref bref2{ho_cmd_pdu->msg, ho_cmd_pdu->get_tailroom()}; if (dl_dcch_msg.pack(bref2) != asn1::SRSASN_SUCCESS) { - rrc_log->error("Failed to pack HandoverCommand\n"); + logger.error("Failed to pack HandoverCommand"); trigger(srslte::failure_ev{}); return; } @@ -679,7 +733,7 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req memcpy(ho_cmd_r8.ho_cmd_msg.data(), ho_cmd_pdu->msg, bref2.distance_bytes()); bref2 = {ho_cmd_pdu->msg, ho_cmd_pdu->get_tailroom()}; if (ho_cmd.pack(bref2) != asn1::SRSASN_SUCCESS) { - rrc_log->error("Failed to pack HandoverCommand\n"); + logger.error("Failed to pack HandoverCommand"); trigger(srslte::failure_ev{}); return; } @@ -694,13 +748,49 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req // Apply PHY updates rrc_ue->apply_reconf_phy_config(recfg_r8, true); - /* send S1AP HandoverRequestAcknowledge */ - std::vector > admitted_erabs; + // Set admitted E-RABs + std::vector admitted_erabs; + auto& fwd_tunnels = get_state()->pending_tunnels; for (auto& erab : rrc_ue->bearer_list.get_erabs()) { admitted_erabs.emplace_back(); - srslte::uint32_to_uint8(erab.second.teid_in, admitted_erabs.back().data()); + asn1::s1ap::erab_admitted_item_s& admitted_erab = admitted_erabs.back(); + admitted_erab.erab_id = erab.second.id; + srslte::uint32_to_uint8(erab.second.teid_in, admitted_erab.gtp_teid.data()); + + // Establish GTPU Forwarding Paths + if (ho_req.transparent_container->erab_info_list_present) { + auto& lst = ho_req.transparent_container->erab_info_list; + auto it = std::find_if( + lst.begin(), + lst.end(), + [&erab](const asn1::s1ap::protocol_ie_single_container_s& fwd_erab) { + return fwd_erab.value.erab_info_list_item().erab_id == erab.second.id; + }); + if (it == lst.end()) { + continue; + } + auto& fwd_erab = it->value.erab_info_list_item(); + + if (fwd_erab.dl_forwarding_present and + fwd_erab.dl_forwarding.value == asn1::s1ap::dl_forwarding_opts::dl_forwarding_proposed) { + admitted_erab.dl_g_tp_teid_present = true; + gtpu_interface_rrc::bearer_props props; + props.flush_before_teidin_present = true; + props.flush_before_teidin = erab.second.teid_in; + uint32_t dl_teid_in = rrc_ue->bearer_list.add_gtpu_bearer( + erab.second.id, erab.second.teid_out, erab.second.address.to_number(), &props); + fwd_tunnels.push_back(dl_teid_in); + srslte::uint32_to_uint8(dl_teid_in, admitted_erabs.back().dl_g_tp_teid.data()); + } + } } - if (not rrc_enb->s1ap->send_ho_req_ack(*ho_req.ho_req_msg, rrc_ue->rnti, std::move(ho_cmd_pdu), admitted_erabs)) { + + // send S1AP HandoverRequestAcknowledge + if (not rrc_enb->s1ap->send_ho_req_ack(*ho_req.ho_req_msg, + rrc_ue->rnti, + rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + std::move(ho_cmd_pdu), + admitted_erabs)) { trigger(srslte::failure_ev{}); return; } @@ -710,16 +800,16 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho const asn1::s1ap::ho_request_s& ho_req_msg) { const ue_cell_ded* target_cell = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); - const cell_cfg_t& target_cell_cfg = target_cell->cell_common->cell_cfg; + const cell_cfg_t& target_cell_cfg = target_cell->cell_common->cell_cfg; // Establish ERABs/DRBs for (const auto& erab_item : ho_req_msg.protocol_ies.erab_to_be_setup_list_ho_req.value) { auto& erab = erab_item.value.erab_to_be_setup_item_ho_req(); if (erab.ext) { - get_log()->warning("Not handling E-RABToBeSetupList extensions\n"); + get_logger().warning("Not handling E-RABToBeSetupList extensions"); } if (erab.transport_layer_address.length() > 32) { - get_log()->error("IPv6 addresses not currently supported\n"); + get_logger().error("IPv6 addresses not currently supported"); trigger(srslte::failure_ev{}); return false; } @@ -727,14 +817,15 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho if (not erab.ie_exts_present or not erab.ie_exts.data_forwarding_not_possible_present or erab.ie_exts.data_forwarding_not_possible.ext.value != asn1::s1ap::data_forwarding_not_possible_opts::data_forwarding_not_possible) { - get_log()->warning("Data Forwarding of E-RABs not supported\n"); + get_logger().warning("Data Forwarding of E-RABs not supported"); } + // Create E-RAB and associated main GTPU tunnel uint32_t teid_out; srslte::uint8_to_uint32(erab.gtp_teid.data(), &teid_out); rrc_ue->bearer_list.add_erab( erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, nullptr); - rrc_ue->bearer_list.add_gtpu_bearer(rrc_enb->gtpu, erab.erab_id); + rrc_ue->bearer_list.add_gtpu_bearer(erab.erab_id); } // Regenerate AS Keys @@ -749,13 +840,13 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho if (cap.rat_type.value == rat_type_opts::eutra) { asn1::cbit_ref bref(cap.ue_cap_rat_container.data(), cap.ue_cap_rat_container.size()); if (rrc_ue->eutra_capabilities.unpack(bref) != asn1::SRSASN_SUCCESS) { - rrc_log->warning("Failed to unpack UE EUTRA Capability\n"); + logger.warning("Failed to unpack UE EUTRA Capability"); continue; } - if (rrc_log->get_level() == srslte::LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { asn1::json_writer js{}; rrc_ue->eutra_capabilities.to_json(js); - rrc_log->debug_long("New rnti=0x%x EUTRA capabilities: %s\n", rrc_ue->rnti, js.to_string().c_str()); + logger.debug("New rnti=0x%x EUTRA capabilities: %s", rrc_ue->rnti, js.to_string().c_str()); } rrc_ue->ue_capabilities = srslte::make_rrc_ue_capabilities(rrc_ue->eutra_capabilities); rrc_ue->eutra_capabilities_unpacked = true; @@ -780,9 +871,9 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho void rrc::ue::rrc_mobility::handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev) { ue_cell_ded* target_cell = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); - rrc_log->info("User rnti=0x%x successfully handovered to cell_id=0x%x\n", - rrc_ue->rnti, - target_cell->cell_common->cell_cfg.cell_id); + logger.info("User rnti=0x%x successfully handovered to cell_id=0x%x", + rrc_ue->rnti, + target_cell->cell_common->cell_cfg.cell_id); uint64_t target_eci = (rrc_enb->cfg.enb_id << 8u) + target_cell->cell_common->cell_cfg.cell_id; rrc_enb->s1ap->send_ho_notify(rrc_ue->rnti, target_eci); @@ -798,7 +889,7 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta const auto& erab_item = erab.value.bearers_subject_to_status_transfer_item(); auto erab_it = rrc_ue->bearer_list.get_erabs().find(erab_item.erab_id); if (erab_it == rrc_ue->bearer_list.get_erabs().end()) { - rrc_log->warning("The E-RAB Id=%d is not recognized\n", erab_item.erab_id); + logger.warning("The E-RAB Id=%d is not recognized", erab_item.erab_id); continue; } const auto& drbs = rrc_ue->bearer_list.get_established_drbs(); @@ -806,7 +897,7 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta auto drb_it = std::find_if(drbs.begin(), drbs.end(), [drbid](const drb_to_add_mod_s& drb) { return drb.drb_id == drbid; }); if (drb_it == drbs.end()) { - rrc_log->warning("The DRB id=%d does not exist\n", erab_item.erab_id - 4); + logger.warning("The DRB id=%d does not exist", erab_item.erab_id - 4); } srslte::pdcp_lte_state_t drb_state{}; @@ -814,14 +905,21 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta drb_state.next_pdcp_tx_sn = erab_item.dl_coun_tvalue.pdcp_sn; drb_state.rx_hfn = erab_item.ul_coun_tvalue.hfn; drb_state.next_pdcp_rx_sn = erab_item.ul_coun_tvalue.pdcp_sn; - drb_state.last_submitted_pdcp_rx_sn = erab_item.ul_coun_tvalue.pdcp_sn; - rrc_log->info("Setting lcid=%d PDCP state to {Tx SN: %d, Rx SN: %d}\n", - drb_it->lc_ch_id, - drb_state.next_pdcp_tx_sn, - drb_state.next_pdcp_rx_sn); + uint8_t sn_len = srslte::get_pdcp_drb_sn_len(drb_it->pdcp_cfg); + uint32_t maximum_pdcp_sn = (1u << sn_len) - 1u; + drb_state.last_submitted_pdcp_rx_sn = std::max(erab_item.ul_coun_tvalue.pdcp_sn - 1u, maximum_pdcp_sn); + logger.info("Setting lcid=%d PDCP state to {Tx SN: %d, Rx SN: %d}", + drb_it->lc_ch_id, + drb_state.next_pdcp_tx_sn, + drb_state.next_pdcp_rx_sn); rrc_enb->pdcp->set_bearer_state(rrc_ue->rnti, drb_it->lc_ch_id, drb_state); } + // Enable forwarding of GTPU SDUs to PDCP + for (uint32_t teid : s.pending_tunnels) { + rrc_enb->gtpu->set_tunnel_status(teid, true); + } + // Check if there is any pending Reconfiguration Complete. If there is, self-trigger if (pending_recfg_complete.crit_exts.type().value != rrc_conn_recfg_complete_s::crit_exts_c_::types_opts::nulltype) { trigger(pending_recfg_complete); @@ -844,12 +942,12 @@ void rrc::ue::rrc_mobility::intraenb_ho_st::enter(rrc_mobility* f, const ho_meas target_cell = f->rrc_enb->cell_common_list->get_cell_id(cell_id); source_cell = f->rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common; if (target_cell == nullptr) { - f->log_h->error("The target cell_id=0x%x was not found in the list of eNB cells\n", cell_id); + f->logger.error("The target cell_id=0x%x was not found in the list of eNB cells", cell_id); f->trigger(srslte::failure_ev{}); return; } - f->log_h->info("Starting intraeNB Handover of rnti=0x%x to 0x%x.\n", f->rrc_ue->rnti, meas_report.target_eci); + f->logger.info("Starting intraeNB Handover of rnti=0x%x to 0x%x.", f->rrc_ue->rnti, meas_report.target_eci); if (target_cell == nullptr) { f->trigger(srslte::failure_ev{}); @@ -884,14 +982,14 @@ void rrc::ue::rrc_mobility::intraenb_ho_st::enter(rrc_mobility* f, const ho_meas void rrc::ue::rrc_mobility::handle_crnti_ce(intraenb_ho_st& s, const user_crnti_upd_ev& ev) { - rrc_log->info("UE performing handover updated its temp-crnti=0x%x to rnti=0x%x\n", ev.temp_crnti, ev.crnti); + logger.info("UE performing handover updated its temp-crnti=0x%x to rnti=0x%x", ev.temp_crnti, ev.crnti); bool is_first_crnti_ce = s.last_temp_crnti == SRSLTE_INVALID_RNTI; s.last_temp_crnti = ev.temp_crnti; if (is_first_crnti_ce) { // Need to reset SNs of bearers. - rrc_enb->pdcp->reestablish(rrc_ue->rnti); rrc_enb->rlc->reestablish(rrc_ue->rnti); + rrc_enb->pdcp->reestablish(rrc_ue->rnti); // Change PCell in MAC/Scheduler rrc_ue->mac_ctrl.handle_crnti_ce(ev.temp_crnti); @@ -902,15 +1000,17 @@ void rrc::ue::rrc_mobility::handle_crnti_ce(intraenb_ho_st& s, const user_crnti_ rrc_ue->ue_security_cfg.regenerate_keys_handover(s.target_cell->cell_cfg.pci, s.target_cell->cell_cfg.dl_earfcn); rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_ue_cfg.rr_cfg); rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_ue_cfg.rr_cfg); + + // Send PDCP status report if necessary + rrc_enb->pdcp->send_status_report(rrc_ue->rnti); } else { - rrc_log->info("Received duplicate C-RNTI CE during rnti=0x%x handover.\n", rrc_ue->rnti); + logger.info("Received duplicate C-RNTI CE during rnti=0x%x handover.", rrc_ue->rnti); } } void rrc::ue::rrc_mobility::handle_recfg_complete(intraenb_ho_st& s, const recfg_complete_ev& ev) { - rrc_log->info( - "User rnti=0x%x successfully handovered to cell_id=0x%x\n", rrc_ue->rnti, s.target_cell->cell_cfg.cell_id); + logger.info("User rnti=0x%x successfully handovered to cell_id=0x%x", rrc_ue->rnti, s.target_cell->cell_cfg.cell_id); } } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 3bc8168f8..cf3b3f93b 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -28,11 +28,7 @@ using namespace asn1::rrc_nr; namespace srsenb { -rrc_nr::rrc_nr(srslte::timer_handler* timers_) : - m_log("RRC"), - pool(srslte::byte_buffer_pool::get_instance()), - timers(timers_) -{} +rrc_nr::rrc_nr(srslte::timer_handler* timers_) : m_log("RRC"), timers(timers_) {} void rrc_nr::init(const rrc_nr_cfg_t& cfg_, phy_interface_stack_nr* phy_, @@ -73,7 +69,8 @@ void rrc_nr::init(const rrc_nr_cfg_t& cfg_, srslte::SECURITY_DIRECTION_UPLINK, srslte::PDCP_SN_LEN_18, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t::infinity}; + srslte::pdcp_discard_timer_t::infinity, + false}; pdcp->add_bearer(cfg.coreless.rnti, cfg.coreless.drb_lcid, pdcp_cnfg); m_log->info("Started\n"); @@ -217,7 +214,7 @@ uint32_t rrc_nr::generate_sibs() mib_s& mib = mib_msg.msg.set_mib(); mib = cfg.mib; { - srslte::unique_byte_buffer_t mib_buf = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t mib_buf = srslte::make_byte_buffer(); asn1::bit_ref bref(mib_buf->msg, mib_buf->get_tailroom()); mib_msg.pack(bref); mib_buf->N_bytes = bref.distance_bytes(); @@ -251,7 +248,7 @@ uint32_t rrc_nr::generate_sibs() // Pack payload for all messages for (uint32_t msg_index = 0; msg_index < nof_messages + 1; msg_index++) { - srslte::unique_byte_buffer_t sib = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t sib = srslte::make_byte_buffer(); asn1::bit_ref bref(sib->msg, sib->get_tailroom()); msg[msg_index].pack(bref); sib->N_bytes = bref.distance_bytes(); @@ -344,8 +341,6 @@ void rrc_nr::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_ *******************************************************************************/ rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_) { - pool = srslte::byte_buffer_pool::get_instance(); - // setup periodic RRCSetup send rrc_setup_periodic_timer = parent->timers->get_unique_timer(); rrc_setup_periodic_timer.set(5000, [this](uint32_t tid) { @@ -381,7 +376,7 @@ void rrc_nr::ue::send_connection_setup() void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) { // Allocate a new PDU buffer, pack the message and send to PDCP - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu == nullptr) { parent->m_log->error("Allocating pdu\n"); } @@ -389,7 +384,7 @@ void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) if (dl_ccch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { parent->m_log->error("Failed to pack DL-CCCH message. Discarding msg.\n"); } - pdu->N_bytes = 1u + (uint32_t)bref.distance_bytes(pdu->msg); + pdu->N_bytes = bref.distance_bytes(); char buf[32] = {}; sprintf(buf, "SRB0 - rnti=0x%x", rnti); @@ -397,4 +392,4 @@ void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) parent->rlc->write_sdu(rnti, RB_ID_SRB0, std::move(pdu)); } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 0c71dbed0..0a3099489 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -27,6 +27,9 @@ #include "srslte/asn1/rrc_utils.h" #include "srslte/common/enb_events.h" #include "srslte/common/int_helpers.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" +#include "srslte/interfaces/enb_s1ap_interfaces.h" using namespace asn1::rrc; @@ -42,10 +45,9 @@ namespace srsenb { rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sched_ue_cfg) : parent(outer_rrc), rnti(rnti_), - pool(srslte::byte_buffer_pool::get_instance()), phy_rrc_dedicated_list(sched_ue_cfg.supported_cc_list.size()), ue_cell_list(parent->cfg, *outer_rrc->cell_res_list, *outer_rrc->cell_common_list), - bearer_list(rnti_, parent->cfg), + bearer_list(rnti_, parent->cfg, outer_rrc->gtpu), ue_security_cfg(parent->cfg), mac_ctrl(rnti, ue_cell_list, bearer_list, parent->cfg, parent->mac, *parent->cell_common_list, sched_ue_cfg) {} @@ -103,20 +105,21 @@ void rrc::ue::set_activity() // re-start activity timer with current timeout value activity_timer.run(); - if (parent && parent->rrc_log) { - parent->rrc_log->debug("Activity registered for rnti=0x%x (timeout_value=%dms)\n", rnti, activity_timer.duration()); + if (parent) { + parent->logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration()); } } void rrc::ue::activity_timer_expired() { if (parent) { - if (parent->rrc_log) { - parent->rrc_log->info("Activity timer for rnti=0x%x expired after %d ms\n", rnti, activity_timer.time_elapsed()); - } + parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); if (parent->s1ap->user_exists(rnti)) { parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::user_inactivity); + event_logger::get().log_rrc_disconnect(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + static_cast(rrc_idle_transition_cause::timeout), + rnti); } else { if (rnti != SRSLTE_MRNTI) { parent->rem_user_thread(rnti); @@ -143,12 +146,12 @@ void rrc::ue::set_activity_timeout(const activity_timeout_type_t type) deadline_ms = parent->cfg.inactivity_timeout_ms % 1000; break; default: - parent->rrc_log->error("Unknown timeout type %d", type); + parent->logger.error("Unknown timeout type %d", type); } uint32_t deadline = deadline_s * 1e3 + deadline_ms; activity_timer.set(deadline, [this](uint32_t tid) { activity_timer_expired(); }); - parent->rrc_log->debug("Setting timer for %s for rnti=0x%x to %dms\n", to_string(type).c_str(), rnti, deadline); + parent->logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline); set_activity(); } @@ -171,15 +174,15 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (ul_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or ul_dcch_msg.msg.type().value != ul_dcch_msg_type_c::types_opts::c1) { - parent->rrc_log->error("Failed to unpack UL-DCCH message\n"); + parent->logger.error("Failed to unpack UL-DCCH message"); return; } parent->log_rrc_message( srsenb::to_string((rb_id_t)lcid), Rx, pdu.get(), ul_dcch_msg, ul_dcch_msg.msg.c1().type().to_string()); - // reuse PDU - pdu->clear(); // TODO: name collision with byte_buffer reset + srslte::unique_byte_buffer_t original_pdu = std::move(pdu); + pdu = srslte::make_byte_buffer(); transaction_id = 0; @@ -233,16 +236,16 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) break; case ul_dcch_msg_type_c::c1_c_::types::meas_report: if (mobility_handler != nullptr) { - mobility_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report()); + mobility_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report(), std::move(original_pdu)); } else { - parent->rrc_log->warning("Received MeasReport but no mobility configuration is available\n"); + parent->logger.warning("Received MeasReport but no mobility configuration is available"); } break; case ul_dcch_msg_type_c::c1_c_::types::ue_info_resp_r9: - handle_ue_info_resp(ul_dcch_msg.msg.c1().ue_info_resp_r9()); + handle_ue_info_resp(ul_dcch_msg.msg.c1().ue_info_resp_r9(), std::move(original_pdu)); break; default: - parent->rrc_log->error("Msg: %s not supported\n", ul_dcch_msg.msg.c1().type().to_string().c_str()); + parent->logger.error("Msg: %s not supported", ul_dcch_msg.msg.c1().type().to_string().c_str()); break; } } @@ -259,7 +262,11 @@ std::string rrc::ue::to_string(const activity_timeout_type_t& type) void rrc::ue::handle_rrc_con_req(rrc_conn_request_s* msg) { if (not parent->s1ap->is_mme_connected()) { - parent->rrc_log->error("MME isn't connected. Sending Connection Reject\n"); + parent->logger.error("MME isn't connected. Sending Connection Reject"); + event_logger::get().log_rrc_connected(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + asn1::octstring_to_string(last_ul_msg->msg, last_ul_msg->N_bytes), + static_cast(conn_request_result_t::error_mme_not_connected), + rnti); send_connection_reject(); return; } @@ -312,7 +319,7 @@ void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srsl // Inform PHY about the configuration completion parent->phy->complete_config(rnti); - parent->rrc_log->info("RRCConnectionSetupComplete transaction ID: %d\n", msg->rrc_transaction_id); + parent->logger.info("RRCConnectionSetupComplete transaction ID: %d", msg->rrc_transaction_id); rrc_conn_setup_complete_r8_ies_s* msg_r8 = &msg->crit_exts.c1().rrc_conn_setup_complete_r8(); // TODO: msg->selected_plmn_id - used to select PLMN from SIB1 list @@ -326,15 +333,20 @@ void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srsl asn1::s1ap::rrc_establishment_cause_e s1ap_cause; s1ap_cause.value = (asn1::s1ap::rrc_establishment_cause_opts::options)establishment_cause.value; + + uint32_t enb_cc_idx = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx; if (has_tmsi) { - parent->s1ap->initial_ue(rnti, s1ap_cause, std::move(pdu), m_tmsi, mmec); + parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu), m_tmsi, mmec); } else { - parent->s1ap->initial_ue(rnti, s1ap_cause, std::move(pdu)); + parent->s1ap->initial_ue(rnti, enb_cc_idx, s1ap_cause, std::move(pdu)); } state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; // Log event. - event_logger::get().log_rrc_connected(static_cast(s1ap_cause.value)); + event_logger::get().log_rrc_connected(enb_cc_idx, + asn1::octstring_to_string(last_ul_msg->msg, last_ul_msg->N_bytes), + static_cast(conn_request_result_t::success), + rnti); // 2> if the UE has radio link failure or handover failure information available if (msg->crit_exts.type().value == c1_or_crit_ext_opts::c1 and @@ -362,15 +374,19 @@ void rrc::ue::send_connection_reject() void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) { if (not parent->s1ap->is_mme_connected()) { - parent->rrc_log->error("MME isn't connected. Sending Connection Reject\n"); + parent->logger.error("MME isn't connected. Sending Connection Reject"); + event_logger::get().log_rrc_connected(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + asn1::octstring_to_string(last_ul_msg->msg, last_ul_msg->N_bytes), + static_cast(conn_request_result_t::error_mme_not_connected), + rnti); send_connection_reject(); return; } - parent->rrc_log->debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s\n", - (uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.c_rnti.to_number(), - msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci, - (uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.short_mac_i.to_number(), - msg->crit_exts.rrc_conn_reest_request_r8().reest_cause.to_string().c_str()); + parent->logger.debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s", + (uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.c_rnti.to_number(), + msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci, + (uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.short_mac_i.to_number(), + msg->crit_exts.rrc_conn_reest_request_r8().reest_cause.to_string().c_str()); if (is_idle()) { uint16_t old_rnti = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.c_rnti.to_number(); uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci; @@ -379,8 +395,8 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) // Reject unrecognized rntis, and PCIs that do not belong to eNB if (ue_it != parent->users.end() and old_cell != nullptr and ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) != nullptr) { - parent->rrc_log->info("ConnectionReestablishmentRequest for rnti=0x%x. Sending Connection Reestablishment\n", - old_rnti); + parent->logger.info("ConnectionReestablishmentRequest for rnti=0x%x. Sending Connection Reestablishment", + old_rnti); // Cancel Handover in Target eNB if on-going parent->users.at(old_rnti)->mobility_handler->trigger(rrc_mobility::ho_cancel_ev{}); @@ -399,35 +415,39 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) old_reest_pdcp_state[lcid] = {}; parent->pdcp->get_bearer_state(old_rnti, lcid, &old_reest_pdcp_state[lcid]); - parent->rrc_log->debug("Getting PDCP state for E-RAB with LCID %d\n", lcid); - parent->rrc_log->debug("Got PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, " - "LAST_SUBMITTED_PDCP_RX_SN %d\n", - old_reest_pdcp_state[lcid].tx_hfn, - old_reest_pdcp_state[lcid].next_pdcp_tx_sn, - old_reest_pdcp_state[lcid].rx_hfn, - old_reest_pdcp_state[lcid].next_pdcp_rx_sn, - old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); + parent->logger.debug("Getting PDCP state for E-RAB with LCID %d", lcid); + parent->logger.debug("Got PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, " + "LAST_SUBMITTED_PDCP_RX_SN %d", + old_reest_pdcp_state[lcid].tx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_tx_sn, + old_reest_pdcp_state[lcid].rx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_rx_sn, + old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); } // Make sure UE capabilities are copied over to new RNTI eutra_capabilities = parent->users.at(old_rnti)->eutra_capabilities; eutra_capabilities_unpacked = parent->users.at(old_rnti)->eutra_capabilities_unpacked; ue_capabilities = parent->users.at(old_rnti)->ue_capabilities; - if (parent->rrc_log->get_level() == srslte::LOG_LEVEL_DEBUG) { + if (parent->logger.debug.enabled()) { asn1::json_writer js{}; eutra_capabilities.to_json(js); - parent->rrc_log->debug_long("rnti=0x%x EUTRA capabilities: %s\n", rnti, js.to_string().c_str()); + parent->logger.debug("rnti=0x%x EUTRA capabilities: %s", rnti, js.to_string().c_str()); } old_reest_rnti = old_rnti; state = RRC_STATE_WAIT_FOR_CON_REEST_COMPLETE; set_activity_timeout(UE_INACTIVITY_TIMEOUT); } else { - parent->rrc_log->error("Received ConnectionReestablishment for rnti=0x%x without context\n", old_rnti); + parent->logger.error("Received ConnectionReestablishment for rnti=0x%x without context", old_rnti); + event_logger::get().log_rrc_connected(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + asn1::octstring_to_string(last_ul_msg->msg, last_ul_msg->N_bytes), + static_cast(conn_request_result_t::error_unknown_rnti), + rnti); send_connection_reest_rej(); } } else { - parent->rrc_log->error("Received ReestablishmentRequest from an rnti=0x%x not in IDLE\n", rnti); + parent->logger.error("Received ReestablishmentRequest from an rnti=0x%x not in IDLE", rnti); } } @@ -466,7 +486,7 @@ void rrc::ue::handle_rrc_con_reest_complete(rrc_conn_reest_complete_s* msg, srsl // Inform PHY about the configuration completion parent->phy->complete_config(rnti); - parent->rrc_log->info("RRCConnectionReestablishComplete transaction ID: %d\n", msg->rrc_transaction_id); + parent->logger.info("RRCConnectionReestablishComplete transaction ID: %d", msg->rrc_transaction_id); // TODO: msg->selected_plmn_id - used to select PLMN from SIB1 list // TODO: if(msg->registered_mme_present) - the indicated MME should be used from a pool @@ -494,6 +514,11 @@ void rrc::ue::handle_rrc_con_reest_complete(rrc_conn_reest_complete_s* msg, srsl state = RRC_STATE_REESTABLISHMENT_COMPLETE; + event_logger::get().log_rrc_connected(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + asn1::octstring_to_string(last_ul_msg->msg, last_ul_msg->N_bytes), + 0, + rnti); + // 2> if the UE has radio link failure or handover failure information available if (msg->crit_exts.type().value == rrc_conn_reest_complete_s::crit_exts_c_::types_opts::rrc_conn_reest_complete_r8) { const auto& complete_r8 = msg->crit_exts.rrc_conn_reest_complete_r8(); @@ -517,9 +542,11 @@ void rrc::ue::send_connection_reest_rej() /* * Connection Reconfiguration */ -void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, bool phy_cfg_updated) +void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, + bool phy_cfg_updated, + const asn1::unbounded_octstring* nas_pdu) { - parent->rrc_log->debug("RRC state %d\n", state); + parent->logger.debug("RRC state %d", state); update_scells(); @@ -549,13 +576,24 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, bool phy_ apply_reconf_phy_config(recfg_r8, true); // setup SRB2/DRBs in PDCP and RLC + apply_rlc_rb_updates(recfg_r8.rr_cfg_ded); apply_pdcp_srb_updates(recfg_r8.rr_cfg_ded); apply_pdcp_drb_updates(recfg_r8.rr_cfg_ded); - apply_rlc_rb_updates(recfg_r8.rr_cfg_ded); // UE MAC scheduler updates mac_ctrl.handle_con_reconf(recfg_r8, ue_capabilities); + // Fill in NAS PDU - Only for RRC Connection Reconfiguration during E-RAB Release Command + if (nas_pdu != nullptr and nas_pdu->size() > 0 and !recfg_r8.ded_info_nas_list_present) { + recfg_r8.ded_info_nas_list_present = true; + recfg_r8.ded_info_nas_list.resize(recfg_r8.rr_cfg_ded.drb_to_release_list.size()); + // Add NAS PDU + for (uint32_t idx = 0; idx < recfg_r8.rr_cfg_ded.drb_to_release_list.size(); idx++) { + recfg_r8.ded_info_nas_list[idx].resize(nas_pdu->size()); + memcpy(recfg_r8.ded_info_nas_list[idx].data(), nas_pdu->data(), nas_pdu->size()); + } + } + // Reuse same PDU if (pdu != nullptr) { pdu->clear(); @@ -573,9 +611,8 @@ void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte: parent->phy->complete_config(rnti); if (transaction_id != msg->rrc_transaction_id) { - parent->rrc_log->error("Expected RRCReconfigurationComplete with transaction ID: %d, got %d\n", - transaction_id, - msg->rrc_transaction_id); + parent->logger.error( + "Expected RRCReconfigurationComplete with transaction ID: %d, got %d", transaction_id, msg->rrc_transaction_id); return; } @@ -606,11 +643,12 @@ void rrc::ue::send_ue_info_req() send_dl_dcch(&msg); } -void rrc::ue::handle_ue_info_resp(const asn1::rrc::ue_info_resp_r9_s& msg) +void rrc::ue::handle_ue_info_resp(const asn1::rrc::ue_info_resp_r9_s& msg, srslte::unique_byte_buffer_t pdu) { auto& resp_r9 = msg.crit_exts.c1().ue_info_resp_r9(); if (resp_r9.rlf_report_r9_present) { - // TODO: Handle RLF-Report + std::string msg_str = asn1::octstring_to_string(pdu->msg, pdu->N_bytes); + event_logger::get().log_rlf(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, msg_str, rnti); } if (resp_r9.rach_report_r9_present) { // TODO: Handle RACH-Report @@ -638,14 +676,14 @@ void rrc::ue::send_security_mode_command() void rrc::ue::handle_security_mode_complete(security_mode_complete_s* msg) { - parent->rrc_log->info("SecurityModeComplete transaction ID: %d\n", msg->rrc_transaction_id); + parent->logger.info("SecurityModeComplete transaction ID: %d", msg->rrc_transaction_id); parent->pdcp->enable_encryption(rnti, RB_ID_SRB1); } void rrc::ue::handle_security_mode_failure(security_mode_fail_s* msg) { - parent->rrc_log->info("SecurityModeFailure transaction ID: %d\n", msg->rrc_transaction_id); + parent->logger.info("SecurityModeFailure transaction ID: %d", msg->rrc_transaction_id); } /* @@ -667,38 +705,47 @@ void rrc::ue::send_ue_cap_enquiry() bool rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) { - parent->rrc_log->info("UECapabilityInformation transaction ID: %d\n", msg->rrc_transaction_id); + parent->logger.info("UECapabilityInformation transaction ID: %d", msg->rrc_transaction_id); ue_cap_info_r8_ies_s* msg_r8 = &msg->crit_exts.c1().ue_cap_info_r8(); for (uint32_t i = 0; i < msg_r8->ue_cap_rat_container_list.size(); i++) { if (msg_r8->ue_cap_rat_container_list[i].rat_type != rat_type_e::eutra) { - parent->rrc_log->warning("Not handling UE capability information for RAT type %s\n", - msg_r8->ue_cap_rat_container_list[i].rat_type.to_string().c_str()); - } else { - asn1::cbit_ref bref(msg_r8->ue_cap_rat_container_list[0].ue_cap_rat_container.data(), - msg_r8->ue_cap_rat_container_list[0].ue_cap_rat_container.size()); - if (eutra_capabilities.unpack(bref) != asn1::SRSASN_SUCCESS) { - parent->rrc_log->error("Failed to unpack EUTRA capabilities message\n"); - return false; - } - if (parent->rrc_log->get_level() == srslte::LOG_LEVEL_DEBUG) { - asn1::json_writer js{}; - eutra_capabilities.to_json(js); - parent->rrc_log->debug_long("rnti=0x%x EUTRA capabilities: %s\n", rnti, js.to_string().c_str()); - } - eutra_capabilities_unpacked = true; - ue_capabilities = srslte::make_rrc_ue_capabilities(eutra_capabilities); - - parent->rrc_log->info("UE rnti: 0x%x category: %d\n", rnti, eutra_capabilities.ue_category); + parent->logger.warning("Not handling UE capability information for RAT type %s", + msg_r8->ue_cap_rat_container_list[i].rat_type.to_string().c_str()); + continue; } + asn1::cbit_ref bref(msg_r8->ue_cap_rat_container_list[i].ue_cap_rat_container.data(), + msg_r8->ue_cap_rat_container_list[i].ue_cap_rat_container.size()); + if (eutra_capabilities.unpack(bref) != asn1::SRSASN_SUCCESS) { + parent->logger.error("Failed to unpack EUTRA capabilities message"); + return false; + } + if (parent->logger.debug.enabled()) { + asn1::json_writer js{}; + eutra_capabilities.to_json(js); + parent->logger.debug("rnti=0x%x EUTRA capabilities: %s", rnti, js.to_string().c_str()); + } + eutra_capabilities_unpacked = true; + ue_capabilities = srslte::make_rrc_ue_capabilities(eutra_capabilities); + + parent->logger.info("UE rnti: 0x%x category: %d", rnti, eutra_capabilities.ue_category); + } + + if (eutra_capabilities_unpacked) { + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + asn1::bit_ref bref2{pdu->msg, pdu->get_tailroom()}; + msg->pack(bref2); + asn1::rrc::ue_radio_access_cap_info_s ue_rat_caps; + auto& dest = ue_rat_caps.crit_exts.set_c1().set_ue_radio_access_cap_info_r8().ue_radio_access_cap_info; + dest.resize(bref2.distance_bytes()); + memcpy(dest.data(), pdu->msg, bref2.distance_bytes()); + bref2 = asn1::bit_ref{pdu->msg, pdu->get_tailroom()}; + ue_rat_caps.pack(bref2); + pdu->N_bytes = bref2.distance_bytes(); + parent->s1ap->send_ue_cap_info_indication(rnti, std::move(pdu)); } return true; - - // TODO: Add liblte_rrc support for unpacking UE cap info and repacking into - // inter-node UERadioAccessCapabilityInformation (36.331 v10.0.0 Section 10.2.2). - // This is then passed to S1AP for transfer to EPC. - // parent->s1ap->ue_capabilities(rnti, &eutra_capabilities); } /* @@ -724,7 +771,9 @@ void rrc::ue::send_connection_release() send_dl_dcch(&dl_dcch_msg); // Log rrc release event. - event_logger::get().log_rrc_disconnect(static_cast(rel_ies.release_cause)); + event_logger::get().log_rrc_disconnect(ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + static_cast(rrc_idle_transition_cause::release), + rnti); } /* @@ -733,40 +782,40 @@ void rrc::ue::send_connection_release() void rrc::ue::handle_ue_init_ctxt_setup_req(const asn1::s1ap::init_context_setup_request_s& msg) { if (msg.protocol_ies.add_cs_fallback_ind_present) { - parent->rrc_log->warning("Not handling AdditionalCSFallbackIndicator\n"); + parent->logger.warning("Not handling AdditionalCSFallbackIndicator"); } if (msg.protocol_ies.csg_membership_status_present) { - parent->rrc_log->warning("Not handling CSGMembershipStatus\n"); + parent->logger.warning("Not handling CSGMembershipStatus"); } if (msg.protocol_ies.gummei_id_present) { - parent->rrc_log->warning("Not handling GUMMEI_ID\n"); + parent->logger.warning("Not handling GUMMEI_ID"); } if (msg.protocol_ies.ho_restrict_list_present) { - parent->rrc_log->warning("Not handling HandoverRestrictionList\n"); + parent->logger.warning("Not handling HandoverRestrictionList"); } if (msg.protocol_ies.management_based_mdt_allowed_present) { - parent->rrc_log->warning("Not handling ManagementBasedMDTAllowed\n"); + parent->logger.warning("Not handling ManagementBasedMDTAllowed"); } if (msg.protocol_ies.management_based_mdtplmn_list_present) { - parent->rrc_log->warning("Not handling ManagementBasedMDTPLMNList\n"); + parent->logger.warning("Not handling ManagementBasedMDTPLMNList"); } if (msg.protocol_ies.mme_ue_s1ap_id_minus2_present) { - parent->rrc_log->warning("Not handling MME_UE_S1AP_ID_2\n"); + parent->logger.warning("Not handling MME_UE_S1AP_ID_2"); } if (msg.protocol_ies.registered_lai_present) { - parent->rrc_log->warning("Not handling RegisteredLAI\n"); + parent->logger.warning("Not handling RegisteredLAI"); } if (msg.protocol_ies.srvcc_operation_possible_present) { - parent->rrc_log->warning("Not handling SRVCCOperationPossible\n"); + parent->logger.warning("Not handling SRVCCOperationPossible"); } if (msg.protocol_ies.subscriber_profile_idfor_rfp_present) { - parent->rrc_log->warning("Not handling SubscriberProfileIDforRFP\n"); + parent->logger.warning("Not handling SubscriberProfileIDforRFP"); } if (msg.protocol_ies.trace_activation_present) { - parent->rrc_log->warning("Not handling TraceActivation\n"); + parent->logger.warning("Not handling TraceActivation"); } if (msg.protocol_ies.ue_radio_cap_present) { - parent->rrc_log->warning("Not handling UERadioCapability\n"); + parent->logger.warning("Not handling UERadioCapability"); } set_bitrates(msg.protocol_ies.ueaggregate_maximum_bitrate.value); @@ -799,16 +848,16 @@ bool rrc::ue::handle_ue_ctxt_mod_req(const asn1::s1ap::ue_context_mod_request_s& } if (msg.protocol_ies.add_cs_fallback_ind_present) { - parent->rrc_log->warning("Not handling AdditionalCSFallbackIndicator\n"); + parent->logger.warning("Not handling AdditionalCSFallbackIndicator"); } if (msg.protocol_ies.csg_membership_status_present) { - parent->rrc_log->warning("Not handling CSGMembershipStatus\n"); + parent->logger.warning("Not handling CSGMembershipStatus"); } if (msg.protocol_ies.registered_lai_present) { - parent->rrc_log->warning("Not handling RegisteredLAI\n"); + parent->logger.warning("Not handling RegisteredLAI"); } if (msg.protocol_ies.subscriber_profile_idfor_rfp_present) { - parent->rrc_log->warning("Not handling SubscriberProfileIDforRFP\n"); + parent->logger.warning("Not handling SubscriberProfileIDforRFP"); } // UEAggregateMaximumBitrate @@ -856,13 +905,13 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& for (const auto& item : e) { auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req(); if (erab.ext) { - parent->rrc_log->warning("Not handling E-RABToBeSetupListCtxtSURequest extensions\n"); + parent->logger.warning("Not handling E-RABToBeSetupListCtxtSURequest extensions"); } if (erab.ie_exts_present) { - parent->rrc_log->warning("Not handling E-RABToBeSetupListCtxtSURequest extensions\n"); + parent->logger.warning("Not handling E-RABToBeSetupListCtxtSURequest extensions"); } if (erab.transport_layer_address.length() > 32) { - parent->rrc_log->error("IPv6 addresses not currently supported\n"); + parent->logger.error("IPv6 addresses not currently supported"); return false; } @@ -870,7 +919,7 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& srslte::uint8_to_uint32(erab.gtp_teid.data(), &teid_out); const asn1::unbounded_octstring* nas_pdu = erab.nas_pdu_present ? &erab.nas_pdu : nullptr; bearer_list.add_erab(erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, nas_pdu); - bearer_list.add_gtpu_bearer(parent->gtpu, erab.erab_id); + bearer_list.add_gtpu_bearer(erab.erab_id); } return true; } @@ -880,13 +929,13 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_ for (const auto& item : e) { auto& erab = item.value.erab_to_be_setup_item_bearer_su_req(); if (erab.ext) { - parent->rrc_log->warning("Not handling E-RABToBeSetupListBearerSUReq extensions\n"); + parent->logger.warning("Not handling E-RABToBeSetupListBearerSUReq extensions"); } if (erab.ie_exts_present) { - parent->rrc_log->warning("Not handling E-RABToBeSetupListBearerSUReq extensions\n"); + parent->logger.warning("Not handling E-RABToBeSetupListBearerSUReq extensions"); } if (erab.transport_layer_address.length() > 32) { - parent->rrc_log->error("IPv6 addresses not currently supported\n"); + parent->logger.error("IPv6 addresses not currently supported"); return false; } @@ -894,7 +943,7 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_ srslte::uint8_to_uint32(erab.gtp_teid.data(), &teid_out); bearer_list.add_erab( erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, &erab.nas_pdu); - bearer_list.add_gtpu_bearer(parent->gtpu, erab.erab_id); + bearer_list.add_gtpu_bearer(erab.erab_id); } // Work in progress @@ -943,7 +992,8 @@ void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_se } else { res.protocol_ies.erab_failed_to_setup_list_bearer_su_res_present = true; res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.push_back({}); - auto& item = res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.back(); + auto& item = res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.back(); + item.load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); item.value.erab_item().erab_id = id; item.value.erab_item().cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; @@ -979,7 +1029,7 @@ void rrc::ue::update_scells() not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext.rf_params_v1020_present or eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext.rf_params_v1020.supported_band_combination_r10.size() == 0) { - parent->rrc_log->info("UE doesn't support CA. Skipping SCell activation\n"); + parent->logger.info("UE doesn't support CA. Skipping SCell activation"); return; } @@ -987,14 +1037,7 @@ void rrc::ue::update_scells() ue_cell_list.add_cell(scell->enb_cc_idx); } - parent->rrc_log->info("SCells activated for rnti=0x%x\n", rnti); -} - -/********************** Handover **************************/ - -void rrc::ue::handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container) -{ - mobility_handler->handle_ho_preparation_complete(is_success, std::move(container)); + parent->logger.info("SCells activated for rnti=0x%x", rnti); } /********************** HELPERS ***************************/ @@ -1002,11 +1045,11 @@ void rrc::ue::handle_ho_preparation_complete(bool is_success, srslte::unique_byt void rrc::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) { // Allocate a new PDU buffer, pack the message and send to PDCP - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu) { asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); if (dl_ccch_msg->pack(bref) != asn1::SRSASN_SUCCESS) { - parent->rrc_log->error_hex(pdu->msg, pdu->N_bytes, "Failed to pack DL-CCCH-Msg:\n"); + parent->logger.error(pdu->msg, pdu->N_bytes, "Failed to pack DL-CCCH-Msg:"); return; } pdu->N_bytes = (uint32_t)bref.distance_bytes(); @@ -1016,19 +1059,19 @@ void rrc::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) parent->log_rrc_message(buf, Tx, pdu.get(), *dl_ccch_msg, dl_ccch_msg->msg.c1().type().to_string()); parent->rlc->write_sdu(rnti, RB_ID_SRB0, std::move(pdu)); } else { - parent->rrc_log->error("Allocating pdu\n"); + parent->logger.error("Allocating pdu"); } } bool rrc::ue::send_dl_dcch(const dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffer_t pdu) { if (!pdu) { - pdu = srslte::allocate_unique_buffer(*pool); + pdu = srslte::make_byte_buffer(); } if (pdu) { asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); if (dl_dcch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - parent->rrc_log->error("Failed to encode DL-DCCH-Msg\n"); + parent->logger.error("Failed to encode DL-DCCH-Msg"); return false; } pdu->N_bytes = (uint32_t)bref.distance_bytes(); @@ -1043,7 +1086,7 @@ bool rrc::ue::send_dl_dcch(const dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte parent->pdcp->write_sdu(rnti, lcid, std::move(pdu)); } else { - parent->rrc_log->error("Allocating pdu\n"); + parent->logger.error("Allocating pdu"); return false; } return true; @@ -1206,14 +1249,18 @@ void rrc::ue::apply_pdcp_drb_updates(const rr_cfg_ded_s& pending_rr_cfg) bool is_am = parent->cfg.qci_cfg[erab_pair.second.qos_params.qci].rlc_cfg.type().value == asn1::rrc::rlc_cfg_c::types_opts::am; if (is_am) { - parent->rrc_log->debug("Set PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, " - "LAST_SUBMITTED_PDCP_RX_SN %d\n", - old_reest_pdcp_state[lcid].tx_hfn, - old_reest_pdcp_state[lcid].next_pdcp_tx_sn, - old_reest_pdcp_state[lcid].rx_hfn, - old_reest_pdcp_state[lcid].next_pdcp_rx_sn, - old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); + parent->logger.debug("Set PDCP state: TX HFN %d, NEXT_PDCP_TX_SN %d, RX_HFN %d, NEXT_PDCP_RX_SN %d, " + "LAST_SUBMITTED_PDCP_RX_SN %d", + old_reest_pdcp_state[lcid].tx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_tx_sn, + old_reest_pdcp_state[lcid].rx_hfn, + old_reest_pdcp_state[lcid].next_pdcp_rx_sn, + old_reest_pdcp_state[lcid].last_submitted_pdcp_rx_sn); parent->pdcp->set_bearer_state(rnti, lcid, old_reest_pdcp_state[lcid]); + parent->pdcp->set_bearer_state(rnti, lcid, old_reest_pdcp_state[lcid]); + if (parent->cfg.qci_cfg[erab_pair.second.qos_params.qci].pdcp_cfg.rlc_am.status_report_required) { + parent->pdcp->send_status_report(rnti, lcid); + } } } } @@ -1225,11 +1272,13 @@ void rrc::ue::apply_rlc_rb_updates(const rr_cfg_ded_s& pending_rr_cfg) parent->rlc->add_bearer(rnti, srb.srb_id, srslte::rlc_config_t::srb_config(srb.srb_id)); } if (pending_rr_cfg.drb_to_release_list.size() > 0) { - parent->rrc_log->error("Removing DRBs not currently supported\n"); + for (uint8_t drb_id : pending_rr_cfg.drb_to_release_list) { + parent->rlc->del_bearer(rnti, drb_id + 2); + } } for (const drb_to_add_mod_s& drb : pending_rr_cfg.drb_to_add_mod_list) { if (not drb.rlc_cfg_present) { - parent->rrc_log->warning("Default RLC DRB config not supported\n"); + parent->logger.warning("Default RLC DRB config not supported"); } parent->rlc->add_bearer(rnti, drb.lc_ch_id, srslte::make_rlc_config_t(drb.rlc_cfg)); } @@ -1243,7 +1292,7 @@ int rrc::ue::get_cqi(uint16_t* pmi_idx, uint16_t* n_pucch, uint32_t ue_cc_idx) *n_pucch = c->cqi_res.pucch_res; return SRSLTE_SUCCESS; } else { - parent->rrc_log->error("CQI resources for ue_cc_idx=%d have not been allocated\n", ue_cc_idx); + parent->logger.error("CQI resources for ue_cc_idx=%d have not been allocated", ue_cc_idx); return SRSLTE_ERROR; } } @@ -1282,7 +1331,7 @@ int rrc::ue::get_ri(uint32_t m_ri, uint16_t* ri_idx) I_ri = 805 - N_offset_ri; break; default: - parent->rrc_log->error("Allocating RI: invalid m_ri=%d\n", m_ri); + parent->logger.error("Allocating RI: invalid m_ri=%d", m_ri); } // If ri_dix is available, copy diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index 00a54fc45..77d315ec2 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -31,7 +31,6 @@ namespace srsenb { * measObjToAddMod **********************************/ - bool is_same_earfcn(const meas_obj_t& lhs, const meas_obj_t& rhs) { int freq1 = srslte::get_carrier_freq(lhs); @@ -256,7 +255,7 @@ meas_gap_cfg_c make_measgap(const meas_obj_list& measobjs, const ue_cell_ded& pc case 0: // no meas gaps configured break; default: - srslte::logmap::get("RRC")->error("Error setting measurement gap.\n"); + srslog::fetch_basic_logger("RRC").error("Error setting measurement gap."); } return meas_gap; } @@ -294,8 +293,8 @@ bool apply_meas_gap_updates(const meas_gap_cfg_c& src_gaps, } break; default: - srslte::logmap::get("RRC")->warning("MeasGap of type %s not supported\n", - target_offset.type().to_string().c_str()); + srslog::fetch_basic_logger("RRC").warning("MeasGap of type %s not supported", + target_offset.type().to_string().c_str()); } } } @@ -328,7 +327,7 @@ bool fill_meascfg_enb_cfg(meas_cfg_s& meascfg, const ue_cell_ded_list& ue_cell_l const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); assert(pcell != nullptr); const enb_cell_common* pcell_cfg = pcell->cell_common; - const auto& pcell_meascfg = pcell_cfg->cell_cfg.meas_cfg; + const auto& pcell_meascfg = pcell_cfg->cell_cfg.meas_cfg; // Add PCell+Scells to measObjToAddModList // NOTE: sort by EARFCN to avoid unnecessary reconfigurations of measObjToAddModList @@ -336,11 +335,9 @@ bool fill_meascfg_enb_cfg(meas_cfg_s& meascfg, const ue_cell_ded_list& ue_cell_l for (uint32_t ue_cc_idx = 0; ue_cc_idx < ue_cell_list.nof_cells(); ++ue_cc_idx) { sorted_ue_cells[ue_cc_idx] = ue_cell_list.get_ue_cc_idx(ue_cc_idx); } - std::sort(sorted_ue_cells.begin(), - sorted_ue_cells.end(), - [](const ue_cell_ded* cc1, const ue_cell_ded* cc2) { - return cc1->get_dl_earfcn() < cc2->get_dl_earfcn(); - }); + std::sort(sorted_ue_cells.begin(), sorted_ue_cells.end(), [](const ue_cell_ded* cc1, const ue_cell_ded* cc2) { + return cc1->get_dl_earfcn() < cc2->get_dl_earfcn(); + }); for (auto* cc : sorted_ue_cells) { add_meas_obj(meascfg.meas_obj_to_add_mod_list, cc->get_dl_earfcn()); } @@ -402,16 +399,16 @@ bool compute_diff_meascfg(const meas_cfg_s& current_meascfg, const meas_cfg_s& t return set_meascfg_presence_flags(diff_meascfg); } -bool apply_meascfg_updates(meas_cfg_s& meascfg, - meas_cfg_s& current_meascfg, +bool apply_meascfg_updates(meas_cfg_s& meascfg, + meas_cfg_s& current_meascfg, const ue_cell_ded_list& ue_cell_list, - int prev_earfcn, - int prev_pci) + int prev_earfcn, + int prev_pci) { meascfg = {}; const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); - uint32_t target_earfcn = pcell->get_dl_earfcn(); + uint32_t target_earfcn = pcell->get_dl_earfcn(); if (static_cast(prev_pci) == pcell->get_pci() and static_cast(prev_earfcn) == target_earfcn) { // Shortcut: No PCell change -> no measConfig updates diff --git a/srsenb/src/stack/rrc/ue_rr_cfg.cc b/srsenb/src/stack/rrc/ue_rr_cfg.cc index 04521eab3..5f26001bb 100644 --- a/srsenb/src/stack/rrc/ue_rr_cfg.cc +++ b/srsenb/src/stack/rrc/ue_rr_cfg.cc @@ -45,7 +45,7 @@ namespace srsenb { srb_to_add_mod_s* add_srb(srb_to_add_mod_list_l& srbs, uint8_t srb_id) { if (srb_id > 2 or srb_id == 0) { - srslte::logmap::get("RRC")->error("Invalid SRB id=%d\n", srb_id); + srslog::fetch_basic_logger("RRC").error("Invalid SRB id=%d", srb_id); return nullptr; } @@ -114,7 +114,7 @@ int16_t get_ri(uint32_t m_ri) ri_idx = 805 - N_offset_ri; break; default: - srslte::logmap::get("RRC")->error("Allocating RI: invalid m_ri=%d\n", m_ri); + srslog::fetch_basic_logger("RRC").error("Allocating RI: invalid m_ri=%d", m_ri); return -1; } @@ -144,7 +144,7 @@ int fill_cqi_report_setup(cqi_report_cfg_s& cqi_rep, const rrc_cfg_t& enb_cfg, c if (cqi_rep.cqi_report_periodic_present) { const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); if (pcell == nullptr or not pcell->cqi_res_present) { - srslte::logmap::get("RRC")->warning("PCell CQI resources haven\'t been allocated yet\n"); + srslog::fetch_basic_logger("RRC").warning("PCell CQI resources haven\'t been allocated yet"); return SRSLTE_ERROR; } auto& cqi_periodic = cqi_rep.cqi_report_periodic.setup(); @@ -182,7 +182,7 @@ void fill_cqi_report_reconf(cqi_report_cfg_s& cqi_rep, const rrc_cfg_t& enb_cfg, cqi_setup.ri_cfg_idx_present = true; cqi_setup.ri_cfg_idx = ri_idx; } else { - srslte::logmap::get("RRC")->warning("Warning: Configured wrong M_ri parameter.\n"); + srslog::fetch_basic_logger("RRC").warning("Warning: Configured wrong M_ri parameter."); } } } diff --git a/srsenb/src/stack/upper/CMakeLists.txt b/srsenb/src/stack/upper/CMakeLists.txt index b9414df30..249a41b39 100644 --- a/srsenb/src/stack/upper/CMakeLists.txt +++ b/srsenb/src/stack/upper/CMakeLists.txt @@ -21,8 +21,5 @@ set(SOURCES gtpu.cc pdcp.cc rlc.cc s1ap.cc) add_library(srsenb_upper STATIC ${SOURCES}) -if(ENABLE_5GNR) - set(SOURCES pdcp_nr.cc rlc_nr.cc sdap.cc) - add_library(srsgnb_upper STATIC ${SOURCES}) -endif() - +set(SOURCES pdcp_nr.cc rlc_nr.cc sdap.cc) +add_library(srsgnb_upper STATIC ${SOURCES}) diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index b010f310d..d23902679 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -21,8 +21,9 @@ #include "srslte/upper/gtpu.h" #include "srsenb/hdr/stack/upper/gtpu.h" #include "srslte/common/network_utils.h" +#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" #include -#include #include #include #include @@ -31,7 +32,7 @@ using namespace srslte; namespace srsenb { -gtpu::gtpu() : m1u(this), gtpu_log("GTPU") {} +gtpu::gtpu(srslog::basic_logger& logger) : m1u(this), logger(logger) {} int gtpu::init(std::string gtp_bind_addr_, std::string mme_addr_, @@ -44,7 +45,6 @@ int gtpu::init(std::string gtp_bind_addr_, pdcp = pdcp_; gtp_bind_addr = gtp_bind_addr_; mme_addr = mme_addr_; - pool = byte_buffer_pool::get_instance(); stack = stack_; char errbuf[128] = {}; @@ -52,17 +52,17 @@ int gtpu::init(std::string gtp_bind_addr_, // Set up socket fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - gtpu_log->error("Failed to create socket\n"); + logger.error("Failed to create socket"); return SRSLTE_ERROR; } int enable = 1; #if defined(SO_REUSEADDR) if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) - gtpu_log->error("setsockopt(SO_REUSEADDR) failed\n"); + logger.error("setsockopt(SO_REUSEADDR) failed"); #endif #if defined(SO_REUSEPORT) if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) - gtpu_log->error("setsockopt(SO_REUSEPORT) failed\n"); + logger.error("setsockopt(SO_REUSEPORT) failed"); #endif struct sockaddr_in bindaddr; @@ -73,8 +73,8 @@ int gtpu::init(std::string gtp_bind_addr_, if (bind(fd, (struct sockaddr*)&bindaddr, sizeof(struct sockaddr_in))) { snprintf(errbuf, sizeof(errbuf), "%s", strerror(errno)); - gtpu_log->error("Failed to bind on address %s, port %d: %s\n", gtp_bind_addr.c_str(), GTPU_PORT, errbuf); - srslte::console("Failed to bind on address %s, port %d: %s\n", gtp_bind_addr.c_str(), GTPU_PORT, errbuf); + logger.error("Failed to bind on address %s, port %d: %s", gtp_bind_addr.c_str(), int(GTPU_PORT), errbuf); + srslte::console("Failed to bind on address %s, port %d: %s\n", gtp_bind_addr.c_str(), int(GTPU_PORT), errbuf); return SRSLTE_ERROR; } @@ -100,36 +100,47 @@ void gtpu::stop() // gtpu_interface_pdcp void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) { - gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes); + srslte::span teids = get_lcid_teids(rnti, lcid); + if (teids.empty()) { + return; + } + tunnel& tx_tun = tunnels[teids[0]]; + log_message(tx_tun, false, srslte::make_span(pdu)); + send_pdu_to_tunnel(tx_tun, std::move(pdu)); +} +void gtpu::send_pdu_to_tunnel(tunnel& tx_tun, srslte::unique_byte_buffer_t pdu, int pdcp_sn) +{ // Check valid IP version struct iphdr* ip_pkt = (struct iphdr*)pdu->msg; if (ip_pkt->version != 4 && ip_pkt->version != 6) { - gtpu_log->error("Invalid IP version to SPGW\n"); + logger.error("Invalid IP version to SPGW"); return; } - if (ip_pkt->version == 4) { - if (ntohs(ip_pkt->tot_len) != pdu->N_bytes) { - gtpu_log->error("IP Len and PDU N_bytes mismatch\n"); - } - gtpu_log->debug("Tx S1-U PDU -- IP version %d, Total length %d\n", ip_pkt->version, ntohs(ip_pkt->tot_len)); - gtpu_log->debug("Tx S1-U PDU -- IP src addr %s\n", srslte::gtpu_ntoa(ip_pkt->saddr).c_str()); - gtpu_log->debug("Tx S1-U PDU -- IP dst addr %s\n", srslte::gtpu_ntoa(ip_pkt->daddr).c_str()); - } gtpu_header_t header; header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; header.message_type = GTPU_MSG_DATA_PDU; header.length = pdu->N_bytes; - header.teid = rnti_bearers[rnti].teids_out[lcid]; + header.teid = tx_tun.teid_out; + + if (pdcp_sn >= 0) { + header.flags |= GTPU_FLAGS_EXTENDED_HDR; + header.next_ext_hdr_type = GTPU_EXT_HEADER_PDCP_PDU_NUMBER; + header.ext_buffer.resize(4u); + header.ext_buffer[0] = 0x01u; + header.ext_buffer[1] = (pdcp_sn >> 8u) & 0xffu; + header.ext_buffer[2] = pdcp_sn & 0xffu; + header.ext_buffer[3] = 0; + } struct sockaddr_in servaddr; servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(rnti_bearers[rnti].spgw_addrs[lcid]); + servaddr.sin_addr.s_addr = htonl(tx_tun.spgw_addr); servaddr.sin_port = htons(GTPU_PORT); - if (!gtpu_write_header(&header, pdu.get(), gtpu_log)) { - gtpu_log->error("Error writing GTP-U Header. Flags 0x%x, Message Type 0x%x\n", header.flags, header.message_type); + if (!gtpu_write_header(&header, pdu.get(), logger)) { + logger.error("Error writing GTP-U Header. Flags 0x%x, Message Type 0x%x", header.flags, header.message_type); return; } if (sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)) < 0) { @@ -137,113 +148,159 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t } } -/* Warning: This function is called before calling gtpu::init() during MCCH initialization. - * If access to any element created in init (such as gtpu_log) is required, it must be considered - * the case of it being NULL. - */ -uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) +uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props) { // Allocate a TEID for the incoming tunnel - uint32_t teid_in = allocate_teidin(rnti, lcid); - if (gtpu_log) { - gtpu_log->info("Adding bearer for rnti: 0x%x, lcid: %d, addr: 0x%x, teid_out: 0x%x, teid_in: 0x%x\n", - rnti, - lcid, - addr, - teid_out, - teid_in); - } + uint32_t teid_in = ++next_teid_in; + tunnel& new_tun = tunnels[teid_in]; + new_tun.teid_in = teid_in; + new_tun.rnti = rnti; + new_tun.lcid = lcid; + new_tun.spgw_addr = addr; + new_tun.teid_out = teid_out; - // Initialize maps if it's a new RNTI - if (rnti_bearers.count(rnti) == 0) { - for (int i = 0; i < SRSENB_N_RADIO_BEARERS; i++) { - rnti_bearers[rnti].teids_in[i] = 0; - rnti_bearers[rnti].teids_out[i] = 0; - rnti_bearers[rnti].spgw_addrs[i] = 0; + ue_teidin_db[rnti][lcid].push_back(teid_in); + + logger.info("Adding bearer for rnti: 0x%x, lcid: %d, addr: 0x%x, teid_out: 0x%x, teid_in: 0x%x", + rnti, + lcid, + addr, + teid_out, + teid_in); + + if (props != nullptr) { + if (props->flush_before_teidin_present) { + // GTPU should wait for the bearer ctxt to arrive before sending SDUs from DL tunnel to PDCP + new_tun.dl_enabled = false; + // GTPU should not forward SDUs from main tunnel until the SeNB-TeNB tunnel has been flushed + tunnel& after_tun = tunnels.at(props->flush_before_teidin); + after_tun.dl_enabled = false; + after_tun.prior_teid_in_present = true; + after_tun.prior_teid_in = teid_in; + } + + // Connect tunnels if forwarding is activated + if (props->forward_from_teidin_present) { + if (create_dl_fwd_tunnel(props->forward_from_teidin, teid_in) != SRSLTE_SUCCESS) { + rem_tunnel(teid_in); + return 0; + } } } - rnti_bearers[rnti].teids_in[lcid] = teid_in; - rnti_bearers[rnti].teids_out[lcid] = teid_out; - rnti_bearers[rnti].spgw_addrs[lcid] = addr; - return teid_in; } +void gtpu::set_tunnel_status(uint32_t teidin, bool dl_active) +{ + auto tun_it = tunnels.find(teidin); + if (tun_it == tunnels.end()) { + logger.warning("Setting TEID=%d status", teidin); + return; + } + tun_it->second.dl_enabled = dl_active; + if (dl_active) { + for (auto& sdu_it : tun_it->second.buffer) { + pdcp->write_sdu(tun_it->second.rnti, + tun_it->second.lcid, + std::move(sdu_it.second), + sdu_it.first == undefined_pdcp_sn ? -1 : sdu_it.first); + } + tun_it->second.buffer.clear(); + } +} + void gtpu::rem_bearer(uint16_t rnti, uint32_t lcid) { - gtpu_log->info("Removing bearer for rnti: 0x%x, lcid: %d\n", rnti, lcid); - - // Remove from TEID from map - free_teidin(rnti, lcid); - - // Remove - rnti_bearers[rnti].teids_in[lcid] = 0; - rnti_bearers[rnti].teids_out[lcid] = 0; - - // Remove RNTI if all bearers are removed - bool rem = true; - for (int i = 0; i < SRSENB_N_RADIO_BEARERS; i++) { - if (rnti_bearers[rnti].teids_in[i] != 0) { - rem = false; - } + auto ue_it = ue_teidin_db.find(rnti); + if (ue_it == ue_teidin_db.end()) { + logger.warning("Removing bearer rnti=0x%x, lcid=%d", rnti, lcid); + return; } - if (rem) { - rnti_bearers.erase(rnti); + std::vector& lcid_tuns = ue_it->second[lcid]; + + while (not lcid_tuns.empty()) { + rem_tunnel(lcid_tuns.back()); + } + logger.info("Removing bearer for rnti: 0x%x, lcid: %d", rnti, lcid); + + bool rem_ue = std::all_of( + ue_it->second.begin(), ue_it->second.end(), [](const std::vector& list) { return list.empty(); }); + if (rem_ue) { + ue_teidin_db.erase(ue_it); } } void gtpu::mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) { - gtpu_log->info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x\n", old_rnti, new_rnti); + logger.info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x", old_rnti, new_rnti); - if (rnti_bearers.count(new_rnti) != 0) { - gtpu_log->error("New rnti already exists, aborting.\n"); + if (ue_teidin_db.count(new_rnti) != 0) { + logger.error("New rnti already exists, aborting."); return; } - if (rnti_bearers.count(old_rnti) == 0) { - gtpu_log->error("Old rnti does not exist, aborting.\n"); + auto old_it = ue_teidin_db.find(old_rnti); + if (old_it == ue_teidin_db.end()) { + logger.error("Old rnti does not exist, aborting."); return; } // Change RNTI bearers map - auto entry = rnti_bearers.find(old_rnti); - if (entry != rnti_bearers.end()) { - auto const value = std::move(entry->second); - rnti_bearers.erase(entry); - rnti_bearers.insert({new_rnti, std::move(value)}); - } + ue_teidin_db.insert(std::make_pair(new_rnti, std::move(old_it->second))); + ue_teidin_db.erase(old_it); // Change TEID - for (std::map::iterator it = teidin_to_rntilcid_map.begin(); - it != teidin_to_rntilcid_map.end(); - it++) { - if (it->second.rnti == old_rnti) { - it->second.rnti = new_rnti; + auto new_it = ue_teidin_db.find(new_rnti); + for (auto& bearer : new_it->second) { + for (uint32_t teid : bearer) { + tunnels[teid].rnti = new_rnti; } } } +void gtpu::rem_tunnel(uint32_t teidin) +{ + auto it = tunnels.find(teidin); + if (it == tunnels.end()) { + logger.warning("Removing GTPU tunnel TEID In=0x%x", teidin); + return; + } + if (it->second.fwd_teid_in_present) { + // Forward End Marker to forwarding tunnel, before deleting tunnel + end_marker(it->second.fwd_teid_in); + it->second.fwd_teid_in_present = false; + } + auto ue_it = ue_teidin_db.find(it->second.rnti); + std::vector& lcid_tunnels = ue_it->second[it->second.lcid]; + lcid_tunnels.erase(std::remove(lcid_tunnels.begin(), lcid_tunnels.end(), teidin), lcid_tunnels.end()); + tunnels.erase(it); + logger.debug("TEID In=%d erased", teidin); +} + void gtpu::rem_user(uint16_t rnti) { - // Free from TEID map - free_teidin(rnti); - - // Remove user from RNTI map - rnti_bearers.erase(rnti); + logger.info("Removing rnti=0x%x", rnti); + auto ue_it = ue_teidin_db.find(rnti); + if (ue_it != ue_teidin_db.end()) { + for (auto& bearer : ue_it->second) { + while (not bearer.empty()) { + rem_tunnel(bearer.back()); + } + } + } } void gtpu::handle_gtpu_s1u_rx_packet(srslte::unique_byte_buffer_t pdu, const sockaddr_in& addr) { - gtpu_log->debug("Received %d bytes from S1-U interface\n", pdu->N_bytes); + logger.debug("Received %d bytes from S1-U interface", pdu->N_bytes); pdu->set_timestamp(); gtpu_header_t header; - if (not gtpu_read_header(pdu.get(), &header, gtpu_log)) { + if (not gtpu_read_header(pdu.get(), &header, logger)) { return; } - if (header.teid != 0 && teidin_to_rntilcid_map.count(header.teid) == 0) { + if (header.teid != 0 && tunnels.count(header.teid) == 0) { // Received G-PDU for non-existing and non-zero TEID. // Sending GTP-U error indication error_indication(addr.sin_addr.s_addr, addr.sin_port, header.teid); @@ -256,45 +313,58 @@ void gtpu::handle_gtpu_s1u_rx_packet(srslte::unique_byte_buffer_t pdu, const soc echo_response(addr.sin_addr.s_addr, addr.sin_port, header.seq_number); break; case GTPU_MSG_DATA_PDU: { - rnti_lcid_t rnti_lcid = teidin_to_rntilcid(header.teid); - uint16_t rnti = rnti_lcid.rnti; - uint16_t lcid = rnti_lcid.lcid; + auto& rx_tun = tunnels.find(header.teid)->second; + uint16_t rnti = rx_tun.rnti; + uint16_t lcid = rx_tun.lcid; - bool user_exists = (rnti_bearers.count(rnti) > 0); - - if (not user_exists) { - gtpu_log->error("Unrecognized TEID In=%d for DL PDU. Dropping packet\n", header.teid); - return; - } + log_message(rx_tun, true, srslte::make_span(pdu)); if (lcid < SRSENB_N_SRB || lcid >= SRSENB_N_RADIO_BEARERS) { - gtpu_log->error("Invalid LCID for DL PDU: %d - dropping packet\n", lcid); + logger.error("Invalid LCID for DL PDU: %d - dropping packet", lcid); return; } - - gtpu_log->info_hex( - pdu->msg, pdu->N_bytes, "RX GTPU PDU rnti=0x%x, lcid=%d, n_bytes=%d", rnti, lcid, pdu->N_bytes); - struct iphdr* ip_pkt = (struct iphdr*)pdu->msg; if (ip_pkt->version != 4 && ip_pkt->version != 6) { - gtpu_log->error("Invalid IP version to SPGW\n"); return; } - if (ip_pkt->version == 4) { - if (ntohs(ip_pkt->tot_len) != pdu->N_bytes) { - gtpu_log->error("IP Len and PDU N_bytes mismatch\n"); + if (rx_tun.fwd_teid_in_present) { + tunnel& tx_tun = tunnels.at(rx_tun.fwd_teid_in); + send_pdu_to_tunnel(tx_tun, std::move(pdu)); + } else { + uint32_t pdcp_sn = undefined_pdcp_sn; + if (header.flags & GTPU_FLAGS_EXTENDED_HDR and header.next_ext_hdr_type == GTPU_EXT_HEADER_PDCP_PDU_NUMBER) { + pdcp_sn = (header.ext_buffer[1] << 8u) + header.ext_buffer[2]; + } + if (not rx_tun.dl_enabled) { + rx_tun.buffer.insert(std::make_pair(pdcp_sn, std::move(pdu))); + } else { + pdcp->write_sdu(rnti, lcid, std::move(pdu), pdcp_sn == undefined_pdcp_sn ? -1 : pdcp_sn); } - gtpu_log->debug("Rx S1-U PDU -- IP version %d, Total length %d\n", ip_pkt->version, ntohs(ip_pkt->tot_len)); - gtpu_log->debug("Rx S1-U PDU -- IP src addr %s\n", srslte::gtpu_ntoa(ip_pkt->saddr).c_str()); - gtpu_log->debug("Rx S1-U PDU -- IP dst addr %s\n", srslte::gtpu_ntoa(ip_pkt->daddr).c_str()); } - pdcp->write_sdu(rnti, lcid, std::move(pdu)); } break; case GTPU_MSG_END_MARKER: { - rnti_lcid_t rnti_lcid = teidin_to_rntilcid(header.teid); - uint16_t rnti = rnti_lcid.rnti; - gtpu_log->info("Received GTPU End Marker for rnti=0x%x.\n", rnti); + tunnel& old_tun = tunnels.find(header.teid)->second; + uint16_t rnti = old_tun.rnti; + logger.info("Received GTPU End Marker for rnti=0x%x.", rnti); + + // TS 36.300, Sec 10.1.2.2.1 - Path Switch upon handover + if (old_tun.fwd_teid_in_present) { + // END MARKER should be forwarded to TeNB if forwarding is activated + end_marker(old_tun.fwd_teid_in); + old_tun.fwd_teid_in_present = false; + } else { + // TeNB switches paths, and flush PDUs that have been buffered + std::vector& bearer_tunnels = ue_teidin_db.find(old_tun.rnti)->second[old_tun.lcid]; + for (uint32_t new_teidin : bearer_tunnels) { + tunnel& new_tun = tunnels.at(new_teidin); + if (new_teidin != old_tun.teid_in and new_tun.prior_teid_in_present and + new_tun.prior_teid_in == old_tun.teid_in) { + new_tun.prior_teid_in_present = false; + set_tunnel_status(new_tun.teid_in, true); + } + } + } break; } default: @@ -307,15 +377,46 @@ void gtpu::handle_gtpu_m1u_rx_packet(srslte::unique_byte_buffer_t pdu, const soc m1u.handle_rx_packet(std::move(pdu), addr); } +/// Connect created tunnel with pre-existing tunnel for data forwarding +int gtpu::create_dl_fwd_tunnel(uint32_t rx_teid_in, uint32_t tx_teid_in) +{ + auto rx_tun_pair = tunnels.find(rx_teid_in); + auto tx_tun_pair = tunnels.find(tx_teid_in); + if (rx_tun_pair == tunnels.end() or tx_tun_pair == tunnels.end()) { + logger.error("Failed to create forwarding tunnel between teids 0x%x and 0x%x", rx_teid_in, tx_teid_in); + return SRSLTE_ERROR; + } + + tunnel &rx_tun = rx_tun_pair->second, &tx_tun = tx_tun_pair->second; + rx_tun.fwd_teid_in_present = true; + rx_tun.fwd_teid_in = tx_teid_in; + logger.info("Creating forwarding tunnel for rnti=0x%x, lcid=%d, in={0x%x, 0x%x}->out={0x%x, 0x%x}", + rx_tun.rnti, + rx_tun.lcid, + rx_tun.teid_out, + rx_tun.spgw_addr, + tx_tun.teid_out, + tx_tun.spgw_addr); + + // Get all buffered PDCP PDUs, and forward them through tx tunnel + std::map pdus = pdcp->get_buffered_pdus(rx_tun.rnti, rx_tun.lcid); + for (auto& pdu_pair : pdus) { + log_message(tx_tun, false, srslte::make_span(pdu_pair.second), pdu_pair.first); + send_pdu_to_tunnel(tx_tun, std::move(pdu_pair.second), pdu_pair.first); + } + + return SRSLTE_SUCCESS; +} + /**************************************************************************** * GTP-U Error Indication ***************************************************************************/ void gtpu::error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid) { - gtpu_log->info("TX GTPU Error Indication. Seq: %d, Error TEID: %d\n", tx_seq, err_teid); + logger.info("TX GTPU Error Indication. Seq: %d, Error TEID: %d", tx_seq, err_teid); gtpu_header_t header = {}; - unique_byte_buffer_t pdu = allocate_unique_buffer(*pool); + unique_byte_buffer_t pdu = make_byte_buffer(); // header header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE; @@ -326,7 +427,7 @@ void gtpu::error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid) header.n_pdu = 0; header.next_ext_hdr_type = 0; - gtpu_write_header(&header, pdu.get(), gtpu_log); + gtpu_write_header(&header, pdu.get(), logger); struct sockaddr_in servaddr; servaddr.sin_family = AF_INET; @@ -342,10 +443,10 @@ void gtpu::error_indication(in_addr_t addr, in_port_t port, uint32_t err_teid) ***************************************************************************/ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) { - gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq); + logger.info("TX GTPU Echo Response, Seq: %d", seq); gtpu_header_t header = {}; - unique_byte_buffer_t pdu = allocate_unique_buffer(*pool); + unique_byte_buffer_t pdu = make_byte_buffer(); // header header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE; @@ -356,7 +457,7 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) header.n_pdu = 0; header.next_ext_hdr_type = 0; - gtpu_write_header(&header, pdu.get(), gtpu_log); + gtpu_write_header(&header, pdu.get(), logger); struct sockaddr_in servaddr; servaddr.sin_family = AF_INET; @@ -366,72 +467,103 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq) sendto(fd, pdu->msg, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); } +/**************************************************************************** + * GTP-U END MARKER + ***************************************************************************/ +void gtpu::end_marker(uint32_t teidin) +{ + logger.info("TX GTPU End Marker."); + tunnel& tunnel = tunnels.find(teidin)->second; + + gtpu_header_t header = {}; + unique_byte_buffer_t pdu = make_byte_buffer(); + + // header + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; + header.message_type = GTPU_MSG_END_MARKER; + header.teid = tunnel.teid_out; + header.length = 0; + + gtpu_write_header(&header, pdu.get(), logger); + + struct sockaddr_in servaddr = {}; + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(tunnel.spgw_addr); + servaddr.sin_port = htons(GTPU_PORT); + + sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); +} + /**************************************************************************** * TEID to RNTI/LCID helper functions ***************************************************************************/ -uint32_t gtpu::allocate_teidin(uint16_t rnti, uint16_t lcid) + +gtpu::tunnel* gtpu::get_tunnel(uint32_t teidin) { - uint32_t teid_in = ++next_teid_in; - if (teidin_to_rntilcid_map.count(teid_in) != 0) { - gtpu_log->error("TEID In already exists\n"); - return 0; + auto it = tunnels.find(teidin); + if (it == tunnels.end()) { + logger.error("TEID=%d In does not exist.", teidin); + return nullptr; } - rnti_lcid_t rnti_lcid = {rnti, lcid}; - teidin_to_rntilcid_map[teid_in] = rnti_lcid; - gtpu_log->debug("TEID In=%d added\n", teid_in); - return teid_in; + return &it->second; } -void gtpu::free_teidin(uint16_t rnti, uint16_t lcid) +srslte::span gtpu::get_lcid_teids(uint16_t rnti, uint32_t lcid) { - for (std::map::iterator it = teidin_to_rntilcid_map.begin(); - it != teidin_to_rntilcid_map.end();) { - if (it->second.rnti == rnti && it->second.lcid == lcid) { - gtpu_log->debug("TEID In=%d erased\n", it->first); - it = teidin_to_rntilcid_map.erase(it); + auto ue_it = ue_teidin_db.find(rnti); + if (ue_it == ue_teidin_db.end() or lcid < SRSENB_N_SRB or lcid >= SRSENB_N_RADIO_BEARERS or + ue_it->second[lcid].empty()) { + logger.error("Could not find bearer rnti=0x%x, lcid=%d", rnti, lcid); + return {}; + } + return ue_it->second[lcid]; +} + +void gtpu::log_message(tunnel& tun, bool is_rx, srslte::span pdu, int pdcp_sn) +{ + fmt::basic_memory_buffer strbuf; + struct iphdr* ip_pkt = (struct iphdr*)pdu.data(); + if (ip_pkt->version != 4 && ip_pkt->version != 6) { + logger.error("%s SDU with invalid IP version %s SPGW", is_rx ? "Received" : "Sending", is_rx ? "from" : "to"); + return; + } + + const char* dir = "Tx"; + fmt::memory_buffer strbuf2; + if (is_rx) { + dir = "Rx"; + fmt::format_to(strbuf2, "{}:0x{:0x} > ", srslte::gtpu_ntoa(htonl(tun.spgw_addr)), tun.teid_in); + if (not tun.dl_enabled) { + fmt::format_to(strbuf2, "DL (buffered), "); + } else if (tun.fwd_teid_in_present) { + tunnel& tx_tun = tunnels.at(tun.fwd_teid_in); + fmt::format_to(strbuf2, "{}:0x{:0x} (forwarded), ", srslte::gtpu_ntoa(htonl(tx_tun.spgw_addr)), tx_tun.teid_in); } else { - it++; + fmt::format_to(strbuf2, "DL, "); } - } -} - -void gtpu::free_teidin(uint16_t rnti) -{ - for (std::map::iterator it = teidin_to_rntilcid_map.begin(); - it != teidin_to_rntilcid_map.end();) { - if (it->second.rnti == rnti) { - gtpu_log->debug("TEID In=%d erased\n", it->first); - it = teidin_to_rntilcid_map.erase(it); + } else { + if (pdcp_sn >= 0) { + fmt::format_to(strbuf2, "DL PDCP SDU SN={} ", pdcp_sn); } else { - it++; + fmt::format_to(strbuf2, "UL "); + } + fmt::format_to(strbuf2, "> {}:0x{:0x}, ", srslte::gtpu_ntoa(htonl(tun.spgw_addr)), tun.teid_in); + } + fmt::format_to(strbuf, + "{} S1-U SDU, {}rnti=0x{:0x}, lcid={}, n_bytes={}, IPv{}", + dir, + fmt::to_string(strbuf2), + tun.rnti, + tun.lcid, + pdu.size(), + (int)ip_pkt->version); + if (ip_pkt->version == 4) { + fmt::format_to(strbuf, " {} > {}", srslte::gtpu_ntoa(ip_pkt->saddr), srslte::gtpu_ntoa(ip_pkt->daddr)); + if (ntohs(ip_pkt->tot_len) != pdu.size()) { + logger.error("IP Len and PDU N_bytes mismatch"); } } -} - -gtpu::rnti_lcid_t gtpu::teidin_to_rntilcid(uint32_t teidin) -{ - rnti_lcid_t rnti_lcid = {}; - if (teidin_to_rntilcid_map.count(teidin) == 0) { - gtpu_log->error("TEID=%d In does not exist.\n", teidin); - return rnti_lcid; - } - rnti_lcid.rnti = teidin_to_rntilcid_map[teidin].rnti; - rnti_lcid.lcid = teidin_to_rntilcid_map[teidin].lcid; - return rnti_lcid; -} - -uint32_t gtpu::rntilcid_to_teidin(uint16_t rnti, uint16_t lcid) -{ - uint32_t teidin = 0; - for (const std::pair& item : teidin_to_rntilcid_map) { - if (item.second.rnti == rnti and item.second.lcid == lcid) { - teidin = item.first; - } - } - if (teidin == 0) { - gtpu_log->error("Could not find TEID. RNTI=0x%x, LCID=%d.\n", rnti, lcid); - } - return teidin; + logger.info(pdu.data(), pdu.size(), fmt::to_string(strbuf)); } /**************************************************************************** @@ -451,13 +583,12 @@ bool gtpu::m1u_handler::init(std::string m1u_multiaddr_, std::string m1u_if_addr m1u_multiaddr = std::move(m1u_multiaddr_); m1u_if_addr = std::move(m1u_if_addr_); pdcp = parent->pdcp; - gtpu_log = parent->gtpu_log; // Set up sink socket struct sockaddr_in bindaddr = {}; m1u_sd = socket(AF_INET, SOCK_DGRAM, 0); if (m1u_sd < 0) { - gtpu_log->error("Failed to create M1-U sink socket\n"); + logger.error("Failed to create M1-U sink socket"); return false; } @@ -466,7 +597,7 @@ bool gtpu::m1u_handler::init(std::string m1u_multiaddr_, std::string m1u_if_addr bindaddr.sin_addr.s_addr = htonl(INADDR_ANY); // Multicast sockets require bind to INADDR_ANY bindaddr.sin_port = htons(GTPU_PORT + 1); if (bind(m1u_sd, (struct sockaddr*)&bindaddr, sizeof(bindaddr)) < 0) { - gtpu_log->error("Failed to bind multicast socket\n"); + logger.error("Failed to bind multicast socket"); return false; } @@ -475,11 +606,11 @@ bool gtpu::m1u_handler::init(std::string m1u_multiaddr_, std::string m1u_if_addr mreq.imr_multiaddr.s_addr = inet_addr(m1u_multiaddr.c_str()); // Multicast address of the service mreq.imr_interface.s_addr = inet_addr(m1u_if_addr.c_str()); // Address of the IF the socket will listen to. if (setsockopt(m1u_sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - gtpu_log->error("Register musticast group for M1-U\n"); - gtpu_log->error("M1-U infterface IP: %s, M1-U Multicast Address %s\n", m1u_if_addr.c_str(), m1u_multiaddr.c_str()); + logger.error("Register musticast group for M1-U"); + logger.error("M1-U infterface IP: %s, M1-U Multicast Address %s", m1u_if_addr.c_str(), m1u_multiaddr.c_str()); return false; } - gtpu_log->info("M1-U initialized\n"); + logger.info("M1-U initialized"); initiated = true; lcid_counter = 1; @@ -492,10 +623,10 @@ bool gtpu::m1u_handler::init(std::string m1u_multiaddr_, std::string m1u_if_addr void gtpu::m1u_handler::handle_rx_packet(srslte::unique_byte_buffer_t pdu, const sockaddr_in& addr) { - gtpu_log->debug("Received %d bytes from M1-U interface\n", pdu->N_bytes); + logger.debug("Received %d bytes from M1-U interface", pdu->N_bytes); gtpu_header_t header; - gtpu_read_header(pdu.get(), &header, gtpu_log); + gtpu_read_header(pdu.get(), &header, logger); pdcp->write_sdu(SRSLTE_MRNTI, lcid_counter, std::move(pdu)); } diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 429b0d8a2..026ef5d9e 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -21,13 +21,14 @@ #include "srsenb/hdr/stack/upper/pdcp.h" #include "srsenb/hdr/stack/upper/common_enb.h" +#include "srslte/interfaces/enb_gtpu_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { -pdcp::pdcp(srslte::task_sched_handle task_sched_, const char* logname) : - task_sched(task_sched_), - log_h(logname), - pool(srslte::byte_buffer_pool::get_instance()) +pdcp::pdcp(srslte::task_sched_handle task_sched_, srslog::basic_logger& logger_) : + task_sched(task_sched_), logger(logger_) {} void pdcp::init(rlc_interface_pdcp* rlc_, rrc_interface_pdcp* rrc_, gtpu_interface_pdcp* gtpu_) @@ -48,7 +49,7 @@ void pdcp::stop() void pdcp::add_user(uint16_t rnti) { if (users.count(rnti) == 0) { - srslte::pdcp* obj = new srslte::pdcp(task_sched, log_h->get_service_name().c_str()); + srslte::pdcp* obj = new srslte::pdcp(task_sched, logger.id().c_str()); obj->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].gtpu_itf); users[rnti].rlc_itf.rnti = rnti; users[rnti].gtpu_itf.rnti = rnti; @@ -143,6 +144,55 @@ void pdcp::reestablish(uint16_t rnti) users[rnti].pdcp->reestablish(); } +void pdcp::send_status_report(uint16_t rnti) +{ + if (users.count(rnti) == 0) { + return; + } + users[rnti].pdcp->send_status_report(); +} + +void pdcp::notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +{ + if (users.count(rnti)) { + users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); + } +} + +void pdcp::notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +{ + if (users.count(rnti)) { + users[rnti].pdcp->notify_failure(lcid, pdcp_sns); + } +} + +void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn) +{ + if (users.count(rnti)) { + if (rnti != SRSLTE_MRNTI) { + // TODO: Handle PDCP SN coming from GTPU + users[rnti].pdcp->write_sdu(lcid, std::move(sdu), pdcp_sn); + } else { + users[rnti].pdcp->write_sdu_mch(lcid, std::move(sdu)); + } + } +} + +void pdcp::send_status_report(uint16_t rnti, uint32_t lcid) +{ + if (users.count(rnti)) { + users[rnti].pdcp->send_status_report(lcid); + } +} + +std::map pdcp::get_buffered_pdus(uint16_t rnti, uint32_t lcid) +{ + if (users.count(rnti)) { + return users[rnti].pdcp->get_buffered_pdus(lcid); + } + return {}; +} + void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) { if (users.count(rnti)) { @@ -150,17 +200,6 @@ void pdcp::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t } } -void pdcp::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) -{ - if (users.count(rnti)) { - if (rnti != SRSLTE_MRNTI) { - users[rnti].pdcp->write_sdu(lcid, std::move(sdu)); - } else { - users[rnti].pdcp->write_sdu_mch(lcid, std::move(sdu)); - } - } -} - void pdcp::user_interface_gtpu::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { gtpu->write_pdu(rnti, lcid, std::move(pdu)); @@ -193,17 +232,17 @@ void pdcp::user_interface_rrc::write_pdu(uint32_t lcid, srslte::unique_byte_buff void pdcp::user_interface_rrc::write_pdu_bcch_bch(srslte::unique_byte_buffer_t pdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void pdcp::user_interface_rrc::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void pdcp::user_interface_rrc::write_pdu_pcch(srslte::unique_byte_buffer_t pdu) { - ERROR("Error: Received PCCH from ue=%d\n", rnti); + ERROR("Error: Received PCCH from ue=%d", rnti); } std::string pdcp::user_interface_rrc::get_rb_name(uint32_t lcid) @@ -211,4 +250,14 @@ std::string pdcp::user_interface_rrc::get_rb_name(uint32_t lcid) return to_string((rb_id_t)lcid); } +void pdcp::get_metrics(pdcp_metrics_t& m, const uint32_t nof_tti) +{ + m.ues.resize(users.size()); + size_t count = 0; + for (auto& user : users) { + user.second.pdcp->get_metrics(m.ues[count], nof_tti); + count++; + } +} + } // namespace srsenb diff --git a/srsenb/src/stack/upper/pdcp_nr.cc b/srsenb/src/stack/upper/pdcp_nr.cc index b0ed3b7e0..2d373f7fb 100644 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ b/srsenb/src/stack/upper/pdcp_nr.cc @@ -24,10 +24,7 @@ namespace srsenb { -pdcp_nr::pdcp_nr(srslte::task_sched_handle task_sched_, const char* logname) : - task_sched(task_sched_), - m_log(logname), - pool(srslte::byte_buffer_pool::get_instance()) +pdcp_nr::pdcp_nr(srslte::task_sched_handle task_sched_, const char* logname) : task_sched(task_sched_), m_log(logname) {} void pdcp_nr::init(const pdcp_nr_args_t& args_, @@ -111,6 +108,24 @@ void pdcp_nr::write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer } } +void pdcp_nr::notify_delivery(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +{ + if (users.count(rnti)) { + users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); + } else { + m_log->error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.\n", rnti); + } +} + +void pdcp_nr::notify_failure(uint16_t rnti, uint32_t lcid, const std::vector& pdcp_sns) +{ + if (users.count(rnti)) { + users[rnti].pdcp->notify_failure(lcid, pdcp_sns); + } else { + m_log->error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.\n", rnti); + } +} + void pdcp_nr::write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) { if (users.count(rnti)) { @@ -152,17 +167,17 @@ void pdcp_nr::user_interface_rrc::write_pdu(uint32_t lcid, srslte::unique_byte_b void pdcp_nr::user_interface_rrc::write_pdu_bcch_bch(srslte::unique_byte_buffer_t pdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void pdcp_nr::user_interface_rrc::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void pdcp_nr::user_interface_rrc::write_pdu_pcch(srslte::unique_byte_buffer_t pdu) { - ERROR("Error: Received PCCH from ue=%d\n", rnti); + ERROR("Error: Received PCCH from ue=%d", rnti); } std::string pdcp_nr::user_interface_rrc::get_rb_name(uint32_t lcid) @@ -170,4 +185,4 @@ std::string pdcp_nr::user_interface_rrc::get_rb_name(uint32_t lcid) return srslte::to_string(static_cast(lcid)); } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 51092b5d7..28be263fc 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -21,23 +21,22 @@ #include "srsenb/hdr/stack/upper/rlc.h" #include "srsenb/hdr/stack/upper/common_enb.h" +#include "srslte/interfaces/enb_mac_interfaces.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" namespace srsenb { void rlc::init(pdcp_interface_rlc* pdcp_, rrc_interface_rlc* rrc_, mac_interface_rlc* mac_, - srslte::timer_handler* timers_, - srslte::log_ref log_h_) + srslte::timer_handler* timers_) { pdcp = pdcp_; rrc = rrc_; - log_h = log_h_; mac = mac_; timers = timers_; - pool = srslte::byte_buffer_pool::get_instance(); - pthread_rwlock_init(&rwlock, nullptr); } @@ -66,7 +65,7 @@ void rlc::add_user(uint16_t rnti) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti) == 0) { - std::unique_ptr obj(new srslte::rlc(log_h->get_service_name().c_str())); + std::unique_ptr obj(new srslte::rlc(logger.id().c_str())); obj->init(&users[rnti], &users[rnti], timers, @@ -90,7 +89,7 @@ void rlc::rem_user(uint16_t rnti) users[rnti].rlc->stop(); users.erase(rnti); } else { - log_h->error("Removing rnti=0x%x. Already removed\n", rnti); + logger.error("Removing rnti=0x%x. Already removed", rnti); } pthread_rwlock_unlock(&rwlock); } @@ -105,7 +104,7 @@ void rlc::clear_buffer(uint16_t rnti) mac->rlc_buffer_state(rnti, i, 0, 0); } } - log_h->info("Cleared buffer rnti=0x%x\n", rnti); + logger.info("Cleared buffer rnti=0x%x", rnti); } pthread_rwlock_unlock(&rwlock); } @@ -185,7 +184,7 @@ void rlc::reestablish(uint16_t rnti) // This function is called by UE RLC instance every time the tx/retx buffers are updated void rlc::update_bsr(uint32_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) { - log_h->debug("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d\n", rnti, lcid, tx_queue); + logger.debug("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); } @@ -279,19 +278,29 @@ void rlc::user_interface::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t } } +void rlc::user_interface::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) +{ + pdcp->notify_delivery(rnti, lcid, pdcp_sns); +} + +void rlc::user_interface::notify_failure(uint32_t lcid, const std::vector& pdcp_sns) +{ + pdcp->notify_failure(rnti, lcid, pdcp_sns); +} + void rlc::user_interface::write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void rlc::user_interface::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void rlc::user_interface::write_pdu_pcch(srslte::unique_byte_buffer_t sdu) { - ERROR("Error: Received PCCH from ue=%d\n", rnti); + ERROR("Error: Received PCCH from ue=%d", rnti); } std::string rlc::user_interface::get_rb_name(uint32_t lcid) diff --git a/srsenb/src/stack/upper/rlc_nr.cc b/srsenb/src/stack/upper/rlc_nr.cc index 47ecc9d9d..fd4ca0e38 100644 --- a/srsenb/src/stack/upper/rlc_nr.cc +++ b/srsenb/src/stack/upper/rlc_nr.cc @@ -24,7 +24,7 @@ namespace srsenb { -rlc_nr::rlc_nr(const char* logname) : m_log(logname), pool(srslte::byte_buffer_pool::get_instance()) {} +rlc_nr::rlc_nr(const char* logname) : m_log(logname) {} void rlc_nr::init(pdcp_interface_rlc_nr* pdcp_, rrc_interface_rlc_nr* rrc_, @@ -198,17 +198,17 @@ void rlc_nr::user_interface::write_pdu(uint32_t lcid, srslte::unique_byte_buffer void rlc_nr::user_interface::write_pdu_bcch_bch(srslte::unique_byte_buffer_t sdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void rlc_nr::user_interface::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t sdu) { - ERROR("Error: Received BCCH from ue=%d\n", rnti); + ERROR("Error: Received BCCH from ue=%d", rnti); } void rlc_nr::user_interface::write_pdu_pcch(srslte::unique_byte_buffer_t sdu) { - ERROR("Error: Received PCCH from ue=%d\n", rnti); + ERROR("Error: Received PCCH from ue=%d", rnti); } std::string rlc_nr::user_interface::get_rb_name(uint32_t lcid) @@ -216,4 +216,14 @@ std::string rlc_nr::user_interface::get_rb_name(uint32_t lcid) return srslte::to_string(static_cast(lcid)); } -} // namespace srsenb \ No newline at end of file +void rlc_nr::user_interface::notify_delivery(uint32_t lcid, const std::vector& pdcp_sns) +{ + m_pdcp->notify_delivery(rnti, lcid, pdcp_sns); +} + +void rlc_nr::user_interface::notify_failure(uint32_t lcid, const std::vector& pdcp_sns) +{ + m_pdcp->notify_failure(rnti, lcid, pdcp_sns); +} + +} // namespace srsenb diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index 8e593cfca..35e77e057 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -26,6 +26,7 @@ #include "srslte/common/enb_events.h" #include "srslte/common/int_helpers.h" #include "srslte/common/logmap.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" #include //for inet_ntop() #include @@ -40,9 +41,9 @@ using srslte::s1ap_mccmnc_to_plmn; using srslte::uint32_to_uint8; -#define procError(fmt, ...) s1ap_ptr->s1ap_log->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define procWarning(fmt, ...) s1ap_ptr->s1ap_log->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define procInfo(fmt, ...) s1ap_ptr->s1ap_log->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procError(fmt, ...) s1ap_ptr->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procWarning(fmt, ...) s1ap_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define procInfo(fmt, ...) s1ap_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) using namespace asn1::s1ap; @@ -66,14 +67,16 @@ s1ap::ue::ho_prep_proc_t::ho_prep_proc_t(s1ap::ue* ue_) : ue_ptr(ue_), s1ap_ptr( srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t target_eci_, srslte::plmn_id_t target_plmn_, + srslte::span fwd_erabs, srslte::unique_byte_buffer_t rrc_container_) { + ho_cmd_msg = nullptr; target_eci = target_eci_; target_plmn = target_plmn_; - procInfo("Sending HandoverRequired to MME id=%d\n", ue_ptr->ctxt.mme_ue_s1ap_id); - if (not ue_ptr->send_ho_required(target_eci, target_plmn, std::move(rrc_container_))) { - procError("Failed to send HORequired to cell 0x%x\n", target_eci); + procInfo("Sending HandoverRequired to MME id=%d", ue_ptr->ctxt.mme_ue_s1ap_id); + if (not ue_ptr->send_ho_required(target_eci, target_plmn, fwd_erabs, std::move(rrc_container_))) { + procError("Failed to send HORequired to cell 0x%x", target_eci); return srslte::proc_outcome_t::error; } @@ -85,7 +88,7 @@ srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(ts1_reloc_prep_expired e) { // do nothing for now - procError("timer TS1Relocprep has expired.\n"); + procError("timer TS1Relocprep has expired."); return srslte::proc_outcome_t::error; } srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const ho_prep_fail_s& msg) @@ -93,7 +96,7 @@ srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const ho_prep_fail_s& msg ue_ptr->ts1_reloc_prep.stop(); std::string cause = s1ap_ptr->get_cause(msg.protocol_ies.cause.value); - procError("HO preparation Failure. Cause: %s\n", cause.c_str()); + procError("HO preparation Failure. Cause: %s", cause.c_str()); srslte::console("HO preparation Failure. Cause: %s\n", cause.c_str()); return srslte::proc_outcome_t::error; @@ -113,18 +116,12 @@ srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const asn1::s1ap::ho_cmd_ if (msg.ext or msg.protocol_ies.target_to_source_transparent_container_secondary_present or msg.protocol_ies.handov_type.value.value != handov_type_opts::intralte or msg.protocol_ies.crit_diagnostics_present or msg.protocol_ies.nas_security_paramsfrom_e_utran_present) { - procWarning("Not handling HandoverCommand extensions and non-intraLTE params\n"); + procWarning("Not handling HandoverCommand extensions and non-intraLTE params"); } // Check for E-RABs that could not be admitted in the target if (msg.protocol_ies.erab_to_release_list_ho_cmd_present) { - procWarning("Not handling E-RABtoReleaseList\n"); - // TODO - } - - // Check for E-RABs subject to being forwarded - if (msg.protocol_ies.erab_subjectto_data_forwarding_list_present) { - procWarning("Not handling E-RABSubjecttoDataForwardingList\n"); + procWarning("Not handling E-RABtoReleaseList"); // TODO } @@ -134,21 +131,22 @@ srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const asn1::s1ap::ho_cmd_ msg.protocol_ies.target_to_source_transparent_container.value.size()); asn1::s1ap::targetenb_to_sourceenb_transparent_container_s container; if (container.unpack(bref) != asn1::SRSASN_SUCCESS) { - procError("Failed to decode TargeteNBToSourceeNBTransparentContainer\n"); + procError("Failed to decode TargeteNBToSourceeNBTransparentContainer"); return srslte::proc_outcome_t::error; } if (container.ie_exts_present or container.ext) { - procWarning("Not handling extensions\n"); + procWarning("Not handling extensions"); } // Create a unique buffer out of transparent container to pass to RRC - rrc_container = srslte::allocate_unique_buffer(*s1ap_ptr->pool, false); + rrc_container = srslte::make_byte_buffer(); if (rrc_container == nullptr) { - procError("Fatal Error: Couldn't allocate buffer.\n"); + procError("Fatal Error: Couldn't allocate buffer."); return srslte::proc_outcome_t::error; } memcpy(rrc_container->msg, container.rrc_container.data(), container.rrc_container.size()); rrc_container->N_bytes = container.rrc_container.size(); + ho_cmd_msg = &msg; return srslte::proc_outcome_t::success; } @@ -156,10 +154,10 @@ srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const asn1::s1ap::ho_cmd_ void s1ap::ue::ho_prep_proc_t::then(const srslte::proc_state_t& result) { if (result.is_error()) { - s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, false, {}); + s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, false, *ho_cmd_msg, {}); } else { - s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, true, std::move(rrc_container)); - procInfo("Completed with success\n"); + s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, true, *ho_cmd_msg, std::move(rrc_container)); + procInfo("Completed with success"); } } @@ -169,23 +167,23 @@ void s1ap::ue::ho_prep_proc_t::then(const srslte::proc_state_t& result) srslte::proc_outcome_t s1ap::s1_setup_proc_t::init() { - procInfo("Starting new MME connection.\n"); + procInfo("Starting new MME connection."); return start_mme_connection(); } srslte::proc_outcome_t s1ap::s1_setup_proc_t::start_mme_connection() { if (not s1ap_ptr->running) { - procInfo("S1AP is not running anymore.\n"); + procInfo("S1AP is not running anymore."); return srslte::proc_outcome_t::error; } if (s1ap_ptr->mme_connected) { - procInfo("eNB S1AP is already connected to MME\n"); + procInfo("eNB S1AP is already connected to MME"); return srslte::proc_outcome_t::success; } if (not s1ap_ptr->connect_mme()) { - procInfo("Failed to initiate SCTP socket. Attempting reconnection in %d seconds\n", + procInfo("Failed to initiate SCTP socket. Attempting reconnection in %d seconds", s1ap_ptr->mme_connect_timer.duration() / 1000); srslte::console("Failed to initiate SCTP socket. Attempting reconnection in %d seconds\n", s1ap_ptr->mme_connect_timer.duration() / 1000); @@ -194,14 +192,14 @@ srslte::proc_outcome_t s1ap::s1_setup_proc_t::start_mme_connection() } if (not s1ap_ptr->setup_s1()) { - procError("S1 setup failed. Exiting...\n"); + procError("S1 setup failed. Exiting..."); srslte::console("S1 setup failed\n"); s1ap_ptr->running = false; return srslte::proc_outcome_t::error; } s1ap_ptr->s1setup_timeout.run(); - procInfo("S1SetupRequest sent. Waiting for response...\n"); + procInfo("S1SetupRequest sent. Waiting for response..."); return srslte::proc_outcome_t::yield; } @@ -211,10 +209,10 @@ srslte::proc_outcome_t s1ap::s1_setup_proc_t::react(const srsenb::s1ap::s1_setup s1ap_ptr->s1setup_timeout.stop(); } if (event.success) { - procInfo("S1Setup procedure completed successfully\n"); + procInfo("S1Setup procedure completed successfully"); return srslte::proc_outcome_t::success; } - procError("S1Setup failed. Exiting...\n"); + procError("S1Setup failed. Exiting..."); srslte::console("S1setup failed\n"); return srslte::proc_outcome_t::error; } @@ -223,7 +221,7 @@ void s1ap::s1_setup_proc_t::then(const srslte::proc_state_t& result) const { if (result.is_error()) { s1ap_ptr->s1ap_socket.reset(); - procInfo("S1AP socket closed.\n"); + procInfo("S1AP socket closed."); } } @@ -231,15 +229,15 @@ void s1ap::s1_setup_proc_t::then(const srslte::proc_state_t& result) const * S1AP class *********************************************************/ -s1ap::s1ap(srslte::task_sched_handle task_sched_) : s1setup_proc(this), task_sched(task_sched_) {} +s1ap::s1ap(srslte::task_sched_handle task_sched_, srslog::basic_logger& logger) : + s1setup_proc(this), logger(logger), task_sched(task_sched_) +{} int s1ap::init(s1ap_args_t args_, rrc_interface_s1ap* rrc_, srsenb::stack_interface_s1ap_lte* stack_) { - rrc = rrc_; - args = args_; - s1ap_log = srslte::logmap::get("S1AP"); - stack = stack_; - pool = srslte::byte_buffer_pool::get_instance(); + rrc = rrc_; + args = args_; + stack = stack_; build_tai_cgi(); @@ -247,7 +245,7 @@ int s1ap::init(s1ap_args_t args_, rrc_interface_s1ap* rrc_, srsenb::stack_interf mme_connect_timer = task_sched.get_unique_timer(); auto mme_connect_run = [this](uint32_t tid) { if (not s1setup_proc.launch()) { - s1ap_log->error("Failed to initiate S1Setup procedure.\n"); + logger.error("Failed to initiate S1Setup procedure."); } }; mme_connect_timer.set(10000, mme_connect_run); @@ -264,7 +262,7 @@ int s1ap::init(s1ap_args_t args_, rrc_interface_s1ap* rrc_, srsenb::stack_interf running = true; // starting MME connection if (not s1setup_proc.launch()) { - s1ap_log->error("Failed to initiate S1Setup procedure.\n"); + logger.error("Failed to initiate S1Setup procedure."); } return SRSLTE_SUCCESS; @@ -309,29 +307,35 @@ void s1ap::build_tai_cgi() /******************************************************************************* /* RRC interface ********************************************************************************/ -void s1ap::initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) +void s1ap::initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, + asn1::s1ap::rrc_establishment_cause_e cause, + srslte::unique_byte_buffer_t pdu) { std::unique_ptr ue_ptr{new ue{this}}; - ue_ptr->ctxt.rnti = rnti; - ue* u = users.add_user(std::move(ue_ptr)); + ue_ptr->ctxt.rnti = rnti; + ue_ptr->ctxt.enb_cc_idx = enb_cc_idx; + ue* u = users.add_user(std::move(ue_ptr)); if (u == nullptr) { - s1ap_log->error("Failed to add rnti=0x%x\n", rnti); + logger.error("Failed to add rnti=0x%x", rnti); return; } u->send_initialuemessage(cause, std::move(pdu), false); } void s1ap::initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu, uint32_t m_tmsi, uint8_t mmec) { std::unique_ptr ue_ptr{new ue{this}}; - ue_ptr->ctxt.rnti = rnti; - ue* u = users.add_user(std::move(ue_ptr)); + ue_ptr->ctxt.rnti = rnti; + ue_ptr->ctxt.enb_cc_idx = enb_cc_idx; + ue* u = users.add_user(std::move(ue_ptr)); if (u == nullptr) { - s1ap_log->error("Failed to add rnti=0x%x\n", rnti); + logger.error("Failed to add rnti=0x%x", rnti); return; } u->send_initialuemessage(cause, std::move(pdu), true, m_tmsi, mmec); @@ -339,11 +343,11 @@ void s1ap::initial_ue(uint16_t rnti, void s1ap::write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) { - s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received RRC SDU"); + logger.info(pdu->msg, pdu->N_bytes, "Received RRC SDU"); ue* u = users.find_ue_rnti(rnti); if (u == nullptr) { - s1ap_log->info("The rnti=0x%x does not exist\n", rnti); + logger.info("The rnti=0x%x does not exist", rnti); return; } u->send_ulnastransport(std::move(pdu)); @@ -351,7 +355,7 @@ void s1ap::write_pdu(uint16_t rnti, srslte::unique_byte_buffer_t pdu) bool s1ap::user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) { - s1ap_log->info("User inactivity - RNTI:0x%x\n", rnti); + logger.info("User inactivity - RNTI:0x%x", rnti); ue* u = users.find_ue_rnti(rnti); if (u == nullptr) { @@ -359,7 +363,7 @@ bool s1ap::user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_r } if (u->was_uectxtrelease_requested()) { - s1ap_log->warning("UE context for RNTI:0x%x is in zombie state. Releasing...\n", rnti); + logger.warning("UE context for RNTI:0x%x is in zombie state. Releasing...", rnti); users.erase(u); rrc->release_complete(rnti); return false; @@ -381,13 +385,13 @@ bool s1ap::user_exists(uint16_t rnti) void s1ap::user_mod(uint16_t old_rnti, uint16_t new_rnti) { - s1ap_log->info("Modifying user context. Old rnti: 0x%x, new rnti: 0x%x\n", old_rnti, new_rnti); + logger.info("Modifying user context. Old rnti: 0x%x, new rnti: 0x%x", old_rnti, new_rnti); if (not user_exists(old_rnti)) { - s1ap_log->error("Old rnti does not exist, aborting.\n"); + logger.error("Old rnti does not exist, aborting."); return; } if (user_exists(new_rnti)) { - s1ap_log->error("New rnti already exists, aborting.\n"); + logger.error("New rnti already exists, aborting."); return; } users.find_ue_rnti(old_rnti)->ctxt.rnti = new_rnti; @@ -410,17 +414,12 @@ void s1ap::ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_re { ue* u = users.find_ue_rnti(rnti); if (u == nullptr) { - s1ap_log->error("rnti 0x%x not found\n", rnti); + logger.error("rnti 0x%x not found", rnti); return; } u->send_erab_setup_response(res); } -// void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) -//{ - -//} - bool s1ap::is_mme_connected() { return mme_connected; @@ -432,7 +431,7 @@ bool s1ap::is_mme_connected() bool s1ap::connect_mme() { - s1ap_log->info("Connecting to MME %s:%d\n", args.mme_addr.c_str(), MME_PORT); + logger.info("Connecting to MME %s:%d", args.mme_addr.c_str(), int(MME_PORT)); // Init SCTP socket and bind it if (not srslte::net_utils::sctp_init_client( @@ -448,7 +447,7 @@ bool s1ap::connect_mme() // Assign a handler to rx MME packets (going to run in a different thread) stack->add_mme_socket(s1ap_socket.fd()); - s1ap_log->info("SCTP socket established with MME\n"); + logger.info("SCTP socket established with MME"); return true; } @@ -501,21 +500,21 @@ bool s1ap::handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, if (flags & MSG_NOTIFICATION) { // Received notification union sctp_notification* notification = (union sctp_notification*)pdu->msg; - s1ap_log->debug("SCTP Notification %d\n", notification->sn_header.sn_type); + logger.debug("SCTP Notification %d", notification->sn_header.sn_type); if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) { - s1ap_log->info("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); + logger.info("SCTP Association Shutdown. Association: %d", sri.sinfo_assoc_id); srslte::console("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); stack->remove_mme_socket(s1ap_socket.get_socket()); s1ap_socket.reset(); } else if (notification->sn_header.sn_type == SCTP_PEER_ADDR_CHANGE && notification->sn_paddr_change.spc_state == SCTP_ADDR_UNREACHABLE) { - s1ap_log->info("SCTP peer addres unreachable. Association: %d\n", sri.sinfo_assoc_id); + logger.info("SCTP peer addres unreachable. Association: %d", sri.sinfo_assoc_id); srslte::console("SCTP peer address unreachable. Association: %d\n", sri.sinfo_assoc_id); stack->remove_mme_socket(s1ap_socket.get_socket()); s1ap_socket.reset(); } } else if (pdu->N_bytes == 0) { - s1ap_log->error("SCTP return 0 bytes. Closing socket\n"); + logger.error("SCTP return 0 bytes. Closing socket"); s1ap_socket.reset(); } @@ -523,12 +522,11 @@ bool s1ap::handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, if (not s1ap_socket.is_init()) { mme_connected = false; if (not s1setup_proc.launch()) { - s1ap_log->error("Failed to initiate MME connection procedure.\n"); + logger.error("Failed to initiate MME connection procedure."); } return false; } - s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received S1AP PDU"); handle_s1ap_rx_pdu(pdu.get()); return true; } @@ -544,9 +542,13 @@ bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu) asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (rx_pdu.unpack(bref) != asn1::SRSASN_SUCCESS) { - s1ap_log->error("Failed to unpack received PDU\n"); + logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack received PDU"); + cause_c cause; + cause.set_protocol().value = cause_protocol_opts::transfer_syntax_error; + send_error_indication(SRSLTE_INVALID_RNTI, cause); return false; } + log_s1ap_msg(rx_pdu, srslte::make_span(*pdu), true); switch (rx_pdu.type().value) { case s1ap_pdu_c::types_opts::init_msg: @@ -556,7 +558,7 @@ bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu) case s1ap_pdu_c::types_opts::unsuccessful_outcome: return handle_unsuccessfuloutcome(rx_pdu.unsuccessful_outcome()); default: - s1ap_log->error("Unhandled PDU type %d\n", rx_pdu.type().value); + logger.error("Unhandled PDU type %d", rx_pdu.type().value); return false; } @@ -583,11 +585,11 @@ bool s1ap::handle_initiatingmessage(const init_msg_s& msg) case s1ap_elem_procs_o::init_msg_c::types_opts::ue_context_mod_request: return handle_uecontextmodifyrequest(msg.value.ue_context_mod_request()); case s1ap_elem_procs_o::init_msg_c::types_opts::ho_request: - return handle_ho_request(msg.value.ho_request()); + return handle_handover_request(msg.value.ho_request()); case s1ap_elem_procs_o::init_msg_c::types_opts::mme_status_transfer: return handle_mme_status_transfer(msg.value.mme_status_transfer()); default: - s1ap_log->error("Unhandled initiating message: %s\n", msg.value.type().to_string().c_str()); + logger.error("Unhandled initiating message: %s", msg.value.type().to_string().c_str()); } return true; } @@ -598,12 +600,11 @@ bool s1ap::handle_successfuloutcome(const successful_outcome_s& msg) case s1ap_elem_procs_o::successful_outcome_c::types_opts::s1_setup_resp: return handle_s1setupresponse(msg.value.s1_setup_resp()); case s1ap_elem_procs_o::successful_outcome_c::types_opts::ho_cmd: - return handle_s1hocommand(msg.value.ho_cmd()); + return handle_handover_command(msg.value.ho_cmd()); case s1ap_elem_procs_o::successful_outcome_c::types_opts::ho_cancel_ack: - s1ap_log->info("Received %s\n", msg.value.type().to_string().c_str()); return true; default: - s1ap_log->error("Unhandled successful outcome message: %s\n", msg.value.type().to_string().c_str()); + logger.error("Unhandled successful outcome message: %s", msg.value.type().to_string().c_str()); } return true; } @@ -614,16 +615,15 @@ bool s1ap::handle_unsuccessfuloutcome(const unsuccessful_outcome_s& msg) case s1ap_elem_procs_o::unsuccessful_outcome_c::types_opts::s1_setup_fail: return handle_s1setupfailure(msg.value.s1_setup_fail()); case s1ap_elem_procs_o::unsuccessful_outcome_c::types_opts::ho_prep_fail: - return handle_hopreparationfailure(msg.value.ho_prep_fail()); + return handle_handover_preparation_failure(msg.value.ho_prep_fail()); default: - s1ap_log->error("Unhandled unsuccessful outcome message: %s\n", msg.value.type().to_string().c_str()); + logger.error("Unhandled unsuccessful outcome message: %s", msg.value.type().to_string().c_str()); } return true; } bool s1ap::handle_s1setupresponse(const asn1::s1ap::s1_setup_resp_s& msg) { - s1ap_log->info("Received S1SetupResponse\n"); s1setupresponse = msg; mme_connected = true; s1_setup_proc_t::s1setupresult res; @@ -634,9 +634,8 @@ bool s1ap::handle_s1setupresponse(const asn1::s1ap::s1_setup_resp_s& msg) bool s1ap::handle_dlnastransport(const dl_nas_transport_s& msg) { - s1ap_log->info("Received DownlinkNASTransport\n"); if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { @@ -644,15 +643,15 @@ bool s1ap::handle_dlnastransport(const dl_nas_transport_s& msg) } if (msg.protocol_ies.ho_restrict_list_present) { - s1ap_log->warning("Not handling HandoverRestrictionList\n"); + logger.warning("Not handling HandoverRestrictionList"); } if (msg.protocol_ies.subscriber_profile_idfor_rfp_present) { - s1ap_log->warning("Not handling SubscriberProfileIDforRFP\n"); + logger.warning("Not handling SubscriberProfileIDforRFP"); } - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu == nullptr) { - s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); + logger.error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread()."); return false; } memcpy(pdu->msg, msg.protocol_ies.nas_pdu.value.data(), msg.protocol_ies.nas_pdu.value.size()); @@ -663,9 +662,8 @@ bool s1ap::handle_dlnastransport(const dl_nas_transport_s& msg) bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& msg) { - s1ap_log->info("Received InitialContextSetupRequest\n"); if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { @@ -696,7 +694,7 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms bool s1ap::handle_paging(const asn1::s1ap::paging_s& msg) { if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } uint32_t ueid = msg.protocol_ies.ue_id_idx_value.value.to_number(); rrc->add_paging_id(ueid, msg.protocol_ies.ue_paging_id.value); @@ -705,9 +703,8 @@ bool s1ap::handle_paging(const asn1::s1ap::paging_s& msg) bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg) { - s1ap_log->info("Received ERABSetupRequest\n"); if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { @@ -720,12 +717,11 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg) bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg) { - s1ap_log->info("Received ERABModifyRequest\n"); std::vector erab_successful_modified = {}; std::vector erab_failed_to_modify = {}; if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { @@ -737,21 +733,27 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg) // Send E-RAB modify response back to the MME if (not u->send_erab_modify_response(erab_successful_modified, erab_failed_to_modify)) { - s1ap_log->info("Failed to send ERABReleaseResponse\n"); + logger.info("Failed to send ERABReleaseResponse"); return false; } return true; } +/** + * @brief eNB handles MME's message "E-RAB RELEASE COMMAND" + * @remark TS 36.413, Section 8.2.3.2 - E-RAB Release - MME initiated (successful operation) + * @param erabs_successfully_released + * @param erabs_failed_to_release + * @return true if message was sent + */ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) { - s1ap_log->info("Received ERABReleaseCommand\n"); std::vector erab_successful_release = {}; std::vector erab_failed_to_release = {}; if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { @@ -763,7 +765,7 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) // Send E-RAB release response back to the MME if (not u->send_erab_release_response(erab_successful_release, erab_failed_to_release)) { - s1ap_log->info("Failed to send ERABReleaseResponse\n"); + logger.info("Failed to send ERABReleaseResponse"); return false; } @@ -772,7 +774,6 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg) { - s1ap_log->info("Received UeContextModificationRequest\n"); ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; @@ -805,9 +806,8 @@ bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg) bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) { - s1ap_log->info("Received UEContextReleaseCommand\n"); if (msg.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } ue* u = nullptr; @@ -815,10 +815,10 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) auto& idpair = msg.protocol_ies.ue_s1ap_ids.value.ue_s1ap_id_pair(); if (idpair.ext) { - s1ap_log->warning("Not handling S1AP message extension\n"); + logger.warning("Not handling S1AP message extension"); } if (idpair.ie_exts_present) { - s1ap_log->warning("Not handling S1AP message iE_Extensions\n"); + logger.warning("Not handling S1AP message iE_Extensions"); } u = find_s1apmsg_user(idpair.enb_ue_s1ap_id, idpair.mme_ue_s1ap_id); if (u == nullptr) { @@ -828,7 +828,7 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) uint32_t mme_ue_id = msg.protocol_ies.ue_s1ap_ids.value.mme_ue_s1ap_id(); u = users.find_ue_mmeid(mme_ue_id); if (u == nullptr) { - s1ap_log->warning("UE for mme_ue_s1ap_id:%d not found - discarding message\n", mme_ue_id); + logger.warning("UE for mme_ue_s1ap_id:%d not found - discarding message", mme_ue_id); return false; } } @@ -837,7 +837,7 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) rrc->release_erabs(rnti); u->send_uectxtreleasecomplete(); users.erase(u); - s1ap_log->info("UE context for RNTI:0x%x released\n", rnti); + logger.info("UE context for RNTI:0x%x released", rnti); rrc->release_complete(rnti); return true; } @@ -845,14 +845,13 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) bool s1ap::handle_s1setupfailure(const asn1::s1ap::s1_setup_fail_s& msg) { std::string cause = get_cause(msg.protocol_ies.cause.value); - s1ap_log->error("S1 Setup Failure. Cause: %s\n", cause.c_str()); + logger.error("S1 Setup Failure. Cause: %s", cause.c_str()); srslte::console("S1 Setup Failure. Cause: %s\n", cause.c_str()); return true; } -bool s1ap::handle_hopreparationfailure(const ho_prep_fail_s& msg) +bool s1ap::handle_handover_preparation_failure(const ho_prep_fail_s& msg) { - s1ap_log->info("Received HO Preparation Failure\n"); ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; @@ -861,9 +860,8 @@ bool s1ap::handle_hopreparationfailure(const ho_prep_fail_s& msg) return true; } -bool s1ap::handle_s1hocommand(const asn1::s1ap::ho_cmd_s& msg) +bool s1ap::handle_handover_command(const asn1::s1ap::ho_cmd_s& msg) { - s1ap_log->info("Received S1 HO Command\n"); ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; @@ -876,13 +874,10 @@ bool s1ap::handle_s1hocommand(const asn1::s1ap::ho_cmd_s& msg) * TS 36.413 - Section 8.4.2 - "Handover Resource Allocation" *************************************************************/ -bool s1ap::handle_ho_request(const asn1::s1ap::ho_request_s& msg) +bool s1ap::handle_handover_request(const asn1::s1ap::ho_request_s& msg) { uint16_t rnti = SRSLTE_INVALID_RNTI; - s1ap_log->info("Received S1 HO Request\n"); - srslte::console("Received S1 HO Request\n"); - auto on_scope_exit = srslte::make_scope_exit([this, &rnti, msg]() { // If rnti is not allocated successfully, remove from s1ap and send handover failure if (rnti == SRSLTE_INVALID_RNTI) { @@ -892,14 +887,14 @@ bool s1ap::handle_ho_request(const asn1::s1ap::ho_request_s& msg) if (msg.ext or msg.protocol_ies.ho_restrict_list_present or msg.protocol_ies.handov_type.value.value != handov_type_opts::intralte) { - s1ap_log->error("Not handling S1AP non-intra LTE handovers and extensions\n"); + logger.error("Not handling S1AP non-intra LTE handovers and extensions"); return false; } // Confirm the UE does not exist in TeNB if (users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value) != nullptr) { - s1ap_log->error("The provided MME_UE_S1AP_ID=%" PRIu64 " is already connected to the cell\n", - msg.protocol_ies.mme_ue_s1ap_id.value.value); + logger.error("The provided MME_UE_S1AP_ID=%" PRIu64 " is already connected to the cell", + msg.protocol_ies.mme_ue_s1ap_id.value.value); return false; } @@ -916,7 +911,7 @@ bool s1ap::handle_ho_request(const asn1::s1ap::ho_request_s& msg) asn1::cbit_ref bref{msg.protocol_ies.source_to_target_transparent_container.value.data(), msg.protocol_ies.source_to_target_transparent_container.value.size()}; if (container.unpack(bref) != asn1::SRSASN_SUCCESS) { - s1ap_log->error("Failed to unpack SourceToTargetTransparentContainer\n"); + logger.error("Failed to unpack SourceToTargetTransparentContainer"); return false; } @@ -944,36 +939,43 @@ bool s1ap::send_ho_failure(uint32_t mme_ue_s1ap_id) return sctp_send_s1ap_pdu(tx_pdu, SRSLTE_INVALID_RNTI, "HandoverFailure"); } -bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, - uint16_t rnti, - srslte::unique_byte_buffer_t ho_cmd, - srslte::span > admitted_bearers) +bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, + uint16_t rnti, + uint32_t enb_cc_idx, + srslte::unique_byte_buffer_t ho_cmd, + srslte::span admitted_bearers) { s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_HO_RES_ALLOC); ho_request_ack_ies_container& container = tx_pdu.successful_outcome().value.ho_request_ack().protocol_ies; - ue* ue_ptr = users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value); - ue_ptr->ctxt.rnti = rnti; + ue* ue_ptr = users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue_ptr->ctxt.rnti = rnti; + ue_ptr->ctxt.enb_cc_idx = enb_cc_idx; container.mme_ue_s1ap_id.value = msg.protocol_ies.mme_ue_s1ap_id.value.value; container.enb_ue_s1ap_id.value = ue_ptr->ctxt.enb_ue_s1ap_id; - // TODO: Add admitted E-RABs - for (uint32_t i = 0; i < msg.protocol_ies.erab_to_be_setup_list_ho_req.value.size(); ++i) { - const auto& erab = msg.protocol_ies.erab_to_be_setup_list_ho_req.value[i]; - const erab_to_be_setup_item_ho_req_s& erabsetup = erab.value.erab_to_be_setup_item_ho_req(); - container.erab_admitted_list.value.push_back({}); - container.erab_admitted_list.value.back().load_info_obj(ASN1_S1AP_ID_ERAB_ADMITTED_ITEM); - auto& c = container.erab_admitted_list.value.back().value.erab_admitted_item(); - c.erab_id = erabsetup.erab_id; - c.gtp_teid = admitted_bearers[i]; + // Add admitted E-RABs + container.erab_admitted_list.value.resize(admitted_bearers.size()); + for (size_t i = 0; i < admitted_bearers.size(); ++i) { + container.erab_admitted_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ADMITTED_ITEM); + auto& c = container.erab_admitted_list.value[i].value.erab_admitted_item(); + c = admitted_bearers[i]; c.transport_layer_address = addr_to_asn1(args.gtp_bind_addr.c_str()); - // c.dl_transport_layer_address_present = true; - // c.dl_transport_layer_address = c.transport_layer_address; - // c.ul_transport_layer_address_present = true; - // c.ul_transport_layer_address = c.transport_layer_address; + + // If E-RAB is proposed for forward tunneling + if (c.dl_g_tp_teid_present) { + c.dl_transport_layer_address_present = true; + c.dl_transport_layer_address = c.transport_layer_address; + } + if (c.ul_gtp_teid_present) { + c.ul_transport_layer_address_present = true; + c.ul_transport_layer_address = c.transport_layer_address; + } } + + // Pack transparent container asn1::s1ap::targetenb_to_sourceenb_transparent_container_s transparent_container; transparent_container.rrc_container.resize(ho_cmd->N_bytes); memcpy(transparent_container.rrc_container.data(), ho_cmd->msg, ho_cmd->N_bytes); @@ -981,7 +983,7 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, auto& pdu = ho_cmd; // reuse pdu asn1::bit_ref bref{pdu->msg, pdu->get_tailroom()}; if (transparent_container.pack(bref) != asn1::SRSASN_SUCCESS) { - s1ap_log->error("Failed to pack TargeteNBToSourceeNBTransparentContainer\n"); + logger.error("Failed to pack TargeteNBToSourceeNBTransparentContainer"); return false; } container.target_to_source_transparent_container.value.resize(bref.distance_bytes()); @@ -992,9 +994,6 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, bool s1ap::handle_mme_status_transfer(const asn1::s1ap::mme_status_transfer_s& msg) { - s1ap_log->info("Received S1 MMEStatusTransfer\n"); - srslte::console("Received S1 MMEStatusTransfer\n"); - ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; @@ -1047,6 +1046,55 @@ void s1ap::send_ho_cancel(uint16_t rnti) sctp_send_s1ap_pdu(tx_pdu, rnti, "HandoverCancel"); } +bool s1ap::release_erabs(uint16_t rnti, const std::vector& erabs_successfully_released) +{ + ue* user_ptr = users.find_ue_rnti(rnti); + if (user_ptr == nullptr) { + return false; + } + return user_ptr->send_erab_release_indication(erabs_successfully_released); +} + +bool s1ap::send_ue_cap_info_indication(uint16_t rnti, srslte::unique_byte_buffer_t ue_radio_cap) +{ + ue* user_ptr = users.find_ue_rnti(rnti); + if (user_ptr == nullptr) { + return false; + } + return user_ptr->send_ue_cap_info_indication(std::move(ue_radio_cap)); +} + +bool s1ap::send_error_indication(uint16_t rnti, const asn1::s1ap::cause_c& cause) +{ + if (not mme_connected) { + return false; + } + + s1ap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERROR_IND); + auto& container = tx_pdu.init_msg().value.error_ind().protocol_ies; + + if (rnti != SRSLTE_INVALID_RNTI) { + ue* user_ptr = users.find_ue_rnti(rnti); + if (user_ptr == nullptr) { + return false; + } + container.enb_ue_s1ap_id_present = true; + container.enb_ue_s1ap_id.value = user_ptr->ctxt.enb_ue_s1ap_id; + container.mme_ue_s1ap_id_present = user_ptr->ctxt.mme_ue_s1ap_id_present; + if (user_ptr->ctxt.mme_ue_s1ap_id_present) { + container.mme_ue_s1ap_id.value = user_ptr->ctxt.mme_ue_s1ap_id; + } + } + + container.s_tmsi_present = false; + + container.cause_present = true; + container.cause.value = cause; + + return sctp_send_s1ap_pdu(tx_pdu, rnti, "Error Indication"); +} + /******************************************************************************* /* S1AP message senders ********************************************************************************/ @@ -1123,7 +1171,7 @@ bool s1ap::ue::send_uectxtreleaserequest(const cause_c& cause) } if (!ctxt.mme_ue_s1ap_id_present) { - s1ap_log->error("Cannot send UE context release request without a MME-UE-S1AP-Id allocated.\n"); + logger.error("Cannot send UE context release request without a MME-UE-S1AP-Id allocated."); return false; } @@ -1154,7 +1202,7 @@ bool s1ap::ue::send_uectxtreleasecomplete() container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id; // Log event. - event_logger::get().log_s1_ctx_delete(ctxt.mme_ue_s1ap_id, ctxt.enb_ue_s1ap_id, ctxt.rnti); + event_logger::get().log_s1_ctx_delete(ctxt.enb_cc_idx, ctxt.mme_ue_s1ap_id, ctxt.enb_ue_s1ap_id, ctxt.rnti); return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseComplete"); } @@ -1188,7 +1236,7 @@ bool s1ap::ue::send_initial_ctxt_setup_response(const asn1::s1ap::init_context_s } // Log event. - event_logger::get().log_s1_ctx_create(ctxt.mme_ue_s1ap_id, ctxt.enb_ue_s1ap_id, ctxt.rnti); + event_logger::get().log_s1_ctx_create(ctxt.enb_cc_idx, ctxt.mme_ue_s1ap_id, ctxt.enb_ue_s1ap_id, ctxt.rnti); return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupResponse"); } @@ -1275,6 +1323,13 @@ bool s1ap::ue::send_uectxtmodifyfailure(const cause_c& cause) return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationFailure"); } +/** + * @brief eNB sends MME to "E-RAB RELEASE RESPONSE" + * @remark TS 36.413, Section 8.2.3.2 - E-RAB Release - MME initiated (successful operation) + * @param erabs_successfully_released + * @param erabs_failed_to_release + * @return true if message was sent + */ bool s1ap::ue::send_erab_release_response(const std::vector& erabs_successfully_released, const std::vector& erabs_failed_to_release) { @@ -1357,6 +1412,53 @@ bool s1ap::ue::send_erab_modify_response(const std::vector& erabs_succ return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E_RABReleaseResponse"); } + +bool s1ap::ue::send_erab_release_indication(const std::vector& erabs_successfully_released) +{ + if (not s1ap_ptr->mme_connected) { + return false; + } + if (not erabs_successfully_released.empty()) { + logger.error("Failed to initiate E-RAB RELEASE INDICATION procedure for user rnti=0x%x", ctxt.rnti); + return false; + } + + asn1::s1ap::s1ap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE_IND); + erab_release_ind_ies_container& container = tx_pdu.init_msg().value.erab_release_ind().protocol_ies; + + container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id; + + // Fill in which E-RABs were successfully released + container.erab_released_list.value.resize(erabs_successfully_released.size()); + for (size_t i = 0; i < container.erab_released_list.value.size(); ++i) { + container.erab_released_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); + container.erab_released_list.value[i].value.erab_item().erab_id = erabs_successfully_released[i]; + } + + return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABReleaseIndication"); +} + +bool s1ap::ue::send_ue_cap_info_indication(srslte::unique_byte_buffer_t ue_radio_cap) +{ + if (not s1ap_ptr->mme_connected) { + return false; + } + + asn1::s1ap::s1ap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_UE_CAP_INFO_IND); + ue_cap_info_ind_ies_container& container = tx_pdu.init_msg().value.ue_cap_info_ind().protocol_ies; + + container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id; + + container.ue_radio_cap.value.resize(ue_radio_cap->N_bytes); + memcpy(container.ue_radio_cap.value.data(), ue_radio_cap->msg, ue_radio_cap->N_bytes); + + return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UECapabilityInfoIndication"); +} + /********************* * Handover Messages ********************/ @@ -1364,6 +1466,7 @@ bool s1ap::ue::send_erab_modify_response(const std::vector& erabs_succ bool s1ap::send_ho_required(uint16_t rnti, uint32_t target_eci, srslte::plmn_id_t target_plmn, + srslte::span fwd_erabs, srslte::unique_byte_buffer_t rrc_container) { if (!mme_connected) { @@ -1375,8 +1478,8 @@ bool s1ap::send_ho_required(uint16_t rnti, } // launch procedure - if (not u->ho_prep_proc.launch(target_eci, target_plmn, std::move(rrc_container))) { - s1ap_log->error("Failed to initiate an HandoverPreparation procedure for user rnti=0x%x\n", u->ctxt.rnti); + if (not u->ho_prep_proc.launch(target_eci, target_plmn, fwd_erabs, std::move(rrc_container))) { + logger.error("Failed to initiate an HandoverPreparation procedure for user rnti=0x%x", u->ctxt.rnti); return false; } return true; @@ -1395,38 +1498,6 @@ bool s1ap::send_enb_status_transfer_proc(uint16_t rnti, std::vectorsend_enb_status_transfer_proc(bearer_status_list); } -// bool s1ap::send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) -//{ -// srslte::byte_buffer_t msg; - -// LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; -// tx_pdu.ext = false; -// tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; - -// LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *init = &tx_pdu.choice.initiatingMessage; -// init->procedureCode = LIBLTE_S1AP_PROC_ID_UPLINKNASTRANSPORT; -// init->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECAPABILITYINFOINDICATION; - -// LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *caps = &init->choice.UECapabilityInfoIndication; -// caps->ext = false; -// caps->mme_ue_s1ap_id.mme_ue_s1ap_id = ue_ctxt_map[rnti]->mme_ue_s1ap_id; -// caps->enb_ue_s1ap_id.ENB_UE_S1AP_ID = ue_ctxt_map[rnti]->enb_ue_s1ap_id; -// // TODO: caps->UERadioCapability. - -// liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)&msg); -// s1ap_log->info_hex(msg.msg, msg.N_bytes, "Sending UERadioCapabilityInfo for RNTI:0x%x", rnti); - -// ssize_t n_sent = sctp_sendmsg(socket_fd, msg.msg, msg.N_bytes, -// (struct sockaddr*)&mme_addr, sizeof(struct sockaddr_in), -// htonl(PPID), 0, ue_ctxt_map[rnti]->stream_id, 0, 0); -// if(n_sent == -1) { -// s1ap_log->error("Failed to send UplinkNASTransport for RNTI:0x%x\n", rnti); -// return false; -// } - -// return true; -//} - /********************************************************* * s1ap::user_list class *********************************************************/ @@ -1464,17 +1535,15 @@ s1ap::ue* s1ap::user_list::add_user(std::unique_ptr user) { // Check for ID repetitions if (find_ue_rnti(user->ctxt.rnti) != nullptr) { - srslte::logmap::get("S1AP")->error("The user to be added with rnti=0x%x already exists\n", user->ctxt.rnti); + srslte::logmap::get("S1AP")->error("The user to be added with rnti=0x%x already exists", user->ctxt.rnti); return nullptr; } if (find_ue_enbid(user->ctxt.enb_ue_s1ap_id) != nullptr) { - srslte::logmap::get("S1AP")->error("The user to be added with enb id=%d already exists\n", - user->ctxt.enb_ue_s1ap_id); + srslte::logmap::get("S1AP")->error("The user to be added with enb id=%d already exists", user->ctxt.enb_ue_s1ap_id); return nullptr; } if (find_ue_mmeid(user->ctxt.mme_ue_s1ap_id) != nullptr) { - srslte::logmap::get("S1AP")->error("The user to be added with mme id=%d already exists\n", - user->ctxt.mme_ue_s1ap_id); + srslte::logmap::get("S1AP")->error("The user to be added with mme id=%d already exists", user->ctxt.mme_ue_s1ap_id); return nullptr; } auto p = users.insert(std::make_pair(user->ctxt.enb_ue_s1ap_id, std::move(user))); @@ -1485,7 +1554,7 @@ void s1ap::user_list::erase(ue* ue_ptr) { auto it = users.find(ue_ptr->ctxt.enb_ue_s1ap_id); if (it == users.end()) { - srslte::logmap::get("S1AP")->error("User to be erased does not exist\n"); + srslte::logmap::get("S1AP")->error("User to be erased does not exist"); return; } users.erase(it); @@ -1497,9 +1566,9 @@ void s1ap::user_list::erase(ue* ue_ptr) bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name) { - srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool, false); + srslte::unique_byte_buffer_t buf = srslte::make_byte_buffer(); if (buf == nullptr) { - s1ap_log->error("Fatal Error: Couldn't allocate buffer for %s.\n", procedure_name); + logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); return false; } asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -1512,9 +1581,9 @@ bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnt } if (rnti != SRSLTE_INVALID_RNTI) { - s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti); + logger.info(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti); } else { - s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s to MME", procedure_name); + logger.info(buf->msg, buf->N_bytes, "Sending %s to MME", procedure_name); } uint16_t streamid = rnti == SRSLTE_INVALID_RNTI ? NONUE_STREAM_ID : users.find_ue_rnti(rnti)->stream_id; @@ -1530,9 +1599,9 @@ bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnt 0); if (n_sent == -1) { if (rnti > 0) { - s1ap_log->error("Failed to send %s for rnti=0x%x\n", procedure_name, rnti); + logger.error("Failed to send %s for rnti=0x%x", procedure_name, rnti); } else { - s1ap_log->error("Failed to send %s\n", procedure_name); + logger.error("Failed to send %s", procedure_name); } return false; } @@ -1547,17 +1616,27 @@ bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnt */ s1ap::ue* s1ap::find_s1apmsg_user(uint32_t enb_id, uint32_t mme_id) { - ue* user_ptr = users.find_ue_enbid(enb_id); - if (user_ptr == nullptr) { - s1ap_log->warning("enb_ue_s1ap_id=%d not found - discarding message\n", enb_id); - return nullptr; + ue* user_ptr = users.find_ue_enbid(enb_id); + cause_c cause; + if (user_ptr != nullptr) { + if (not user_ptr->ctxt.mme_ue_s1ap_id_present) { + user_ptr->ctxt.mme_ue_s1ap_id_present = true; + user_ptr->ctxt.mme_ue_s1ap_id = mme_id; + return user_ptr; + } else if (user_ptr->ctxt.mme_ue_s1ap_id == mme_id) { + return user_ptr; + } else { + logger.warning("MME UE S1AP ID=%d not found - discarding message", enb_id); + cause.set_radio_network().value = cause_radio_network_opts::unknown_mme_ue_s1ap_id; + } + } else { + logger.warning("ENB UE S1AP ID=%d not found - discarding message", enb_id); + cause.set_radio_network().value = users.find_ue_mmeid(mme_id) != nullptr + ? cause_radio_network_opts::unknown_enb_ue_s1ap_id + : cause_radio_network_opts::unknown_pair_ue_s1ap_id; } - if (user_ptr->ctxt.mme_ue_s1ap_id_present and user_ptr->ctxt.mme_ue_s1ap_id != mme_id) { - s1ap_log->warning("MME_UE_S1AP_ID has changed - old:%d, new:%d\n", user_ptr->ctxt.mme_ue_s1ap_id, mme_id); - } - user_ptr->ctxt.mme_ue_s1ap_id_present = true; - user_ptr->ctxt.mme_ue_s1ap_id = mme_id; - return user_ptr; + send_error_indication(SRSLTE_INVALID_RNTI, cause); + return nullptr; } std::string s1ap::get_cause(const cause_c& c) @@ -1595,7 +1674,7 @@ void s1ap::start_pcap(srslte::s1ap_pcap* pcap_) /* s1ap::ue Class ********************************************************************************/ -s1ap::ue::ue(s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), s1ap_log(s1ap_ptr_->s1ap_log), ho_prep_proc(this) +s1ap::ue::ue(s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), ho_prep_proc(this), logger(s1ap_ptr->logger) { ctxt.enb_ue_s1ap_id = s1ap_ptr->next_enb_ue_s1ap_id++; gettimeofday(&ctxt.init_timestamp, nullptr); @@ -1612,6 +1691,7 @@ s1ap::ue::ue(s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), s1ap_log(s1ap_ptr_->s1ap_lo bool s1ap::ue::send_ho_required(uint32_t target_eci, srslte::plmn_id_t target_plmn, + srslte::span fwd_erabs, srslte::unique_byte_buffer_t rrc_container) { /*** Setup S1AP PDU as HandoverRequired ***/ @@ -1646,8 +1726,17 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, /*** fill the transparent container ***/ container.source_to_target_transparent_container_secondary_present = false; sourceenb_to_targetenb_transparent_container_s transparent_cntr; - transparent_cntr.erab_info_list_present = false; // TODO: CHECK + transparent_cntr.erab_info_list_present = true; // TODO: CHECK transparent_cntr.subscriber_profile_idfor_rfp_present = false; // TODO: CHECK + + transparent_cntr.erab_info_list.resize(fwd_erabs.size()); + for (uint32_t i = 0; i < fwd_erabs.size(); ++i) { + transparent_cntr.erab_info_list[i].load_info_obj(ASN1_S1AP_ID_ERAB_INFO_LIST_ITEM); + transparent_cntr.erab_info_list[i].value.erab_info_list_item().erab_id = fwd_erabs[i]; + transparent_cntr.erab_info_list[i].value.erab_info_list_item().dl_forwarding_present = true; + transparent_cntr.erab_info_list[i].value.erab_info_list_item().dl_forwarding.value = + dl_forwarding_opts::dl_forwarding_proposed; + } // - set target cell ID target_plmn.to_s1ap_plmn_bytes(transparent_cntr.target_cell_id.plm_nid.data()); transparent_cntr.target_cell_id.cell_id.from_number(target_eci); // [ENBID|CELLID|0] @@ -1670,17 +1759,22 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, transparent_cntr.rrc_container.resize(rrc_container->N_bytes); memcpy(transparent_cntr.rrc_container.data(), rrc_container->msg, rrc_container->N_bytes); - /*** pack Transparent Container into HORequired message ***/ - uint8_t buffer[4096]; - asn1::bit_ref bref(buffer, sizeof(buffer)); + // pack Transparent Container into HORequired message + srslte::unique_byte_buffer_t buffer = srslte::make_byte_buffer(); + if (buffer == nullptr) { + logger.error("Failed to allocate buffer for HORequired message packing"); + return false; + } + asn1::bit_ref bref(buffer->msg, buffer->get_tailroom()); if (transparent_cntr.pack(bref) != asn1::SRSASN_SUCCESS) { - s1ap_log->error("Failed to pack transparent container of HO Required message\n"); + logger.error("Failed to pack transparent container of HO Required message"); return false; } container.source_to_target_transparent_container.value.resize(bref.distance_bytes()); - memcpy(container.source_to_target_transparent_container.value.data(), buffer, bref.distance_bytes()); + memcpy(container.source_to_target_transparent_container.value.data(), buffer->msg, bref.distance_bytes()); - return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "HORequired"); + // Send to HandoverRequired message to MME + return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "Handover Required"); } bool s1ap::ue::send_enb_status_transfer_proc(std::vector& bearer_status_list) @@ -1713,10 +1807,32 @@ bool s1ap::ue::send_enb_status_transfer_proc(std::vector& be // asn1::json_writer jw; // asn1bearer.to_json(jw); - // printf("Bearer to add %s\n", jw.to_string().c_str()); + // printf("Bearer to add %s", jw.to_string().c_str()); } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "ENBStatusTransfer"); } +void s1ap::log_s1ap_msg(const asn1::s1ap::s1ap_pdu_c& msg, srslte::const_span sdu, bool is_rx) +{ + std::string msg_type; + + switch (msg.type().value) { + case s1ap_pdu_c::types_opts::init_msg: + msg_type = msg.init_msg().value.type().to_string(); + break; + case s1ap_pdu_c::types_opts::successful_outcome: + msg_type = msg.successful_outcome().value.type().to_string(); + break; + case s1ap_pdu_c::types_opts::unsuccessful_outcome: + msg_type = msg.unsuccessful_outcome().value.type().to_string(); + break; + default: + logger.warning("Unrecognized S1AP message type\n"); + return; + } + + logger.info(sdu.data(), sdu.size(), "%s S1AP SDU - %s", is_rx ? "Rx" : "Tx", msg_type.c_str()); +} + } // namespace srsenb diff --git a/srsenb/src/stack/upper/sdap.cc b/srsenb/src/stack/upper/sdap.cc index 3b0ff5792..0a40bb9cc 100644 --- a/srsenb/src/stack/upper/sdap.cc +++ b/srsenb/src/stack/upper/sdap.cc @@ -23,7 +23,7 @@ namespace srsenb { -sdap::sdap() : m_log("SDAP") {} +sdap::sdap() {} bool sdap::init(pdcp_interface_sdap_nr* pdcp_, gtpu_interface_sdap_nr* gtpu_, srsue::gw_interface_pdcp* gw_) { diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index 2ce5ee9d4..fdd30d92f 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -23,6 +23,12 @@ #define SRSENB_DUMMY_CLASSES_H #include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_mac_interfaces.h" +#include "srslte/interfaces/enb_pdcp_interfaces.h" +#include "srslte/interfaces/enb_phy_interfaces.h" +#include "srslte/interfaces/enb_rlc_interfaces.h" +#include "srslte/interfaces/enb_rrc_interfaces.h" +#include "srslte/interfaces/enb_s1ap_interfaces.h" namespace srsenb { @@ -64,13 +70,13 @@ public: void reestablish(uint16_t rnti) override {} }; -class pdcp_dummy : public pdcp_interface_rrc +class pdcp_dummy : public pdcp_interface_rrc, public pdcp_interface_gtpu { public: void reset(uint16_t rnti) override {} void add_user(uint16_t rnti) override {} void rem_user(uint16_t rnti) override {} - void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override {} + void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn) override {} void add_bearer(uint16_t rnti, uint32_t lcid, srslte::pdcp_config_t cnfg) override {} void del_bearer(uint16_t rnti, uint32_t lcid) override {} void config_security(uint16_t rnti, uint32_t lcid, srslte::as_security_config_t sec_cfg_) override {} @@ -79,14 +85,24 @@ public: bool get_bearer_state(uint16_t rnti, uint32_t lcid, srslte::pdcp_lte_state_t* state) override { return true; } bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) override { return true; } void reestablish(uint16_t rnti) override {} + void send_status_report(uint16_t rnti) override {} + void send_status_report(uint16_t rnti, uint32_t lcid) override {} + std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) override + { + return {}; + } }; class s1ap_dummy : public s1ap_interface_rrc { public: - void initial_ue(uint16_t rnti, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu) override + void initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, + asn1::s1ap::rrc_establishment_cause_e cause, + srslte::unique_byte_buffer_t pdu) override {} void initial_ue(uint16_t rnti, + uint32_t enb_cc_idx, asn1::s1ap::rrc_establishment_cause_e cause, srslte::unique_byte_buffer_t pdu, uint32_t m_tmsi, @@ -102,6 +118,7 @@ public: bool send_ho_required(uint16_t rnti, uint32_t target_eci, srslte::plmn_id_t target_plmn, + srslte::span fwd_erabs, srslte::unique_byte_buffer_t rrc_container) override { return true; @@ -110,16 +127,23 @@ public: { return true; } - bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, - uint16_t rnti, - srslte::unique_byte_buffer_t ho_cmd, - srslte::span > admitted_bearers) override + bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, + uint16_t rnti, + uint32_t enb_cc_idx, + srslte::unique_byte_buffer_t ho_cmd, + srslte::span admitted_bearers) override { return true; } void send_ho_notify(uint16_t rnti, uint64_t target_eci) override {} void send_ho_cancel(uint16_t rnti) override {} + + bool release_erabs(uint16_t rnti, const std::vector& erabs_successfully_released) override { return true; } + bool send_ue_cap_info_indication(uint16_t rnti, const srslte::unique_byte_buffer_t ue_radio_cap) override + { + return true; + } }; class phy_dummy : public phy_interface_rrc_lte @@ -133,10 +157,15 @@ public: class gtpu_dummy : public gtpu_interface_rrc { public: - uint32_t add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out) override { return 0; } - void rem_bearer(uint16_t rnti, uint32_t lcid) override {} - void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) override {} - void rem_user(uint16_t rnti) override {} + uint32_t + add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props) override + { + return 0; + } + void set_tunnel_status(uint32_t teidin, bool dl_active) override {} + void rem_bearer(uint16_t rnti, uint32_t lcid) override {} + void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) override {} + void rem_user(uint16_t rnti) override {} }; } // namespace srsenb diff --git a/srsenb/test/mac/sched_ca_test.cc b/srsenb/test/mac/sched_ca_test.cc index 11db47b49..2e0cf77cc 100644 --- a/srsenb/test/mac/sched_ca_test.cc +++ b/srsenb/test/mac/sched_ca_test.cc @@ -32,20 +32,24 @@ uint32_t const seed = std::chrono::system_clock::now().time_since_epoch().count( * Logging * *******************/ -class sched_test_log final : public srslte::test_log_filter +/// RAII style class that prints the test diagnostic info on destruction. +class sched_diagnostic_printer { public: - sched_test_log() : srslte::test_log_filter("TEST") { exit_on_error = true; } - ~sched_test_log() override { log_diagnostics(); } + explicit sched_diagnostic_printer(srslte::log_sink_spy& s) : s(s) {} - void log_diagnostics() override + ~sched_diagnostic_printer() { - info("[TESTER] Number of assertion warnings: %u\n", warn_counter); - info("[TESTER] Number of assertion errors: %u\n", error_counter); - info("[TESTER] This was the seed: %u\n", seed); + auto& logger = srslog::fetch_basic_logger("TEST"); + logger.info("[TESTER] Number of assertion warnings: %u", s.get_warning_counter()); + logger.info("[TESTER] Number of assertion errors: %u", s.get_error_counter()); + logger.info("[TESTER] This was the seed: %u", seed); + srslog::flush(); } + +private: + srslte::log_sink_spy& s; }; -srslte::scoped_log log_global{}; /****************************** * Scheduler Tests @@ -109,7 +113,6 @@ int test_scell_activation(test_scell_activation_params params) /* Setup simulation arguments struct */ sim_sched_args sim_args = generate_default_sim_args(nof_prb, nof_ccs); - sim_args.sim_log = log_global.get(); sim_args.start_tti = start_tti; sim_args.default_ue_sim_cfg.ue_cfg.supported_cc_list.resize(1); sim_args.default_ue_sim_cfg.ue_cfg.supported_cc_list[0].active = true; @@ -121,7 +124,6 @@ int test_scell_activation(test_scell_activation_params params) sched_sim_event_generator generator; // Setup scheduler common_sched_tester tester; - tester.init(nullptr); tester.sim_cfg(sim_args); /* Simulation */ @@ -235,7 +237,7 @@ int test_scell_activation(test_scell_activation_params params) TESTASSERT(tot_dl_sched_data > 0); TESTASSERT(tot_ul_sched_data > 0); - log_global->info("[TESTER] Sim1 finished successfully\n"); + srslog::fetch_basic_logger("TEST").info("[TESTER] Sim1 finished successfully"); return SRSLTE_SUCCESS; } @@ -244,6 +246,28 @@ int main() // Setup rand seed set_randseed(seed); + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srslte::log_sink_spy::name(), + std::unique_ptr(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSLTE_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srslte::log_sink_spy::name())); + if (!spy) { + return SRSLTE_ERROR; + } + + auto& mac_log = srslog::fetch_basic_logger("MAC"); + mac_log.set_level(srslog::basic_levels::info); + auto& test_log = srslog::fetch_basic_logger("TEST", *spy, false); + test_log.set_level(srslog::basic_levels::info); + + // Start the log backend. + srslog::init(); + + sched_diagnostic_printer printer(*spy); + srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); printf("[TESTER] This is the chosen seed: %u\n", seed); uint32_t N_runs = 20; @@ -259,5 +283,7 @@ int main() TESTASSERT(test_scell_activation(p) == SRSLTE_SUCCESS); } + srslog::flush(); + return 0; } diff --git a/srsenb/test/mac/sched_common_test_suite.cc b/srsenb/test/mac/sched_common_test_suite.cc index d3de5fcdc..03342fc3a 100644 --- a/srsenb/test/mac/sched_common_test_suite.cc +++ b/srsenb/test/mac/sched_common_test_suite.cc @@ -36,10 +36,10 @@ int test_pusch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co prbmask_t ul_allocs(nof_prb); auto try_ul_fill = [&](prb_interval alloc, const char* ch_str, bool strict = true) { - CONDERROR(alloc.stop() > nof_prb, "Allocated RBs %s out-of-bounds\n", alloc.to_string().c_str()); - CONDERROR(alloc.empty(), "Allocations must have at least one PRB\n"); + CONDERROR(alloc.stop() > nof_prb, "Allocated RBs %s out-of-bounds", alloc.to_string().c_str()); + CONDERROR(alloc.empty(), "Allocations must have at least one PRB"); if (strict and ul_allocs.any(alloc.start(), alloc.stop())) { - TESTERROR("Collision Detected of %s alloc=%s and cumulative_mask=0x%s\n", + TESTERROR("Collision Detected of %s alloc=%s and cumulative_mask=0x%s", ch_str, alloc.to_string().c_str(), ul_allocs.to_hex().c_str()); @@ -71,7 +71,7 @@ int test_pusch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co } CONDERROR(expected_ul_mask != nullptr and *expected_ul_mask != ul_allocs, - "The derived UL PRB mask %s does not match the expected one %s\n", + "The derived UL PRB mask %s does not match the expected one %s", ul_allocs.to_string().c_str(), expected_ul_mask->to_string().c_str()); @@ -89,7 +89,7 @@ int extract_dl_prbmask(const srslte_cell_t& cell, alloc_mask.reset(); CONDERROR(srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, false, &dci, &grant) == SRSLTE_ERROR, - "Failed to decode PDSCH grant\n"); + "Failed to decode PDSCH grant"); for (uint32_t j = 0; j < alloc_mask.size(); ++j) { if (grant.prb_idx[0][j]) { alloc_mask.set(j); @@ -109,9 +109,9 @@ int test_pdsch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co if (extract_dl_prbmask(cell_params.cfg.cell, dci, alloc_mask) != SRSLTE_SUCCESS) { return SRSLTE_ERROR; } - CONDERROR(alloc_mask.none(), "DL allocation must occupy at least one RBG.\n"); + CONDERROR(alloc_mask.none(), "DL allocation must occupy at least one RBG."); if ((dl_allocs & alloc_mask).any()) { - TESTERROR("Detected collision in the DL %s allocation (%s intersects %s)\n", + TESTERROR("Detected collision in the DL %s allocation (%s intersects %s)", channel, dl_allocs.to_string().c_str(), alloc_mask.to_string().c_str()); @@ -150,14 +150,14 @@ int test_pdsch_collisions(const sf_output_res_t& sf_out, uint32_t enb_cc_idx, co for (uint32_t i = 0; i < cell_params.nof_rbgs; ++i) { uint32_t lim = SRSLTE_MIN((i + 1) * cell_params.P, dl_allocs.size()); bool val = dl_allocs.any(i * cell_params.P, lim); - CONDERROR(rev_alloc.any(i * cell_params.P, lim) and val, "No holes can be left in an RBG\n"); + CONDERROR(rev_alloc.any(i * cell_params.P, lim) and val, "No holes can be left in an RBG"); if (val) { rbgmask.set(i); } } CONDERROR(expected_rbgmask != nullptr and *expected_rbgmask != rbgmask, - "The derived DL RBG mask %s does not match the expected one %s\n", + "The derived DL RBG mask %s does not match the expected one %s", rbgmask.to_string().c_str(), expected_rbgmask->to_string().c_str()); @@ -183,17 +183,17 @@ int test_sib_scheduling(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) /* Test if SIB1 was correctly scheduled */ auto it = std::find_if(bc_begin, bc_end, [](bc_elem& elem) { return elem.index == 0; }); - CONDERROR(sib1_expected and it == bc_end, "Failed to allocate SIB1 in even sfn, sf_idx==5\n"); - CONDERROR(not sib1_expected and it != bc_end, "SIB1 allocated in wrong TTI.\n"); + CONDERROR(sib1_expected and it == bc_end, "Failed to allocate SIB1 in even sfn, sf_idx==5"); + CONDERROR(not sib1_expected and it != bc_end, "SIB1 allocated in wrong TTI."); /* Test if any SIB was scheduled with wrong index, tbs, or outside of its window */ for (bc_elem* bc = bc_begin; bc != bc_end; ++bc) { if (bc->index == 0) { continue; } - CONDERROR(bc->index >= sched_interface::MAX_SIBS, "Invalid SIB idx=%d\n", bc->index + 1); + CONDERROR(bc->index >= sched_interface::MAX_SIBS, "Invalid SIB idx=%d", bc->index + 1); CONDERROR(bc->tbs < cell_params.cfg.sibs[bc->index].len, - "Allocated BC process with TBS=%d < sib_len=%d\n", + "Allocated BC process with TBS=%d < sib_len=%d", bc->tbs, cell_params.cfg.sibs[bc->index].len); uint32_t x = (bc->index - 1) * cell_params.cfg.si_window_ms; @@ -204,7 +204,7 @@ int test_sib_scheduling(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) } srslte::tti_point win_start{sfn_start * 10 + sf}; srslte::tti_interval window{win_start, win_start + cell_params.cfg.si_window_ms}; - CONDERROR(not window.contains(to_tx_dl(sf_out.tti_rx)), "Scheduled SIB is outside of its SIB window\n"); + CONDERROR(not window.contains(to_tx_dl(sf_out.tti_rx)), "Scheduled SIB is outside of its SIB window"); } return SRSLTE_SUCCESS; } @@ -224,14 +224,11 @@ int test_pdcch_collisions(const sf_output_res_t& sf_out, // Helper Function: checks if there is any collision. If not, fills the PDCCH mask auto try_cce_fill = [&](const srslte_dci_location_t& dci_loc, const char* ch) { uint32_t cce_start = dci_loc.ncce, cce_stop = dci_loc.ncce + (1u << dci_loc.L); - CONDERROR(dci_loc.L == 0, "The aggregation level %d is not valid\n", dci_loc.L); + CONDERROR(dci_loc.L == 0, "The aggregation level %d is not valid", dci_loc.L); CONDERROR( - cce_start >= ncce or cce_stop > ncce, "The CCE positions (%u, %u) do not fit in PDCCH\n", cce_start, cce_stop); - CONDERROR(used_cce.any(cce_start, cce_stop), - "%s DCI collision between CCE positions (%u, %u)\n", - ch, - cce_start, - cce_stop); + cce_start >= ncce or cce_stop > ncce, "The CCE positions (%u, %u) do not fit in PDCCH", cce_start, cce_stop); + CONDERROR( + used_cce.any(cce_start, cce_stop), "%s DCI collision between CCE positions (%u, %u)", ch, cce_start, cce_stop); used_cce.fill(cce_start, cce_stop); return SRSLTE_SUCCESS; }; @@ -256,7 +253,7 @@ int test_pdcch_collisions(const sf_output_res_t& sf_out, } CONDERROR(expected_cce_mask != nullptr and *expected_cce_mask != used_cce, - "The derived PDCCH mask %s does not match the expected one %s\n", + "The derived PDCCH mask %s does not match the expected one %s", used_cce.to_string().c_str(), expected_cce_mask->to_string().c_str()); @@ -273,18 +270,18 @@ int test_dci_content_common(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) for (uint32_t i = 0; i < ul_result.nof_dci_elems; ++i) { const auto& pusch = ul_result.pusch[i]; uint16_t rnti = pusch.dci.rnti; - CONDERROR(pusch.tbs == 0, "Allocated PUSCH with invalid TBS=%d\n", pusch.tbs); - CONDERROR(alloc_rntis.count(rnti) > 0, "The user rnti=0x%x got allocated multiple times in UL\n", rnti); + CONDERROR(pusch.tbs == 0, "Allocated PUSCH with invalid TBS=%d", pusch.tbs); + CONDERROR(alloc_rntis.count(rnti) > 0, "The user rnti=0x%x got allocated multiple times in UL", rnti); alloc_rntis.insert(pusch.dci.rnti); - CONDERROR(not((pusch.current_tx_nb == 0) xor (pusch.dci.tb.rv != 0)), "Number of txs incorrectly set\n"); + CONDERROR(not((pusch.current_tx_nb == 0) xor (pusch.dci.tb.rv != 0)), "Number of txs incorrectly set"); if (not pusch.needs_pdcch) { // In case of non-adaptive retx or Msg3 continue; } if (pusch.dci.tb.rv == 0) { // newTx - CONDERROR(pusch.dci.format != SRSLTE_DCI_FORMAT0, "Incorrect UL DCI format\n"); - CONDERROR(pusch.dci.tb.mcs_idx > 28, "Incorrect UL MCS index\n"); + CONDERROR(pusch.dci.format != SRSLTE_DCI_FORMAT0, "Incorrect UL DCI format"); + CONDERROR(pusch.dci.tb.mcs_idx > 28, "Incorrect UL MCS index"); } } @@ -292,8 +289,8 @@ int test_dci_content_common(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) for (uint32_t i = 0; i < dl_result.nof_data_elems; ++i) { auto& data = dl_result.data[i]; uint16_t rnti = data.dci.rnti; - CONDERROR(data.tbs[0] == 0 and data.tbs[1] == 0, "Allocated DL data has empty TBS\n"); - CONDERROR(alloc_rntis.count(rnti) > 0, "The user rnti=0x%x got allocated multiple times in DL\n", rnti); + CONDERROR(data.tbs[0] == 0 and data.tbs[1] == 0, "Allocated DL data has empty TBS"); + CONDERROR(alloc_rntis.count(rnti) > 0, "The user rnti=0x%x got allocated multiple times in DL", rnti); alloc_rntis.insert(data.dci.rnti); for (uint32_t tb = 0; tb < 2; ++tb) { if (data.tbs[tb] == 0) { @@ -301,15 +298,15 @@ int test_dci_content_common(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) } if (data.dci.tb[tb].rv == 0) { // newTx - CONDERROR(data.nof_pdu_elems[tb] == 0, "Allocated DL grant does not have MAC SDUs\n"); + CONDERROR(data.nof_pdu_elems[tb] == 0, "Allocated DL grant does not have MAC SDUs"); CONDERROR(data.nof_pdu_elems[tb] > sched_interface::MAX_RLC_PDU_LIST, - "Number of SDUs in DL grant exceeds limit\n"); + "Number of SDUs in DL grant exceeds limit"); uint32_t alloc_bytes = 0; for (uint32_t pdu = 0; pdu < data.nof_pdu_elems[tb]; ++pdu) { alloc_bytes += data.pdu[tb][pdu].nbytes; } - CONDERROR(alloc_bytes > data.tbs[tb], "The bytes allocated to individual MAC SDUs is larger than total TBS\n"); - CONDERROR(data.dci.tb[tb].mcs_idx > 28, "Incorrect DL MCS index\n"); + CONDERROR(alloc_bytes > data.tbs[tb], "The bytes allocated to individual MAC SDUs is larger than total TBS"); + CONDERROR(data.dci.tb[tb].mcs_idx > 28, "Incorrect DL MCS index"); } } } @@ -317,18 +314,18 @@ int test_dci_content_common(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) auto& bc = dl_result.bc[i]; if (bc.type == sched_interface::dl_sched_bc_t::BCCH) { CONDERROR(bc.tbs < cell_params.cfg.sibs[bc.index].len, - "Allocated BC process with TBS=%d < sib_len=%d\n", + "Allocated BC process with TBS=%d < sib_len=%d", bc.tbs, cell_params.cfg.sibs[bc.index].len); } else if (bc.type == sched_interface::dl_sched_bc_t::PCCH) { - CONDERROR(bc.tbs == 0, "Allocated paging process with invalid TBS=%d\n", bc.tbs); + CONDERROR(bc.tbs == 0, "Allocated paging process with invalid TBS=%d", bc.tbs); } else { - TESTERROR("Invalid broadcast process id=%d\n", (int)bc.type); + TESTERROR("Invalid broadcast process id=%d", (int)bc.type); } } for (uint32_t i = 0; i < dl_result.nof_rar_elems; ++i) { const auto& rar = dl_result.rar[i]; - CONDERROR(rar.tbs == 0, "Allocated RAR process with invalid TBS=%d\n", rar.tbs); + CONDERROR(rar.tbs == 0, "Allocated RAR process with invalid TBS=%d", rar.tbs); } return SRSLTE_SUCCESS; diff --git a/srsenb/test/mac/sched_grid_test.cc b/srsenb/test/mac/sched_grid_test.cc index 335e3cc79..e4b7d4c22 100644 --- a/srsenb/test/mac/sched_grid_test.cc +++ b/srsenb/test/mac/sched_grid_test.cc @@ -54,10 +54,8 @@ int test_pdcch_one_ue() sched_interface::sched_args_t sched_args{}; TESTASSERT(cell_params[ENB_CC_IDX].set_cfg(ENB_CC_IDX, cell_cfg, sched_args)); - pdcch_grid_t pdcch; - sched_ue sched_ue{}; - sched_ue.init(rnti, cell_params); - sched_ue.set_cfg(ue_cfg); + sf_cch_allocator pdcch; + sched_ue sched_ue{rnti, cell_params, ue_cfg}; pdcch.init(cell_params[PCell_IDX]); TESTASSERT(pdcch.nof_alloc_combinations() == 0); @@ -75,12 +73,12 @@ int test_pdcch_one_ue() sched_ue.set_dl_cqi(to_tx_dl(tti_rx), ENB_CC_IDX, dl_cqi); uint32_t aggr_idx = get_aggr_level(sched_ue, PCell_IDX, cell_params); uint32_t max_nof_cce_locs = - sched_ue.get_locations(ENB_CC_IDX, pdcch_grid_t::MAX_CFI, to_tx_dl(tti_rx).sf_idx())->nof_loc[aggr_idx]; + (*sched_ue.get_locations(ENB_CC_IDX, sf_cch_allocator::MAX_CFI, to_tx_dl(tti_rx).sf_idx()))[aggr_idx].size(); // allocate DL user - uint32_t prev_cfi = pdcch.get_cfi(); - const srsenb::sched_dci_cce_t* dci_cce = sched_ue.get_locations(ENB_CC_IDX, prev_cfi, to_tx_dl(tti_rx).sf_idx()); - uint32_t prev_nof_cce_locs = dci_cce->nof_loc[aggr_idx]; + uint32_t prev_cfi = pdcch.get_cfi(); + const cce_cfi_position_table* dci_cce = sched_ue.get_locations(ENB_CC_IDX, prev_cfi, to_tx_dl(tti_rx).sf_idx()); + uint32_t prev_nof_cce_locs = (*dci_cce)[aggr_idx].size(); TESTASSERT(pdcch.alloc_dci(alloc_type_t::DL_DATA, aggr_idx, &sched_ue)); TESTASSERT(pdcch.nof_allocs() == 1); @@ -92,27 +90,26 @@ int test_pdcch_one_ue() TESTASSERT(pdcch.get_cfi() == prev_cfi); } - dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx()); - uint32_t nof_dci_locs = dci_cce->nof_loc[aggr_idx]; - const uint32_t* dci_locs = dci_cce->cce_start[aggr_idx]; + dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx()); + const cce_position_list& dci_locs = (*dci_cce)[aggr_idx]; // TEST: Check the first alloc of the pdcch result (e.g. rnti, valid cce mask, etc.) - pdcch_grid_t::alloc_result_t pdcch_result; - pdcch_mask_t pdcch_mask; + sf_cch_allocator::alloc_result_t pdcch_result; + pdcch_mask_t pdcch_mask; pdcch.get_allocs(&pdcch_result, &pdcch_mask, 0); TESTASSERT(pdcch_result.size() == 1); TESTASSERT(pdcch_result[0]->rnti == sched_ue.get_rnti()); TESTASSERT(pdcch_result[0]->total_mask.size() == cell_params[ENB_CC_IDX].nof_cce_table[pdcch.get_cfi() - 1]); TESTASSERT(pdcch_result[0]->current_mask == pdcch_result[0]->total_mask); TESTASSERT(pdcch_result[0]->current_mask.count() == 1u << aggr_idx); - TESTASSERT(std::count(dci_locs, dci_locs + nof_dci_locs, pdcch_result[0]->dci_pos.ncce) > 0); + TESTASSERT(std::count(dci_locs.begin(), dci_locs.end(), pdcch_result[0]->dci_pos.ncce) > 0); // allocate UL user if (max_nof_cce_locs == pdcch.nof_allocs()) { // no more space continue; } - prev_nof_cce_locs = nof_dci_locs; + prev_nof_cce_locs = dci_locs.size(); prev_cfi = pdcch.get_cfi(); TESTASSERT(pdcch.alloc_dci(alloc_type_t::UL_DATA, aggr_idx, &sched_ue)); TESTASSERT(pdcch.nof_allocs() == 2); @@ -124,9 +121,8 @@ int test_pdcch_one_ue() TESTASSERT(pdcch.get_cfi() == prev_cfi); } - dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx()); - nof_dci_locs = dci_cce->nof_loc[aggr_idx]; - dci_locs = dci_cce->cce_start[aggr_idx]; + dci_cce = sched_ue.get_locations(ENB_CC_IDX, pdcch.get_cfi(), to_tx_dl(tti_rx).sf_idx()); + const cce_position_list& dci_locs2 = (*dci_cce)[aggr_idx]; pdcch.get_allocs(&pdcch_result, &pdcch_mask, 0); TESTASSERT(pdcch_result.size() == pdcch.nof_allocs()); @@ -135,9 +131,9 @@ int test_pdcch_one_ue() TESTASSERT((pdcch_result[1]->current_mask & pdcch_result[0]->current_mask).none()); TESTASSERT(pdcch_result[1]->current_mask.count() == 1u << aggr_idx); TESTASSERT(pdcch_result[1]->total_mask == (pdcch_result[0]->current_mask | pdcch_result[1]->current_mask)); - TESTASSERT(std::count(dci_locs, dci_locs + nof_dci_locs, pdcch_result[0]->dci_pos.ncce) > 0); + TESTASSERT(std::count(dci_locs2.begin(), dci_locs2.end(), pdcch_result[0]->dci_pos.ncce) > 0); - srslte::logmap::get("TEST")->info("PDCCH alloc result: %s\n", pdcch.result_to_string(true).c_str()); + srslog::fetch_basic_logger("TEST").info("PDCCH alloc result: %s", pdcch.result_to_string(true).c_str()); } TESTASSERT(tti_counter == nof_ttis); @@ -148,8 +144,16 @@ int main() { srsenb::set_randseed(seed); printf("This is the chosen seed: %u\n", seed); - srslte::logmap::get("TEST")->set_level(srslte::LOG_LEVEL_INFO); + + auto& test_log = srslog::fetch_basic_logger("TEST", false); + test_log.set_level(srslog::basic_levels::info); + + // Start the log backend. + srslog::init(); TESTASSERT(test_pdcch_one_ue() == SRSLTE_SUCCESS); + + srslog::flush(); + printf("Success\n"); } diff --git a/srsenb/test/mac/sched_lc_ch_test.cc b/srsenb/test/mac/sched_lc_ch_test.cc index 5066db7ed..6cd8fd7ec 100644 --- a/srsenb/test/mac/sched_lc_ch_test.cc +++ b/srsenb/test/mac/sched_lc_ch_test.cc @@ -26,10 +26,12 @@ using namespace srsenb; const uint32_t seed = std::chrono::system_clock::now().time_since_epoch().count(); -uint32_t rlc_overhead(uint32_t lcid) + +uint32_t rlc_overhead(uint32_t lcid) { return lcid == 0 ? 0 : 3; } + uint32_t add_rlc_overhead(uint32_t lcid, uint32_t rlc_payload_size) { return rlc_payload_size + (rlc_payload_size == 0 ? 0 : rlc_overhead(lcid)); @@ -199,9 +201,17 @@ int main() { srsenb::set_randseed(seed); srslte::console("This is the chosen seed: %u\n", seed); - srslte::logmap::get("TEST")->set_level(srslte::LOG_LEVEL_INFO); + + auto& test_log = srslog::fetch_basic_logger("TEST", false); + test_log.set_level(srslog::basic_levels::info); + + // Start the log backend. + srslog::init(); TESTASSERT(test_lc_ch_pbr_infinity() == SRSLTE_SUCCESS); TESTASSERT(test_lc_ch_pbr_finite() == SRSLTE_SUCCESS); + + srslog::flush(); + srslte::console("Success\n"); } diff --git a/srsenb/test/mac/sched_sim_ue.cc b/srsenb/test/mac/sched_sim_ue.cc index 9c0e56892..73ce11d5d 100644 --- a/srsenb/test/mac/sched_sim_ue.cc +++ b/srsenb/test/mac/sched_sim_ue.cc @@ -49,7 +49,8 @@ bool sim_ue_ctxt_t::is_last_dl_retx(uint32_t ue_cc_idx, uint32_t pid) const ue_sim::ue_sim(uint16_t rnti_, const sched_interface::ue_cfg_t& ue_cfg_, srslte::tti_point prach_tti_rx_, - uint32_t preamble_idx) + uint32_t preamble_idx) : + logger(srslog::fetch_basic_logger("MAC")) { ctxt.rnti = rnti_; ctxt.prach_tti_rx = prach_tti_rx_; @@ -223,14 +224,14 @@ int sched_sim_base::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_ { CONDERROR(!srslte_prach_tti_opportunity_config_fdd( (*cell_params)[ue_cfg_.supported_cc_list[0].enb_cc_idx].prach_config, current_tti_rx.to_uint(), -1), - "New user added in a non-PRACH TTI\n"); + "New user added in a non-PRACH TTI"); TESTASSERT(ue_db.count(rnti) == 0); final_ue_cfg[rnti] = ue_cfg_; auto rach_cfg = generate_rach_ue_cfg(ue_cfg_); ue_db.insert(std::make_pair(rnti, ue_sim(rnti, rach_cfg, current_tti_rx, preamble_idx))); - CONDERROR(sched_ptr->ue_cfg(rnti, rach_cfg) != SRSLTE_SUCCESS, "Configuring new user rnti=0x%x to sched\n", rnti); + CONDERROR(sched_ptr->ue_cfg(rnti, rach_cfg) != SRSLTE_SUCCESS, "Configuring new user rnti=0x%x to sched", rnti); sched_interface::dl_sched_rar_info_t rar_info = {}; rar_info.prach_tti = current_tti_rx.to_uint(); @@ -245,9 +246,9 @@ int sched_sim_base::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_ int sched_sim_base::ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_) { - CONDERROR(ue_db.count(rnti) == 0, "User must already exist to be configured\n"); + CONDERROR(ue_db.count(rnti) == 0, "User must already exist to be configured"); ue_db.at(rnti).set_cfg(ue_cfg_); - CONDERROR(sched_ptr->ue_cfg(rnti, ue_cfg_) != SRSLTE_SUCCESS, "Configuring new user rnti=0x%x to sched\n", rnti); + CONDERROR(sched_ptr->ue_cfg(rnti, ue_cfg_) != SRSLTE_SUCCESS, "Configuring new user rnti=0x%x to sched", rnti); return SRSLTE_SUCCESS; } @@ -339,7 +340,7 @@ int sched_sim_base::apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events auto& h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[cc_feedback.dl_pid]; if (cc_feedback.dl_ack) { - log_h->info("DL ACK rnti=0x%x tti_dl_tx=%u pid=%d\n", + logger.info("DL ACK rnti=0x%x tti_dl_tx=%u pid=%d", ue_ctxt.rnti, to_tx_dl(h.last_tti_rx).to_uint(), cc_feedback.dl_pid); @@ -348,7 +349,7 @@ int sched_sim_base::apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events // update scheduler if (sched_ptr->dl_ack_info( events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.tb, cc_feedback.dl_ack) < 0) { - log_h->error("The ACKed DL Harq pid=%d does not exist.\n", cc_feedback.dl_pid); + logger.error("The ACKed DL Harq pid=%d does not exist.", cc_feedback.dl_pid); error_counter++; } @@ -362,7 +363,7 @@ int sched_sim_base::apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events auto& h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[cc_feedback.dl_pid]; if (cc_feedback.ul_ack) { - log_h->info("UL ACK rnti=0x%x tti_ul_tx=%u pid=%d\n", + logger.info("UL ACK rnti=0x%x tti_ul_tx=%u pid=%d", ue_ctxt.rnti, to_tx_ul(h.last_tti_rx).to_uint(), cc_feedback.ul_pid); @@ -370,7 +371,7 @@ int sched_sim_base::apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events // update scheduler if (sched_ptr->ul_crc_info(events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) { - log_h->error("The ACKed UL Harq pid=%d does not exist.\n", cc_feedback.ul_pid); + logger.error("The ACKed UL Harq pid=%d does not exist.", cc_feedback.ul_pid); error_counter++; } } diff --git a/srsenb/test/mac/sched_sim_ue.h b/srsenb/test/mac/sched_sim_ue.h index 0efdc8ae3..46562d39a 100644 --- a/srsenb/test/mac/sched_sim_ue.h +++ b/srsenb/test/mac/sched_sim_ue.h @@ -24,7 +24,9 @@ #include "sched_common_test_suite.h" #include "srslte/interfaces/sched_interface.h" +#include "srslte/srslog/srslog.h" #include +#include namespace srsenb { @@ -99,15 +101,15 @@ private: void update_dl_harqs(const sf_output_res_t& sf_out); void update_ul_harqs(const sf_output_res_t& sf_out); - srslte::log_ref log_h{"MAC"}; - sim_ue_ctxt_t ctxt; + srslog::basic_logger& logger; + sim_ue_ctxt_t ctxt; }; class sched_sim_base { public: sched_sim_base(sched_interface* sched_ptr_, const std::vector& cell_params_) : - sched_ptr(sched_ptr_), cell_params(&cell_params_) + logger(srslog::fetch_basic_logger("MAC")), sched_ptr(sched_ptr_), cell_params(&cell_params_) { sched_ptr->cell_cfg(cell_params_); // call parent cfg } @@ -151,7 +153,7 @@ private: int set_default_tti_events(const sim_ue_ctxt_t& ue_ctxt, ue_tti_events& pending_events); int apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events& events); - srslte::log_ref log_h{"MAC"}; + srslog::basic_logger& logger; sched_interface* sched_ptr; const std::vector* cell_params; diff --git a/srsenb/test/mac/sched_test_common.cc b/srsenb/test/mac/sched_test_common.cc index 7211bec39..694ea0d6a 100644 --- a/srsenb/test/mac/sched_test_common.cc +++ b/srsenb/test/mac/sched_test_common.cc @@ -134,19 +134,17 @@ int common_sched_tester::sim_cfg(sim_sched_args args) { sim_args0 = std::move(args); - sched::set_sched_cfg(&sim_args0.sched_args); + sched::init(nullptr, sim_args0.sched_args); sched_sim.reset(new sched_sim_random{this, sim_args0.cell_cfg}); sched_stats.reset(new sched_result_stats{sim_args0.cell_cfg}); - tester_log = sim_args0.sim_log; - return SRSLTE_SUCCESS; } int common_sched_tester::add_user(uint16_t rnti, const ue_ctxt_test_cfg& ue_cfg_) { - tester_log->info("Adding user rnti=0x%x\n", rnti); + logger.info("Adding user rnti=0x%x", rnti); sched_sim->ue_sim_cfg_map[rnti] = ue_cfg_; return sched_sim->add_user(rnti, ue_cfg_.ue_cfg, tti_info.nof_prachs++); } @@ -158,7 +156,7 @@ int common_sched_tester::reconf_user(uint16_t rnti, const sched_interface::ue_cf int common_sched_tester::rem_user(uint16_t rnti) { - tester_log->info("Removing user rnti=0x%x\n", rnti); + logger.info("Removing user rnti=0x%x", rnti); sched_sim->ue_sim_cfg_map.erase(rnti); return sched_sim->rem_user(rnti); } @@ -177,7 +175,7 @@ void common_sched_tester::new_test_tti() tti_info.dl_sched_result.resize(sched_cell_params.size()); tti_info.ul_sched_result.resize(sched_cell_params.size()); - tester_log->step(tti_rx.to_uint()); + logger.set_context(tti_rx.to_uint()); } int common_sched_tester::run_ue_ded_tests_and_update_ctxt(const sf_output_res_t& sf_out) @@ -224,7 +222,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev) // configure bearers if (ue_ev.bearer_cfg != nullptr) { - CONDERROR(not sched_sim->user_exists(ue_ev.rnti), "User rnti=0x%x does not exist\n", ue_ev.rnti); + CONDERROR(not sched_sim->user_exists(ue_ev.rnti), "User rnti=0x%x does not exist", ue_ev.rnti); // TODO: Instantiate more bearers TESTASSERT(sched_sim->bearer_cfg(ue_ev.rnti, 0, *ue_ev.bearer_cfg) == SRSLTE_SUCCESS); } @@ -233,12 +231,12 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev) // push UL SRs and DL packets if (ue_ev.buffer_ev != nullptr) { - CONDERROR(user == nullptr, "TESTER ERROR: Trying to schedule data for user that does not exist\n"); + CONDERROR(user == nullptr, "TESTER ERROR: Trying to schedule data for user that does not exist"); const auto& ue_sim_ctxt = user->get_ctxt(); if (ue_ev.buffer_ev->dl_data > 0 and ue_sim_ctxt.conres_rx) { // If Msg4 has already been tx and there DL data to transmit uint32_t lcid = RB_ID_DRB1; - uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data(); + uint32_t pending_dl_new_data = ue_db[ue_ev.rnti]->get_pending_dl_rlc_data(); // DRB is set. Update DL buffer uint32_t tot_dl_data = pending_dl_new_data + ue_ev.buffer_ev->dl_data; // TODO: derive pending based on rx dl_rlc_buffer_state(ue_ev.rnti, lcid, tot_dl_data, 0); // TODO: Check retx_queue @@ -246,7 +244,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev) if (ue_ev.buffer_ev->sr_data > 0 and ue_sim_ctxt.conres_rx) { uint32_t tot_ul_data = - ue_db[ue_ev.rnti].get_pending_ul_new_data(to_tx_ul(tti_rx), -1) + ue_ev.buffer_ev->sr_data; + ue_db[ue_ev.rnti]->get_pending_ul_new_data(to_tx_ul(tti_rx), -1) + ue_ev.buffer_ev->sr_data; uint32_t lcg = 1; ul_bsr(ue_ev.rnti, lcg, tot_ul_data); } @@ -258,7 +256,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev) int common_sched_tester::run_tti(const tti_ev& tti_events) { new_test_tti(); - tester_log->info("---- tti=%u | nof_ues=%zd ----\n", tti_rx.to_uint(), ue_db.size()); + logger.info("---- tti=%u | nof_ues=%zd ----", tti_rx.to_uint(), ue_db.size()); sched_sim->new_tti(tti_rx); process_tti_events(tti_events); diff --git a/srsenb/test/mac/sched_test_common.h b/srsenb/test/mac/sched_test_common.h index 01e0c0cd3..85a083f6d 100644 --- a/srsenb/test/mac/sched_test_common.h +++ b/srsenb/test/mac/sched_test_common.h @@ -25,6 +25,7 @@ #include "sched_sim_ue.h" #include "sched_test_utils.h" #include "srsenb/hdr/stack/mac/sched.h" +#include "srslte/srslog/srslog.h" #include namespace srsenb { @@ -87,6 +88,7 @@ public: std::vector ul_sched_result; }; + common_sched_tester() : logger(srslog::fetch_basic_logger("TEST")) {} ~common_sched_tester() override = default; const ue_cfg_t* get_current_ue_cfg(uint16_t rnti) const; @@ -104,8 +106,8 @@ public: int run_ue_ded_tests_and_update_ctxt(const sf_output_res_t& sf_out); // args - sim_sched_args sim_args0; ///< arguments used to generate TTI events - srslte::log* tester_log = nullptr; + sim_sched_args sim_args0; ///< arguments used to generate TTI events + srslog::basic_logger& logger; // tti specific params tti_info_t tti_info; diff --git a/srsenb/test/mac/sched_test_rand.cc b/srsenb/test/mac/sched_test_rand.cc index 8474050e3..2e0bf5ca7 100644 --- a/srsenb/test/mac/sched_test_rand.cc +++ b/srsenb/test/mac/sched_test_rand.cc @@ -30,7 +30,6 @@ #include #include "srslte/common/log_filter.h" -#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/sched_interface.h" #include "srslte/phy/utils/debug.h" @@ -57,34 +56,38 @@ ue_stats_t ue_tot_stats; * Logging * *******************/ -class sched_test_log final : public srslte::test_log_filter +/// RAII style class that prints the test diagnostic info on destruction. +class sched_diagnostic_printer { public: - sched_test_log() : srslte::test_log_filter("TEST") { exit_on_error = true; } - ~sched_test_log() override { log_diagnostics(); } + explicit sched_diagnostic_printer(srslte::log_sink_spy& s) : s(s) {} - void log_diagnostics() override + ~sched_diagnostic_printer() { - info("UE stats:\n"); - info("all: {DL/UL RBs: %" PRIu32 "/%" PRIu32 ", DL/UL bitrates: %0.2f/%0.2f Mbps}\n", - ue_tot_stats.nof_dl_rbs, - ue_tot_stats.nof_ul_rbs, - ue_tot_stats.nof_dl_bytes * 8 * 0.001 / ue_tot_stats.nof_ttis, - ue_tot_stats.nof_ul_bytes * 8 * 0.001 / ue_tot_stats.nof_ttis); - for (auto& e : ue_stats) { - info("0x%x: {DL/UL RBs: %" PRIu32 "/%" PRIu32 ", DL/UL bitrates: %0.2f/%0.2f Mbps}\n", - e.first, - e.second.nof_dl_rbs, - e.second.nof_ul_rbs, - e.second.nof_dl_bytes * 8 * 0.001 / e.second.nof_ttis, - e.second.nof_ul_bytes * 8 * 0.001 / e.second.nof_ttis); + auto& logger = srslog::fetch_basic_logger("TEST"); + logger.info("UE stats:"); + logger.info("all: {DL/UL RBs: %" PRIu32 "/%" PRIu32 ", DL/UL bitrates: %0.2f/%0.2f Mbps}", + ue_tot_stats.nof_dl_rbs, + ue_tot_stats.nof_ul_rbs, + ue_tot_stats.nof_dl_bytes * 8 * 0.001 / ue_tot_stats.nof_ttis, + ue_tot_stats.nof_ul_bytes * 8 * 0.001 / ue_tot_stats.nof_ttis); + for (const auto& e : ue_stats) { + logger.info("0x%x: {DL/UL RBs: %" PRIu32 "/%" PRIu32 ", DL/UL bitrates: %0.2f/%0.2f Mbps}", + e.first, + e.second.nof_dl_rbs, + e.second.nof_ul_rbs, + e.second.nof_dl_bytes * 8 * 0.001 / e.second.nof_ttis, + e.second.nof_ul_bytes * 8 * 0.001 / e.second.nof_ttis); } - info("Number of assertion warnings: %u\n", warn_counter); - info("Number of assertion errors: %u\n", error_counter); - info("This was the seed: %u\n", seed); + logger.info("Number of assertion warnings: %u", s.get_warning_counter()); + logger.info("Number of assertion errors: %u", s.get_error_counter()); + logger.info("This was the seed: %u", seed); + srslog::flush(); } + +private: + srslte::log_sink_spy& s; }; -srslte::scoped_log log_global{}; /******************* * Dummies * @@ -134,7 +137,7 @@ void sched_tester::before_sched() // check pending data buffers for (auto& it : ue_db) { uint16_t rnti = it.first; - srsenb::sched_ue* user = &it.second; + srsenb::sched_ue* user = it.second.get(); tester_user_results d; tti_data.ue_data.insert(std::make_pair(rnti, d)); @@ -171,33 +174,33 @@ int sched_tester::test_harqs() const auto& data = tti_info.dl_sched_result[CARRIER_IDX].data[i]; uint32_t h_id = data.dci.pid; uint16_t rnti = data.dci.rnti; - const srsenb::dl_harq_proc& h = ue_db[rnti].get_dl_harq(h_id, CARRIER_IDX); + const srsenb::dl_harq_proc& h = ue_db[rnti]->get_dl_harq(h_id, CARRIER_IDX); CONDERROR(h.get_tti() != srsenb::to_tx_dl(tti_rx), - "The scheduled DL harq pid=%d does not a valid tti=%u\n", + "The scheduled DL harq pid=%d does not a valid tti=%u", h_id, srsenb::to_tx_dl(tti_rx).to_uint()); - CONDERROR(h.get_n_cce() != data.dci.location.ncce, "Harq DCI location does not match with result\n"); + CONDERROR(h.get_n_cce() != data.dci.location.ncce, "Harq DCI location does not match with result"); } /* Check PHICH allocations */ for (uint32_t i = 0; i < tti_info.ul_sched_result[CARRIER_IDX].nof_phich_elems; ++i) { const auto& phich = tti_info.ul_sched_result[CARRIER_IDX].phich[i]; const auto& hprev = tti_data.ue_data[phich.rnti].ul_harq; - const auto* h = ue_db[phich.rnti].get_ul_harq(srsenb::to_tx_ul(tti_rx), CARRIER_IDX); - CONDERROR(not hprev.has_pending_phich(), "Alloc PHICH did not have any pending ack\n"); + const auto* h = ue_db[phich.rnti]->get_ul_harq(srsenb::to_tx_ul(tti_rx), CARRIER_IDX); + CONDERROR(not hprev.has_pending_phich(), "Alloc PHICH did not have any pending ack"); bool maxretx_flag = hprev.nof_retx(0) + 1 >= hprev.max_nof_retx(); if (phich.phich == sched_interface::ul_sched_phich_t::ACK) { // The harq can be either ACKed or Resumed if (not hprev.is_empty()) { // In case it was resumed - CONDERROR(h == nullptr or h->is_empty(), "Cannot resume empty UL harq\n"); + CONDERROR(h == nullptr or h->is_empty(), "Cannot resume empty UL harq"); for (uint32_t j = 0; j < tti_info.ul_sched_result[CARRIER_IDX].nof_dci_elems; ++j) { auto& pusch = tti_info.ul_sched_result[CARRIER_IDX].pusch[j]; - CONDERROR(pusch.dci.rnti == phich.rnti, "Cannot send PHICH::ACK for same harq that got UL grant.\n"); + CONDERROR(pusch.dci.rnti == phich.rnti, "Cannot send PHICH::ACK for same harq that got UL grant."); } } } else { - CONDERROR(h->get_pending_data() == 0 and !maxretx_flag, "NACKed harq has no pending data\n"); + CONDERROR(h->get_pending_data() == 0 and !maxretx_flag, "NACKed harq has no pending data"); } } @@ -248,7 +251,6 @@ void test_scheduler_rand(sched_sim_events sim) sched_tester tester; srsenb::sched my_sched; - tester.init(nullptr); tester.sim_cfg(std::move(sim.sim_args)); tester.test_next_ttis(sim.tti_events); @@ -294,7 +296,6 @@ sched_sim_events rand_sim_params(uint32_t nof_ttis) sim_gen.sim_args.default_ue_sim_cfg.ue_cfg.measgap_offset = std::uniform_int_distribution{ 0, sim_gen.sim_args.default_ue_sim_cfg.ue_cfg.measgap_period}(srsenb::get_rand_gen()); sim_gen.sim_args.start_tti = 0; - sim_gen.sim_args.sim_log = log_global.get(); sim_gen.sim_args.sched_args.pdsch_mcs = boolean_dist() ? -1 : std::uniform_int_distribution<>{0, 24}(srsenb::get_rand_gen()); sim_gen.sim_args.sched_args.pusch_mcs = @@ -335,9 +336,29 @@ int main() srsenb::set_randseed(seed); printf("This is the chosen seed: %u\n", seed); - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srslte::log_sink_spy::name(), + std::unique_ptr(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSLTE_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srslte::log_sink_spy::name())); + if (!spy) { + return SRSLTE_ERROR; + } + + auto& mac_log = srslog::fetch_basic_logger("MAC"); + mac_log.set_level(srslog::basic_levels::info); + auto& test_log = srslog::fetch_basic_logger("TEST", *spy, false); + test_log.set_level(srslog::basic_levels::info); + + // Start the log backend. + srslog::init(); + uint32_t N_runs = 1, nof_ttis = 10240 + 10; + sched_diagnostic_printer printer(*spy); for (uint32_t n = 0; n < N_runs; ++n) { printf("Sim run number: %u\n", n + 1); sched_sim_events sim = rand_sim_params(nof_ttis); diff --git a/srsenb/test/mac/sched_test_utils.h b/srsenb/test/mac/sched_test_utils.h index cb2b5ea0e..307831f8f 100644 --- a/srsenb/test/mac/sched_test_utils.h +++ b/srsenb/test/mac/sched_test_utils.h @@ -163,7 +163,6 @@ struct tti_ev { struct sim_sched_args { uint32_t start_tti = 0; std::vector cell_cfg; - srslte::log* sim_log = nullptr; ue_ctxt_test_cfg default_ue_sim_cfg{}; srsenb::sched_interface::sched_args_t sched_args = {}; }; diff --git a/srsenb/test/mac/sched_ue_ded_test_suite.cc b/srsenb/test/mac/sched_ue_ded_test_suite.cc index 571af63ac..3cbf70e56 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -76,28 +76,28 @@ int test_pdsch_grant(const sim_enb_ctxt_t& enb_ctxt, const sched_interface::cell_cfg_t& cell_params = (*enb_ctxt.cell_params)[enb_cc_idx]; // TEST: Check if CC is configured and active - CONDERROR(cc_cfg == nullptr or not cc_cfg->active, "PDSCH allocation for disabled or unavailable cc\n"); - CONDERROR(pdsch.dci.ue_cc_idx != std::distance(&ue_ctxt.ue_cfg.supported_cc_list.front(), cc_cfg), - "Inconsistent enb_cc_idx -> ue_cc_idx mapping\n"); + CONDERROR(cc_cfg == nullptr or not cc_cfg->active, "PDSCH allocation for disabled or unavailable cc"); + CONDERROR(pdsch.dci.ue_cc_idx != (uint32_t)std::distance(&ue_ctxt.ue_cfg.supported_cc_list.front(), cc_cfg), + "Inconsistent enb_cc_idx -> ue_cc_idx mapping"); // TEST: DCI is consistent with current UE DL harq state auto& h = ue_ctxt.cc_list[pdsch.dci.ue_cc_idx].dl_harqs[pdsch.dci.pid]; uint32_t nof_retx = get_nof_retx(pdsch.dci.tb[0].rv); // 0..3 if (h.nof_txs == 0 or h.ndi != pdsch.dci.tb[0].ndi) { // It is newtx - CONDERROR(nof_retx != 0, "Invalid rv index for new tx\n"); - CONDERROR(h.active, "DL newtx for already active DL harq pid=%d\n", h.pid); + CONDERROR(nof_retx != 0, "Invalid rv index for new tx"); + CONDERROR(h.active, "DL newtx for already active DL harq pid=%d", h.pid); } else { // it is retx - CONDERROR(get_rvidx(h.nof_retxs + 1) != (uint32_t)pdsch.dci.tb[0].rv, "Invalid rv index for retx\n"); - CONDERROR(not h.active, "retx for inactive dl harq pid=%d\n", h.pid); - CONDERROR(to_tx_dl_ack(h.last_tti_rx) > tti_rx, "harq pid=%d reused too soon\n", h.pid); + CONDERROR(get_rvidx(h.nof_retxs + 1) != (uint32_t)pdsch.dci.tb[0].rv, "Invalid rv index for retx"); + CONDERROR(not h.active, "retx for inactive dl harq pid=%d", h.pid); + CONDERROR(to_tx_dl_ack(h.last_tti_rx) > tti_rx, "harq pid=%d reused too soon", h.pid); CONDERROR(h.nof_retxs + 1 > ue_ctxt.ue_cfg.maxharq_tx, - "The number of retx=%d exceeded its max=%d\n", + "The number of retx=%d exceeded its max=%d", h.nof_retxs + 1, ue_ctxt.ue_cfg.maxharq_tx); - // CONDERROR(h.dci_loc.L != pdsch.dci.location.L, "Harq DCI aggregation level changed.\n"); - CONDERROR(h.tbs != pdsch.tbs[0], "TBS changed during HARQ retx\n"); + // CONDERROR(h.dci_loc.L != pdsch.dci.location.L, "Harq DCI aggregation level changed."); + CONDERROR(h.tbs != pdsch.tbs[0], "TBS changed during HARQ retx"); } // TEST: max coderate is not exceeded @@ -113,7 +113,7 @@ int test_pdsch_grant(const sim_enb_ctxt_t& enb_ctxt, srslte_mod_t mod = srslte_ra_dl_mod_from_mcs(pdsch.dci.tb[0].mcs_idx, ue_ctxt.ue_cfg.use_tbs_index_alt); uint32_t max_Qm = ue_ctxt.ue_cfg.use_tbs_index_alt ? 8 : 6; uint32_t Qm = std::min(max_Qm, srslte_mod_bits_x_symbol(mod)); - CONDERROR(coderate > 0.930f * Qm, "Max coderate was exceeded\n"); + CONDERROR(coderate > 0.930f * Qm, "Max coderate was exceeded"); } return SRSLTE_SUCCESS; @@ -125,7 +125,7 @@ int test_dl_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& for (uint32_t i = 0; i < sf_out.dl_cc_result[cc].nof_data_elems; ++i) { const sched_interface::dl_sched_data_t& data = sf_out.dl_cc_result[cc].data[i]; CONDERROR( - enb_ctxt.ue_db.count(data.dci.rnti) == 0, "Allocated DL grant for non-existent rnti=0x%x\n", data.dci.rnti); + enb_ctxt.ue_db.count(data.dci.rnti) == 0, "Allocated DL grant for non-existent rnti=0x%x", data.dci.rnti); TESTASSERT(test_pdsch_grant(enb_ctxt, sf_out, cc, data) == SRSLTE_SUCCESS); } } @@ -146,7 +146,7 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& CONDERROR(std::any_of(phich_begin, phich_end, [&enb_ctxt](const phich_t& phich) { return enb_ctxt.ue_db.count(phich.rnti) == 0; }), - "Scheduled PHICH does not have associated rnti\n"); + "Scheduled PHICH does not have associated rnti"); // TEST: rnti must exist for all PUSCH CONDERROR(std::any_of(pusch_begin, @@ -166,8 +166,8 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& // TEST: Check that idle CCs do not receive PUSCH grants or PHICH if (ue_cc_idx < 0 or not ue.ue_cfg.supported_cc_list[ue_cc_idx].active) { - CONDERROR(phich_ptr != nullptr, "PHICH cannot be allocated in idle cells\n"); - CONDERROR(pusch_ptr != nullptr, "PUSCH cannot be allocated in idle cells\n"); + CONDERROR(phich_ptr != nullptr, "PHICH cannot be allocated in idle cells"); + CONDERROR(pusch_ptr != nullptr, "PUSCH cannot be allocated in idle cells"); continue; } @@ -178,45 +178,44 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& bool h_inactive = (not h.active) or (phich_ack or last_retx); // TEST: Already active UL HARQs have to receive PHICH - CONDERROR( - h.active and phich_ptr == nullptr, "PHICH not received for rnti=0x%x active UL HARQ pid=%d\n", rnti, pid); + CONDERROR(h.active and phich_ptr == nullptr, "PHICH not received for rnti=0x%x active UL HARQ pid=%d", rnti, pid); CONDERROR(not h.active and phich_ptr != nullptr, - "PHICH for rnti=0x%x corresponds to inactive UL HARQ pid=%d\n", + "PHICH for rnti=0x%x corresponds to inactive UL HARQ pid=%d", rnti, pid); // TEST: absent PUSCH grants for active UL HARQs must be either ACKs, last retx, or interrupted HARQs if ((phich_ptr != nullptr) and (pusch_ptr == nullptr)) { - CONDERROR(not h_inactive, "PHICH NACK received for rnti=0x%x but no PUSCH retx reallocated\n", rnti); + CONDERROR(not h_inactive, "PHICH NACK received for rnti=0x%x but no PUSCH retx reallocated", rnti); } if (pusch_ptr != nullptr) { - CONDERROR(pusch_ptr->dci.ue_cc_idx != (uint32_t)ue_cc_idx, "Inconsistent enb_cc_idx -> ue_cc_idx mapping\n"); + CONDERROR(pusch_ptr->dci.ue_cc_idx != (uint32_t)ue_cc_idx, "Inconsistent enb_cc_idx -> ue_cc_idx mapping"); // TEST: DCI is consistent with current UE UL harq state uint32_t nof_retx = get_nof_retx(pusch_ptr->dci.tb.rv); // 0..3 if (h.nof_txs == 0 or h.ndi != pusch_ptr->dci.tb.ndi) { // newtx - CONDERROR(nof_retx != 0, "Invalid rv index for new tx\n"); - CONDERROR(pusch_ptr->current_tx_nb != 0, "UL HARQ retxs need to have been previously transmitted\n"); - CONDERROR(not h_inactive, "New tx for already active UL HARQ\n"); + CONDERROR(nof_retx != 0, "Invalid rv index for new tx"); + CONDERROR(pusch_ptr->current_tx_nb != 0, "UL HARQ retxs need to have been previously transmitted"); + CONDERROR(not h_inactive, "New tx for already active UL HARQ"); } else { - CONDERROR(pusch_ptr->current_tx_nb == 0, "UL retx has to have nof tx > 0\n"); + CONDERROR(pusch_ptr->current_tx_nb == 0, "UL retx has to have nof tx > 0"); if (not h.active) { // the HARQ is being resumed - CONDERROR(not pusch_ptr->needs_pdcch, "Resumed UL HARQs need to be signalled in PDCCH\n"); + CONDERROR(not pusch_ptr->needs_pdcch, "Resumed UL HARQs need to be signalled in PDCCH"); } else { if (pusch_ptr->needs_pdcch) { - CONDERROR(pusch_ptr->dci.type2_alloc.riv == h.riv, "Adaptive retx must change riv\n"); + CONDERROR(pusch_ptr->dci.type2_alloc.riv == h.riv, "Adaptive retx must change riv"); } else { // non-adaptive retx - CONDERROR(pusch_ptr->dci.type2_alloc.riv != h.riv, "Non-adaptive retx must keep the same riv\n"); + CONDERROR(pusch_ptr->dci.type2_alloc.riv != h.riv, "Non-adaptive retx must keep the same riv"); } } - CONDERROR(get_rvidx(h.nof_retxs + 1) != (uint32_t)pusch_ptr->dci.tb.rv, "Invalid rv index for retx\n"); - CONDERROR(h.tbs != pusch_ptr->tbs, "TBS changed during HARQ retx\n"); - CONDERROR(to_tx_ul(h.last_tti_rx) > sf_out.tti_rx, "UL harq pid=%d was reused too soon\n", h.pid); + CONDERROR(get_rvidx(h.nof_retxs + 1) != (uint32_t)pusch_ptr->dci.tb.rv, "Invalid rv index for retx"); + CONDERROR(h.tbs != pusch_ptr->tbs, "TBS changed during HARQ retx"); + CONDERROR(to_tx_ul(h.last_tti_rx) > sf_out.tti_rx, "UL harq pid=%d was reused too soon", h.pid); } } } @@ -247,11 +246,11 @@ int test_ra(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) if (not rar_window.contains(tti_tx_dl)) { CONDERROR(not ue.rar_tti_rx.is_valid() and tti_tx_dl > rar_window.stop(), - "rnti=0x%x RAR not scheduled within the RAR Window\n", + "rnti=0x%x RAR not scheduled within the RAR Window", rnti); for (uint32_t i = 0; i < sf_out.dl_cc_result[cc].nof_rar_elems; ++i) { CONDERROR(sf_out.dl_cc_result[cc].rar[i].dci.rnti == rnti, - "No RAR allocations allowed outside of user RAR window\n"); + "No RAR allocations allowed outside of user RAR window"); } } else { // Inside RAR window @@ -260,19 +259,19 @@ int test_ra(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) for (const auto& grant : dl_cc_res.rar[i].msg3_grant) { const auto& data = grant.data; if (data.prach_tti == (uint32_t)ue.prach_tti_rx.to_uint() and data.preamble_idx == ue.preamble_idx) { - CONDERROR(rnti != data.temp_crnti, "RAR grant C-RNTI does not match the expected.\n"); + CONDERROR(rnti != data.temp_crnti, "RAR grant C-RNTI does not match the expected."); nof_rars++; } } } - CONDERROR(nof_rars > 1, "There was more than one RAR for the same user\n"); + CONDERROR(nof_rars > 1, "There was more than one RAR for the same user"); } // TEST: Msg3 was allocated if (ue.rar_tti_rx.is_valid() and not ue.msg3_tti_rx.is_valid()) { // RAR scheduled, Msg3 not yet scheduled srslte::tti_point expected_msg3_tti_rx = ue.rar_tti_rx + MSG3_DELAY_MS; - CONDERROR(expected_msg3_tti_rx < sf_out.tti_rx, "No UL msg3 alloc was made\n"); + CONDERROR(expected_msg3_tti_rx < sf_out.tti_rx, "No UL msg3 alloc was made"); if (expected_msg3_tti_rx == sf_out.tti_rx) { // Msg3 should exist @@ -280,13 +279,13 @@ int test_ra(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) for (uint32_t i = 0; i < ul_cc_res.nof_dci_elems; ++i) { if (ul_cc_res.pusch[i].dci.rnti == rnti) { msg3_count++; - CONDERROR(ul_cc_res.pusch[i].needs_pdcch, "Msg3 allocations do not require PDCCH\n"); + CONDERROR(ul_cc_res.pusch[i].needs_pdcch, "Msg3 allocations do not require PDCCH"); CONDERROR(ue.msg3_riv != ul_cc_res.pusch[i].dci.type2_alloc.riv, - "The Msg3 was not allocated in the expected PRBs.\n"); + "The Msg3 was not allocated in the expected PRBs."); } } - CONDERROR(msg3_count == 0, "Msg3 was not transmitted.\n"); - CONDERROR(msg3_count > 1, "Only one Msg3 allower per user.\n"); + CONDERROR(msg3_count == 0, "Msg3 was not transmitted."); + CONDERROR(msg3_count > 1, "Only one Msg3 allower per user."); } } @@ -297,33 +296,33 @@ int test_ra(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) for (uint32_t i = 0; i < dl_cc_res.nof_data_elems; ++i) { if (dl_cc_res.data[i].dci.rnti == rnti) { CONDERROR(to_tx_dl(sf_out.tti_rx) < to_tx_ul(ue.msg3_tti_rx), - "Msg4 cannot be scheduled without Msg3 being tx\n"); + "Msg4 cannot be scheduled without Msg3 being tx"); for (uint32_t j = 0; j < dl_cc_res.data[i].nof_pdu_elems[0]; ++j) { if (dl_cc_res.data[i].pdu[0][j].lcid == (uint32_t)srslte::dl_sch_lcid::CON_RES_ID) { // ConRes found CONDERROR(dl_cc_res.data[i].dci.format != SRSLTE_DCI_FORMAT1 and dl_cc_res.data[i].dci.format != SRSLTE_DCI_FORMAT1A, - "ConRes must be format1/1a\n"); + "ConRes must be format1/1a"); msg4_count++; } } - CONDERROR(msg4_count == 0, "No ConRes CE was scheduled in Msg4\n"); + CONDERROR(msg4_count == 0, "No ConRes CE was scheduled in Msg4"); } } - CONDERROR(msg4_count > 1, "Duplicate ConRes CE for the same rnti\n"); + CONDERROR(msg4_count > 1, "Duplicate ConRes CE for the same rnti"); } if (not ue.msg4_tti_rx.is_valid()) { // TEST: No UL allocs except for Msg3 before Msg4 for (uint32_t i = 0; i < ul_cc_res.nof_dci_elems; ++i) { if (ul_cc_res.pusch[i].dci.rnti == rnti) { - CONDERROR(not ue.rar_tti_rx.is_valid(), "No UL allocs before RAR allowed\n"); + CONDERROR(not ue.rar_tti_rx.is_valid(), "No UL allocs before RAR allowed"); srslte::tti_point expected_msg3_tti = ue.rar_tti_rx + MSG3_DELAY_MS; - CONDERROR(expected_msg3_tti > sf_out.tti_rx, "No UL allocs before Msg3 is scheduled\n"); + CONDERROR(expected_msg3_tti > sf_out.tti_rx, "No UL allocs before Msg3 is scheduled"); if (expected_msg3_tti < sf_out.tti_rx) { bool msg3_retx = ((ue.msg3_tti_rx - expected_msg3_tti) % (FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS)) == 0; - CONDERROR(not msg3_retx, "No UL txs allowed except for Msg3 before user received Msg4\n"); + CONDERROR(not msg3_retx, "No UL txs allowed except for Msg3 before user received Msg4"); } } } @@ -331,7 +330,7 @@ int test_ra(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) // TEST: No DL allocs before Msg3 if (not ue.msg3_tti_rx.is_valid()) { for (uint32_t i = 0; i < dl_cc_res.nof_data_elems; ++i) { - CONDERROR(dl_cc_res.data[i].dci.rnti == rnti, "No DL data allocs allowed before Msg3 is scheduled\n"); + CONDERROR(dl_cc_res.data[i].dci.rnti == rnti, "No DL data allocs allowed before Msg3 is scheduled"); } } } @@ -348,7 +347,7 @@ int test_ra(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) return ctxt.preamble_idx == preamble_idx and ((uint32_t)ctxt.prach_tti_rx.to_uint() == prach_tti); }); CONDERROR(it == enb_ctxt.ue_db.end(), "There was a RAR allocation with no associated user"); - CONDERROR(it->second->ue_cfg.supported_cc_list[0].enb_cc_idx != cc, "The allocated RAR is in the wrong cc\n"); + CONDERROR(it->second->ue_cfg.supported_cc_list[0].enb_cc_idx != cc, "The allocated RAR is in the wrong cc"); } } } @@ -381,12 +380,12 @@ int test_meas_gaps(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out if (is_in_measgap(tti_tx_ul, ue.ue_cfg.measgap_period, ue.ue_cfg.measgap_offset) or is_in_measgap(tti_tx_phich, ue.ue_cfg.measgap_period, ue.ue_cfg.measgap_offset)) { const pusch_t* pusch_ptr = find_pusch_grant(rnti, ul_cc_res); - CONDERROR(pusch_ptr != nullptr, "PUSCH grants and PHICH cannot fall in UE measGap\n"); + CONDERROR(pusch_ptr != nullptr, "PUSCH grants and PHICH cannot fall in UE measGap"); } if (is_in_measgap(tti_tx_dl, ue.ue_cfg.measgap_period, ue.ue_cfg.measgap_offset) or is_in_measgap(tti_tx_dl_ack, ue.ue_cfg.measgap_period, ue.ue_cfg.measgap_offset)) { const pdsch_t* pdsch_ptr = find_pdsch_grant(rnti, dl_cc_res); - CONDERROR(pdsch_ptr != nullptr, "PDSCH grants and respective ACKs cannot fall in UE measGap\n"); + CONDERROR(pdsch_ptr != nullptr, "PDSCH grants and respective ACKs cannot fall in UE measGap"); } } } diff --git a/srsenb/test/phy/CMakeLists.txt b/srsenb/test/phy/CMakeLists.txt index 924641ffd..4dfef85a3 100644 --- a/srsenb/test/phy/CMakeLists.txt +++ b/srsenb/test/phy/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "srsenb;phy") + add_executable(enb_phy_test enb_phy_test.cc) target_link_libraries(enb_phy_test srsenb_phy @@ -33,32 +35,28 @@ set(ENB_PHY_TEST_DURATION 128) # - Transmission Mode 1 # - 1 eNb cell/carrier (no carrier aggregation) # - 100 PRB -add_test(enb_phy_test_tm1 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=1) -set_tests_properties(enb_phy_test_tm1 PROPERTIES LABELS "long;phy;srsenb") +add_lte_test(enb_phy_test_tm1 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=1) # Single carrier TM2 eNb PHY test: # - Single carrier # - Transmission Mode 2 # - 1 eNb cell/carrier (no carrier aggregation) # - 100 PRB -add_test(enb_phy_test_tm2 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=2) -set_tests_properties(enb_phy_test_tm2 PROPERTIES LABELS "long;phy;srsenb") +add_lte_test(enb_phy_test_tm2 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=2) # Single carrier TM3 eNb PHY test: # - Single carrier # - Transmission Mode 3 # - 1 eNb cell/carrier (no carrier aggregation) # - 100 PRB -add_test(enb_phy_test_tm3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=3) -set_tests_properties(enb_phy_test_tm3 PROPERTIES LABELS "long;phy;srsenb") +add_lte_test(enb_phy_test_tm3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=3) # Single carrier eNb PHY test: # - Single carrier # - Transmission Mode 4 # - 1 eNb cell/carrier (no carrier aggregation) # - 100 PRB -add_test(enb_phy_test_tm4 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=4) -set_tests_properties(enb_phy_test_tm4 PROPERTIES LABELS "long;phy;srsenb") +add_lte_test(enb_phy_test_tm4 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=4) # Five carrier aggregation using PUCCH3: # - 6 eNb cell/carrier @@ -66,7 +64,7 @@ set_tests_properties(enb_phy_test_tm4 PROPERTIES LABELS "long;phy;srsenb") # - 5 Aggregated carriers # - 6 PRB # - PUCCH format 3 ACK/NACK feedback mode and more than 2 ACK/NACK bits in PUSCH -add_test(enb_phy_test_tm1_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=3,4,0,1,2 --ack_mode=pucch3 --cell.nof_prb=6 --tm=1) +add_lte_test(enb_phy_test_tm1_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=3,4,0,1,2 --ack_mode=pucch3 --cell.nof_prb=6 --tm=1) # Five carrier aggregation using PUCCH3: # - 6 eNb cell/carrier @@ -74,7 +72,7 @@ add_test(enb_phy_test_tm1_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURAT # - 5 Aggregated carriers # - 6 PRB # - PUCCH format 3 ACK/NACK feedback mode and more than 2 ACK/NACK bits in PUSCH -add_test(enb_phy_test_tm4_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=0,4,3,1,2 --ack_mode=pucch3 --cell.nof_prb=6 --tm=4) +add_lte_test(enb_phy_test_tm4_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=0,4,3,1,2 --ack_mode=pucch3 --cell.nof_prb=6 --tm=4) # Two carrier aggregation using Channel Selection: # - 6 eNb cell/carrier @@ -82,7 +80,7 @@ add_test(enb_phy_test_tm4_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURAT # - 2 Aggregated carriers # - 6 PRB # - PUCCH format 1b with Channel selection ACK/NACK feedback mode -add_test(enb_phy_test_tm1_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=5,4 --ack_mode=cs --cell.nof_prb=6 --tm=1) +add_lte_test(enb_phy_test_tm1_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=5,4 --ack_mode=cs --cell.nof_prb=6 --tm=1) # Two carrier aggregation using Channel Selection: # - 6 eNb cell/carrier @@ -90,7 +88,7 @@ add_test(enb_phy_test_tm1_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} # - 2 Aggregated carriers # - 6 PRB # - PUCCH format 1b with Channel selection ACK/NACK feedback mode -add_test(enb_phy_test_tm4_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=1,5 --ack_mode=cs --cell.nof_prb=6 --tm=4) +add_lte_test(enb_phy_test_tm4_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=1,5 --ack_mode=cs --cell.nof_prb=6 --tm=4) # Two carrier aggregation using Channel Selection and HO: # - 3 eNb cell/carrier @@ -98,5 +96,4 @@ add_test(enb_phy_test_tm4_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} # - 2 Aggregated carriers # - 100 PRB # - PUCCH format 1b with Channel selection ACK/NACK feedback mode -add_test(enb_phy_test_tm1_ca_cs_ho enb_phy_test --duration=1000 --nof_enb_cells=3 --ue_cell_list=2,0 --ack_mode=cs --cell.nof_prb=100 --tm=1 --rotation=100) -set_tests_properties(enb_phy_test_tm1_ca_cs_ho PROPERTIES LABELS "long;phy;srsenb") +add_lte_test(enb_phy_test_tm1_ca_cs_ho enb_phy_test --duration=1000 --nof_enb_cells=3 --ue_cell_list=2,0 --ack_mode=cs --cell.nof_prb=100 --tm=1 --rotation=100) diff --git a/srsenb/test/phy/enb_phy_test.cc b/srsenb/test/phy/enb_phy_test.cc index 500a39846..3589f8dfc 100644 --- a/srsenb/test/phy/enb_phy_test.cc +++ b/srsenb/test/phy/enb_phy_test.cc @@ -18,6 +18,7 @@ * and at http://www.gnu.org/licenses/. * */ + #include #include #include @@ -28,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -58,7 +58,7 @@ public: expired = (cvar.wait_until(lock, expire_time) == std::cv_status::timeout); \ } \ if (expired) { \ - log_h.warning("Expired " #NAME " waiting\n"); \ + logger.warning("Expired " #NAME " waiting"); \ } \ return received_##NAME; \ } \ @@ -71,7 +71,7 @@ private: { \ std::unique_lock lock(mutex); \ cvar.notify_all(); \ - log_h.debug(#NAME " received\n"); \ + logger.debug(#NAME " received"); \ received_##NAME = true; \ } @@ -80,7 +80,7 @@ class dummy_radio final : public srslte::radio_interface_phy private: std::mutex mutex; std::condition_variable cvar; - srslte::log_filter log_h; + srslog::basic_logger& logger; std::vector ringbuffers_tx; std::vector ringbuffers_rx; srslte::rf_timestamp_t ts_rx = {}; @@ -111,19 +111,20 @@ private: CALLBACK(get_info); public: - explicit dummy_radio(uint32_t nof_channels, uint32_t nof_prb, const std::string& log_level) : log_h("RADIO") + explicit dummy_radio(uint32_t nof_channels, uint32_t nof_prb, const std::string& log_level) : + logger(srslog::fetch_basic_logger("RADIO", false)) { - log_h.set_level(log_level); + logger.set_level(srslog::str_to_basic_level(log_level)); // Allocate receive ring buffer for (uint32_t i = 0; i < nof_channels; i++) { auto* rb = (srslte_ringbuffer_t*)srslte_vec_malloc(sizeof(srslte_ringbuffer_t)); if (not rb) { - ERROR("Allocating ring buffer\n"); + ERROR("Allocating ring buffer"); } if (srslte_ringbuffer_init(rb, SRSLTE_SF_LEN_PRB(nof_prb) * SRSLTE_NOF_SF_X_FRAME * (uint32_t)sizeof(cf_t))) { - ERROR("Initiating ring buffer\n"); + ERROR("Initiating ring buffer"); } ringbuffers_tx.push_back(rb); @@ -133,11 +134,11 @@ public: for (uint32_t i = 0; i < nof_channels; i++) { auto* rb = (srslte_ringbuffer_t*)srslte_vec_malloc(sizeof(srslte_ringbuffer_t)); if (not rb) { - ERROR("Allocating ring buffer\n"); + ERROR("Allocating ring buffer"); } if (srslte_ringbuffer_init(rb, SRSLTE_SF_LEN_PRB(nof_prb) * SRSLTE_NOF_SF_X_FRAME * (uint32_t)sizeof(cf_t))) { - ERROR("Initiating ring buffer\n"); + ERROR("Initiating ring buffer"); } ringbuffers_rx.push_back(rb); @@ -167,7 +168,7 @@ public: int err = SRSLTE_SUCCESS; uint32_t nbytes = static_cast(sizeof(cf_t)) * nof_samples; - log_h.debug("read_tx %d\n", nof_samples); + logger.debug("read_tx %d", nof_samples); for (uint32_t i = 0; i < ringbuffers_tx.size() and i < buffers.size(); i++) { do { @@ -182,7 +183,7 @@ public: { uint32_t nbytes = static_cast(sizeof(cf_t)) * nof_samples; - log_h.debug("write_rx %d\n", nof_samples); + logger.debug("write_rx %d", nof_samples); for (uint32_t i = 0; i < ringbuffers_rx.size() and i < buffers.size(); i++) { srslte_ringbuffer_write(ringbuffers_rx[i], buffers[i], nbytes); @@ -200,7 +201,7 @@ public: // Get number of bytes to write uint32_t nbytes = static_cast(sizeof(cf_t)) * buffer.get_nof_samples(); - log_h.debug("tx %d\n", buffer.get_nof_samples()); + logger.debug("tx %d", buffer.get_nof_samples()); // Write ring buffer for (uint32_t i = 0; i < ringbuffers_tx.size() and err >= SRSLTE_SUCCESS; i++) { @@ -225,7 +226,7 @@ public: return true; } - log_h.info("rx_now %d\n", buffer.get_nof_samples()); + logger.info("rx_now %d", buffer.get_nof_samples()); // Get number of bytes to read uint32_t nbytes = static_cast(sizeof(cf_t)) * buffer.get_nof_samples(); @@ -274,15 +275,15 @@ typedef std::unique_ptr unique_dummy_radio_t; class dummy_stack final : public srsenb::stack_interface_phy_lte { private: - static constexpr float prob_dl_grant = 0.50f; - static constexpr float prob_ul_grant = 0.10f; - static constexpr uint32_t cfi = 2; + static constexpr float prob_dl_grant = 0.50f; + static constexpr float prob_ul_grant = 0.10f; + static constexpr uint32_t cfi = 2; srsenb::phy_cell_cfg_list_t phy_cell_cfg; srsenb::phy_interface_rrc_lte::phy_rrc_cfg_list_t phy_rrc; std::mutex mutex; std::condition_variable cvar; - srslte::log_filter log_h; + srslog::basic_logger& logger; srslte_softbuffer_tx_t softbuffer_tx = {}; srslte_softbuffer_rx_t softbuffer_rx[SRSLTE_MAX_CARRIERS][SRSLTE_FDD_NOF_HARQ] = {}; uint8_t* data = nullptr; @@ -336,22 +337,22 @@ private: std::queue tti_cqi_info_queue; std::vector active_cell_list; - uint32_t nof_locations[SRSLTE_NOF_SF_X_FRAME] = {}; + uint32_t nof_locations[SRSLTE_NOF_SF_X_FRAME] = {}; srslte_dci_location_t dci_locations[SRSLTE_NOF_SF_X_FRAME][SRSLTE_MAX_CANDIDATES_UE] = {}; - uint32_t ul_riv = 0; + uint32_t ul_riv = 0; public: explicit dummy_stack(const srsenb::phy_cfg_t& phy_cfg_, const srsenb::phy_interface_rrc_lte::phy_rrc_cfg_list_t& phy_rrc_, const std::string& log_level, uint16_t rnti_) : - log_h("STACK"), + logger(srslog::fetch_basic_logger("STACK", false)), ue_rnti(rnti_), random_gen(srslte_random_init(rnti_)), phy_cell_cfg(phy_cfg_.phy_cell_cfg), phy_rrc(phy_rrc_) { - log_h.set_level(log_level); + logger.set_level(srslog::str_to_basic_level(log_level)); srslte_softbuffer_tx_init(&softbuffer_tx, SRSLTE_MAX_PRB); for (uint32_t i = 0; i < phy_rrc.size(); i++) { for (auto& sb : softbuffer_rx[i]) { @@ -371,7 +372,7 @@ public: sf_cfg_dl.cfi = cfi; sf_cfg_dl.sf_type = SRSLTE_SF_NORM; - uint32_t _nof_locations = {}; + uint32_t _nof_locations = {}; srslte_dci_location_t _dci_locations[SRSLTE_MAX_CANDIDATES_UE] = {}; _nof_locations = srslte_pdcch_ue_locations(&pdcch, &sf_cfg_dl, _dci_locations, SRSLTE_MAX_CANDIDATES_UE, ue_rnti); @@ -425,7 +426,7 @@ public: notify_sr_detected(); - log_h.info("Received SR tti=%d; rnti=0x%x\n", tti, rnti); + logger.info("Received SR tti=%d; rnti=0x%x", tti, rnti); return SRSLTE_SUCCESS; } @@ -437,7 +438,7 @@ public: { notify_ri_info(); - log_h.info("Received RI tti=%d; rnti=0x%x; cc_idx=%d; ri=%d;\n", tti, rnti, cc_idx, ri_value); + logger.info("Received RI tti=%d; rnti=0x%x; cc_idx=%d; ri=%d;", tti, rnti, cc_idx, ri_value); return 0; } @@ -445,7 +446,7 @@ public: { notify_pmi_info(); - log_h.info("Received PMI tti=%d; rnti=0x%x; cc_idx=%d; pmi=%d;\n", tti, rnti, cc_idx, pmi_value); + logger.info("Received PMI tti=%d; rnti=0x%x; cc_idx=%d; pmi=%d;", tti, rnti, cc_idx, pmi_value); return 0; } @@ -459,7 +460,7 @@ public: notify_cqi_info(); - log_h.info("Received CQI tti=%d; rnti=0x%x; cc_idx=%d; cqi=%d;\n", tti, rnti, cc_idx, cqi_value); + logger.info("Received CQI tti=%d; rnti=0x%x; cc_idx=%d; cqi=%d;", tti, rnti, cc_idx, cqi_value); return SRSLTE_SUCCESS; } @@ -470,7 +471,7 @@ public: } int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override { - log_h.info("Received TA INFO tti=%d; rnti=0x%x; ta=%.1f us\n", tti, rnti, ta_us); + logger.info("Received TA INFO tti=%d; rnti=0x%x; ta=%.1f us", tti, rnti, ta_us); notify_ta_info(); return 0; } @@ -484,7 +485,7 @@ public: tti_dl_info.ack = ack; tti_dl_info_ack_queue.push(tti_dl_info); - log_h.info("Received DL ACK tti=%d; rnti=0x%x; cc=%d; tb=%d; ack=%d;\n", tti, rnti, cc_idx, tb_idx, ack); + logger.info("Received DL ACK tti=%d; rnti=0x%x; cc=%d; tb=%d; ack=%d;", tti, rnti, cc_idx, tb_idx, ack); notify_ack_info(); return 0; } @@ -497,14 +498,14 @@ public: tti_ul_info.crc = crc_res; tti_ul_info_ack_queue.push(tti_ul_info); - log_h.info("Received UL ACK tti=%d; rnti=0x%x; cc=%d; ack=%d;\n", tti, rnti, cc_idx, crc_res); + logger.info("Received UL ACK tti=%d; rnti=0x%x; cc=%d; ack=%d;", tti, rnti, cc_idx, crc_res); notify_crc_info(); return 0; } int push_pdu(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) override { - log_h.info("Received push_pdu tti=%d; rnti=0x%x; ack=%d;\n", tti, rnti, crc_res); + logger.info("Received push_pdu tti=%d; rnti=0x%x; ack=%d;", tti, rnti, crc_res); notify_push_pdu(); return 0; @@ -586,7 +587,7 @@ public: uint32_t cw_count = 0; for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { if (sched_tb[tb]) { - log_h.debug("Transmitted DL grant tti=%d; rnti=0x%x; cc=%d; tb=%d;\n", tti, ue_rnti, cc_idx, tb); + logger.debug("Transmitted DL grant tti=%d; rnti=0x%x; cc=%d; tb=%d;", tti, ue_rnti, cc_idx, tb); // Create Grant with maximum safe MCS dl_sched.pdsch[0].dci.tb[tb].cw_idx = cw_count++; @@ -751,7 +752,7 @@ public: uint32_t elapsed_tti = TTI_SUB(tti_sr_info2.tti, tti_sr_info1.tti); // Log SR info - log_h.info("SR: tti1=%d; tti2=%d; elapsed %d;\n", tti_sr_info1.tti, tti_sr_info2.tti, elapsed_tti); + logger.info("SR: tti1=%d; tti2=%d; elapsed %d;", tti_sr_info1.tti, tti_sr_info2.tti, elapsed_tti); // Check first TTI TESTASSERT(tti_sr_info1.tti % 20 == 0); @@ -782,27 +783,26 @@ private: srslte_softbuffer_tx_t softbuffer_tx = {}; uint8_t* tx_data = nullptr; srsenb::phy_interface_rrc_lte::phy_rrc_cfg_list_t phy_rrc_cfg = {}; - srslte::log_filter log_h; + srslog::basic_logger& logger; std::map last_ri = {}; public: dummy_ue(dummy_radio* _radio, const srsenb::phy_cell_cfg_list_t& cell_list, std::string log_level, uint16_t rnti_) : - radio(_radio), - log_h("UPHY", nullptr, true) + radio(_radio), logger(srslog::fetch_basic_logger("UPHY")) { // Calculate subframe length nof_ports = cell_list[0].cell.nof_ports; sf_len = static_cast(SRSLTE_SF_LEN_PRB(cell_list[0].cell.nof_prb)); rnti = rnti_; - log_h.set_level(std::move(log_level)); + logger.set_level(srslog::str_to_basic_level(log_level)); // Initialise one buffer per eNb for (uint32_t i = 0; i < cell_list.size() * nof_ports; i++) { // Allocate buffers cf_t* buffer = srslte_vec_cf_malloc(sf_len); if (not buffer) { - ERROR("Allocating UE DL buffer\n"); + ERROR("Allocating UE DL buffer"); } buffers.push_back(buffer); @@ -817,18 +817,18 @@ public: // Allocate UE DL auto* ue_dl = (srslte_ue_dl_t*)srslte_vec_malloc(sizeof(srslte_ue_dl_t)); if (not ue_dl) { - ERROR("Allocatin UE DL\n"); + ERROR("Allocatin UE DL"); } ue_dl_v.push_back(ue_dl); // Initialise UE DL if (srslte_ue_dl_init(ue_dl, &buffers[cc_idx * nof_ports], cell.nof_prb, cell.nof_ports)) { - ERROR("Initiating UE DL\n"); + ERROR("Initiating UE DL"); } // Set Cell if (srslte_ue_dl_set_cell(ue_dl, cell)) { - ERROR("Setting UE DL cell\n"); + ERROR("Setting UE DL cell"); } // Set RNTI @@ -837,18 +837,18 @@ public: // Allocate UE UL auto* ue_ul = (srslte_ue_ul_t*)srslte_vec_malloc(sizeof(srslte_ue_ul_t)); if (not ue_ul) { - ERROR("Allocatin UE UL\n"); + ERROR("Allocatin UE UL"); } ue_ul_v.push_back(ue_ul); // Initialise UE UL if (srslte_ue_ul_init(ue_ul, buffers[cc_idx * nof_ports], cell.nof_prb)) { - ERROR("Setting UE UL cell\n"); + ERROR("Setting UE UL cell"); } // Set cell if (srslte_ue_ul_set_cell(ue_ul, cell)) { - ERROR("Setting UE DL cell\n"); + ERROR("Setting UE DL cell"); } // Set RNTI @@ -857,13 +857,13 @@ public: // Initialise softbuffer if (srslte_softbuffer_tx_init(&softbuffer_tx, cell_list[0].cell.nof_prb)) { - ERROR("Initialising Tx softbuffer\n"); + ERROR("Initialising Tx softbuffer"); } // Initialise dummy tx data tx_data = srslte_vec_u8_malloc(SRSENB_MAX_BUFFER_SIZE_BYTES); if (not tx_data) { - ERROR("Allocating Tx data\n"); + ERROR("Allocating Tx data"); } for (uint32_t i = 0; i < SRSENB_MAX_BUFFER_SIZE_BYTES; i++) { @@ -957,17 +957,17 @@ public: if (nof_dl_grants) { char str[256] = {}; srslte_dci_dl_info(dci_dl, str, sizeof(str)); - log_h.info("[DL DCI] %s\n", str); + logger.info("[DL DCI] %s", str); if (srslte_ue_dl_dci_to_pdsch_grant( ue_dl_v[cc_idx], &sf_dl_cfg, &ue_dl_cfg, dci_dl, &ue_dl_cfg.cfg.pdsch.grant)) { - log_h.error("Converting DCI message to DL dci\n"); + logger.error("Converting DCI message to DL dci"); return SRSLTE_ERROR; } srslte_pdsch_tx_info(&ue_dl_cfg.cfg.pdsch, str, 512); - log_h.info("[DL PDSCH %d] cc=%d, %s\n", sf_dl_cfg.tti, cc_idx, str); + logger.info("[DL PDSCH %d] cc=%d, %s", sf_dl_cfg.tti, cc_idx, str); pdsch_ack.cc[ue_cc_idx].M = 1; pdsch_ack.cc[ue_cc_idx].m[0].present = true; @@ -1080,7 +1080,7 @@ public: char str[256] = {}; srslte_ue_ul_info(&ue_ul_cfg, &sf_ul_cfg, &pusch_data.uci, str, sizeof(str)); if (str[0]) { - log_h.info("[UL INFO %d] %s\n", i, str); + logger.info("[UL INFO %d] %s", i, str); } } @@ -1105,7 +1105,7 @@ public: char str[256] = {}; srslte_ue_ul_info(&ue_ul_cfg, &sf_ul_cfg, &pusch_data.uci, str, sizeof(str)); if (str[0]) { - log_h.info("[UL INFO %d] %s\n", 0, str); + logger.info("[UL INFO %d] %s", 0, str); } } @@ -1121,7 +1121,7 @@ public: srslte_pdsch_ack_t pdsch_ack = {}; // Set logging TTI - log_h.step(sf_dl_cfg.tti); + logger.set_context(sf_dl_cfg.tti); // Work DL TESTASSERT(work_dl(pdsch_ack, uci_data) == SRSLTE_SUCCESS); @@ -1196,7 +1196,7 @@ private: unique_dummy_stack_t stack; unique_srsenb_phy_t enb_phy; unique_dummy_ue_phy_t ue_phy; - srslte::log_filter log_h; + srslog::basic_logger& logger; args_t args = {}; ///< Test arguments srsenb::phy_args_t phy_args; ///< PHY arguments @@ -1212,13 +1212,14 @@ private: change_state_t change_state = change_state_assert; public: - phy_test_bench(args_t& args_, srslte::logger& logger_) : log_h("TEST BENCH") + phy_test_bench(args_t& args_, srslog::sink& log_sink) : + logger(srslog::fetch_basic_logger("TEST BENCH", log_sink, false)) { // Copy test arguments args = args_; // Configure logger - log_h.set_level(args.log_level); + logger.set_level(srslog::str_to_basic_level(args.log_level)); // PHY arguments phy_args.log.phy_level = args.log_level; @@ -1310,7 +1311,7 @@ public: stack->set_active_cell_list(args.ue_cell_list); /// eNb PHY initialisation instance - enb_phy = unique_srsenb_phy_t(new srsenb::phy(&logger_)); + enb_phy = unique_srsenb_phy_t(new srsenb::phy(log_sink)); /// Initiate eNb PHY with the given RNTI enb_phy->init(phy_args, phy_cfg, radio.get(), stack.get()); @@ -1344,7 +1345,7 @@ public: switch (change_state) { case change_state_assert: if (args.period_pcell_rotate > 0 and tti_counter >= args.period_pcell_rotate) { - log_h.warning("******* Cell rotation: Disable scheduling *******\n"); + logger.warning("******* Cell rotation: Disable scheduling *******"); // Disable all cells std::vector active_cells; stack->set_active_cell_list(active_cells); @@ -1355,7 +1356,7 @@ public: break; case change_state_flush: if (tti_counter >= 2 * FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS) { - log_h.warning("******* Cell rotation: Reconfigure *******\n"); + logger.warning("******* Cell rotation: Reconfigure *******"); std::array activation = {}; ///< Activation/Deactivation vector @@ -1382,7 +1383,7 @@ public: break; case change_state_wait_steady: if (tti_counter >= FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS) { - log_h.warning("******* Cell rotation: Enable scheduling *******\n"); + logger.warning("******* Cell rotation: Enable scheduling *******"); std::vector active_cell_list; @@ -1469,21 +1470,10 @@ int main(int argc, char** argv) test_args.init(); // Setup logging. - srslog::sink* log_sink = srslog::create_stdout_sink(); - if (!log_sink) { - return SRSLTE_ERROR; - } - - srslog::log_channel* chan = srslog::create_log_channel("main_channel", *log_sink); - if (!chan) { - return SRSLTE_ERROR; - } - srslte::srslog_wrapper log_wrapper(*chan); - srslog::init(); // Create Test Bench - unique_phy_test_bench test_bench = unique_phy_test_bench(new phy_test_bench(test_args, log_wrapper)); + unique_phy_test_bench test_bench = unique_phy_test_bench(new phy_test_bench(test_args, srslog::get_default_sink())); // Run Simulation for (uint32_t i = 0; i < test_args.duration; i++) { @@ -1492,6 +1482,8 @@ int main(int argc, char** argv) test_bench->stop(); + srslog::flush(); + std::cout << "Passed" << std::endl; return SRSLTE_SUCCESS; diff --git a/srsenb/test/rrc/CMakeLists.txt b/srsenb/test/rrc/CMakeLists.txt index 7a0a6d72e..e5d681d51 100644 --- a/srsenb/test/rrc/CMakeLists.txt +++ b/srsenb/test/rrc/CMakeLists.txt @@ -18,8 +18,7 @@ # and at http://www.gnu.org/licenses/. # -if (ENABLE_5GNR) - add_executable(rrc_nr_test rrc_nr_test.cc) - target_link_libraries(rrc_nr_test srsgnb_rrc srslte_common rrc_nr_asn1) - add_test(rrc_nr_test rrc_nr_test) -endif () +add_executable(rrc_nr_test rrc_nr_test.cc) +target_link_libraries(rrc_nr_test srsgnb_rrc srslte_common rrc_nr_asn1) +add_test(rrc_nr_test rrc_nr_test) + diff --git a/srsenb/test/upper/CMakeLists.txt b/srsenb/test/upper/CMakeLists.txt index 8ffa5fcf5..cd6897b90 100644 --- a/srsenb/test/upper/CMakeLists.txt +++ b/srsenb/test/upper/CMakeLists.txt @@ -34,7 +34,12 @@ target_link_libraries(erab_setup_test srsenb_rrc rrc_asn1 s1ap_asn1 srslte_commo add_executable(rrc_meascfg_test rrc_meascfg_test.cc) target_link_libraries(rrc_meascfg_test test_helpers) +add_executable(gtpu_test gtpu_test.cc) +target_link_libraries(gtpu_test srslte_common s1ap_asn1 srsenb_upper srslte_upper ${SCTP_LIBRARIES}) + add_test(rrc_mobility_test rrc_mobility_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) add_test(erab_setup_test erab_setup_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) add_test(rrc_meascfg_test rrc_meascfg_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) +add_test(plmn_test plmn_test) +add_test(gtpu_test gtpu_test) diff --git a/srsenb/test/upper/erab_setup_test.cc b/srsenb/test/upper/erab_setup_test.cc index ce2eecef8..1485977c4 100644 --- a/srsenb/test/upper/erab_setup_test.cc +++ b/srsenb/test/upper/erab_setup_test.cc @@ -26,17 +26,22 @@ #include "test_helpers.h" #include -int test_erab_setup(bool qci_exists) +int test_erab_setup(srslte::log_sink_spy& spy, bool qci_exists) { printf("\n===== TEST: test_erab_setup() =====\n"); - srslte::scoped_log rrc_log("RRC "); - srslte::task_scheduler task_sched; - srslte::unique_byte_buffer_t pdu; + + srslte::task_scheduler task_sched; + srslte::unique_byte_buffer_t pdu; srsenb::all_args_t args; rrc_cfg_t cfg; TESTASSERT(test_helpers::parse_default_cfg(&cfg, args) == SRSLTE_SUCCESS); + spy.reset_counters(); + auto& logger = srslog::fetch_basic_logger("RRC", false); + logger.set_hex_dump_max_size(1024); + logger.set_level(srslog::basic_levels::info); + srsenb::rrc rrc{&task_sched}; mac_dummy mac; rlc_dummy rlc; @@ -44,8 +49,6 @@ int test_erab_setup(bool qci_exists) phy_dummy phy; test_dummies::s1ap_mobility_dummy s1ap; gtpu_dummy gtpu; - rrc_log->set_level(srslte::LOG_LEVEL_INFO); - rrc_log->set_hex_limit(1024); rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu); uint16_t rnti = 0x46; @@ -55,13 +58,13 @@ int test_erab_setup(bool qci_exists) ue_cfg.supported_cc_list[0].enb_cc_idx = 0; rrc.add_user(rnti, ue_cfg); - rrc_log->set_level(srslte::LOG_LEVEL_NONE); // mute all the startup log + // mute all the startup log + logger.set_level(srslog::basic_levels::none); // Do all the handshaking until the first RRC Connection Reconf test_helpers::bring_rrc_to_reconf_state(rrc, *task_sched.get_timer_handler(), rnti); - rrc_log->set_level(srslte::LOG_LEVEL_DEBUG); - rrc_log->set_hex_limit(1024); + logger.set_level(srslog::basic_levels::debug); // MME sends 2nd ERAB Setup request for DRB2 (QCI exists in config) uint8_t drb2_erab_setup_request_ok[] = { @@ -99,10 +102,10 @@ int test_erab_setup(bool qci_exists) if (qci_exists) { // NOTE: It does not add DRB1/ERAB-ID=5 bc that bearer already existed TESTASSERT(s1ap.added_erab_ids.size() == 1); - TESTASSERT(rrc_log->error_counter == 0); + TESTASSERT(spy.get_error_counter() == 0); } else { TESTASSERT(s1ap.added_erab_ids.empty()); - TESTASSERT(rrc_log->error_counter > 0); + TESTASSERT(spy.get_error_counter() > 0); } return SRSLTE_SUCCESS; @@ -110,15 +113,31 @@ int test_erab_setup(bool qci_exists) int main(int argc, char** argv) { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srslte::log_sink_spy::name(), + std::unique_ptr(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSLTE_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srslte::log_sink_spy::name())); + if (!spy) { + return SRSLTE_ERROR; + } + srslog::set_default_sink(*spy); + + // Start the log backend. + srslog::init(); if (argc < 3) { argparse::usage(argv[0]); return -1; } argparse::parse_args(argc, argv); - TESTASSERT(test_erab_setup(true) == SRSLTE_SUCCESS); - TESTASSERT(test_erab_setup(false) == SRSLTE_SUCCESS); + TESTASSERT(test_erab_setup(*spy, true) == SRSLTE_SUCCESS); + TESTASSERT(test_erab_setup(*spy, false) == SRSLTE_SUCCESS); + + srslog::flush(); printf("\nSuccess\n"); diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc new file mode 100644 index 000000000..15abb173f --- /dev/null +++ b/srsenb/test/upper/gtpu_test.cc @@ -0,0 +1,265 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/asn1/s1ap.h" +#include +#include +#include + +#include "srsenb/hdr/stack/upper/gtpu.h" +#include "srsenb/test/common/dummy_classes.h" +#include "srslte/common/network_utils.h" +#include "srslte/common/test_common.h" +#include "srslte/upper/gtpu.h" + +namespace srsenb { + +static const size_t PDU_HEADER_SIZE = 20; + +class stack_tester : public stack_interface_gtpu_lte +{ +public: + int s1u_fd; + void add_gtpu_s1u_socket_handler(int fd) { s1u_fd = fd; } + void add_gtpu_m1u_socket_handler(int fd) {} +}; + +class pdcp_tester : public pdcp_dummy +{ +public: + void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn) override + { + last_sdu = std::move(sdu); + last_pdcp_sn = pdcp_sn; + last_rnti = rnti; + last_lcid = lcid; + } + std::map get_buffered_pdus(uint16_t rnti, uint32_t lcid) override + { + return std::move(buffered_pdus); + } + void send_status_report(uint16_t rnti) override {} + void send_status_report(uint16_t rnti, uint32_t lcid) override {} + + void push_buffered_pdu(uint32_t sn, srslte::unique_byte_buffer_t pdu) { buffered_pdus[sn] = std::move(pdu); } + + void clear() + { + last_sdu = nullptr; + last_pdcp_sn = -1; + last_lcid = 0; + last_rnti = SRSLTE_INVALID_RNTI; + } + + std::map buffered_pdus; + srslte::unique_byte_buffer_t last_sdu; + int last_pdcp_sn = -1; + uint16_t last_rnti = SRSLTE_INVALID_RNTI; + uint32_t last_lcid = 0; +}; + +int GTPU_PORT = 2152; + +srslte::unique_byte_buffer_t encode_ipv4_packet(srslte::span data, + uint32_t teid, + const struct sockaddr_in& src_sockaddr_in, + const struct sockaddr_in& dest_sockaddr_in) +{ + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + + struct iphdr ip_pkt = {}; + ip_pkt.version = 4; + ip_pkt.tot_len = htons(data.size() + sizeof(struct iphdr)); + ip_pkt.saddr = src_sockaddr_in.sin_addr.s_addr; + ip_pkt.daddr = dest_sockaddr_in.sin_addr.s_addr; + pdu->append_bytes((uint8_t*)&ip_pkt, sizeof(struct iphdr)); + pdu->append_bytes(data.data(), data.size()); + + return pdu; +} + +srslte::unique_byte_buffer_t encode_gtpu_packet(srslte::span data, + uint32_t teid, + const struct sockaddr_in& src_sockaddr_in, + const struct sockaddr_in& dest_sockaddr_in) +{ + srslte::unique_byte_buffer_t pdu = encode_ipv4_packet(data, teid, src_sockaddr_in, dest_sockaddr_in); + + // header + srslte::gtpu_header_t header = {}; + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; + header.message_type = GTPU_MSG_DATA_PDU; + header.length = pdu->N_bytes; + header.teid = teid; + + gtpu_write_header(&header, pdu.get(), srslog::fetch_basic_logger("GTPU")); + return pdu; +} + +srslte::unique_byte_buffer_t encode_end_marker(uint32_t teid) +{ + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + + // header + srslte::gtpu_header_t header = {}; + header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL; + header.message_type = GTPU_MSG_END_MARKER; + header.length = 0; + header.teid = teid; + + gtpu_write_header(&header, pdu.get(), srslog::fetch_basic_logger("GTPU")); + return pdu; +} + +srslte::unique_byte_buffer_t read_socket(int fd) +{ + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + pdu->N_bytes = read(fd, pdu->msg, pdu->get_tailroom()); + return pdu; +} + +int test_gtpu_direct_tunneling() +{ + uint16_t rnti = 0x46, rnti2 = 0x50; + uint32_t drb1 = 3; + uint32_t sgw_teidout1 = 1, sgw_teidout2 = 2; + const char * sgw_addr_str = "127.0.0.1", *senb_addr_str = "127.0.1.1", *tenb_addr_str = "127.0.1.2"; + struct sockaddr_in senb_sockaddr = {}, sgw_sockaddr = {}, tenb_sockaddr = {}; + srslte::net_utils::set_sockaddr(&senb_sockaddr, senb_addr_str, GTPU_PORT); + srslte::net_utils::set_sockaddr(&sgw_sockaddr, sgw_addr_str, GTPU_PORT); + srslte::net_utils::set_sockaddr(&tenb_sockaddr, tenb_addr_str, GTPU_PORT); + uint32_t tenb_addr = ntohl(tenb_sockaddr.sin_addr.s_addr); + uint32_t senb_addr = ntohl(senb_sockaddr.sin_addr.s_addr); + uint32_t sgw_addr = ntohl(sgw_sockaddr.sin_addr.s_addr); + + srslte::unique_byte_buffer_t pdu; + + // Initiate layers + srslog::basic_logger& logger1 = srslog::fetch_basic_logger("GTPU1"); + logger1.set_hex_dump_max_size(2048); + srslog::basic_logger& logger2 = srslog::fetch_basic_logger("GTPU2"); + logger2.set_hex_dump_max_size(2048); + srsenb::gtpu senb_gtpu(logger1), tenb_gtpu(logger2); + stack_tester senb_stack, tenb_stack; + pdcp_tester senb_pdcp, tenb_pdcp; + senb_gtpu.init(senb_addr_str, sgw_addr_str, "", "", &senb_pdcp, &senb_stack, false); + tenb_gtpu.init(tenb_addr_str, sgw_addr_str, "", "", &tenb_pdcp, &tenb_stack, false); + + // create tunnels MME-SeNB and MME-TeNB + uint32_t senb_teid_in = senb_gtpu.add_bearer(rnti, drb1, sgw_addr, sgw_teidout1); + uint32_t tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1, sgw_addr, sgw_teidout2); + + // Buffer PDUs in SeNB PDCP + for (size_t sn = 6; sn < 10; ++sn) { + std::vector data(10, sn); + pdu = encode_ipv4_packet(data, senb_teid_in, sgw_sockaddr, senb_sockaddr); + senb_pdcp.push_buffered_pdu(sn, std::move(pdu)); + } + + // create direct tunnel SeNB-TeNB + gtpu::bearer_props props; + props.flush_before_teidin_present = true; + props.flush_before_teidin = tenb_teid_in; + uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1, senb_addr, 0, &props); + props = {}; + props.forward_from_teidin_present = true; + props.forward_from_teidin = senb_teid_in; + senb_gtpu.add_bearer(rnti, drb1, tenb_addr, dl_tenb_teid_in, &props); + + std::random_device rd; + std::mt19937 g(rd()); + std::vector data_vec(10); + std::iota(data_vec.begin(), data_vec.end(), 0); + std::vector encoded_data; + srslte::span pdu_view{}; + + // TEST: GTPU buffers incoming PDCP buffered SNs until the TEID is explicitly activated + tenb_gtpu.handle_gtpu_s1u_rx_packet(read_socket(tenb_stack.s1u_fd), senb_sockaddr); + TESTASSERT(tenb_pdcp.last_sdu == nullptr); + tenb_gtpu.handle_gtpu_s1u_rx_packet(read_socket(tenb_stack.s1u_fd), senb_sockaddr); + TESTASSERT(tenb_pdcp.last_sdu == nullptr); + tenb_gtpu.set_tunnel_status(dl_tenb_teid_in, true); + pdu_view = srslte::make_span(tenb_pdcp.last_sdu); + TESTASSERT(std::count(pdu_view.begin() + PDU_HEADER_SIZE, pdu_view.end(), 7) == 10); + TESTASSERT(tenb_pdcp.last_rnti == rnti2); + TESTASSERT(tenb_pdcp.last_lcid == drb1); + TESTASSERT(tenb_pdcp.last_pdcp_sn == (int)7); + + // TEST: verify that PDCP buffered SNs have been forwarded through SeNB->TeNB tunnel + for (size_t sn = 8; sn < 10; ++sn) { + tenb_gtpu.handle_gtpu_s1u_rx_packet(read_socket(tenb_stack.s1u_fd), senb_sockaddr); + pdu_view = srslte::make_span(tenb_pdcp.last_sdu); + TESTASSERT(std::count(pdu_view.begin() + PDU_HEADER_SIZE, pdu_view.end(), sn) == 10); + TESTASSERT(tenb_pdcp.last_rnti == rnti2); + TESTASSERT(tenb_pdcp.last_lcid == drb1); + TESTASSERT(tenb_pdcp.last_pdcp_sn == (int)sn); + } + + // TEST: verify that incoming DL data MME->SeNB is forwarded through SeNB->TeNB tunnel + std::shuffle(data_vec.begin(), data_vec.end(), g); + pdu = encode_gtpu_packet(data_vec, senb_teid_in, sgw_sockaddr, senb_sockaddr); + encoded_data.assign(pdu->msg + 8u, pdu->msg + pdu->N_bytes); + senb_gtpu.handle_gtpu_s1u_rx_packet(std::move(pdu), sgw_sockaddr); + tenb_gtpu.handle_gtpu_s1u_rx_packet(read_socket(tenb_stack.s1u_fd), senb_sockaddr); + pdu_view = srslte::make_span(tenb_pdcp.last_sdu); + TESTASSERT(pdu_view.size() == encoded_data.size() and + std::equal(pdu_view.begin(), pdu_view.end(), encoded_data.begin())); + TESTASSERT(tenb_pdcp.last_rnti == rnti2 and tenb_pdcp.last_lcid == drb1); + + // TEST: verify that MME->TeNB packets are buffered until SeNB->TeNB tunnel is closed + tenb_pdcp.clear(); + size_t N_pdus = std::uniform_int_distribution{1, 30}(g); + for (size_t i = 0; i < N_pdus; ++i) { + std::fill(data_vec.begin(), data_vec.end(), i); + pdu = encode_gtpu_packet(data_vec, senb_teid_in, sgw_sockaddr, tenb_sockaddr); + tenb_gtpu.handle_gtpu_s1u_rx_packet(std::move(pdu), sgw_sockaddr); + // The PDUs are being buffered + TESTASSERT(tenb_pdcp.last_sdu == nullptr); + } + // PDUs coming from SeNB-TeNB tunnel are forwarded + std::iota(data_vec.begin(), data_vec.end(), 0); + std::shuffle(data_vec.begin(), data_vec.end(), g); + pdu = encode_gtpu_packet(data_vec, senb_teid_in, sgw_sockaddr, senb_sockaddr); + encoded_data.assign(pdu->msg + 8u, pdu->msg + pdu->N_bytes); + senb_gtpu.handle_gtpu_s1u_rx_packet(std::move(pdu), sgw_sockaddr); + tenb_gtpu.handle_gtpu_s1u_rx_packet(read_socket(tenb_stack.s1u_fd), senb_sockaddr); + TESTASSERT(tenb_pdcp.last_sdu->N_bytes == encoded_data.size() and + memcmp(tenb_pdcp.last_sdu->msg, encoded_data.data(), encoded_data.size()) == 0); + tenb_pdcp.clear(); + // EndMarker is forwarded via MME->SeNB->TeNB, and TeNB buffered PDUs are flushed + pdu = encode_end_marker(senb_teid_in); + senb_gtpu.handle_gtpu_s1u_rx_packet(std::move(pdu), sgw_sockaddr); + tenb_gtpu.handle_gtpu_s1u_rx_packet(read_socket(tenb_stack.s1u_fd), senb_sockaddr); + srslte::span encoded_data2{tenb_pdcp.last_sdu->msg + 20u, tenb_pdcp.last_sdu->msg + 30u}; + TESTASSERT(std::all_of(encoded_data2.begin(), encoded_data2.end(), [N_pdus](uint8_t b) { return b == N_pdus - 1; })); + + return SRSLTE_SUCCESS; +} + +} // namespace srsenb + +int main() +{ + // Setup logging. + auto& logger = srslog::fetch_basic_logger("GTPU", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + + // Start the log backend. + srslog::init(); + + TESTASSERT(srsenb::test_gtpu_direct_tunneling() == SRSLTE_SUCCESS); + + srslog::flush(); + + srslte::console("Success"); +} diff --git a/srsenb/test/upper/rrc_meascfg_test.cc b/srsenb/test/upper/rrc_meascfg_test.cc index 04d2df8d1..cd4c6453c 100644 --- a/srsenb/test/upper/rrc_meascfg_test.cc +++ b/srsenb/test/upper/rrc_meascfg_test.cc @@ -249,8 +249,8 @@ int test_correct_meascfg_calculation() freq_res_common_list freq_res{cfg}; // measConfig only includes earfcns of active carriers for a given pcell - meas_cfg_s cell_meas_cfg; - ue_cell_ded_list ue_cell_list{cfg, freq_res, cell_list}; + meas_cfg_s cell_meas_cfg; + ue_cell_ded_list ue_cell_list{cfg, freq_res, cell_list}; ue_cell_list.set_cells({0}); TESTASSERT(fill_meascfg_enb_cfg(cell_meas_cfg, ue_cell_list)); const auto& measobjs = cell_meas_cfg.meas_obj_to_add_mod_list; @@ -306,9 +306,9 @@ int test_minimize_meascfg_reordering() TESTASSERT(cell_list.get_cc_idx(0)->scells.size() == 1); TESTASSERT(cell_list.get_cc_idx(0)->scells[0] == cell_list.get_cc_idx(1)); TESTASSERT(cell_list.get_cc_idx(1)->scells.empty()); - freq_res_common_list freq_res{cfg1}; - ue_cell_ded_list ue_cell_list1{cfg1, freq_res, cell_list}; - ue_cell_ded_list ue_cell_list2{cfg1, freq_res, cell_list}; + freq_res_common_list freq_res{cfg1}; + ue_cell_ded_list ue_cell_list1{cfg1, freq_res, cell_list}; + ue_cell_ded_list ue_cell_list2{cfg1, freq_res, cell_list}; meas_cfg_s mcfg1{}, mcfg2{}; ue_cell_list1.set_cells({0, 1}); @@ -336,15 +336,22 @@ int test_minimize_meascfg_reordering() int main(int argc, char** argv) { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); + auto& logger = srslog::fetch_basic_logger("RRC", false); + logger.set_level(srslog::basic_levels::info); + srslog::init(); if (argc < 3) { argparse::usage(argv[0]); return -1; } argparse::parse_args(argc, argv); + TESTASSERT(test_correct_meascfg_insertion() == 0); TESTASSERT(test_correct_meascfg_calculation() == 0); TESTASSERT(test_minimize_meascfg_reordering() == 0); + + srslog::flush(); + srslte::console("Success\n"); return 0; diff --git a/srsenb/test/upper/rrc_mobility_test.cc b/srsenb/test/upper/rrc_mobility_test.cc index 1a9618fec..d2a43c472 100644 --- a/srsenb/test/upper/rrc_mobility_test.cc +++ b/srsenb/test/upper/rrc_mobility_test.cc @@ -61,16 +61,19 @@ struct mobility_test_params { }; struct mobility_tester { - explicit mobility_tester(const mobility_test_params& args_) : args(args_), rrc(&task_sched) + explicit mobility_tester(const mobility_test_params& args_) : + args(args_), logger(srslog::fetch_basic_logger("RRC")), rrc(&task_sched) { - rrc_log->set_level(srslte::LOG_LEVEL_INFO); - rrc_log->set_hex_limit(1024); + logger.set_level(srslog::basic_levels::info); + logger.set_hex_dump_max_size(1024); } virtual int generate_rrc_cfg() = 0; virtual int setup_rrc() { return setup_rrc_common(); } int run_preamble() { - rrc_log->set_level(srslte::LOG_LEVEL_NONE); // mute all the startup log + // mute all the startup log + logger.set_level(srslog::basic_levels::none); + // add user sched_interface::ue_cfg_t ue_cfg{}; ue_cfg.supported_cc_list.resize(1); @@ -80,14 +83,14 @@ struct mobility_tester { // Do all the handshaking until the first RRC Connection Reconf test_helpers::bring_rrc_to_reconf_state(rrc, *task_sched.get_timer_handler(), rnti); - rrc_log->set_level(srslte::LOG_LEVEL_INFO); + logger.set_level(srslog::basic_levels::info); return SRSLTE_SUCCESS; } - mobility_test_params args; - srslte::scoped_log rrc_log{"RRC"}; - srslte::task_scheduler task_sched; - rrc_cfg_t cfg; + mobility_test_params args; + srslog::basic_logger& logger; + srslte::task_scheduler task_sched; + rrc_cfg_t cfg; srsenb::rrc rrc; test_dummies::mac_mobility_dummy mac; @@ -161,10 +164,11 @@ struct intraenb_mobility_tester : public mobility_tester { } }; -int test_s1ap_mobility(mobility_test_params test_params) +int test_s1ap_mobility(srslte::log_sink_spy& spy, mobility_test_params test_params) { printf("\n===== TEST: test_s1ap_mobility() for event %s =====\n", test_params.to_string()); - s1ap_mobility_tester tester{test_params}; + s1ap_mobility_tester tester{test_params}; + spy.reset_counters(); srslte::unique_byte_buffer_t pdu; TESTASSERT(tester.generate_rrc_cfg() == SRSLTE_SUCCESS); @@ -195,7 +199,7 @@ int test_s1ap_mobility(mobility_test_params test_params) /* Test Case: the MeasReport is not valid */ if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) { TESTASSERT(s1ap.last_ho_required.rrc_container == nullptr); - TESTASSERT(tester.rrc_log->warn_counter == 1); + TESTASSERT(spy.get_warning_counter() == 1); return SRSLTE_SUCCESS; } TESTASSERT(s1ap.last_ho_required.rrc_container != nullptr); @@ -231,8 +235,8 @@ int test_s1ap_mobility(mobility_test_params test_params) /* Test Case: HandoverPreparation has failed */ if (test_params.fail_at == mobility_test_params::test_event::ho_prep_failure) { - tester.rrc.ho_preparation_complete(tester.rnti, false, nullptr); - // TESTASSERT(rrc_log->error_counter == 1); + tester.rrc.ho_preparation_complete(tester.rnti, false, {}, nullptr); + // TESTASSERT(spy.get_error_counter() == 1); TESTASSERT(not s1ap.last_enb_status.status_present); return SRSLTE_SUCCESS; } @@ -244,9 +248,9 @@ int test_s1ap_mobility(mobility_test_params test_params) 0x86, 0x0d, 0x30, 0x00, 0x0b, 0x5a, 0x02, 0x17, 0x86, 0x00, 0x05, 0xa0, 0x20}; test_helpers::copy_msg_to_buffer(pdu, ho_cmd_rrc_container); TESTASSERT(s1ap.last_enb_status.rnti != tester.rnti); - tester.rrc.ho_preparation_complete(tester.rnti, true, std::move(pdu)); + tester.rrc.ho_preparation_complete(tester.rnti, true, asn1::s1ap::ho_cmd_s{}, std::move(pdu)); TESTASSERT(s1ap.last_enb_status.status_present); - TESTASSERT(tester.rrc_log->error_counter == 0); + TESTASSERT(spy.get_error_counter() == 0); asn1::rrc::dl_dcch_msg_s ho_cmd; TESTASSERT(test_helpers::unpack_asn1(ho_cmd, srslte::make_span(tester.pdcp.last_sdu.sdu))); recfg_r8 = ho_cmd.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8(); @@ -287,6 +291,13 @@ int test_s1ap_tenb_mobility(mobility_test_params test_params) 0x5c, 0xe1, 0x86, 0x35, 0x39, 0x80, 0x0e, 0x06, 0xa4, 0x40, 0x0f, 0x22, 0x78}; // 0a100b818000018000f3020800001580001406a402f00404f00014804a000000021231b6f83ea06f05e465141d39d0544c00025400200460000000100100c000000000020500041400670dfbc46606500f00080020800c14ca2d5ce1863539800e06a4400f2278 container.rrc_container.resize(sizeof(ho_prep_container)); + container.erab_info_list_present = true; + container.erab_info_list.resize(1); + container.erab_info_list[0].load_info_obj(ASN1_S1AP_ID_ERAB_INFO_LIST_ITEM); + container.erab_info_list[0].value.erab_info_list_item().erab_id = 5; + container.erab_info_list[0].value.erab_info_list_item().dl_forwarding_present = true; + container.erab_info_list[0].value.erab_info_list_item().dl_forwarding.value = + asn1::s1ap::dl_forwarding_opts::dl_forwarding_proposed; memcpy(container.rrc_container.data(), ho_prep_container, sizeof(ho_prep_container)); tester.rrc.start_ho_ue_resource_alloc(ho_req, container); tester.tic(); @@ -366,10 +377,11 @@ int test_s1ap_tenb_mobility(mobility_test_params test_params) return SRSLTE_SUCCESS; } -int test_intraenb_mobility(mobility_test_params test_params) +int test_intraenb_mobility(srslte::log_sink_spy& spy, mobility_test_params test_params) { printf("\n===== TEST: test_intraenb_mobility() for event %s =====\n", test_params.to_string()); - intraenb_mobility_tester tester{test_params}; + intraenb_mobility_tester tester{test_params}; + spy.reset_counters(); srslte::unique_byte_buffer_t pdu; TESTASSERT(tester.generate_rrc_cfg() == SRSLTE_SUCCESS); @@ -403,7 +415,7 @@ int test_intraenb_mobility(mobility_test_params test_params) /* Test Case: the MeasReport is not valid */ if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) { - TESTASSERT(tester.rrc_log->warn_counter == 1); + TESTASSERT(spy.get_warning_counter() == 1); TESTASSERT(tester.pdcp.last_sdu.sdu == nullptr); return SRSLTE_SUCCESS; } @@ -423,7 +435,7 @@ int test_intraenb_mobility(mobility_test_params test_params) } /* Test Case: the HandoverCommand was sent to the lower layers */ - TESTASSERT(tester.rrc_log->error_counter == 0); + TESTASSERT(spy.get_error_counter() == 0); TESTASSERT(tester.pdcp.last_sdu.rnti == tester.rnti); TESTASSERT(tester.pdcp.last_sdu.lcid == 1); // SRB1 asn1::rrc::dl_dcch_msg_s ho_cmd; @@ -496,7 +508,25 @@ int test_intraenb_mobility(mobility_test_params test_params) int main(int argc, char** argv) { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srslte::log_sink_spy::name(), + std::unique_ptr(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSLTE_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srslte::log_sink_spy::name())); + if (!spy) { + return SRSLTE_ERROR; + } + srslog::set_default_sink(*spy); + + auto& logger = srslog::fetch_basic_logger("RRC", false); + logger.set_level(srslog::basic_levels::info); + logger.set_hex_dump_max_size(1024); + + srslog::init(); + using event = mobility_test_params::test_event; if (argc < 3) { @@ -506,18 +536,20 @@ int main(int argc, char** argv) argparse::parse_args(argc, argv); // S1AP Handover - TESTASSERT(test_s1ap_mobility(mobility_test_params{event::wrong_measreport}) == 0); - TESTASSERT(test_s1ap_mobility(mobility_test_params{event::concurrent_ho}) == 0); - TESTASSERT(test_s1ap_mobility(mobility_test_params{event::ho_prep_failure}) == 0); - TESTASSERT(test_s1ap_mobility(mobility_test_params{event::success}) == 0); + TESTASSERT(test_s1ap_mobility(*spy, mobility_test_params{event::wrong_measreport}) == 0); + TESTASSERT(test_s1ap_mobility(*spy, mobility_test_params{event::concurrent_ho}) == 0); + TESTASSERT(test_s1ap_mobility(*spy, mobility_test_params{event::ho_prep_failure}) == 0); + TESTASSERT(test_s1ap_mobility(*spy, mobility_test_params{event::success}) == 0); TESTASSERT(test_s1ap_tenb_mobility(mobility_test_params{event::success}) == 0); // intraeNB Handover - TESTASSERT(test_intraenb_mobility(mobility_test_params{event::wrong_measreport}) == 0); - TESTASSERT(test_intraenb_mobility(mobility_test_params{event::concurrent_ho}) == 0); - TESTASSERT(test_intraenb_mobility(mobility_test_params{event::duplicate_crnti_ce}) == 0); - TESTASSERT(test_intraenb_mobility(mobility_test_params{event::success}) == 0); + TESTASSERT(test_intraenb_mobility(*spy, mobility_test_params{event::wrong_measreport}) == 0); + TESTASSERT(test_intraenb_mobility(*spy, mobility_test_params{event::concurrent_ho}) == 0); + TESTASSERT(test_intraenb_mobility(*spy, mobility_test_params{event::duplicate_crnti_ce}) == 0); + TESTASSERT(test_intraenb_mobility(*spy, mobility_test_params{event::success}) == 0); + + srslog::flush(); printf("\nSuccess\n"); diff --git a/srsenb/test/upper/test_helpers.cc b/srsenb/test/upper/test_helpers.cc index d35cbbf6b..da3a7982f 100644 --- a/srsenb/test/upper/test_helpers.cc +++ b/srsenb/test/upper/test_helpers.cc @@ -38,7 +38,7 @@ int parse_default_cfg_phy(rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, srsenb::all_ar args.enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; args.enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; args.enb_files.drb_config = argparse::repository_dir + "/drb.conf.example"; - srslte::logmap::get("TEST")->debug("sib file path=%s\n", args.enb_files.sib_config.c_str()); + srslog::fetch_basic_logger("TEST").debug("sib file path=%s", args.enb_files.sib_config.c_str()); args.enb.enb_id = 0x19B; TESTASSERT(srslte::string_to_mcc("001", &args.stack.s1ap.mcc)); @@ -58,7 +58,7 @@ int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args) args.enb_files.sib_config = argparse::repository_dir + "/sib.conf.example"; args.enb_files.rr_config = argparse::repository_dir + "/rr.conf.example"; args.enb_files.drb_config = argparse::repository_dir + "/drb.conf.example"; - srslte::logmap::get("TEST")->debug("sib file path=%s\n", args.enb_files.sib_config.c_str()); + srslog::fetch_basic_logger("TEST").debug("sib file path=%s", args.enb_files.sib_config.c_str()); args.enb.enb_id = 0x19B; args.enb.dl_earfcn = 3400; diff --git a/srsenb/test/upper/test_helpers.h b/srsenb/test/upper/test_helpers.h index d00f55a3e..7d88e6f69 100644 --- a/srsenb/test/upper/test_helpers.h +++ b/srsenb/test/upper/test_helpers.h @@ -84,14 +84,15 @@ public: } last_enb_status = {}; std::vector added_erab_ids; struct ho_req_ack { - uint16_t rnti; - srslte::unique_byte_buffer_t ho_cmd_pdu; - std::vector > admitted_bearers; + uint16_t rnti; + srslte::unique_byte_buffer_t ho_cmd_pdu; + std::vector admitted_bearers; } last_ho_req_ack; bool send_ho_required(uint16_t rnti, uint32_t target_eci, srslte::plmn_id_t target_plmn, + srslte::span fwd_erabs, srslte::unique_byte_buffer_t rrc_container) final { last_ho_required = ho_req_data{rnti, target_eci, target_plmn, std::move(rrc_container)}; @@ -102,10 +103,11 @@ public: last_enb_status = {true, rnti, bearer_status_list}; return true; } - bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, - uint16_t rnti, - srslte::unique_byte_buffer_t ho_cmd, - srslte::span > admitted_bearers) override + bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, + uint16_t rnti, + uint32_t enb_cc_idx, + srslte::unique_byte_buffer_t ho_cmd, + srslte::span admitted_bearers) override { last_ho_req_ack.rnti = rnti; last_ho_req_ack.ho_cmd_pdu = std::move(ho_cmd); @@ -139,7 +141,7 @@ public: }; std::map > bearers; - void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override + void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu, int pdcp_sn) override { last_sdu.rnti = rnti; last_sdu.lcid = lcid; @@ -225,7 +227,7 @@ bool unpack_asn1(ASN1Type& asn1obj, srslte::const_byte_span pdu) { asn1::cbit_ref bref{pdu.data(), (uint32_t)pdu.size()}; if (asn1obj.unpack(bref) != asn1::SRSASN_SUCCESS) { - srslte::logmap::get("TEST")->error("Failed to unpack ASN1 type\n"); + srslog::fetch_basic_logger("TEST").error("Failed to unpack ASN1 type"); return false; } return true; @@ -233,8 +235,7 @@ bool unpack_asn1(ASN1Type& asn1obj, srslte::const_byte_span pdu) inline void copy_msg_to_buffer(srslte::unique_byte_buffer_t& pdu, srslte::const_byte_span msg) { - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - pdu = srslte::allocate_unique_buffer(*pool, true); + pdu = srslte::make_byte_buffer(); memcpy(pdu->msg, msg.data(), msg.size()); pdu->N_bytes = msg.size(); } diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 740cb7bfa..222d6410a 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -32,6 +32,7 @@ #include "srslte/common/log.h" #include "srslte/common/log_filter.h" #include "srslte/interfaces/epc_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -77,7 +78,7 @@ class hss : public hss_interface_nas public: static hss* get_instance(void); static void cleanup(void); - int init(hss_args_t* hss_args, srslte::log_filter* hss_log); + int init(hss_args_t* hss_args); void stop(void); virtual bool gen_auth_info_answer(uint64_t imsi, uint8_t* k_asme, uint8_t* autn, uint8_t* rand, uint8_t* xres); @@ -120,7 +121,7 @@ private: std::string db_file; /*Logs*/ - srslte::log_filter* m_hss_log; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("HSS"); uint16_t mcc; uint16_t mnc; diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index 05b0897e2..596ab84fb 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -33,6 +33,7 @@ #include "srslte/common/log_filter.h" #include "srslte/common/logmap.h" #include "srslte/common/threads.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #include @@ -63,7 +64,7 @@ class mbms_gw : public srslte::thread public: static mbms_gw* get_instance(void); static void cleanup(void); - int init(mbms_gw_args_t* args, srslte::log_ref mbms_gw_log); + int init(mbms_gw_args_t* args); void stop(); void run_thread(); @@ -79,9 +80,8 @@ private: uint16_t in_cksum(uint16_t* iphdr, int count); /* Members */ - bool m_running; - srslte::byte_buffer_pool* m_pool; - srslte::log_ref m_mbms_gw_log; + bool m_running; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("MBMS"); bool m_sgi_mb_up; int m_sgi_mb_if; diff --git a/srsepc/hdr/mme/mme.h b/srsepc/hdr/mme/mme.h index 6c6b5d28e..11a0f6de1 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -55,10 +55,7 @@ public: static mme* get_instance(void); static void cleanup(void); - int init(mme_args_t* args, - srslte::log_filter* nas_log, - srslte::log_filter* s1ap_log, - srslte::log_filter* mme_gtpc_log); + int init(mme_args_t* args); void stop(); int get_s1_mme(); void run_thread(); @@ -75,9 +72,8 @@ private: s1ap* m_s1ap; mme_gtpc* m_mme_gtpc; - bool m_running; - srslte::byte_buffer_pool* m_pool; - fd_set m_set; + bool m_running; + fd_set m_set; // Timer map std::vector timers; @@ -86,9 +82,7 @@ private: void handle_timer_expire(int timer_fd); // Logs - srslte::log_filter* m_nas_log; - srslte::log_filter* m_s1ap_log; - srslte::log_filter* m_mme_gtpc_log; + srslog::basic_logger& m_s1ap_logger = srslog::fetch_basic_logger("S1AP"); }; } // namespace srsepc diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 61f8db1d7..a5261743d 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -46,7 +46,7 @@ public: static mme_gtpc* get_instance(); - bool init(srslte::log_filter* mme_gtpc_log); + bool init(); bool send_s11_pdu(const srslte::gtpc_pdu& pdu); void handle_s11_pdu(srslte::byte_buffer_t* msg); @@ -65,8 +65,8 @@ public: private: mme_gtpc() = default; - srslte::log_filter* m_mme_gtpc_log; - s1ap* m_s1ap; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("MME GTPC"); + s1ap* m_s1ap; uint32_t m_next_ctrl_teid; std::map m_mme_ctr_teid_to_imsi; diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 777921931..5f6feaa79 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -27,6 +27,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/security.h" #include "srslte/interfaces/epc_interfaces.h" +#include "srslte/srslog/srslog.h" #include namespace srsepc { @@ -150,7 +151,7 @@ typedef struct { class nas { public: - nas(const nas_init_t& args, const nas_if_t& itf, srslte::log* nas_log); + nas(const nas_init_t& args, const nas_if_t& itf); void reset(); /*********************** @@ -161,16 +162,14 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); static bool handle_imsi_attach_request_unknown_ue(uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo* enb_sri, const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); static bool handle_imsi_attach_request_known_ue(nas* nas_ctx, uint32_t enb_ue_s1ap_id, @@ -179,16 +178,14 @@ public: const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); static bool handle_guti_attach_request_unknown_ue(uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo* enb_sri, const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); static bool handle_guti_attach_request_known_ue(nas* nas_ctx, uint32_t enb_ue_s1ap_id, @@ -197,8 +194,7 @@ public: const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); // Service request messages static bool handle_service_request(uint32_t m_tmsi, @@ -206,8 +202,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); // Dettach request messages static bool handle_detach_request(uint32_t m_tmsi, @@ -215,8 +210,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); // Tracking area update request messages static bool handle_tracking_area_update_request(uint32_t m_tmsi, @@ -224,8 +218,7 @@ public: struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log); + const nas_if_t& itf); /* Uplink NAS messages handling */ bool handle_attach_request(srslte::byte_buffer_t* nas_rx); @@ -267,12 +260,11 @@ public: sec_ctx_t m_sec_ctx = {}; private: - srslte::byte_buffer_pool* m_pool = nullptr; - srslte::log* m_nas_log = nullptr; - gtpc_interface_nas* m_gtpc = nullptr; - s1ap_interface_nas* m_s1ap = nullptr; - hss_interface_nas* m_hss = nullptr; - mme_interface_nas* m_mme = nullptr; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("NAS"); + gtpc_interface_nas* m_gtpc = nullptr; + s1ap_interface_nas* m_s1ap = nullptr; + hss_interface_nas* m_hss = nullptr; + mme_interface_nas* m_mme = nullptr; uint16_t m_mcc = 0; uint16_t m_mnc = 0; diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 80ed1f2a8..5e1435b82 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -36,6 +36,7 @@ #include "srslte/common/log.h" #include "srslte/common/s1ap_pcap.h" #include "srslte/interfaces/epc_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -58,7 +59,7 @@ public: static void cleanup(); int enb_listen(); - int init(s1ap_args_t s1ap_args, srslte::log_filter* s1ap_log, srslte::log_filter* nas_log); + int init(s1ap_args_t s1ap_args); void stop(); int get_s1_mme(); @@ -95,9 +96,8 @@ public: uint32_t allocate_m_tmsi(uint64_t imsi); virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi); - s1ap_args_t m_s1ap_args; - srslte::log_filter* m_s1ap_log; - srslte::log_filter* m_nas_log; + s1ap_args_t m_s1ap_args; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("S1AP"); s1ap_mngmt_proc* m_s1ap_mngmt_proc; s1ap_nas_transport* m_s1ap_nas_transport; @@ -134,8 +134,7 @@ private: static s1ap* m_instance; - uint32_t m_plmn; - srslte::byte_buffer_pool* m_pool; + uint32_t m_plmn; hss_interface_nas* m_hss; int m_s1mme; diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index 379c20a1f..0ec144074 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -52,13 +52,12 @@ private: s1ap_ctx_mngmt_proc(); virtual ~s1ap_ctx_mngmt_proc(); - s1ap* m_s1ap; - srslte::log_filter* m_s1ap_log; + s1ap* m_s1ap; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("S1AP"); s1ap_args_t m_s1ap_args; - mme_gtpc* m_mme_gtpc; - srslte::byte_buffer_pool* m_pool; + mme_gtpc* m_mme_gtpc; }; } // namespace srsepc diff --git a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h index 8c030a0cf..e74a85b4c 100644 --- a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h @@ -57,13 +57,12 @@ private: s1ap_erab_mngmt_proc(); virtual ~s1ap_erab_mngmt_proc(); - s1ap* m_s1ap = nullptr; - srslte::log_filter* m_s1ap_log = nullptr; + s1ap* m_s1ap = nullptr; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("S1AP"); s1ap_args_t m_s1ap_args; - mme_gtpc* m_mme_gtpc = nullptr; - srslte::byte_buffer_pool* m_pool = nullptr; + mme_gtpc* m_mme_gtpc = nullptr; }; } // namespace srsepc diff --git a/srsepc/hdr/mme/s1ap_mngmt_proc.h b/srsepc/hdr/mme/s1ap_mngmt_proc.h index 9dec6cd1b..f68338b4b 100644 --- a/srsepc/hdr/mme/s1ap_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_mngmt_proc.h @@ -25,6 +25,7 @@ #include "srslte/asn1/s1ap.h" #include "srslte/common/common.h" #include "srslte/common/log_filter.h" +#include "srslte/srslog/srslog.h" namespace srsepc { @@ -50,8 +51,8 @@ private: s1ap_mngmt_proc(); virtual ~s1ap_mngmt_proc(); - s1ap* m_s1ap; - srslte::log_filter* m_s1ap_log; + s1ap* m_s1ap; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("S1AP"); int m_s1mme; s1ap_args_t m_s1ap_args; diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 07f2e52c5..7c2dcc078 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -49,8 +49,7 @@ private: s1ap_nas_transport(); virtual ~s1ap_nas_transport(); - srslte::log* m_s1ap_log; - srslte::byte_buffer_pool* m_pool; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("S1AP"); s1ap* m_s1ap; diff --git a/srsepc/hdr/mme/s1ap_paging.h b/srsepc/hdr/mme/s1ap_paging.h index 5b1662ca8..f6a2e8dd2 100644 --- a/srsepc/hdr/mme/s1ap_paging.h +++ b/srsepc/hdr/mme/s1ap_paging.h @@ -25,6 +25,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/common.h" #include "srslte/common/log_filter.h" +#include "srslte/srslog/srslog.h" namespace srsepc { @@ -45,12 +46,11 @@ public: bool send_paging(uint64_t imsi, uint16_t erab_to_setup); private: - mme* m_mme; - s1ap* m_s1ap; - srslte::log_filter* m_s1ap_log; + mme* m_mme; + s1ap* m_s1ap; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("S1AP"); - s1ap_args_t m_s1ap_args; - srslte::byte_buffer_pool* m_pool; + s1ap_args_t m_s1ap_args; }; } // namespace srsepc diff --git a/srsepc/hdr/spgw/gtpc.h b/srsepc/hdr/spgw/gtpc.h index d37a8b85c..a95356356 100644 --- a/srsepc/hdr/spgw/gtpc.h +++ b/srsepc/hdr/spgw/gtpc.h @@ -24,6 +24,7 @@ #include "srsepc/hdr/spgw/spgw.h" #include "srslte/asn1/gtpc.h" #include "srslte/interfaces/epc_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include #include @@ -35,11 +36,7 @@ class spgw::gtpc : public gtpc_interface_gtpu public: gtpc(); virtual ~gtpc(); - int init(spgw_args_t* args, - spgw* spgw, - gtpu_interface_gtpc* gtpu, - srslte::log_filter* gtpc_log, - const std::map& ip_to_imsi); + int init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, const std::map& ip_to_imsi); void stop(); int init_s11(spgw_args_t* args); @@ -67,8 +64,8 @@ public: const srslte::gtpc_header& header, const srslte::gtpc_downlink_data_notification_failure_indication& not_fail); - virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::byte_buffer_t* msg); - virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid); + virtual bool queue_downlink_packet(uint32_t spgw_ctr_teid, srslte::unique_byte_buffer_t msg) override; + virtual bool send_downlink_data_notification(uint32_t spgw_ctr_teid) override; spgw_tunnel_ctx_t* create_gtpc_ctx(const srslte::gtpc_create_session_request& cs_req); bool delete_gtpc_ctx(uint32_t ctrl_teid); @@ -94,8 +91,7 @@ public: std::set m_ue_ip_addr_pool; std::map m_imsi_to_ip; - srslte::log_filter* m_gtpc_log; - srslte::byte_buffer_pool* m_pool; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("SPGW GTPC"); }; inline int spgw::gtpc::get_s11() diff --git a/srsepc/hdr/spgw/gtpu.h b/srsepc/hdr/spgw/gtpu.h index b3c03017a..127039cf9 100644 --- a/srsepc/hdr/spgw/gtpu.h +++ b/srsepc/hdr/spgw/gtpu.h @@ -27,6 +27,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/logmap.h" #include "srslte/interfaces/epc_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include @@ -37,7 +38,7 @@ class spgw::gtpu : public gtpu_interface_gtpc public: gtpu(); virtual ~gtpu(); - int init(spgw_args_t* args, spgw* spgw, gtpc_interface_gtpu* gtpc, srslte::log_ref gtpu_log); + int init(spgw_args_t* args, spgw* spgw, gtpc_interface_gtpu* gtpc); void stop(); int init_sgi(spgw_args_t* args); @@ -45,7 +46,7 @@ public: int get_sgi(); int get_s1u(); - void handle_sgi_pdu(srslte::byte_buffer_t* msg); + void handle_sgi_pdu(srslte::unique_byte_buffer_t msg); void handle_s1u_pdu(srslte::byte_buffer_t* msg); void send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer_t* msg); @@ -54,8 +55,8 @@ public: virtual bool modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtp_fteid_t dw_user_fteid, uint32_t up_ctr_fteid); virtual bool delete_gtpu_tunnel(in_addr_t ue_ipv4); virtual bool delete_gtpc_tunnel(in_addr_t ue_ipv4); - virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, - std::queue& pkt_queue); + virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, + std::queue& pkt_queue); spgw* m_spgw; gtpc_interface_gtpu* m_gtpc; @@ -72,10 +73,7 @@ public: // UE is attached without an active user-plane // for downlink notifications. - srslte::log_ref m_gtpu_log; - -private: - srslte::byte_buffer_pool* m_pool; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("GTPU"); }; inline int spgw::gtpu::get_sgi() diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index feabd79af..e6e10d67f 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -33,6 +33,7 @@ #include "srslte/common/log_filter.h" #include "srslte/common/logmap.h" #include "srslte/common/threads.h" +#include "srslte/srslog/srslog.h" #include #include @@ -50,15 +51,15 @@ typedef struct { } spgw_args_t; typedef struct spgw_tunnel_ctx { - uint64_t imsi; - in_addr_t ue_ipv4; - uint8_t ebi; - srslte::gtp_fteid_t up_ctrl_fteid; - srslte::gtp_fteid_t up_user_fteid; - srslte::gtp_fteid_t dw_ctrl_fteid; - srslte::gtp_fteid_t dw_user_fteid; - bool paging_pending; - std::queue paging_queue; + uint64_t imsi; + in_addr_t ue_ipv4; + uint8_t ebi; + srslte::gtp_fteid_t up_ctrl_fteid; + srslte::gtp_fteid_t up_user_fteid; + srslte::gtp_fteid_t dw_ctrl_fteid; + srslte::gtp_fteid_t dw_user_fteid; + bool paging_pending; + std::queue paging_queue; } spgw_tunnel_ctx_t; class spgw : public srslte::thread @@ -69,11 +70,7 @@ class spgw : public srslte::thread public: static spgw* get_instance(void); static void cleanup(void); - int init(spgw_args_t* args, - srslte::log_ref gtpu_log, - srslte::log_filter* gtpc_log, - srslte::log_filter* spgw_log, - const std::map& ip_to_imsi); + int init(spgw_args_t* args, const std::map& ip_to_imsi); void stop(); void run_thread(); @@ -85,16 +82,15 @@ private: spgw_tunnel_ctx_t* create_gtp_ctx(struct srslte::gtpc_create_session_request* cs_req); bool delete_gtp_ctx(uint32_t ctrl_teid); - bool m_running; - srslte::byte_buffer_pool* m_pool; - mme_gtpc* m_mme_gtpc; + bool m_running; + mme_gtpc* m_mme_gtpc; // GTP-C and GTP-U handlers gtpc* m_gtpc; gtpu* m_gtpu; // Logs - srslte::log_filter* m_spgw_log; + srslog::basic_logger& m_logger = srslog::fetch_basic_logger("SPGW"); }; } // namespace srsepc diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 22d2a6afb..5913f76dd 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -63,11 +63,9 @@ void hss::cleanup() pthread_mutex_unlock(&hss_instance_mutex); } -int hss::init(hss_args_t* hss_args, srslte::log_filter* hss_log) +int hss::init(hss_args_t* hss_args) { srand(time(NULL)); - /*Init loggers*/ - m_hss_log = hss_log; /*Read user information from DB*/ if (read_db_file(hss_args->db_file) == false) { @@ -80,7 +78,7 @@ int hss::init(hss_args_t* hss_args, srslte::log_filter* hss_log) db_file = hss_args->db_file; - m_hss_log->info("HSS Initialized. DB file %s, MCC: %d, MNC: %d\n", hss_args->db_file.c_str(), mcc, mnc); + m_logger.info("HSS Initialized. DB file %s, MCC: %d, MNC: %d", hss_args->db_file.c_str(), mcc, mnc); srslte::console("HSS Initialized.\n"); return 0; } @@ -99,7 +97,7 @@ bool hss::read_db_file(std::string db_filename) if (!m_db_file.is_open()) { return false; } - m_hss_log->info("Opened DB file: %s\n", db_filename.c_str()); + m_logger.info("Opened DB file: %s", db_filename.c_str()); std::string line; while (std::getline(m_db_file, line)) { @@ -107,8 +105,8 @@ bool hss::read_db_file(std::string db_filename) uint column_size = 10; std::vector split = split_string(line, ','); if (split.size() != column_size) { - m_hss_log->error("Error parsing UE database. Wrong number of columns in .csv\n"); - m_hss_log->error("Columns: %zd, Expected %d.\n", split.size(), column_size); + m_logger.error("Error parsing UE database. Wrong number of columns in .csv"); + m_logger.error("Columns: %zd, Expected %d.", split.size(), column_size); srslte::console("\nError parsing UE database. Wrong number of columns in user database CSV.\n"); srslte::console("Perhaps you are using an old user_db.csv?\n"); @@ -122,7 +120,7 @@ bool hss::read_db_file(std::string db_filename) } else if (split[1] == std::string("mil")) { ue_ctx->algo = HSS_ALGO_MILENAGE; } else { - m_hss_log->error("Neither XOR nor MILENAGE configured.\n"); + m_logger.error("Neither XOR nor MILENAGE configured."); return false; } ue_ctx->imsi = strtoull(split[2].c_str(), nullptr, 10); @@ -135,22 +133,22 @@ bool hss::read_db_file(std::string db_filename) ue_ctx->op_configured = false; get_uint_vec_from_hex_str(split[5], ue_ctx->opc, 16); } else { - m_hss_log->error("Neither OP nor OPc configured.\n"); + m_logger.error("Neither OP nor OPc configured."); return false; } get_uint_vec_from_hex_str(split[6], ue_ctx->amf, 2); get_uint_vec_from_hex_str(split[7], ue_ctx->sqn, 6); - m_hss_log->debug("Added user from DB, IMSI: %015" PRIu64 "\n", ue_ctx->imsi); - m_hss_log->debug_hex(ue_ctx->key, 16, "User Key : "); + m_logger.debug("Added user from DB, IMSI: %015" PRIu64 "", ue_ctx->imsi); + m_logger.debug(ue_ctx->key, 16, "User Key : "); if (ue_ctx->op_configured) { - m_hss_log->debug_hex(ue_ctx->op, 16, "User OP : "); + m_logger.debug(ue_ctx->op, 16, "User OP : "); } - m_hss_log->debug_hex(ue_ctx->opc, 16, "User OPc : "); - m_hss_log->debug_hex(ue_ctx->amf, 2, "AMF : "); - m_hss_log->debug_hex(ue_ctx->sqn, 6, "SQN : "); + m_logger.debug(ue_ctx->opc, 16, "User OPc : "); + m_logger.debug(ue_ctx->amf, 2, "AMF : "); + m_logger.debug(ue_ctx->sqn, 6, "SQN : "); ue_ctx->qci = (uint16_t)strtol(split[8].c_str(), nullptr, 10); - m_hss_log->debug("Default Bearer QCI: %d\n", ue_ctx->qci); + m_logger.debug("Default Bearer QCI: %d", ue_ctx->qci); if (split[9] == std::string("dynamic")) { ue_ctx->static_ip_addr = "0.0.0.0"; @@ -159,13 +157,13 @@ bool hss::read_db_file(std::string db_filename) if (inet_pton(AF_INET, split[9].c_str(), buf)) { if (m_ip_to_imsi.insert(std::make_pair(split[9], ue_ctx->imsi)).second) { ue_ctx->static_ip_addr = split[9]; - m_hss_log->info("static ip addr %s\n", ue_ctx->static_ip_addr.c_str()); + m_logger.info("static ip addr %s", ue_ctx->static_ip_addr.c_str()); } else { - m_hss_log->info("duplicate static ip addr %s\n", split[9].c_str()); + m_logger.info("duplicate static ip addr %s", split[9].c_str()); return false; } } else { - m_hss_log->info("invalid static ip addr %s, %s\n", split[9].c_str(), strerror(errno)); + m_logger.info("invalid static ip addr %s, %s", split[9].c_str(), strerror(errno)); return false; } } @@ -194,7 +192,7 @@ bool hss::write_db_file(std::string db_filename) if (!m_db_file.is_open()) { return false; } - m_hss_log->info("Opened DB file: %s\n", db_filename.c_str()); + m_logger.info("Opened DB file: %s", db_filename.c_str()); // Write comment info m_db_file << "# \n" @@ -258,11 +256,11 @@ bool hss::write_db_file(std::string db_filename) bool hss::gen_auth_info_answer(uint64_t imsi, uint8_t* k_asme, uint8_t* autn, uint8_t* rand, uint8_t* xres) { - m_hss_log->debug("Generating AUTH info answer\n"); + m_logger.debug("Generating AUTH info answer"); hss_ue_ctx_t* ue_ctx = get_ue_ctx(imsi); if (ue_ctx == nullptr) { srslte::console("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi); - m_hss_log->error("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi); + m_logger.error("User not found at HSS. IMSI: %015" PRIu64 "", imsi); return false; } @@ -300,24 +298,24 @@ void hss::gen_auth_info_answer_milenage(hss_ue_ctx_t* ue_ctx, srslte::security_milenage_f2345(k, opc, rand, xres, ck, ik, ak); - m_hss_log->debug_hex(k, 16, "User Key : "); - m_hss_log->debug_hex(opc, 16, "User OPc : "); - m_hss_log->debug_hex(rand, 16, "User Rand : "); - m_hss_log->debug_hex(xres, 8, "User XRES: "); - m_hss_log->debug_hex(ck, 16, "User CK: "); - m_hss_log->debug_hex(ik, 16, "User IK: "); - m_hss_log->debug_hex(ak, 6, "User AK: "); + m_logger.debug(k, 16, "User Key : "); + m_logger.debug(opc, 16, "User OPc : "); + m_logger.debug(rand, 16, "User Rand : "); + m_logger.debug(xres, 8, "User XRES: "); + m_logger.debug(ck, 16, "User CK: "); + m_logger.debug(ik, 16, "User IK: "); + m_logger.debug(ak, 6, "User AK: "); srslte::security_milenage_f1(k, opc, rand, sqn, amf, mac); - m_hss_log->debug_hex(sqn, 6, "User SQN : "); - m_hss_log->debug_hex(mac, 8, "User MAC : "); + m_logger.debug(sqn, 6, "User SQN : "); + m_logger.debug(mac, 8, "User MAC : "); // Generate K_asme srslte::security_generate_k_asme(ck, ik, ak, sqn, mcc, mnc, k_asme); - m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc); - m_hss_log->debug_hex(k_asme, 32, "User k_asme : "); + m_logger.debug("User MCC : %x MNC : %x ", mcc, mnc); + m_logger.debug(k_asme, 32, "User k_asme : "); // Generate AUTN (autn = sqn ^ ak |+| amf |+| mac) for (int i = 0; i < 6; i++) { @@ -329,7 +327,7 @@ void hss::gen_auth_info_answer_milenage(hss_ue_ctx_t* ue_ctx, for (int i = 0; i < 8; i++) { autn[8 + i] = mac[i]; } - m_hss_log->debug_hex(autn, 16, "User AUTN: "); + m_logger.debug(autn, 16, "User AUTN: "); // Set last RAND ue_ctx->set_last_rand(rand); @@ -372,13 +370,13 @@ void hss::gen_auth_info_answer_xor(hss_ue_ctx_t* ue_ctx, uint8_t* k_asme, uint8_ ak[i] = xdout[i + 3]; } - m_hss_log->debug_hex(k, 16, "User Key : "); - m_hss_log->debug_hex(opc, 16, "User OPc : "); - m_hss_log->debug_hex(rand, 16, "User Rand : "); - m_hss_log->debug_hex(xres, 8, "User XRES: "); - m_hss_log->debug_hex(ck, 16, "User CK: "); - m_hss_log->debug_hex(ik, 16, "User IK: "); - m_hss_log->debug_hex(ak, 6, "User AK: "); + m_logger.debug(k, 16, "User Key : "); + m_logger.debug(opc, 16, "User OPc : "); + m_logger.debug(rand, 16, "User Rand : "); + m_logger.debug(xres, 8, "User XRES: "); + m_logger.debug(ck, 16, "User CK: "); + m_logger.debug(ik, 16, "User IK: "); + m_logger.debug(ak, 6, "User AK: "); // Generate cdout for (i = 0; i < 6; i++) { @@ -393,8 +391,8 @@ void hss::gen_auth_info_answer_xor(hss_ue_ctx_t* ue_ctx, uint8_t* k_asme, uint8_ mac[i] = xdout[i] ^ cdout[i]; } - m_hss_log->debug_hex(sqn, 6, "User SQN : "); - m_hss_log->debug_hex(mac, 8, "User MAC : "); + m_logger.debug(sqn, 6, "User SQN : "); + m_logger.debug(mac, 8, "User MAC : "); // Generate AUTN (autn = sqn ^ ak |+| amf |+| mac) for (int i = 0; i < 6; i++) { @@ -410,8 +408,8 @@ void hss::gen_auth_info_answer_xor(hss_ue_ctx_t* ue_ctx, uint8_t* k_asme, uint8_ // Generate K_asme srslte::security_generate_k_asme(ck, ik, ak, sqn, mcc, mnc, k_asme); - m_hss_log->debug("User MCC : %x MNC : %x \n", mcc, mnc); - m_hss_log->debug_hex(k_asme, 32, "User k_asme : "); + m_logger.debug("User MCC : %x MNC : %x ", mcc, mnc); + m_logger.debug(k_asme, 32, "User k_asme : "); // Generate AUTN (autn = sqn ^ ak |+| amf |+| mac) for (int i = 0; i < 6; i++) { @@ -424,7 +422,7 @@ void hss::gen_auth_info_answer_xor(hss_ue_ctx_t* ue_ctx, uint8_t* k_asme, uint8_ autn[8 + i] = mac[i]; } - m_hss_log->debug_hex(autn, 8, "User AUTN: "); + m_logger.debug(autn, 8, "User AUTN: "); // Set last RAND ue_ctx->set_last_rand(rand); @@ -435,23 +433,23 @@ bool hss::gen_update_loc_answer(uint64_t imsi, uint8_t* qci) { std::map >::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); if (ue_ctx_it == m_imsi_to_ue_ctx.end()) { - m_hss_log->info("User not found. IMSI: %015" PRIu64 "\n", imsi); + m_logger.info("User not found. IMSI: %015" PRIu64 "", imsi); srslte::console("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi); return false; } const std::unique_ptr& ue_ctx = ue_ctx_it->second; - m_hss_log->info("Found User %015" PRIu64 "\n", imsi); + m_logger.info("Found User %015" PRIu64 "", imsi); *qci = ue_ctx->qci; return true; } bool hss::resync_sqn(uint64_t imsi, uint8_t* auts) { - m_hss_log->debug("Re-syncing SQN\n"); + m_logger.debug("Re-syncing SQN"); hss_ue_ctx_t* ue_ctx = get_ue_ctx(imsi); if (ue_ctx == nullptr) { srslte::console("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi); - m_hss_log->error("User not found at HSS. IMSI: %015" PRIu64 "\n", imsi); + m_logger.error("User not found at HSS. IMSI: %015" PRIu64 "", imsi); return false; } @@ -470,7 +468,7 @@ bool hss::resync_sqn(uint64_t imsi, uint8_t* auts) void hss::resync_sqn_xor(hss_ue_ctx_t* ue_ctx, uint8_t* auts) { - m_hss_log->error("XOR SQN synchronization not supported yet\n"); + m_logger.error("XOR SQN synchronization not supported yet"); srslte::console("XOR SQNs synchronization not supported yet\n"); return; } @@ -499,30 +497,30 @@ void hss::resync_sqn_milenage(hss_ue_ctx_t* ue_ctx, uint8_t* auts) mac_s[i] = auts[i + 6]; } - m_hss_log->debug_hex(k, 16, "User Key : "); - m_hss_log->debug_hex(opc, 16, "User OPc : "); - m_hss_log->debug_hex(amf, 2, "User AMF : "); - m_hss_log->debug_hex(last_rand, 16, "User Last Rand : "); - m_hss_log->debug_hex(auts, 16, "AUTS : "); - m_hss_log->debug_hex(sqn_ms_xor_ak, 6, "SQN xor AK : "); - m_hss_log->debug_hex(mac_s, 8, "MAC : "); + m_logger.debug(k, 16, "User Key : "); + m_logger.debug(opc, 16, "User OPc : "); + m_logger.debug(amf, 2, "User AMF : "); + m_logger.debug(last_rand, 16, "User Last Rand : "); + m_logger.debug(auts, 16, "AUTS : "); + m_logger.debug(sqn_ms_xor_ak, 6, "SQN xor AK : "); + m_logger.debug(mac_s, 8, "MAC : "); srslte::security_milenage_f5_star(k, opc, last_rand, ak); - m_hss_log->debug_hex(ak, 6, "Resynch AK : "); + m_logger.debug(ak, 6, "Resynch AK : "); uint8_t sqn_ms[6]; for (int i = 0; i < 6; i++) { sqn_ms[i] = sqn_ms_xor_ak[i] ^ ak[i]; } - m_hss_log->debug_hex(sqn_ms, 6, "SQN MS : "); - m_hss_log->debug_hex(sqn, 6, "SQN HE : "); + m_logger.debug(sqn_ms, 6, "SQN MS : "); + m_logger.debug(sqn, 6, "SQN HE : "); uint8_t mac_s_tmp[8]; uint8_t dummy_amf[2] = {}; srslte::security_milenage_f1_star(k, opc, last_rand, sqn_ms, dummy_amf, mac_s_tmp); - m_hss_log->debug_hex(mac_s_tmp, 8, "MAC calc : "); + m_logger.debug(mac_s_tmp, 8, "MAC calc : "); ue_ctx->set_sqn(sqn_ms); return; @@ -531,8 +529,8 @@ void hss::resync_sqn_milenage(hss_ue_ctx_t* ue_ctx, uint8_t* auts) void hss::increment_ue_sqn(hss_ue_ctx_t* ue_ctx) { increment_sqn(ue_ctx->sqn, ue_ctx->sqn); - m_hss_log->debug("Incremented SQN -- IMSI: %015" PRIu64 "\n", ue_ctx->imsi); - m_hss_log->debug_hex(ue_ctx->sqn, 6, "SQN: "); + m_logger.debug("Incremented SQN -- IMSI: %015" PRIu64 "", ue_ctx->imsi); + m_logger.debug(ue_ctx->sqn, 6, "SQN: "); } void hss::increment_sqn(uint8_t* sqn, uint8_t* next_sqn) @@ -607,7 +605,7 @@ hss_ue_ctx_t* hss::get_ue_ctx(uint64_t imsi) { std::map >::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi); if (ue_ctx_it == m_imsi_to_ue_ctx.end()) { - m_hss_log->info("User not found. IMSI: %015" PRIu64 "\n", imsi); + m_logger.info("User not found. IMSI: %015" PRIu64 "", imsi); return nullptr; } diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index d22aeec32..e06c4d94c 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -400,14 +400,14 @@ int main(int argc, char* argv[]) return SRSLTE_ERROR; } srslte::srslog_wrapper log_wrapper(*chan); + srslog::set_default_sink(*log_sink); // Start the log backend. srslog::init(); if (args.log_args.filename != "stdout") { - log_wrapper.log_char("\n\n"); - log_wrapper.log_char(get_build_string().c_str()); - log_wrapper.log_char("\n--- Software Radio Systems EPC log ---\n\n"); + auto& epc_logger = srslog::fetch_basic_logger("EPC", false); + epc_logger.info("\n\n%s\n--- Software Radio Systems EPC log ---\n\n", get_build_string().c_str()); } srslte::logmap::set_default_logger(&log_wrapper); @@ -417,50 +417,71 @@ int main(int argc, char* argv[]) nas_log.init("NAS ", &log_wrapper); nas_log.set_level(level(args.log_args.nas_level)); nas_log.set_hex_limit(args.log_args.nas_hex_limit); + auto& nas_logger = srslog::fetch_basic_logger("NAS", false); + nas_logger.set_level(srslog::str_to_basic_level(args.log_args.nas_level)); + nas_logger.set_hex_dump_max_size(args.log_args.nas_hex_limit); srslte::log_filter s1ap_log; s1ap_log.init("S1AP", &log_wrapper); s1ap_log.set_level(level(args.log_args.s1ap_level)); s1ap_log.set_hex_limit(args.log_args.s1ap_hex_limit); + auto& s1ap_logger = srslog::fetch_basic_logger("S1AP", false); + s1ap_logger.set_level(srslog::str_to_basic_level(args.log_args.s1ap_level)); + s1ap_logger.set_hex_dump_max_size(args.log_args.s1ap_hex_limit); srslte::log_filter mme_gtpc_log; mme_gtpc_log.init("MME GTPC", &log_wrapper); mme_gtpc_log.set_level(level(args.log_args.mme_gtpc_level)); mme_gtpc_log.set_hex_limit(args.log_args.mme_gtpc_hex_limit); + auto& mme_gtpc_logger = srslog::fetch_basic_logger("MME GTPC", false); + mme_gtpc_logger.set_level(srslog::str_to_basic_level(args.log_args.mme_gtpc_level)); + mme_gtpc_logger.set_hex_dump_max_size(args.log_args.mme_gtpc_hex_limit); srslte::log_filter hss_log; hss_log.init("HSS ", &log_wrapper); hss_log.set_level(level(args.log_args.hss_level)); hss_log.set_hex_limit(args.log_args.hss_hex_limit); + auto& hss_logger = srslog::fetch_basic_logger("HSS", false); + hss_logger.set_level(srslog::str_to_basic_level(args.log_args.hss_level)); + hss_logger.set_hex_dump_max_size(args.log_args.hss_hex_limit); srslte::log_filter spgw_gtpc_log; spgw_gtpc_log.init("SPGW GTPC", &log_wrapper); spgw_gtpc_log.set_level(level(args.log_args.spgw_gtpc_level)); spgw_gtpc_log.set_hex_limit(args.log_args.spgw_gtpc_hex_limit); + auto& spgw_gtpc_logger = srslog::fetch_basic_logger("SPGW GTPC", false); + spgw_gtpc_logger.set_level(srslog::str_to_basic_level(args.log_args.spgw_gtpc_level)); + spgw_gtpc_logger.set_hex_dump_max_size(args.log_args.spgw_gtpc_hex_limit); srslte::log_ref gtpu_log{"GTPU"}; gtpu_log->set_level(level(args.log_args.mme_gtpc_level)); gtpu_log->set_hex_limit(args.log_args.mme_gtpc_hex_limit); + auto& gtpu_logger = srslog::fetch_basic_logger("GTPU", false); + gtpu_logger.set_level(srslog::str_to_basic_level(args.log_args.gtpu_level)); + gtpu_logger.set_hex_dump_max_size(args.log_args.gtpu_hex_limit); srslte::log_filter spgw_log; spgw_log.init("SPGW", &log_wrapper); spgw_log.set_level(level(args.log_args.spgw_level)); spgw_log.set_hex_limit(args.log_args.spgw_hex_limit); + auto& spgw_logger = srslog::fetch_basic_logger("SPGW", false); + spgw_logger.set_level(srslog::str_to_basic_level(args.log_args.spgw_level)); + spgw_logger.set_hex_dump_max_size(args.log_args.spgw_hex_limit); hss* hss = hss::get_instance(); - if (hss->init(&args.hss_args, &hss_log)) { + if (hss->init(&args.hss_args)) { cout << "Error initializing HSS" << endl; exit(1); } mme* mme = mme::get_instance(); - if (mme->init(&args.mme_args, &nas_log, &s1ap_log, &mme_gtpc_log)) { + if (mme->init(&args.mme_args)) { cout << "Error initializing MME" << endl; exit(1); } spgw* spgw = spgw::get_instance(); - if (spgw->init(&args.spgw_args, gtpu_log, &spgw_gtpc_log, &spgw_log, hss->get_ip_to_imsi())) { + if (spgw->init(&args.spgw_args, hss->get_ip_to_imsi())) { cout << "Error initializing SP-GW" << endl; exit(1); } diff --git a/srsepc/src/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index 6fb76999a..ed60e07d4 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -76,7 +76,6 @@ string config_file; void parse_args(all_args_t* args, int argc, char* argv[]) { - string mbms_gw_name; string mbms_gw_sgi_mb_if_name; string mbms_gw_sgi_mb_if_addr; @@ -205,12 +204,14 @@ int main(int argc, char* argv[]) return SRSLTE_ERROR; } srslte::srslog_wrapper log_wrapper(*chan); + srslog::set_default_sink(*log_sink); // Start the log backend. srslog::init(); if (args.log_args.filename != "stdout") { - log_wrapper.log_char("\n--- Software Radio Systems MBMS log ---\n\n"); + auto& mbms_gw_logger = srslog::fetch_basic_logger("MBMS GW", false); + mbms_gw_logger.info("\n--- Software Radio Systems MBMS log ---\n\n"); } srslte::logmap::set_default_logger(&log_wrapper); @@ -218,9 +219,12 @@ int main(int argc, char* argv[]) srslte::log_ref mbms_gw_log{"MBMS"}; mbms_gw_log->set_level(level(args.log_args.mbms_gw_level)); mbms_gw_log->set_hex_limit(args.log_args.mbms_gw_hex_limit); + auto& mbms_gw_logger = srslog::fetch_basic_logger("MBMS", false); + mbms_gw_logger.set_level(srslog::str_to_basic_level(args.log_args.mbms_gw_level)); + mbms_gw_logger.set_hex_dump_max_size(args.log_args.mbms_gw_hex_limit); mbms_gw* mbms_gw = mbms_gw::get_instance(); - if (mbms_gw->init(&args.mbms_gw_args, mbms_gw_log)) { + if (mbms_gw->init(&args.mbms_gw_args)) { cout << "Error initializing MBMS-GW" << endl; exit(1); } diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index 23ab5ee20..7a15c80be 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -69,27 +69,23 @@ void mbms_gw::cleanup(void) pthread_mutex_unlock(&mbms_gw_instance_mutex); } -int mbms_gw::init(mbms_gw_args_t* args, srslte::log_ref mbms_gw_log) +int mbms_gw::init(mbms_gw_args_t* args) { int err; - m_pool = srslte::byte_buffer_pool::get_instance(); - - // Init log - m_mbms_gw_log = mbms_gw_log; err = init_sgi_mb_if(args); if (err != SRSLTE_SUCCESS) { srslte::console("Error initializing SGi-MB.\n"); - m_mbms_gw_log->error("Error initializing SGi-MB.\n"); + m_logger.error("Error initializing SGi-MB."); return SRSLTE_ERROR_CANT_START; } err = init_m1_u(args); if (err != SRSLTE_SUCCESS) { srslte::console("Error initializing SGi-MB.\n"); - m_mbms_gw_log->error("Error initializing SGi-MB.\n"); + m_logger.error("Error initializing SGi-MB."); return SRSLTE_ERROR_CANT_START; } - m_mbms_gw_log->info("MBMS GW Initiated\n"); + m_logger.info("MBMS GW Initiated"); srslte::console("MBMS GW Initiated\n"); return SRSLTE_SUCCESS; } @@ -99,7 +95,7 @@ void mbms_gw::stop() if (m_running) { if (m_sgi_mb_up) { close(m_sgi_mb_if); - m_mbms_gw_log->info("Closed SGi-MB interface\n"); + m_logger.info("Closed SGi-MB interface"); } m_running = false; thread_cancel(); @@ -118,9 +114,9 @@ int mbms_gw::init_sgi_mb_if(mbms_gw_args_t* args) // Construct the TUN device m_sgi_mb_if = open("/dev/net/tun", O_RDWR); - m_mbms_gw_log->info("TUN file descriptor = %d\n", m_sgi_mb_if); + m_logger.info("TUN file descriptor = %d", m_sgi_mb_if); if (m_sgi_mb_if < 0) { - m_mbms_gw_log->error("Failed to open TUN device: %s\n", strerror(errno)); + m_logger.error("Failed to open TUN device: %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } @@ -132,23 +128,23 @@ int mbms_gw::init_sgi_mb_if(mbms_gw_args_t* args) ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; if (ioctl(m_sgi_mb_if, TUNSETIFF, &ifr) < 0) { - m_mbms_gw_log->error("Failed to set TUN device name: %s\n", strerror(errno)); + m_logger.error("Failed to set TUN device name: %s", strerror(errno)); close(m_sgi_mb_if); return SRSLTE_ERROR_CANT_START; } else { - m_mbms_gw_log->debug("Set TUN device name: %s\n", args->sgi_mb_if_name.c_str()); + m_logger.debug("Set TUN device name: %s", args->sgi_mb_if_name.c_str()); } // Bring up the interface int sgi_mb_sock = socket(AF_INET, SOCK_DGRAM, 0); if (sgi_mb_sock < 0) { - m_mbms_gw_log->error("Failed to bring up socket: %s\n", strerror(errno)); + m_logger.error("Failed to bring up socket: %s", strerror(errno)); close(m_sgi_mb_if); return SRSLTE_ERROR_CANT_START; } if (ioctl(sgi_mb_sock, SIOCGIFFLAGS, &ifr) < 0) { - m_mbms_gw_log->error("Failed to bring up interface: %s\n", strerror(errno)); + m_logger.error("Failed to bring up interface: %s", strerror(errno)); close(m_sgi_mb_if); close(sgi_mb_sock); return SRSLTE_ERROR_CANT_START; @@ -156,7 +152,7 @@ int mbms_gw::init_sgi_mb_if(mbms_gw_args_t* args) ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if (ioctl(sgi_mb_sock, SIOCSIFFLAGS, &ifr) < 0) { - m_mbms_gw_log->error("Failed to set socket flags: %s\n", strerror(errno)); + m_logger.error("Failed to set socket flags: %s", strerror(errno)); close(sgi_mb_sock); close(m_sgi_mb_if); return SRSLTE_ERROR_CANT_START; @@ -169,8 +165,8 @@ int mbms_gw::init_sgi_mb_if(mbms_gw_args_t* args) addr->sin_port = 0; if (ioctl(sgi_mb_sock, SIOCSIFADDR, &ifr) < 0) { - m_mbms_gw_log->error( - "Failed to set TUN interface IP. Address: %s, Error: %s\n", args->sgi_mb_if_addr.c_str(), strerror(errno)); + m_logger.error( + "Failed to set TUN interface IP. Address: %s, Error: %s", args->sgi_mb_if_addr.c_str(), strerror(errno)); close(m_sgi_mb_if); close(sgi_mb_sock); return SRSLTE_ERROR_CANT_START; @@ -179,7 +175,7 @@ int mbms_gw::init_sgi_mb_if(mbms_gw_args_t* args) ifr.ifr_netmask.sa_family = AF_INET; ((struct sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr(args->sgi_mb_if_mask.c_str()); if (ioctl(sgi_mb_sock, SIOCSIFNETMASK, &ifr) < 0) { - m_mbms_gw_log->error("Failed to set TUN interface Netmask. Error: %s\n", strerror(errno)); + m_logger.error("Failed to set TUN interface Netmask. Error: %s", strerror(errno)); close(m_sgi_mb_if); close(sgi_mb_sock); return SRSLTE_ERROR_CANT_START; @@ -196,7 +192,7 @@ int mbms_gw::init_m1_u(mbms_gw_args_t* args) struct sockaddr_in addr; m_m1u = socket(AF_INET, SOCK_DGRAM, 0); if (m_m1u < 0) { - m_mbms_gw_log->error("Failed to open socket: %s\n", strerror(errno)); + m_logger.error("Failed to open socket: %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } m_m1u_up = true; @@ -204,10 +200,10 @@ int mbms_gw::init_m1_u(mbms_gw_args_t* args) /* set no loopback */ char loopch = 0; if (setsockopt(m_m1u, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&loopch, sizeof(char)) < 0) { - m_mbms_gw_log->error("Failed to disable loopback: %s\n", strerror(errno)); + m_logger.error("Failed to disable loopback: %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } else { - m_mbms_gw_log->debug("Loopback disabled\n"); + m_logger.debug("Loopback disabled"); } /* Set local interface for outbound multicast packets*/ @@ -215,7 +211,7 @@ int mbms_gw::init_m1_u(mbms_gw_args_t* args) struct in_addr local_if; local_if.s_addr = inet_addr(args->m1u_multi_if.c_str()); if (setsockopt(m_m1u, IPPROTO_IP, IP_MULTICAST_IF, (char*)&local_if, sizeof(struct in_addr)) < 0) { - m_mbms_gw_log->error("Error %s setting multicast interface %s.\n", strerror(errno), args->m1u_multi_if.c_str()); + m_logger.error("Error %s setting multicast interface %s.", strerror(errno), args->m1u_multi_if.c_str()); return SRSLTE_ERROR_CANT_START; } else { printf("Multicast interface specified. Address: %s\n", args->m1u_multi_if.c_str()); @@ -231,7 +227,7 @@ int mbms_gw::init_m1_u(mbms_gw_args_t* args) m_m1u_multi_addr.sin_family = AF_INET; m_m1u_multi_addr.sin_port = htons(GTPU_RX_PORT + 1); m_m1u_multi_addr.sin_addr.s_addr = inet_addr(args->m1u_multi_addr.c_str()); - m_mbms_gw_log->info("Initialized M1-U\n"); + m_logger.info("Initialized M1-U"); return SRSLTE_SUCCESS; } @@ -239,9 +235,8 @@ int mbms_gw::init_m1_u(mbms_gw_args_t* args) void mbms_gw::run_thread() { // Mark the thread as running - m_running = true; - srslte::byte_buffer_t* msg; - msg = m_pool->allocate(); + m_running = true; + srslte::unique_byte_buffer_t msg = srslte::make_byte_buffer(); uint8_t seq = 0; while (m_running) { @@ -252,13 +247,12 @@ void mbms_gw::run_thread() } while (n == -1 && errno == EAGAIN); if (n < 0) { - m_mbms_gw_log->error("Error reading from TUN interface. Error: %s\n", strerror(errno)); + m_logger.error("Error reading from TUN interface. Error: %s", strerror(errno)); } else { msg->N_bytes = n; - handle_sgi_md_pdu(msg); + handle_sgi_md_pdu(msg.get()); } } - m_pool->deallocate(msg); return; } @@ -275,19 +269,19 @@ void mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t* msg) // Sanity Check IP packet if (msg->N_bytes < 20) { - m_mbms_gw_log->error("IPv4 min len: %d, drop msg len %d\n", 20, msg->N_bytes); + m_logger.error("IPv4 min len: %d, drop msg len %d", 20, msg->N_bytes); return; } // IP Headers struct iphdr* iph = (struct iphdr*)msg->msg; if (iph->version != 4) { - m_mbms_gw_log->info("IPv6 not supported yet.\n"); + m_logger.info("IPv6 not supported yet."); return; } // Write GTP-U header into packet - if (!srslte::gtpu_write_header(&header, msg, m_mbms_gw_log)) { + if (!srslte::gtpu_write_header(&header, msg, m_logger)) { srslte::console("Error writing GTP-U header on PDU\n"); } @@ -295,7 +289,7 @@ void mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t* msg) if (n < 0) { srslte::console("Error writing to M1-U socket.\n"); } else { - m_mbms_gw_log->debug("Sent %d Bytes\n", msg->N_bytes); + m_logger.debug("Sent %d Bytes", msg->N_bytes); } } diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index 871105751..51fed7156 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -33,7 +33,6 @@ pthread_mutex_t mme_instance_mutex = PTHREAD_MUTEX_INITIALIZER; mme::mme() : m_running(false), thread("MME") { - m_pool = srslte::byte_buffer_pool::get_instance(); return; } @@ -62,32 +61,24 @@ void mme::cleanup(void) pthread_mutex_unlock(&mme_instance_mutex); } -int mme::init(mme_args_t* args, - srslte::log_filter* nas_log, - srslte::log_filter* s1ap_log, - srslte::log_filter* mme_gtpc_log) +int mme::init(mme_args_t* args) { - /*Init logger*/ - m_nas_log = nas_log; - m_s1ap_log = s1ap_log; - m_mme_gtpc_log = mme_gtpc_log; - /*Init S1AP*/ m_s1ap = s1ap::get_instance(); - if (m_s1ap->init(args->s1ap_args, nas_log, s1ap_log)) { - m_s1ap_log->error("Error initializing MME S1APP\n"); + if (m_s1ap->init(args->s1ap_args)) { + m_s1ap_logger.error("Error initializing MME S1APP"); exit(-1); } /*Init GTP-C*/ m_mme_gtpc = mme_gtpc::get_instance(); - if (!m_mme_gtpc->init(m_mme_gtpc_log)) { + if (!m_mme_gtpc->init()) { srslte::console("Error initializing GTP-C\n"); exit(-1); } /*Log successful initialization*/ - m_s1ap_log->info("MME Initialized. MCC: 0x%x, MNC: 0x%x\n", args->s1ap_args.mcc, args->s1ap_args.mnc); + m_s1ap_logger.info("MME Initialized. MCC: 0x%x, MNC: 0x%x", args->s1ap_args.mcc, args->s1ap_args.mnc); srslte::console("MME Initialized. MCC: 0x%x, MNC: 0x%x\n", args->s1ap_args.mcc, args->s1ap_args.mnc); return 0; } @@ -106,8 +97,8 @@ void mme::stop() void mme::run_thread() { - srslte::byte_buffer_t* pdu = m_pool->allocate("mme::run_thread"); - uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET; + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer("mme::run_thread"); + uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET; struct sockaddr_in enb_addr; struct sctp_sndrcvinfo sri; @@ -135,48 +126,48 @@ void mme::run_thread() for (std::vector::iterator it = timers.begin(); it != timers.end(); ++it) { FD_SET(it->fd, &m_set); max_fd = std::max(max_fd, it->fd); - m_s1ap_log->debug("Adding Timer fd %d to fd_set\n", it->fd); + m_s1ap_logger.debug("Adding Timer fd %d to fd_set", it->fd); } - m_s1ap_log->debug("Waiting for S1-MME or S11 Message\n"); + m_s1ap_logger.debug("Waiting for S1-MME or S11 Message"); int n = select(max_fd + 1, &m_set, NULL, NULL, NULL); if (n == -1) { - m_s1ap_log->error("Error from select\n"); + m_s1ap_logger.error("Error from select"); } else if (n) { // Handle S1-MME if (FD_ISSET(s1mme, &m_set)) { rd_sz = sctp_recvmsg(s1mme, pdu->msg, sz, (struct sockaddr*)&enb_addr, &fromlen, &sri, &msg_flags); if (rd_sz == -1 && errno != EAGAIN) { - m_s1ap_log->error("Error reading from SCTP socket: %s", strerror(errno)); + m_s1ap_logger.error("Error reading from SCTP socket: %s", strerror(errno)); } else if (rd_sz == -1 && errno == EAGAIN) { - m_s1ap_log->debug("Socket timeout reached"); + m_s1ap_logger.debug("Socket timeout reached"); } else { if (msg_flags & MSG_NOTIFICATION) { // Received notification union sctp_notification* notification = (union sctp_notification*)pdu->msg; - m_s1ap_log->debug("SCTP Notification %d\n", notification->sn_header.sn_type); + m_s1ap_logger.debug("SCTP Notification %d", notification->sn_header.sn_type); if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) { - m_s1ap_log->info("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); + m_s1ap_logger.info("SCTP Association Shutdown. Association: %d", sri.sinfo_assoc_id); srslte::console("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); m_s1ap->delete_enb_ctx(sri.sinfo_assoc_id); } } else { // Received data pdu->N_bytes = rd_sz; - m_s1ap_log->info("Received S1AP msg. Size: %d\n", pdu->N_bytes); - m_s1ap->handle_s1ap_rx_pdu(pdu, &sri); + m_s1ap_logger.info("Received S1AP msg. Size: %d", pdu->N_bytes); + m_s1ap->handle_s1ap_rx_pdu(pdu.get(), &sri); } } } // Handle S11 if (FD_ISSET(s11, &m_set)) { pdu->N_bytes = recvfrom(s11, pdu->msg, sz, 0, NULL, NULL); - m_mme_gtpc->handle_s11_pdu(pdu); + m_mme_gtpc->handle_s11_pdu(pdu.get()); } // Handle NAS Timers for (std::vector::iterator it = timers.begin(); it != timers.end();) { if (FD_ISSET(it->fd, &m_set)) { - m_s1ap_log->info("Timer expired\n"); + m_s1ap_logger.info("Timer expired"); uint64_t exp; rd_sz = read(it->fd, &exp, sizeof(uint64_t)); m_s1ap->expire_nas_timer(it->type, it->imsi); @@ -187,7 +178,7 @@ void mme::run_thread() } } } else { - m_s1ap_log->debug("No data from select.\n"); + m_s1ap_logger.debug("No data from select."); } } return; @@ -198,7 +189,7 @@ void mme::run_thread() */ bool mme::add_nas_timer(int timer_fd, nas_timer_type type, uint64_t imsi) { - m_s1ap_log->debug("Adding NAS timer to MME. IMSI %" PRIu64 ", Type %d, Fd: %d\n", imsi, type, timer_fd); + m_s1ap_logger.debug("Adding NAS timer to MME. IMSI %" PRIu64 ", Type %d, Fd: %d", imsi, type, timer_fd); mme_timer_t timer; timer.fd = timer_fd; @@ -229,12 +220,12 @@ bool mme::remove_nas_timer(nas_timer_type type, uint64_t imsi) } } if (it == timers.end()) { - m_s1ap_log->warning("Could not find timer to remove. IMSI %" PRIu64 ", Type %d\n", imsi, type); + m_s1ap_logger.warning("Could not find timer to remove. IMSI %" PRIu64 ", Type %d", imsi, type); return false; } // removing timer - m_s1ap_log->debug("Removing NAS timer from MME. IMSI %" PRIu64 ", Type %d, Fd: %d\n", imsi, type, it->fd); + m_s1ap_logger.debug("Removing NAS timer from MME. IMSI %" PRIu64 ", Type %d, Fd: %d", imsi, type, it->fd); FD_CLR(it->fd, &m_set); close(it->fd); timers.erase(it); diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 8dd44639e..938e9cf0d 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -33,21 +33,18 @@ mme_gtpc* mme_gtpc::get_instance() return instance.get(); } -bool mme_gtpc::init(srslte::log_filter* mme_gtpc_log) +bool mme_gtpc::init() { - /*Init log*/ - m_mme_gtpc_log = mme_gtpc_log; - m_next_ctrl_teid = 1; m_s1ap = s1ap::get_instance(); if (!init_s11()) { - m_mme_gtpc_log->error("Error Initializing MME S11 Interface\n"); + m_logger.error("Error Initializing MME S11 Interface"); return false; } - m_mme_gtpc_log->info("MME GTP-C Initialized\n"); + m_logger.info("MME GTP-C Initialized"); srslte::console("MME GTP-C Initialized\n"); return true; } @@ -60,12 +57,12 @@ bool mme_gtpc::init_s11() char spgw_addr_name[] = "@spgw_s11"; // Logs - m_mme_gtpc_log->info("Initializing MME S11 interface.\n"); + m_logger.info("Initializing MME S11 interface."); // Open Socket m_s11 = socket(AF_UNIX, SOCK_DGRAM, 0); if (m_s11 < 0) { - m_mme_gtpc_log->error("Error opening UNIX socket. Error %s\n", strerror(errno)); + m_logger.error("Error opening UNIX socket. Error %s", strerror(errno)); return false; } @@ -77,7 +74,7 @@ bool mme_gtpc::init_s11() // Bind socket to address if (bind(m_s11, (const struct sockaddr*)&m_mme_addr, sizeof(m_mme_addr)) == -1) { - m_mme_gtpc_log->error("Error binding UNIX socket. Error %s\n", strerror(errno)); + m_logger.error("Error binding UNIX socket. Error %s", strerror(errno)); return false; } @@ -87,7 +84,7 @@ bool mme_gtpc::init_s11() snprintf(m_spgw_addr.sun_path, sizeof(m_spgw_addr.sun_path), "%s", spgw_addr_name); m_spgw_addr.sun_path[0] = '\0'; - m_mme_gtpc_log->info("MME S11 Initialized\n"); + m_logger.info("MME S11 Initialized"); srslte::console("MME S11 Initialized\n"); return true; } @@ -95,28 +92,28 @@ bool mme_gtpc::init_s11() bool mme_gtpc::send_s11_pdu(const srslte::gtpc_pdu& pdu) { int n; - m_mme_gtpc_log->debug("Sending S-11 GTP-C PDU\n"); + m_logger.debug("Sending S-11 GTP-C PDU"); // TODO Add GTP-C serialization code // Send S11 message to SPGW n = sendto(m_s11, &pdu, sizeof(pdu), 0, (const sockaddr*)&m_spgw_addr, sizeof(m_spgw_addr)); if (n < 0) { - m_mme_gtpc_log->error("Error sending to socket. Error %s\n", strerror(errno)); + m_logger.error("Error sending to socket. Error %s", strerror(errno)); srslte::console("Error sending to socket. Error %s\n", strerror(errno)); return false; } else { - m_mme_gtpc_log->debug("MME S11 Sent %d Bytes.\n", n); + m_logger.debug("MME S11 Sent %d Bytes.", n); } return true; } void mme_gtpc::handle_s11_pdu(srslte::byte_buffer_t* msg) { - m_mme_gtpc_log->debug("Received S11 message\n"); + m_logger.debug("Received S11 message"); srslte::gtpc_pdu* pdu; pdu = (srslte::gtpc_pdu*)msg->msg; - m_mme_gtpc_log->debug("MME Received GTP-C PDU. Message type %s\n", srslte::gtpc_msg_type_to_str(pdu->header.type)); + m_logger.debug("MME Received GTP-C PDU. Message type %s", srslte::gtpc_msg_type_to_str(pdu->header.type)); switch (pdu->header.type) { case srslte::GTPC_MSG_TYPE_CREATE_SESSION_RESPONSE: handle_create_session_response(pdu); @@ -128,14 +125,14 @@ void mme_gtpc::handle_s11_pdu(srslte::byte_buffer_t* msg) handle_downlink_data_notification(pdu); break; default: - m_mme_gtpc_log->error("Unhandled GTP-C Message type\n"); + m_logger.error("Unhandled GTP-C Message type"); } return; } bool mme_gtpc::send_create_session_request(uint64_t imsi) { - m_mme_gtpc_log->info("Sending Create Session Request.\n"); + m_logger.info("Sending Create Session Request."); srslte::console("Sending Create Session Request.\n"); struct srslte::gtpc_pdu cs_req_pdu; // Initialize GTP-C message to zero @@ -154,8 +151,8 @@ bool mme_gtpc::send_create_session_request(uint64_t imsi) // Control TEID allocated cs_req->sender_f_teid.teid = get_new_ctrl_teid(); - m_mme_gtpc_log->info("Next MME control TEID: %d\n", m_next_ctrl_teid); - m_mme_gtpc_log->info("Allocated MME control TEID: %d\n", cs_req->sender_f_teid.teid); + m_logger.info("Next MME control TEID: %d", m_next_ctrl_teid); + m_logger.info("Allocated MME control TEID: %d", cs_req->sender_f_teid.teid); srslte::console("Creating Session Response -- IMSI: %" PRIu64 "\n", imsi); srslte::console("Creating Session Response -- MME control TEID: %d\n", cs_req->sender_f_teid.teid); @@ -172,12 +169,11 @@ bool mme_gtpc::send_create_session_request(uint64_t imsi) // Check whether this UE is already registed std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); if (it != m_imsi_to_gtpc_ctx.end()) { - m_mme_gtpc_log->warning("Create Session Request being called for an UE with an active GTP-C connection.\n"); - m_mme_gtpc_log->warning("Deleting previous GTP-C connection.\n"); + m_logger.warning("Create Session Request being called for an UE with an active GTP-C connection."); + m_logger.warning("Deleting previous GTP-C connection."); std::map::iterator jt = m_mme_ctr_teid_to_imsi.find(it->second.mme_ctr_fteid.teid); if (jt == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->error("Could not find IMSI from MME Ctrl TEID. MME Ctr TEID: %d\n", - it->second.mme_ctr_fteid.teid); + m_logger.error("Could not find IMSI from MME Ctrl TEID. MME Ctr TEID: %d", it->second.mme_ctr_fteid.teid); } else { m_mme_ctr_teid_to_imsi.erase(jt); } @@ -203,15 +199,15 @@ bool mme_gtpc::send_create_session_request(uint64_t imsi) bool mme_gtpc::handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu) { struct srslte::gtpc_create_session_response* cs_resp = &cs_resp_pdu->choice.create_session_response; - m_mme_gtpc_log->info("Received Create Session Response\n"); + m_logger.info("Received Create Session Response"); srslte::console("Received Create Session Response\n"); if (cs_resp_pdu->header.type != srslte::GTPC_MSG_TYPE_CREATE_SESSION_RESPONSE) { - m_mme_gtpc_log->warning("Could not create GTPC session. Not a create session response\n"); + m_logger.warning("Could not create GTPC session. Not a create session response"); // TODO Handle error return false; } if (cs_resp->cause.cause_value != srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED) { - m_mme_gtpc_log->warning("Could not create GTPC session. Create Session Request not accepted\n"); + m_logger.warning("Could not create GTPC session. Create Session Request not accepted"); // TODO Handle error return false; } @@ -219,12 +215,12 @@ bool mme_gtpc::handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu) // Get IMSI from the control TEID std::map::iterator id_it = m_mme_ctr_teid_to_imsi.find(cs_resp_pdu->header.teid); if (id_it == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->warning("Could not find IMSI from Ctrl TEID.\n"); + m_logger.warning("Could not find IMSI from Ctrl TEID."); return false; } uint64_t imsi = id_it->second; - m_mme_gtpc_log->info("MME GTPC Ctrl TEID %" PRIu64 ", IMSI %" PRIu64 "\n", cs_resp_pdu->header.teid, imsi); + m_logger.info("MME GTPC Ctrl TEID %" PRIu64 ", IMSI %" PRIu64 "", cs_resp_pdu->header.teid, imsi); // Get S-GW Control F-TEID srslte::gtp_fteid_t sgw_ctr_fteid = {}; @@ -233,30 +229,30 @@ bool mme_gtpc::handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu) // Get S-GW S1-u F-TEID if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false) { - m_mme_gtpc_log->error("Did not receive SGW S1-U F-TEID in create session response\n"); + m_logger.error("Did not receive SGW S1-U F-TEID in create session response"); return false; } srslte::console("Create Session Response -- SPGW control TEID %d\n", sgw_ctr_fteid.teid); - m_mme_gtpc_log->info("Create Session Response -- SPGW control TEID %d\n", sgw_ctr_fteid.teid); + m_logger.info("Create Session Response -- SPGW control TEID %d", sgw_ctr_fteid.teid); in_addr s1u_addr; s1u_addr.s_addr = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4; srslte::console("Create Session Response -- SPGW S1-U Address: %s\n", inet_ntoa(s1u_addr)); - m_mme_gtpc_log->info("Create Session Response -- SPGW S1-U Address: %s\n", inet_ntoa(s1u_addr)); + m_logger.info("Create Session Response -- SPGW S1-U Address: %s", inet_ntoa(s1u_addr)); // Check UE Ipv4 address was allocated if (cs_resp->paa_present != true) { - m_mme_gtpc_log->error("PDN Adress Allocation not present\n"); + m_logger.error("PDN Adress Allocation not present"); return false; } if (cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) { - m_mme_gtpc_log->error("IPv6 not supported yet\n"); + m_logger.error("IPv6 not supported yet"); return false; } // Save create session response info to E-RAB context nas* nas_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL) { - m_mme_gtpc_log->error("Could not find UE context. IMSI %015" PRIu64 "\n", imsi); + m_logger.error("Could not find UE context. IMSI %015" PRIu64 "", imsi); return false; } emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; @@ -270,7 +266,7 @@ bool mme_gtpc::handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu) std::map::iterator it_g = m_imsi_to_gtpc_ctx.find(imsi); if (it_g == m_imsi_to_gtpc_ctx.end()) { // Could not find GTP-C Context - m_mme_gtpc_log->error("Could not find GTP-C context\n"); + m_logger.error("Could not find GTP-C context"); return false; } gtpc_ctx_t* gtpc_ctx = &it_g->second; @@ -288,13 +284,13 @@ bool mme_gtpc::handle_create_session_response(srslte::gtpc_pdu* cs_resp_pdu) bool mme_gtpc::send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t* enb_fteid) { - m_mme_gtpc_log->info("Sending GTP-C Modify bearer request\n"); + m_logger.info("Sending GTP-C Modify bearer request"); srslte::gtpc_pdu mb_req_pdu; std::memset(&mb_req_pdu, 0, sizeof(mb_req_pdu)); std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); if (it == m_imsi_to_gtpc_ctx.end()) { - m_mme_gtpc_log->error("Modify bearer request for UE without GTP-C connection\n"); + m_logger.error("Modify bearer request for UE without GTP-C connection"); return false; } srslte::gtp_fteid_t sgw_ctr_fteid = it->second.sgw_ctr_fteid; @@ -309,10 +305,10 @@ bool mme_gtpc::send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.ipv4 = enb_fteid->ipv4; mb_req->eps_bearer_context_to_modify.s1_u_enb_f_teid.teid = enb_fteid->teid; - m_mme_gtpc_log->info("GTP-C Modify bearer request -- S-GW Control TEID %d\n", sgw_ctr_fteid.teid); + m_logger.info("GTP-C Modify bearer request -- S-GW Control TEID %d", sgw_ctr_fteid.teid); struct in_addr addr; addr.s_addr = enb_fteid->ipv4; - m_mme_gtpc_log->info("GTP-C Modify bearer request -- S1-U TEID 0x%x, IP %s\n", enb_fteid->teid, inet_ntoa(addr)); + m_logger.info("GTP-C Modify bearer request -- S1-U TEID 0x%x, IP %s", enb_fteid->teid, inet_ntoa(addr)); // Send msg to SPGW send_s11_pdu(mb_req_pdu); @@ -324,12 +320,12 @@ void mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu* mb_resp_pdu) uint32_t mme_ctrl_teid = mb_resp_pdu->header.teid; std::map::iterator imsi_it = m_mme_ctr_teid_to_imsi.find(mme_ctrl_teid); if (imsi_it == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->error("Could not find IMSI from control TEID\n"); + m_logger.error("Could not find IMSI from control TEID"); return; } uint8_t ebi = mb_resp_pdu->choice.modify_bearer_response.eps_bearer_context_modified.ebi; - m_mme_gtpc_log->debug("Activating EPS bearer with id %d\n", ebi); + m_logger.debug("Activating EPS bearer with id %d", ebi); m_s1ap->activate_eps_bearer(imsi_it->second, ebi); return; @@ -337,7 +333,7 @@ void mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu* mb_resp_pdu) bool mme_gtpc::send_delete_session_request(uint64_t imsi) { - m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request. IMSI %" PRIu64 "\n", imsi); + m_logger.info("Sending GTP-C Delete Session Request request. IMSI %" PRIu64 "", imsi); srslte::gtpc_pdu del_req_pdu; std::memset(&del_req_pdu, 0, sizeof(del_req_pdu)); srslte::gtp_fteid_t sgw_ctr_fteid; @@ -346,7 +342,7 @@ bool mme_gtpc::send_delete_session_request(uint64_t imsi) // Get S-GW Ctr TEID std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); if (it_ctx == m_imsi_to_gtpc_ctx.end()) { - m_mme_gtpc_log->error("Could not find GTP-C context to remove\n"); + m_logger.error("Could not find GTP-C context to remove"); return false; } @@ -359,7 +355,7 @@ bool mme_gtpc::send_delete_session_request(uint64_t imsi) srslte::gtpc_delete_session_request* del_req = &del_req_pdu.choice.delete_session_request; del_req->cause.cause_value = srslte::GTPC_CAUSE_VALUE_ISR_DEACTIVATION; - m_mme_gtpc_log->info("GTP-C Delete Session Request -- S-GW Control TEID %d\n", sgw_ctr_fteid.teid); + m_logger.info("GTP-C Delete Session Request -- S-GW Control TEID %d", sgw_ctr_fteid.teid); // Send msg to SPGW send_s11_pdu(del_req_pdu); @@ -367,7 +363,7 @@ bool mme_gtpc::send_delete_session_request(uint64_t imsi) // Delete GTP-C context std::map::iterator it_imsi = m_mme_ctr_teid_to_imsi.find(mme_ctr_fteid.teid); if (it_imsi == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->error("Could not find IMSI from MME ctr TEID"); + m_logger.error("Could not find IMSI from MME ctr TEID"); } else { m_mme_ctr_teid_to_imsi.erase(it_imsi); } @@ -378,7 +374,7 @@ bool mme_gtpc::send_delete_session_request(uint64_t imsi) void mme_gtpc::send_release_access_bearers_request(uint64_t imsi) { // The GTP-C connection will not be torn down, just the user plane bearers. - m_mme_gtpc_log->info("Sending GTP-C Release Access Bearers Request\n"); + m_logger.info("Sending GTP-C Release Access Bearers Request"); srslte::gtpc_pdu rel_req_pdu; std::memset(&rel_req_pdu, 0, sizeof(rel_req_pdu)); srslte::gtp_fteid_t sgw_ctr_fteid; @@ -386,7 +382,7 @@ void mme_gtpc::send_release_access_bearers_request(uint64_t imsi) // Get S-GW Ctr TEID std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); if (it_ctx == m_imsi_to_gtpc_ctx.end()) { - m_mme_gtpc_log->error("Could not find GTP-C context to remove\n"); + m_logger.error("Could not find GTP-C context to remove"); return; } sgw_ctr_fteid = it_ctx->second.sgw_ctr_fteid; @@ -398,7 +394,7 @@ void mme_gtpc::send_release_access_bearers_request(uint64_t imsi) header->type = srslte::GTPC_MSG_TYPE_RELEASE_ACCESS_BEARERS_REQUEST; srslte::gtpc_release_access_bearers_request* rel_req = &rel_req_pdu.choice.release_access_bearers_request; - m_mme_gtpc_log->info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d\n", sgw_ctr_fteid.teid); + m_logger.info("GTP-C Release Access Berarers Request -- S-GW Control TEID %d", sgw_ctr_fteid.teid); // Send msg to SPGW send_s11_pdu(rel_req_pdu); @@ -412,16 +408,16 @@ bool mme_gtpc::handle_downlink_data_notification(srslte::gtpc_pdu* dl_not_pdu) srslte::gtpc_downlink_data_notification* dl_not = &dl_not_pdu->choice.downlink_data_notification; std::map::iterator imsi_it = m_mme_ctr_teid_to_imsi.find(mme_ctrl_teid); if (imsi_it == m_mme_ctr_teid_to_imsi.end()) { - m_mme_gtpc_log->error("Could not find IMSI from control TEID\n"); + m_logger.error("Could not find IMSI from control TEID"); return false; } if (!dl_not->eps_bearer_id_present) { - m_mme_gtpc_log->error("No EPS bearer Id in downlink data notification\n"); + m_logger.error("No EPS bearer Id in downlink data notification"); return false; } uint8_t ebi = dl_not->eps_bearer_id; - m_mme_gtpc_log->debug("Downlink Data Notification -- IMSI: %015" PRIu64 ", EBI %d\n", imsi_it->second, ebi); + m_logger.debug("Downlink Data Notification -- IMSI: %015" PRIu64 ", EBI %d", imsi_it->second, ebi); m_s1ap->send_paging(imsi_it->second, ebi); return true; @@ -429,7 +425,7 @@ bool mme_gtpc::handle_downlink_data_notification(srslte::gtpc_pdu* dl_not_pdu) void mme_gtpc::send_downlink_data_notification_acknowledge(uint64_t imsi, enum srslte::gtpc_cause_value cause) { - m_mme_gtpc_log->debug("Sending GTP-C Data Notification Acknowledge. Cause %d\n", cause); + m_logger.debug("Sending GTP-C Data Notification Acknowledge. Cause %d", cause); srslte::gtpc_pdu not_ack_pdu; srslte::gtp_fteid_t sgw_ctr_fteid; std::memset(¬_ack_pdu, 0, sizeof(not_ack_pdu)); @@ -437,7 +433,7 @@ void mme_gtpc::send_downlink_data_notification_acknowledge(uint64_t imsi, enum s // get s-gw ctr teid std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); if (it_ctx == m_imsi_to_gtpc_ctx.end()) { - m_mme_gtpc_log->error("could not find gtp-c context to remove\n"); + m_logger.error("could not find gtp-c context to remove"); return; } sgw_ctr_fteid = it_ctx->second.sgw_ctr_fteid; @@ -450,7 +446,7 @@ void mme_gtpc::send_downlink_data_notification_acknowledge(uint64_t imsi, enum s srslte::gtpc_downlink_data_notification_acknowledge* not_ack = ¬_ack_pdu.choice.downlink_data_notification_acknowledge; - m_mme_gtpc_log->info("gtp-c downlink data notification acknowledge -- s-gw control teid %d\n", sgw_ctr_fteid.teid); + m_logger.info("gtp-c downlink data notification acknowledge -- s-gw control teid %d", sgw_ctr_fteid.teid); // send msg to spgw send_s11_pdu(not_ack_pdu); @@ -459,7 +455,7 @@ void mme_gtpc::send_downlink_data_notification_acknowledge(uint64_t imsi, enum s bool mme_gtpc::send_downlink_data_notification_failure_indication(uint64_t imsi, enum srslte::gtpc_cause_value cause) { - m_mme_gtpc_log->debug("Sending GTP-C Data Notification Failure Indication. Cause %d\n", cause); + m_logger.debug("Sending GTP-C Data Notification Failure Indication. Cause %d", cause); srslte::gtpc_pdu not_fail_pdu; srslte::gtp_fteid_t sgw_ctr_fteid; std::memset(¬_fail_pdu, 0, sizeof(not_fail_pdu)); @@ -467,7 +463,7 @@ bool mme_gtpc::send_downlink_data_notification_failure_indication(uint64_t imsi, // get s-gw ctr teid std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); if (it_ctx == m_imsi_to_gtpc_ctx.end()) { - m_mme_gtpc_log->error("could not find gtp-c context to send paging failure\n"); + m_logger.error("could not find gtp-c context to send paging failure"); return false; } sgw_ctr_fteid = it_ctx->second.sgw_ctr_fteid; @@ -481,7 +477,7 @@ bool mme_gtpc::send_downlink_data_notification_failure_indication(uint64_t imsi, srslte::gtpc_downlink_data_notification_failure_indication* not_fail = ¬_fail_pdu.choice.downlink_data_notification_failure_indication; not_fail->cause.cause_value = cause; - m_mme_gtpc_log->info("Downlink Data Notification Failure Indication -- SP-GW control teid %d\n", sgw_ctr_fteid.teid); + m_logger.info("Downlink Data Notification Failure Indication -- SP-GW control teid %d", sgw_ctr_fteid.teid); // send msg to spgw send_s11_pdu(not_fail_pdu); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index b8175476e..128c7dd61 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -31,9 +31,7 @@ namespace srsepc { -nas::nas(const nas_init_t& args, const nas_if_t& itf, srslte::log* nas_log) : - m_pool(srslte::byte_buffer_pool::get_instance()), - m_nas_log(nas_log), +nas::nas(const nas_init_t& args, const nas_if_t& itf) : m_gtpc(itf.gtpc), m_s1ap(itf.s1ap), m_hss(itf.hss), @@ -49,7 +47,7 @@ nas::nas(const nas_init_t& args, const nas_if_t& itf, srslte::log* nas_log) : { m_sec_ctx.integ_algo = args.integ_algo; m_sec_ctx.cipher_algo = args.cipher_algo; - m_nas_log->debug("NAS Context Initialized. MCC: 0x%x, MNC 0x%x\n", m_mcc, m_mnc); + m_logger.debug("NAS Context Initialized. MCC: 0x%x, MNC 0x%x", m_mcc, m_mnc); } void nas::reset() @@ -76,13 +74,13 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { uint32_t m_tmsi = 0; uint64_t imsi = 0; LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req = {}; LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req = {}; + auto& nas_logger = srslog::fetch_basic_logger("NAS"); // Interfaces s1ap_interface_nas* s1ap = itf.s1ap; @@ -92,13 +90,13 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, // Get NAS Attach Request and PDN connectivity request messages LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &attach_req); if (err != LIBLTE_SUCCESS) { - nas_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); + nas_logger.error("Error unpacking NAS attach request. Error: %s", liblte_error_text[err]); return false; } // Get PDN Connectivity Request*/ err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req); if (err != LIBLTE_SUCCESS) { - nas_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); + nas_logger.error("Error unpacking NAS PDN Connectivity Request. Error: %s", liblte_error_text[err]); return false; } @@ -108,22 +106,22 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, imsi += attach_req.eps_mobile_id.imsi[i] * std::pow(10, 14 - i); } srslte::console("Attach request -- IMSI: %015" PRIu64 "\n", imsi); - nas_log->info("Attach request -- IMSI: %015" PRIu64 "\n", imsi); + nas_logger.info("Attach request -- IMSI: %015" PRIu64 "", imsi); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); srslte::console("Attach request -- M-TMSI: 0x%x\n", m_tmsi); - nas_log->info("Attach request -- M-TMSI: 0x%x\n", m_tmsi); + nas_logger.info("Attach request -- M-TMSI: 0x%x", m_tmsi); } else { - nas_log->error("Unhandled Mobile Id type in attach request\n"); + nas_logger.error("Unhandled Mobile Id type in attach request"); return false; } // Log Attach Request Information srslte::console("Attach request -- eNB-UE S1AP Id: %d\n", enb_ue_s1ap_id); - nas_log->info("Attach request -- eNB-UE S1AP Id: %d\n", enb_ue_s1ap_id); + nas_logger.info("Attach request -- eNB-UE S1AP Id: %d", enb_ue_s1ap_id); srslte::console("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); - nas_log->info("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); + nas_logger.info("Attach request -- Attach type: %d", attach_req.eps_attach_type); srslte::console("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", attach_req.ue_network_cap.eea[0], attach_req.ue_network_cap.eea[1], @@ -133,15 +131,15 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, attach_req.ue_network_cap.eea[5], attach_req.ue_network_cap.eea[6], attach_req.ue_network_cap.eea[7]); - nas_log->info("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d\n", - attach_req.ue_network_cap.eea[0], - attach_req.ue_network_cap.eea[1], - attach_req.ue_network_cap.eea[2], - attach_req.ue_network_cap.eea[3], - attach_req.ue_network_cap.eea[4], - attach_req.ue_network_cap.eea[5], - attach_req.ue_network_cap.eea[6], - attach_req.ue_network_cap.eea[7]); + nas_logger.info("Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d", + attach_req.ue_network_cap.eea[0], + attach_req.ue_network_cap.eea[1], + attach_req.ue_network_cap.eea[2], + attach_req.ue_network_cap.eea[3], + attach_req.ue_network_cap.eea[4], + attach_req.ue_network_cap.eea[5], + attach_req.ue_network_cap.eea[6], + attach_req.ue_network_cap.eea[7]); srslte::console("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n", attach_req.ue_network_cap.eia[0], attach_req.ue_network_cap.eia[1], @@ -151,48 +149,48 @@ bool nas::handle_attach_request(uint32_t enb_ue_s1ap_id, attach_req.ue_network_cap.eia[5], attach_req.ue_network_cap.eia[6], attach_req.ue_network_cap.eia[7]); - nas_log->info("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d\n", - attach_req.ue_network_cap.eia[0], - attach_req.ue_network_cap.eia[1], - attach_req.ue_network_cap.eia[2], - attach_req.ue_network_cap.eia[3], - attach_req.ue_network_cap.eia[4], - attach_req.ue_network_cap.eia[5], - attach_req.ue_network_cap.eia[6], - attach_req.ue_network_cap.eia[7]); + nas_logger.info("Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d", + attach_req.ue_network_cap.eia[0], + attach_req.ue_network_cap.eia[1], + attach_req.ue_network_cap.eia[2], + attach_req.ue_network_cap.eia[3], + attach_req.ue_network_cap.eia[4], + attach_req.ue_network_cap.eia[5], + attach_req.ue_network_cap.eia[6], + attach_req.ue_network_cap.eia[7]); srslte::console("Attach Request -- MS Network Capabilities Present: %s\n", attach_req.ms_network_cap_present ? "true" : "false"); - nas_log->info("Attach Request -- MS Network Capabilities Present: %s\n", - attach_req.ms_network_cap_present ? "true" : "false"); + nas_logger.info("Attach Request -- MS Network Capabilities Present: %s", + attach_req.ms_network_cap_present ? "true" : "false"); srslte::console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); - nas_log->info("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); + nas_logger.info("PDN Connectivity Request -- EPS Bearer Identity requested: %d", pdn_con_req.eps_bearer_id); srslte::console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); - nas_log->info("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); + nas_logger.info("PDN Connectivity Request -- Procedure Transaction Id: %d", pdn_con_req.proc_transaction_id); srslte::console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); - nas_log->info("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", - pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); + nas_logger.info("PDN Connectivity Request -- ESM Information Transfer requested: %s", + pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); // Get NAS Context if UE is known nas* nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL) { // Get attach type from attach request if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { - nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf, nas_log); + nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { - nas::handle_guti_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf, nas_log); + nas::handle_guti_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf); } else { return false; } } else { - nas_log->info("Attach Request -- Found previously attached UE.\n"); + nas_logger.info("Attach Request -- Found previously attached UE."); srslte::console("Attach Request -- Found previously attach UE.\n"); if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { nas::handle_imsi_attach_request_known_ue( - nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx, args, itf, nas_log); + nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx, args, itf); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { nas::handle_guti_attach_request_known_ue( - nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx, args, itf, nas_log); + nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx, args, itf); } else { return false; } @@ -205,12 +203,11 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - nas* nas_ctx; - srslte::byte_buffer_t* nas_tx; - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + nas* nas_ctx; + srslte::unique_byte_buffer_t nas_tx; + auto& nas_logger = srslog::fetch_basic_logger("NAS"); // Interfaces s1ap_interface_nas* s1ap = itf.s1ap; @@ -224,7 +221,7 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t } // Create UE context - nas_ctx = new nas(args, itf, nas_log); + nas_ctx = new nas(args, itf); // Save IMSI, eNB UE S1AP Id, MME UE S1AP Id and make sure UE is EMM_DEREGISTERED nas_ctx->m_emm_ctx.imsi = imsi; @@ -271,8 +268,7 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t nas_ctx->m_sec_ctx.rand, nas_ctx->m_sec_ctx.xres)) { srslte::console("User not found. IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi); - nas_log->info("User not found. IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi); - delete nas_ctx; + nas_logger.info("User not found. IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); return false; } @@ -286,15 +282,14 @@ bool nas::handle_imsi_attach_request_unknown_ue(uint32_t s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); // Pack NAS Authentication Request in Downlink NAS Transport msg - nas_tx = pool->allocate(); - nas_ctx->pack_authentication_request(nas_tx); + nas_tx = srslte::make_byte_buffer(); + nas_ctx->pack_authentication_request(nas_tx.get()); // Send reply to eNB s1ap->send_downlink_nas_transport( - nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri); - pool->deallocate(nas_tx); + nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), nas_ctx->m_ecm_ctx.enb_sri); - nas_log->info("Downlink NAS: Sending Authentication Request\n"); + nas_logger.info("Downlink NAS: Sending Authentication Request"); srslte::console("Downlink NAS: Sending Authentication Request\n"); return true; } @@ -306,10 +301,10 @@ bool nas::handle_imsi_attach_request_known_ue(nas* const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - bool err; + bool err; + auto& nas_logger = srslog::fetch_basic_logger("NAS"); // Interfaces s1ap_interface_nas* s1ap = itf.s1ap; @@ -327,8 +322,7 @@ bool nas::handle_imsi_attach_request_known_ue(nas* s1ap->delete_ue_ctx(nas_ctx->m_emm_ctx.imsi); // Handle new attach - err = - nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf, nas_log); + err = nas::handle_imsi_attach_request_unknown_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, args, itf); return err; } @@ -337,13 +331,11 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT& attach_req, const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - nas* nas_ctx; - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - srslte::byte_buffer_t* nas_tx; + nas* nas_ctx; + srslte::unique_byte_buffer_t nas_tx; // Interfaces s1ap_interface_nas* s1ap = itf.s1ap; @@ -351,7 +343,7 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t gtpc_interface_nas* gtpc = itf.gtpc; // Create new NAS context. - nas_ctx = new nas(args, itf, nas_log); + nas_ctx = new nas(args, itf); // Could not find IMSI from M-TMSI, send Id request // The IMSI will be set when the identity response is received @@ -399,11 +391,10 @@ bool nas::handle_guti_attach_request_unknown_ue(uint32_t s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); // Send Identity Request - nas_tx = pool->allocate(); - nas_ctx->pack_identity_request(nas_tx); + nas_tx = srslte::make_byte_buffer(); + nas_ctx->pack_identity_request(nas_tx.get()); s1ap->send_downlink_nas_transport( - nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx, nas_ctx->m_ecm_ctx.enb_sri); - pool->deallocate(nas_tx); + nas_ctx->m_ecm_ctx.enb_ue_s1ap_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), nas_ctx->m_ecm_ctx.enb_sri); return true; } @@ -415,12 +406,11 @@ bool nas::handle_guti_attach_request_known_ue(nas* const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT& pdn_con_req, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - bool msg_valid = false; - srslte::byte_buffer_t* nas_tx; - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + bool msg_valid = false; + srslte::unique_byte_buffer_t nas_tx; + auto& nas_logger = srslog::fetch_basic_logger("NAS"); emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; ecm_ctx_t* ecm_ctx = &nas_ctx->m_ecm_ctx; @@ -441,8 +431,8 @@ bool nas::handle_guti_attach_request_known_ue(nas* if (msg_valid == true && emm_ctx->state == EMM_STATE_DEREGISTERED) { srslte::console( "GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d\n", sec_ctx->ul_nas_count, sec_ctx->dl_nas_count); - nas_log->info( - "GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d\n", sec_ctx->ul_nas_count, sec_ctx->dl_nas_count); + nas_logger.info( + "GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d", sec_ctx->ul_nas_count, sec_ctx->dl_nas_count); // Create new MME UE S1AP Identity ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); @@ -472,31 +462,30 @@ bool nas::handle_guti_attach_request_known_ue(nas* // Re-generate K_eNB srslte::security_generate_k_enb(sec_ctx->k_asme, sec_ctx->ul_nas_count, sec_ctx->k_enb); - nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); + nas_logger.info("Generating KeNB with UL NAS COUNT: %d", sec_ctx->ul_nas_count); srslte::console("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); - nas_log->info_hex(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)\n"); + nas_logger.info(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)"); // Send reply - nas_tx = pool->allocate(); + nas_tx = srslte::make_byte_buffer(); if (ecm_ctx->eit) { srslte::console("Secure ESM information transfer requested.\n"); - nas_log->info("Secure ESM information transfer requested.\n"); - nas_ctx->pack_esm_information_request(nas_tx); - s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); + nas_logger.info("Secure ESM information transfer requested."); + nas_ctx->pack_esm_information_request(nas_tx.get()); + s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri); } else { // Get subscriber info from HSS uint8_t default_bearer = 5; hss->gen_update_loc_answer(emm_ctx->imsi, &nas_ctx->m_esm_ctx[default_bearer].qci); - nas_log->debug("Getting subscription information -- QCI %d\n", nas_ctx->m_esm_ctx[default_bearer].qci); + nas_logger.debug("Getting subscription information -- QCI %d", nas_ctx->m_esm_ctx[default_bearer].qci); srslte::console("Getting subscription information -- QCI %d\n", nas_ctx->m_esm_ctx[default_bearer].qci); gtpc->send_create_session_request(emm_ctx->imsi); } sec_ctx->ul_nas_count++; - pool->deallocate(nas_tx); return true; } else { if (emm_ctx->state != EMM_STATE_DEREGISTERED) { - nas_log->error("Received GUTI-Attach Request from attached user.\n"); + nas_logger.error("Received GUTI-Attach Request from attached user."); srslte::console("Received GUTI-Attach Request from attached user.\n"); // Delete previous Ctx, restart authentication @@ -545,19 +534,18 @@ bool nas::handle_guti_attach_request_known_ue(nas* // Get Authentication Vectors from HSS if (!hss->gen_auth_info_answer(emm_ctx->imsi, sec_ctx->k_asme, sec_ctx->autn, sec_ctx->rand, sec_ctx->xres)) { srslte::console("User not found. IMSI %015" PRIu64 "\n", emm_ctx->imsi); - nas_log->info("User not found. IMSI %015" PRIu64 "\n", emm_ctx->imsi); + nas_logger.info("User not found. IMSI %015" PRIu64 "", emm_ctx->imsi); return false; } // Restarting security context. Reseting eKSI to 0. sec_ctx->eksi = 0; - nas_tx = pool->allocate(); - nas_ctx->pack_authentication_request(nas_tx); + nas_tx = srslte::unique_byte_buffer_t(); + nas_ctx->pack_authentication_request(nas_tx.get()); // Send reply to eNB - s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); - pool->deallocate(nas_tx); - nas_log->info("Downlink NAS: Sent Authentication Request\n"); + s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri); + nas_logger.info("Downlink NAS: Sent Authentication Request"); srslte::console("Downlink NAS: Sent Authentication Request\n"); return true; } @@ -569,17 +557,17 @@ bool nas::handle_service_request(uint32_t m_tmsi, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - nas_log->info("Service request -- S-TMSI 0x%x\n", m_tmsi); + auto& nas_logger = srslog::fetch_basic_logger("NAS"); + + nas_logger.info("Service request -- S-TMSI 0x%x", m_tmsi); srslte::console("Service request -- S-TMSI 0x%x\n", m_tmsi); - nas_log->info("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + nas_logger.info("Service request -- eNB UE S1AP Id %d", enb_ue_s1ap_id); srslte::console("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); bool mac_valid = false; LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); // Interfaces s1ap_interface_nas* s1ap = itf.s1ap; @@ -589,37 +577,35 @@ bool nas::handle_service_request(uint32_t m_tmsi, LIBLTE_ERROR_ENUM err = liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &service_req); if (err != LIBLTE_SUCCESS) { - nas_log->error("Could not unpack service request\n"); + nas_logger.error("Could not unpack service request"); return false; } uint64_t imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); if (imsi == 0) { srslte::console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - nas_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - nas nas_tmp(args, itf, nas_log); + nas_logger.error("Could not find IMSI from M-TMSI. M-TMSI 0x%x", m_tmsi); + nas nas_tmp(args, itf); nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); - srslte::byte_buffer_t* nas_tx = pool->allocate(); - nas_tmp.pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); - s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); - pool->deallocate(nas_tx); + srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer(); + nas_tmp.pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); + s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri); return true; } nas* nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL || nas_ctx->m_emm_ctx.state != EMM_STATE_REGISTERED) { srslte::console("UE is not EMM-Registered.\n"); - nas_log->error("UE is not EMM-Registered.\n"); - nas nas_tmp(args, itf, nas_log); + nas_logger.error("UE is not EMM-Registered."); + nas nas_tmp(args, itf); nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); - srslte::byte_buffer_t* nas_tx = pool->allocate(); - nas_tmp.pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); - s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); - pool->deallocate(nas_tx); + srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer(); + nas_tmp.pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); + s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri); return true; } emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; @@ -629,14 +615,14 @@ bool nas::handle_service_request(uint32_t m_tmsi, mac_valid = nas_ctx->short_integrity_check(nas_rx); if (mac_valid) { srslte::console("Service Request -- Short MAC valid\n"); - nas_log->info("Service Request -- Short MAC valid\n"); + nas_logger.info("Service Request -- Short MAC valid"); if (ecm_ctx->state == ECM_STATE_CONNECTED) { - nas_log->error("Service Request -- User is ECM CONNECTED\n"); + nas_logger.error("Service Request -- User is ECM CONNECTED"); // Release previous context - nas_log->info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d\n", - ecm_ctx->enb_ue_s1ap_id, - ecm_ctx->mme_ue_s1ap_id); + nas_logger.info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d", + ecm_ctx->enb_ue_s1ap_id, + ecm_ctx->mme_ue_s1ap_id); s1ap->send_ue_context_release_command(ecm_ctx->mme_ue_s1ap_id); s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); } @@ -645,7 +631,7 @@ bool nas::handle_service_request(uint32_t m_tmsi, // UE not connect. Connect normally. srslte::console("Service Request -- User is ECM DISCONNECTED\n"); - nas_log->info("Service Request -- User is ECM DISCONNECTED\n"); + nas_logger.info("Service Request -- User is ECM DISCONNECTED"); // Create ECM context ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); @@ -659,16 +645,16 @@ bool nas::handle_service_request(uint32_t m_tmsi, // Get UE IP, and uplink F-TEID if (emm_ctx->ue_ip.s_addr == 0) { - nas_log->error("UE has no valid IP assigned upon reception of service request"); + nas_logger.error("UE has no valid IP assigned upon reception of service request"); } srslte::console("UE previously assigned IP: %s\n", inet_ntoa(emm_ctx->ue_ip)); // Re-generate K_eNB srslte::security_generate_k_enb(sec_ctx->k_asme, sec_ctx->ul_nas_count, sec_ctx->k_enb); - nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); + nas_logger.info("Generating KeNB with UL NAS COUNT: %d", sec_ctx->ul_nas_count); srslte::console("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); - nas_log->info_hex(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)\n"); + nas_logger.info(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)"); srslte::console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); // Stop T3413 if running @@ -682,14 +668,14 @@ bool nas::handle_service_request(uint32_t m_tmsi, sec_ctx->ul_nas_count++; } else { srslte::console("Service Request -- Short MAC invalid\n"); - nas_log->info("Service Request -- Short MAC invalid\n"); + nas_logger.info("Service Request -- Short MAC invalid"); if (ecm_ctx->state == ECM_STATE_CONNECTED) { - nas_log->error("Service Request -- User is ECM CONNECTED\n"); + nas_logger.error("Service Request -- User is ECM CONNECTED"); // Release previous context - nas_log->info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d\n", - ecm_ctx->enb_ue_s1ap_id, - ecm_ctx->mme_ue_s1ap_id); + nas_logger.info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d", + ecm_ctx->enb_ue_s1ap_id, + ecm_ctx->mme_ue_s1ap_id); s1ap->send_ue_context_release_command(ecm_ctx->mme_ue_s1ap_id); s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); } @@ -701,14 +687,13 @@ bool nas::handle_service_request(uint32_t m_tmsi, ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); - srslte::byte_buffer_t* nas_tx = pool->allocate(); - nas_ctx->pack_service_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); - s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); - pool->deallocate(nas_tx); + srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer(); + nas_ctx->pack_service_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK); + s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx.get(), *enb_sri); srslte::console("Service Request -- Short MAC invalid. Sending service reject.\n"); - nas_log->warning("Service Request -- Short MAC invalid. Sending service reject.\n"); - nas_log->info("Service Reject -- eNB_UE_S1AP_ID %d MME_UE_S1AP_ID %d.\n", enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); + nas_logger.warning("Service Request -- Short MAC invalid. Sending service reject."); + nas_logger.info("Service Reject -- eNB_UE_S1AP_ID %d MME_UE_S1AP_ID %d.", enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id); } return true; } @@ -718,12 +703,13 @@ bool nas::handle_detach_request(uint32_t m_tmsi, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - nas_log->info("Detach Request -- S-TMSI 0x%x\n", m_tmsi); + auto& nas_logger = srslog::fetch_basic_logger("NAS"); + + nas_logger.info("Detach Request -- S-TMSI 0x%x", m_tmsi); srslte::console("Detach Request -- S-TMSI 0x%x\n", m_tmsi); - nas_log->info("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + nas_logger.info("Detach Request -- eNB UE S1AP Id %d", enb_ue_s1ap_id); srslte::console("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); bool mac_valid = false; @@ -736,21 +722,21 @@ bool nas::handle_detach_request(uint32_t m_tmsi, LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &detach_req); if (err != LIBLTE_SUCCESS) { - nas_log->error("Could not unpack detach request\n"); + nas_logger.error("Could not unpack detach request"); return false; } uint64_t imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); if (imsi == 0) { srslte::console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - nas_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + nas_logger.error("Could not find IMSI from M-TMSI. M-TMSI 0x%x", m_tmsi); return true; } nas* nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL) { srslte::console("Could not find UE context from IMSI\n"); - nas_log->error("Could not find UE context from IMSI\n"); + nas_logger.error("Could not find UE context from IMSI"); return true; } @@ -781,18 +767,17 @@ bool nas::handle_tracking_area_update_request(uint32_t m_tmsi, struct sctp_sndrcvinfo* enb_sri, srslte::byte_buffer_t* nas_rx, const nas_init_t& args, - const nas_if_t& itf, - srslte::log* nas_log) + const nas_if_t& itf) { - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + auto& nas_logger = srslog::fetch_basic_logger("NAS"); - nas_log->info("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); + nas_logger.info("Tracking Area Update Request -- S-TMSI 0x%x", m_tmsi); srslte::console("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); - nas_log->info("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + nas_logger.info("Tracking Area Update Request -- eNB UE S1AP Id %d", enb_ue_s1ap_id); srslte::console("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); srslte::console("Warning: Tracking area update requests are not handled yet.\n"); - nas_log->warning("Tracking area update requests are not handled yet.\n"); + nas_logger.warning("Tracking area update requests are not handled yet."); // Interfaces s1ap_interface_nas* s1ap = itf.s1ap; @@ -802,14 +787,13 @@ bool nas::handle_tracking_area_update_request(uint32_t m_tmsi, // TODO don't search for NAS ctxt, just send that reject // with context we could enable integrity protection - nas nas_tmp(args, itf, nas_log); + nas nas_tmp(args, itf); nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); - srslte::byte_buffer_t* nas_tx = pool->allocate(); - nas_tmp.pack_tracking_area_update_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); - s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); - pool->deallocate(nas_tx); + srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer(); + nas_tmp.pack_tracking_area_update_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); + s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), *enb_sri); return true; } @@ -828,13 +812,13 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx) // Get NAS Attach Request and PDN connectivity request messages LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &attach_req); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS attach request. Error: %s", liblte_error_text[err]); return false; } // Get PDN Connectivity Request*/ err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS PDN Connectivity Request. Error: %s", liblte_error_text[err]); return false; } @@ -844,20 +828,20 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx) imsi += attach_req.eps_mobile_id.imsi[i] * std::pow(10, 14 - i); } srslte::console("Attach request -- IMSI: %015" PRIu64 "\n", imsi); - m_nas_log->info("Attach request -- IMSI: %015" PRIu64 "\n", imsi); + m_logger.info("Attach request -- IMSI: %015" PRIu64 "", imsi); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; imsi = m_s1ap->find_imsi_from_m_tmsi(m_tmsi); srslte::console("Attach request -- M-TMSI: 0x%x\n", m_tmsi); - m_nas_log->info("Attach request -- M-TMSI: 0x%x\n", m_tmsi); + m_logger.info("Attach request -- M-TMSI: 0x%x", m_tmsi); } else { - m_nas_log->error("Unhandled Mobile Id type in attach request\n"); + m_logger.error("Unhandled Mobile Id type in attach request"); return false; } // Is UE known? if (m_emm_ctx.imsi == 0) { - m_nas_log->info("Attach request from Unkonwn UE\n"); + m_logger.info("Attach request from Unkonwn UE"); // Get IMSI uint64_t imsi = 0; for (int i = 0; i <= 14; i++) { @@ -898,7 +882,7 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx) if (!m_hss->gen_auth_info_answer( m_emm_ctx.imsi, m_sec_ctx.k_asme, m_sec_ctx.autn, m_sec_ctx.rand, m_sec_ctx.xres)) { srslte::console("User not found. IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); - m_nas_log->info("User not found. IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); + m_logger.info("User not found. IMSI %015" PRIu64 "", m_emm_ctx.imsi); return false; } @@ -910,40 +894,40 @@ bool nas::handle_attach_request(srslte::byte_buffer_t* nas_rx) m_s1ap->add_nas_ctx_to_imsi_map(this); // Pack NAS Authentication Request in Downlink NAS Transport msg - srslte::byte_buffer_t* nas_tx = m_pool->allocate(); - pack_authentication_request(nas_tx); + srslte::unique_byte_buffer_t nas_tx = srslte::make_byte_buffer(); + pack_authentication_request(nas_tx.get()); // Send reply to eNB - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); - m_pool->deallocate(nas_tx); + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); - m_nas_log->info("Downlink NAS: Sending Authentication Request\n"); + m_logger.info("Downlink NAS: Sending Authentication Request"); srslte::console("Downlink NAS: Sending Authentication Request\n"); return true; } else { - m_nas_log->error("Attach request from known UE\n"); + m_logger.error("Attach request from known UE"); } return true; } bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx) { - srslte::byte_buffer_t* nas_tx; + srslte::unique_byte_buffer_t nas_tx; LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp; bool ue_valid = true; // Get NAS authentication response LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &auth_resp); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS authentication response. Error: %s", liblte_error_text[err]); return false; } // Log received authentication response srslte::console("Authentication Response -- IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); - m_nas_log->info("Authentication Response -- IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); - m_nas_log->info_hex(auth_resp.res, 8, "Authentication response -- RES"); - m_nas_log->info_hex(m_sec_ctx.xres, 8, "Authentication response -- XRES"); + m_logger.info("Authentication Response -- IMSI %015" PRIu64 "", m_emm_ctx.imsi); + m_logger.info(auth_resp.res, 8, "Authentication response -- RES"); + m_logger.info(m_sec_ctx.xres, 8, "Authentication response -- XRES"); // Check UE authentication for (int i = 0; i < 8; i++) { @@ -952,68 +936,68 @@ bool nas::handle_authentication_response(srslte::byte_buffer_t* nas_rx) } } - nas_tx = m_pool->allocate(); + nas_tx = srslte::make_byte_buffer(); if (!ue_valid) { // Authentication rejected srslte::console("UE Authentication Rejected.\n"); - m_nas_log->warning("UE Authentication Rejected.\n"); + m_logger.warning("UE Authentication Rejected."); // Send back Athentication Reject - pack_authentication_reject(nas_tx); - m_nas_log->info("Downlink NAS: Sending Authentication Reject.\n"); + pack_authentication_reject(nas_tx.get()); + m_logger.info("Downlink NAS: Sending Authentication Reject."); } else { // Authentication accepted srslte::console("UE Authentication Accepted.\n"); - m_nas_log->info("UE Authentication Accepted.\n"); + m_logger.info("UE Authentication Accepted."); // Send Security Mode Command m_sec_ctx.ul_nas_count = 0; // Reset the NAS uplink counter for the right key k_enb derivation - pack_security_mode_command(nas_tx); + pack_security_mode_command(nas_tx.get()); srslte::console("Downlink NAS: Sending NAS Security Mode Command.\n"); } // Send reply - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); - m_pool->deallocate(nas_tx); + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); return true; } bool nas::handle_security_mode_complete(srslte::byte_buffer_t* nas_rx) { - srslte::byte_buffer_t* nas_tx; + srslte::unique_byte_buffer_t nas_tx; LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp; // Get NAS security mode complete LIBLTE_ERROR_ENUM err = liblte_mme_unpack_security_mode_complete_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &sm_comp); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS authentication response. Error: %s", liblte_error_text[err]); return false; } // Log security mode complete - m_nas_log->info("Security Mode Command Complete -- IMSI: %015" PRIu64 "\n", m_emm_ctx.imsi); + m_logger.info("Security Mode Command Complete -- IMSI: %015" PRIu64 "", m_emm_ctx.imsi); srslte::console("Security Mode Command Complete -- IMSI: %015" PRIu64 "\n", m_emm_ctx.imsi); // Check wether secure ESM information transfer is required - nas_tx = m_pool->allocate(); + nas_tx = srslte::make_byte_buffer(); if (m_ecm_ctx.eit == true) { // Secure ESM information transfer is required srslte::console("Sending ESM information request\n"); - m_nas_log->info("Sending ESM information request\n"); + m_logger.info("Sending ESM information request"); // Packing ESM information request - pack_esm_information_request(nas_tx); - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); + pack_esm_information_request(nas_tx.get()); + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); } else { // Secure ESM information transfer not necessary // Sending create session request to SP-GW. uint8_t default_bearer = 5; m_hss->gen_update_loc_answer(m_emm_ctx.imsi, &m_esm_ctx[default_bearer].qci); - m_nas_log->debug("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); + m_logger.debug("Getting subscription information -- QCI %d", m_esm_ctx[default_bearer].qci); srslte::console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); m_gtpc->send_create_session_request(m_emm_ctx.imsi); } - m_pool->deallocate(nas_tx); return true; } @@ -1022,20 +1006,20 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx) LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp; uint8_t pd, msg_type; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer; - srslte::byte_buffer_t* nas_tx; + srslte::unique_byte_buffer_t nas_tx; // Get NAS authentication response std::memset(&attach_comp, 0, sizeof(attach_comp)); LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_complete_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &attach_comp); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS authentication response. Error: %s", liblte_error_text[err]); return false; } err = liblte_mme_unpack_activate_default_eps_bearer_context_accept_msg((LIBLTE_BYTE_MSG_STRUCT*)&attach_comp.esm_msg, &act_bearer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking Activate EPS Bearer Context Accept Msg. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking Activate EPS Bearer Context Accept Msg. Error: %s", liblte_error_text[err]); return false; } @@ -1043,7 +1027,7 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx) srslte::console("Unpacked Activate Default EPS Bearer message. EPS Bearer id %d\n", act_bearer.eps_bearer_id); if (act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 15) { - m_nas_log->error("EPS Bearer ID out of range\n"); + m_logger.error("EPS Bearer ID out of range"); return false; } if (m_emm_ctx.state == EMM_STATE_DEREGISTERED) { @@ -1052,14 +1036,14 @@ bool nas::handle_attach_complete(srslte::byte_buffer_t* nas_rx) m_emm_ctx.imsi, act_bearer.eps_bearer_id, &m_esm_ctx[act_bearer.eps_bearer_id].enb_fteid); // Send reply to EMM Info to UE - nas_tx = m_pool->allocate(); - pack_emm_information(nas_tx); + nas_tx = srslte::make_byte_buffer(); + pack_emm_information(nas_tx.get()); - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); - m_pool->deallocate(nas_tx); + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); srslte::console("Sending EMM Information\n"); - m_nas_log->info("Sending EMM Information\n"); + m_logger.info("Sending EMM Information"); } m_emm_ctx.state = EMM_STATE_REGISTERED; return true; @@ -1073,24 +1057,24 @@ bool nas::handle_esm_information_response(srslte::byte_buffer_t* nas_rx) LIBLTE_ERROR_ENUM err = srslte_mme_unpack_esm_information_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &esm_info_resp); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS authentication response. Error: %s", liblte_error_text[err]); return false; } - m_nas_log->info("ESM Info: EPS bearer id %d\n", esm_info_resp.eps_bearer_id); + m_logger.info("ESM Info: EPS bearer id %d", esm_info_resp.eps_bearer_id); if (esm_info_resp.apn_present) { - m_nas_log->info("ESM Info: APN %s\n", esm_info_resp.apn.apn); + m_logger.info("ESM Info: APN %s", esm_info_resp.apn.apn); srslte::console("ESM Info: APN %s\n", esm_info_resp.apn.apn); } if (esm_info_resp.protocol_cnfg_opts_present) { - m_nas_log->info("ESM Info: %d Protocol Configuration Options\n", esm_info_resp.protocol_cnfg_opts.N_opts); + m_logger.info("ESM Info: %d Protocol Configuration Options", esm_info_resp.protocol_cnfg_opts.N_opts); srslte::console("ESM Info: %d Protocol Configuration Options\n", esm_info_resp.protocol_cnfg_opts.N_opts); } // Get subscriber info from HSS uint8_t default_bearer = 5; m_hss->gen_update_loc_answer(m_emm_ctx.imsi, &m_esm_ctx[default_bearer].qci); - m_nas_log->debug("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); + m_logger.debug("Getting subscription information -- QCI %d", m_esm_ctx[default_bearer].qci); srslte::console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); // TODO The packging of GTP-C messages is not ready. @@ -1101,12 +1085,12 @@ bool nas::handle_esm_information_response(srslte::byte_buffer_t* nas_rx) bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) { - srslte::byte_buffer_t* nas_tx; + srslte::unique_byte_buffer_t nas_tx; LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp; LIBLTE_ERROR_ENUM err = liblte_mme_unpack_identity_response_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &id_resp); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS identity response. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS identity response. Error: %s", liblte_error_text[err]); return false; } @@ -1115,7 +1099,7 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) imsi += id_resp.mobile_id.imsi[i] * std::pow(10, 14 - i); } - m_nas_log->info("ID response -- IMSI: %015" PRIu64 "\n", imsi); + m_logger.info("ID response -- IMSI: %015" PRIu64 "", imsi); srslte::console("ID Response -- IMSI: %015" PRIu64 "\n", imsi); // Set UE's IMSI @@ -1124,7 +1108,7 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) // Get Authentication Vectors from HSS if (!m_hss->gen_auth_info_answer(imsi, m_sec_ctx.k_asme, m_sec_ctx.autn, m_sec_ctx.rand, m_sec_ctx.xres)) { srslte::console("User not found. IMSI %015" PRIu64 "\n", imsi); - m_nas_log->info("User not found. IMSI %015" PRIu64 "\n", imsi); + m_logger.info("User not found. IMSI %015" PRIu64 "", imsi); return false; } // Identity reponse from unknown GUTI atach. Assigning new eKSI. @@ -1133,7 +1117,7 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) // Make sure UE context was not previously stored in IMSI map nas* nas_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); if (nas_ctx != nullptr) { - m_nas_log->warning("UE context already exists.\n"); + m_logger.warning("UE context already exists."); m_s1ap->delete_ue_ctx(imsi); } @@ -1141,14 +1125,14 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) m_s1ap->add_nas_ctx_to_imsi_map(this); // Pack NAS Authentication Request in Downlink NAS Transport msg - nas_tx = m_pool->allocate(); - pack_authentication_request(nas_tx); + nas_tx = srslte::make_byte_buffer(); + pack_authentication_request(nas_tx.get()); // Send reply to eNB - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); - m_pool->deallocate(nas_tx); + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); - m_nas_log->info("Downlink NAS: Sent Authentication Request\n"); + m_logger.info("Downlink NAS: Sent Authentication Request"); srslte::console("Downlink NAS: Sent Authentication Request\n"); return true; } @@ -1156,63 +1140,62 @@ bool nas::handle_identity_response(srslte::byte_buffer_t* nas_rx) bool nas::handle_tracking_area_update_request(srslte::byte_buffer_t* nas_rx) { srslte::console("Warning: Tracking Area Update Request messages not handled yet.\n"); - m_nas_log->warning("Warning: Tracking Area Update Request messages not handled yet.\n"); + m_logger.warning("Warning: Tracking Area Update Request messages not handled yet."); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); - srslte::byte_buffer_t* nas_tx; + srslte::unique_byte_buffer_t nas_tx; /* TAU handling unsupported, therefore send TAU reject with cause IMPLICITLY DETACHED. * this will trigger full re-attach by the UE, instead of going to a TAU request loop */ - nas_tx = pool->allocate(); + nas_tx = srslte::make_byte_buffer(); // TODO we could enable integrity protection in some cases, but UE should comply anyway - pack_tracking_area_update_reject(nas_tx, LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); + pack_tracking_area_update_reject(nas_tx.get(), LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED); // Send reply - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); - pool->deallocate(nas_tx); + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); return true; } bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx) { - m_nas_log->info("Received Authentication Failure\n"); + m_logger.info("Received Authentication Failure"); - srslte::byte_buffer_t* nas_tx; + srslte::unique_byte_buffer_t nas_tx; LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_fail; LIBLTE_ERROR_ENUM err; err = liblte_mme_unpack_authentication_failure_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx, &auth_fail); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error unpacking NAS authentication failure. Error: %s\n", liblte_error_text[err]); + m_logger.error("Error unpacking NAS authentication failure. Error: %s", liblte_error_text[err]); return false; } switch (auth_fail.emm_cause) { case 20: srslte::console("MAC code failure\n"); - m_nas_log->info("MAC code failure\n"); + m_logger.info("MAC code failure"); break; case 26: srslte::console("Non-EPS authentication unacceptable\n"); - m_nas_log->info("Non-EPS authentication unacceptable\n"); + m_logger.info("Non-EPS authentication unacceptable"); break; case 21: srslte::console("Authentication Failure -- Synchronization Failure\n"); - m_nas_log->info("Authentication Failure -- Synchronization Failure\n"); + m_logger.info("Authentication Failure -- Synchronization Failure"); if (auth_fail.auth_fail_param_present == false) { - m_nas_log->error("Missing fail parameter\n"); + m_logger.error("Missing fail parameter"); return false; } if (!m_hss->resync_sqn(m_emm_ctx.imsi, auth_fail.auth_fail_param)) { srslte::console("Resynchronization failed. IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); - m_nas_log->info("Resynchronization failed. IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); + m_logger.info("Resynchronization failed. IMSI %015" PRIu64 "", m_emm_ctx.imsi); return false; } // Get Authentication Vectors from HSS if (!m_hss->gen_auth_info_answer( m_emm_ctx.imsi, m_sec_ctx.k_asme, m_sec_ctx.autn, m_sec_ctx.rand, m_sec_ctx.xres)) { srslte::console("User not found. IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); - m_nas_log->info("User not found. IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); + m_logger.info("User not found. IMSI %015" PRIu64 "", m_emm_ctx.imsi); return false; } @@ -1220,15 +1203,14 @@ bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx) m_sec_ctx.eksi = (m_sec_ctx.eksi + 1) % 6; // Pack NAS Authentication Request in Downlink NAS Transport msg - nas_tx = m_pool->allocate(); - pack_authentication_request(nas_tx); + nas_tx = srslte::make_byte_buffer(); + pack_authentication_request(nas_tx.get()); // Send reply to eNB m_s1ap->send_downlink_nas_transport( - m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx, m_ecm_ctx.enb_sri); - m_pool->deallocate(nas_tx); + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); - m_nas_log->info("Downlink NAS: Sent Authentication Request\n"); + m_logger.info("Downlink NAS: Sent Authentication Request"); srslte::console("Downlink NAS: Sent Authentication Request\n"); // TODO Start T3460 Timer! break; @@ -1238,14 +1220,13 @@ bool nas::handle_authentication_failure(srslte::byte_buffer_t* nas_rx) bool nas::handle_detach_request(srslte::byte_buffer_t* nas_msg) { - srslte::console("Detach request -- IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); - m_nas_log->info("Detach request -- IMSI %015" PRIu64 "\n", m_emm_ctx.imsi); + m_logger.info("Detach request -- IMSI %015" PRIu64 "", m_emm_ctx.imsi); LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_req; LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &detach_req); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Could not unpack detach request\n"); + m_logger.error("Could not unpack detach request"); return false; } @@ -1266,7 +1247,7 @@ bool nas::handle_detach_request(srslte::byte_buffer_t* nas_msg) /*Packing/Unpacking helper functions*/ bool nas::pack_authentication_request(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing Authentication Request\n"); + m_logger.info("Packing Authentication Request"); // Pack NAS msg LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req; @@ -1277,7 +1258,7 @@ bool nas::pack_authentication_request(srslte::byte_buffer_t* nas_buffer) LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_request_msg(&auth_req, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing Authentication Request\n"); + m_logger.error("Error packing Authentication Request"); srslte::console("Error packing Authentication Request\n"); return false; } @@ -1286,12 +1267,12 @@ bool nas::pack_authentication_request(srslte::byte_buffer_t* nas_buffer) bool nas::pack_authentication_reject(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing Authentication Reject\n"); + m_logger.info("Packing Authentication Reject"); LIBLTE_MME_AUTHENTICATION_REJECT_MSG_STRUCT auth_rej; LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_reject_msg(&auth_rej, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing Authentication Reject\n"); + m_logger.error("Error packing Authentication Reject"); srslte::console("Error packing Authentication Reject\n"); return false; } @@ -1300,7 +1281,7 @@ bool nas::pack_authentication_reject(srslte::byte_buffer_t* nas_buffer) bool nas::pack_security_mode_command(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing Security Mode Command\n"); + m_logger.info("Packing Security Mode Command"); // Pack NAS PDU LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sm_cmd; @@ -1340,14 +1321,14 @@ bool nas::pack_security_mode_command(srslte::byte_buffer_t* nas_buffer) srslte::security_generate_k_nas( m_sec_ctx.k_asme, m_sec_ctx.cipher_algo, m_sec_ctx.integ_algo, m_sec_ctx.k_nas_enc, m_sec_ctx.k_nas_int); - m_nas_log->info_hex(m_sec_ctx.k_nas_enc, 32, "Key NAS Encryption (k_nas_enc)\n"); - m_nas_log->info_hex(m_sec_ctx.k_nas_int, 32, "Key NAS Integrity (k_nas_int)\n"); + m_logger.info(m_sec_ctx.k_nas_enc, 32, "Key NAS Encryption (k_nas_enc)"); + m_logger.info(m_sec_ctx.k_nas_int, 32, "Key NAS Integrity (k_nas_int)"); uint8_t key_enb[32]; srslte::security_generate_k_enb(m_sec_ctx.k_asme, m_sec_ctx.ul_nas_count, m_sec_ctx.k_enb); - m_nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", m_sec_ctx.ul_nas_count); + m_logger.info("Generating KeNB with UL NAS COUNT: %d", m_sec_ctx.ul_nas_count); srslte::console("Generating KeNB with UL NAS COUNT: %d\n", m_sec_ctx.ul_nas_count); - m_nas_log->info_hex(m_sec_ctx.k_enb, 32, "Key eNodeB (k_enb)\n"); + m_logger.info(m_sec_ctx.k_enb, 32, "Key eNodeB (k_enb)"); // Generate MAC for integrity protection uint8_t mac[4]; @@ -1358,7 +1339,7 @@ bool nas::pack_security_mode_command(srslte::byte_buffer_t* nas_buffer) bool nas::pack_esm_information_request(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing ESM Information request\n"); + m_logger.info("Packing ESM Information request"); LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req; esm_info_req.eps_bearer_id = 0; @@ -1370,7 +1351,7 @@ bool nas::pack_esm_information_request(srslte::byte_buffer_t* nas_buffer) LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg( &esm_info_req, sec_hdr_type, m_sec_ctx.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing ESM information request\n"); + m_logger.error("Error packing ESM information request"); srslte::console("Error packing ESM information request\n"); return false; } @@ -1385,7 +1366,7 @@ bool nas::pack_esm_information_request(srslte::byte_buffer_t* nas_buffer) bool nas::pack_attach_accept(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing Attach Accept\n"); + m_logger.info("Packing Attach Accept"); LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req; @@ -1420,7 +1401,7 @@ bool nas::pack_attach_accept(srslte::byte_buffer_t* nas_buffer) attach_accept.tai_list.tai[0].mnc = mnc; attach_accept.tai_list.tai[0].tac = m_tac; - m_nas_log->info("Attach Accept -- MCC 0x%x, MNC 0x%x\n", m_mcc, m_mnc); + m_logger.info("Attach Accept -- MCC 0x%x, MNC 0x%x", m_mcc, m_mnc); // Allocate a GUTI ot the UE attach_accept.guti_present = true; @@ -1430,12 +1411,12 @@ bool nas::pack_attach_accept(srslte::byte_buffer_t* nas_buffer) attach_accept.guti.guti.mme_group_id = m_mme_group; attach_accept.guti.guti.mme_code = m_mme_code; attach_accept.guti.guti.m_tmsi = m_s1ap->allocate_m_tmsi(m_emm_ctx.imsi); - m_nas_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n", - attach_accept.guti.guti.mcc, - attach_accept.guti.guti.mnc, - attach_accept.guti.guti.mme_group_id, - attach_accept.guti.guti.mme_code, - attach_accept.guti.guti.m_tmsi); + m_logger.debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x", + attach_accept.guti.guti.mcc, + attach_accept.guti.guti.mnc, + attach_accept.guti.guti.mme_group_id, + attach_accept.guti.guti.mme_code, + attach_accept.guti.guti.m_tmsi); memcpy(&m_sec_ctx.guti, &attach_accept.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT)); @@ -1510,20 +1491,20 @@ bool nas::pack_attach_accept(srslte::byte_buffer_t* nas_buffer) memcpy(&nas_buffer->msg[1], mac, 4); // Log attach accept info - m_nas_log->info("Packed Attach Accept\n"); + m_logger.info("Packed Attach Accept"); return true; } bool nas::pack_identity_request(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing Identity Request\n"); + m_logger.info("Packing Identity Request"); LIBLTE_MME_ID_REQUEST_MSG_STRUCT id_req; id_req.id_type = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI; LIBLTE_ERROR_ENUM err = liblte_mme_pack_identity_request_msg(&id_req, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing Identity Request\n"); - srslte::console("Error packing Identity REquest\n"); + m_logger.error("Error packing Identity Request"); + srslte::console("Error packing Identity Request\n"); return false; } return true; @@ -1531,7 +1512,7 @@ bool nas::pack_identity_request(srslte::byte_buffer_t* nas_buffer) bool nas::pack_emm_information(srslte::byte_buffer_t* nas_buffer) { - m_nas_log->info("Packing EMM Information\n"); + m_logger.info("Packing EMM Information"); LIBLTE_MME_EMM_INFORMATION_MSG_STRUCT emm_info; emm_info.full_net_name_present = true; @@ -1557,7 +1538,7 @@ bool nas::pack_emm_information(srslte::byte_buffer_t* nas_buffer) emm_info.utc_and_local_time_zone.tz = 0; emm_info.utc_and_local_time_zone_present = true; } else { - m_nas_log->error("Error getting current time: %s\n", strerror(errno)); + m_logger.error("Error getting current time: %s", strerror(errno)); } uint8_t sec_hdr_type = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED; @@ -1565,7 +1546,7 @@ bool nas::pack_emm_information(srslte::byte_buffer_t* nas_buffer) LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg( &emm_info, sec_hdr_type, m_sec_ctx.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing EMM Information\n"); + m_logger.error("Error packing EMM Information"); srslte::console("Error packing EMM Information\n"); return false; } @@ -1578,7 +1559,7 @@ bool nas::pack_emm_information(srslte::byte_buffer_t* nas_buffer) integrity_generate(nas_buffer, mac); memcpy(&nas_buffer->msg[1], mac, 4); - m_nas_log->info("Packed UE EMM information\n"); + m_logger.info("Packed UE EMM information"); return true; } @@ -1595,7 +1576,7 @@ bool nas::pack_service_reject(srslte::byte_buffer_t* nas_buffer, uint8_t emm_cau LIBLTE_ERROR_ENUM err = liblte_mme_pack_service_reject_msg( &service_rej, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, 0, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing Service Reject\n"); + m_logger.error("Error packing Service Reject"); srslte::console("Error packing Service Reject\n"); return false; } @@ -1611,13 +1592,13 @@ bool nas::pack_tracking_area_update_reject(srslte::byte_buffer_t* nas_buffer, ui if (emm_cause == LIBLTE_MME_EMM_CAUSE_CONGESTION) { // Standard would want T3446 set in this case - m_nas_log->error("Tracking Area Update Reject EMM Cause set to \"CONGESTION\", but back-off timer not set.\n"); + m_logger.error("Tracking Area Update Reject EMM Cause set to \"CONGESTION\", but back-off timer not set."); } LIBLTE_ERROR_ENUM err = liblte_mme_pack_tracking_area_update_reject_msg( &tau_rej, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, 0, (LIBLTE_BYTE_MSG_STRUCT*)nas_buffer); if (err != LIBLTE_SUCCESS) { - m_nas_log->error("Error packing Tracking Area Update Reject\n"); + m_logger.error("Error packing Tracking Area Update Reject"); srslte::console("Error packing Tracking Area Update Reject\n"); return false; } @@ -1636,7 +1617,7 @@ bool nas::short_integrity_check(srslte::byte_buffer_t* pdu) int i; if (pdu->N_bytes < 4) { - m_nas_log->warning("NAS message to short for short integrity check (pdu len: %d)", pdu->N_bytes); + m_logger.warning("NAS message to short for short integrity check (pdu len: %d)", pdu->N_bytes); return false; } @@ -1676,21 +1657,20 @@ bool nas::short_integrity_check(srslte::byte_buffer_t* pdu) // Check if expected mac equals the sent mac for (i = 0; i < 2; i++) { if (exp_mac[i + 2] != mac[i]) { - m_nas_log->warning("Short integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " - "Received: count=%d, [%02x %02x]\n", - m_sec_ctx.ul_nas_count, - exp_mac[0], - exp_mac[1], - exp_mac[2], - exp_mac[3], - pdu->msg[1] & 0x1F, - mac[0], - mac[1]); + m_logger.warning("Short integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " + "Received: count=%d, [%02x %02x]", + m_sec_ctx.ul_nas_count, + exp_mac[0], + exp_mac[1], + exp_mac[2], + exp_mac[3], + pdu->msg[1] & 0x1F, + mac[0], + mac[1]); return false; } } - m_nas_log->info( - "Integrity check ok. Local: count=%d, Received: count=%d\n", m_sec_ctx.ul_nas_count, pdu->msg[1] & 0x1F); + m_logger.info("Integrity check ok. Local: count=%d, Received: count=%d", m_sec_ctx.ul_nas_count, pdu->msg[1] & 0x1F); return true; } @@ -1737,24 +1717,24 @@ bool nas::integrity_check(srslte::byte_buffer_t* pdu) // Check if expected mac equals the sent mac for (int i = 0; i < 4; i++) { if (exp_mac[i] != mac[i]) { - m_nas_log->warning("Integrity check failure. Algorithm=EIA%d\n", (int)m_sec_ctx.integ_algo); - m_nas_log->warning("UL Local: est_count=%d, old_count=%d, MAC=[%02x %02x %02x %02x], " - "Received: UL count=%d, MAC=[%02x %02x %02x %02x]\n", - estimated_count, - m_sec_ctx.ul_nas_count, - exp_mac[0], - exp_mac[1], - exp_mac[2], - exp_mac[3], - pdu->msg[5], - mac[0], - mac[1], - mac[2], - mac[3]); + m_logger.warning("Integrity check failure. Algorithm=EIA%d", (int)m_sec_ctx.integ_algo); + m_logger.warning("UL Local: est_count=%d, old_count=%d, MAC=[%02x %02x %02x %02x], " + "Received: UL count=%d, MAC=[%02x %02x %02x %02x]", + estimated_count, + m_sec_ctx.ul_nas_count, + exp_mac[0], + exp_mac[1], + exp_mac[2], + exp_mac[3], + pdu->msg[5], + mac[0], + mac[1], + mac[2], + mac[3]); return false; } } - m_nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", estimated_count, pdu->msg[5]); + m_logger.info("Integrity check ok. Local: count=%d, Received: count=%d", estimated_count, pdu->msg[5]); m_sec_ctx.ul_nas_count = estimated_count; return true; @@ -1795,9 +1775,9 @@ void nas::integrity_generate(srslte::byte_buffer_t* pdu, uint8_t* mac) default: break; } - m_nas_log->debug("Generating MAC with inputs: Algorithm %s, DL COUNT %d\n", - srslte::integrity_algorithm_id_text[m_sec_ctx.integ_algo], - m_sec_ctx.dl_nas_count); + m_logger.debug("Generating MAC with inputs: Algorithm %s, DL COUNT %d", + srslte::integrity_algorithm_id_text[m_sec_ctx.integ_algo], + m_sec_ctx.dl_nas_count); } void nas::cipher_decrypt(srslte::byte_buffer_t* pdu) @@ -1815,7 +1795,7 @@ void nas::cipher_decrypt(srslte::byte_buffer_t* pdu) pdu->N_bytes - 6, &tmp_pdu.msg[6]); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); - m_nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); + m_logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA2: srslte::security_128_eea2(&m_sec_ctx.k_nas_enc[16], @@ -1825,7 +1805,7 @@ void nas::cipher_decrypt(srslte::byte_buffer_t* pdu) &pdu->msg[6], pdu->N_bytes - 6, &tmp_pdu.msg[6]); - m_nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); + m_logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA3: @@ -1836,11 +1816,11 @@ void nas::cipher_decrypt(srslte::byte_buffer_t* pdu) &pdu->msg[6], pdu->N_bytes - 6, &tmp_pdu.msg[6]); - m_nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); + m_logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); break; default: - m_nas_log->error("Ciphering algorithms not known\n"); + m_logger.error("Ciphering algorithms not known"); break; } } @@ -1860,7 +1840,7 @@ void nas::cipher_encrypt(srslte::byte_buffer_t* pdu) pdu->N_bytes - 6, &pdu_tmp.msg[6]); memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); - m_nas_log->debug_hex(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); + m_logger.debug(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA2: srslte::security_128_eea2(&m_sec_ctx.k_nas_enc[16], @@ -1871,7 +1851,7 @@ void nas::cipher_encrypt(srslte::byte_buffer_t* pdu) pdu->N_bytes - 6, &pdu_tmp.msg[6]); memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); - m_nas_log->debug_hex(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); + m_logger.debug(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); break; case srslte::CIPHERING_ALGORITHM_ID_128_EEA3: srslte::security_128_eea3(&m_sec_ctx.k_nas_enc[16], @@ -1882,10 +1862,10 @@ void nas::cipher_encrypt(srslte::byte_buffer_t* pdu) pdu->N_bytes - 6, &pdu_tmp.msg[6]); memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); - m_nas_log->debug_hex(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); + m_logger.debug(pdu_tmp.msg, pdu->N_bytes, "Encrypted"); break; default: - m_nas_log->error("Ciphering algorithm not known\n"); + m_logger.error("Ciphering algorithm not known"); break; } } @@ -1897,28 +1877,28 @@ void nas::cipher_encrypt(srslte::byte_buffer_t* pdu) **************************/ bool nas::start_timer(enum nas_timer_type type) { - m_nas_log->debug("Starting NAS timer\n"); + m_logger.debug("Starting NAS timer"); bool err = false; switch (type) { case T_3413: err = start_t3413(); break; default: - m_nas_log->error("Invalid timer type\n"); + m_logger.error("Invalid timer type"); } return err; } bool nas::expire_timer(enum nas_timer_type type) { - m_nas_log->debug("NAS timer expired\n"); + m_logger.debug("NAS timer expired"); bool err = false; switch (type) { case T_3413: err = expire_t3413(); break; default: - m_nas_log->error("Invalid timer type\n"); + m_logger.error("Invalid timer type"); } return err; } @@ -1926,15 +1906,15 @@ bool nas::expire_timer(enum nas_timer_type type) // T3413 -> Paging timer bool nas::start_t3413() { - m_nas_log->info("Starting T3413 Timer: Timeout value %d\n", m_t3413); + m_logger.info("Starting T3413 Timer: Timeout value %d", m_t3413); if (m_emm_ctx.state != EMM_STATE_REGISTERED) { - m_nas_log->error("EMM invalid status to start T3413\n"); + m_logger.error("EMM invalid status to start T3413"); return false; } int fdt = timerfd_create(CLOCK_MONOTONIC, 0); if (fdt < 0) { - m_nas_log->error("Error creating timer. %s\n", strerror(errno)); + m_logger.error("Error creating timer. %s", strerror(errno)); return false; } struct itimerspec t_value; @@ -1944,7 +1924,7 @@ bool nas::start_t3413() t_value.it_interval.tv_nsec = 0; if (timerfd_settime(fdt, 0, &t_value, NULL) == -1) { - m_nas_log->error("Could not set timer\n"); + m_logger.error("Could not set timer"); close(fdt); return false; } @@ -1955,10 +1935,10 @@ bool nas::start_t3413() bool nas::expire_t3413() { - m_nas_log->info("T3413 expired -- Could not page the ue.\n"); + m_logger.info("T3413 expired -- Could not page the ue."); srslte::console("T3413 expired -- Could not page the ue.\n"); if (m_emm_ctx.state != EMM_STATE_REGISTERED) { - m_nas_log->error("EMM invalid status upon T3413 expiration\n"); + m_logger.error("EMM invalid status upon T3413 expiration"); return false; } // Send Paging Failure to the SPGW diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index d3ae8533e..45e955bae 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -31,10 +31,7 @@ namespace srsepc { s1ap* s1ap::m_instance = NULL; pthread_mutex_t s1ap_instance_mutex = PTHREAD_MUTEX_INITIALIZER; -s1ap::s1ap() : m_s1mme(-1), m_next_mme_ue_s1ap_id(1), m_mme_gtpc(NULL), m_pool(NULL) -{ - return; -} +s1ap::s1ap() : m_s1mme(-1), m_next_mme_ue_s1ap_id(1), m_mme_gtpc(NULL) {} s1ap::~s1ap() { @@ -61,18 +58,12 @@ void s1ap::cleanup(void) pthread_mutex_unlock(&s1ap_instance_mutex); } -int s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter* nas_log, srslte::log_filter* s1ap_log) +int s1ap::init(s1ap_args_t s1ap_args) { - m_pool = srslte::byte_buffer_pool::get_instance(); - m_s1ap_args = s1ap_args; srslte::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &m_plmn); m_next_m_tmsi = rand(); - // Init log - m_nas_log = nas_log; - m_s1ap_log = s1ap_log; - // Get pointer to the HSS m_hss = hss::get_instance(); @@ -98,7 +89,7 @@ int s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter* nas_log, srslte::log_f if (m_pcap_enable) { m_pcap.open(s1ap_args.pcap_filename.c_str()); } - m_s1ap_log->info("S1AP Initialized\n"); + m_logger.info("S1AP Initialized"); return 0; } @@ -109,7 +100,7 @@ void s1ap::stop() } std::map::iterator enb_it = m_active_enbs.begin(); while (enb_it != m_active_enbs.end()) { - m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_it->second->enb_id); + m_logger.info("Deleting eNB context. eNB Id: 0x%x", enb_it->second->enb_id); srslte::console("Deleting eNB context. eNB Id: 0x%x\n", enb_it->second->enb_id); delete enb_it->second; m_active_enbs.erase(enb_it++); @@ -117,7 +108,7 @@ void s1ap::stop() std::map::iterator ue_it = m_imsi_to_nas_ctx.begin(); while (ue_it != m_imsi_to_nas_ctx.end()) { - m_s1ap_log->info("Deleting UE EMM context. IMSI: %015" PRIu64 "\n", ue_it->first); + m_logger.info("Deleting UE EMM context. IMSI: %015" PRIu64 "", ue_it->first); srslte::console("Deleting UE EMM context. IMSI: %015" PRIu64 "\n", ue_it->first); delete ue_it->second; m_imsi_to_nas_ctx.erase(ue_it++); @@ -152,7 +143,7 @@ int s1ap::enb_listen() struct sockaddr_in s1mme_addr; struct sctp_event_subscribe evnts; - m_s1ap_log->info("S1-MME Initializing\n"); + m_logger.info("S1-MME Initializing"); sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); if (sock_fd == -1) { srslte::console("Could not create SCTP socket\n"); @@ -178,7 +169,7 @@ int s1ap::enb_listen() err = bind(sock_fd, (struct sockaddr*)&s1mme_addr, sizeof(s1mme_addr)); if (err != 0) { close(sock_fd); - m_s1ap_log->error("Error binding SCTP socket\n"); + m_logger.error("Error binding SCTP socket"); srslte::console("Error binding SCTP socket\n"); return -1; } @@ -187,7 +178,7 @@ int s1ap::enb_listen() err = listen(sock_fd, SOMAXCONN); if (err != 0) { close(sock_fd); - m_s1ap_log->error("Error in SCTP socket listen\n"); + m_logger.error("Error in SCTP socket listen"); srslte::console("Error in SCTP socket listen\n"); return -1; } @@ -197,16 +188,16 @@ int s1ap::enb_listen() bool s1ap::s1ap_tx_pdu(const asn1::s1ap::s1ap_pdu_c& pdu, struct sctp_sndrcvinfo* enb_sri) { - m_s1ap_log->debug("Transmitting S1AP PDU. eNB SCTP association Id: %d\n", enb_sri->sinfo_assoc_id); + m_logger.debug("Transmitting S1AP PDU. eNB SCTP association Id: %d", enb_sri->sinfo_assoc_id); - srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*m_pool); + srslte::unique_byte_buffer_t buf = srslte::make_byte_buffer(); if (buf == nullptr) { - m_s1ap_log->error("Fatal Error: Couldn't allocate buffer for S1AP PDU.\n"); + m_logger.error("Fatal Error: Couldn't allocate buffer for S1AP PDU."); return false; } asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { - m_s1ap_log->error("Could not pack S1AP PDU correctly.\n"); + m_logger.error("Could not pack S1AP PDU correctly."); return false; } buf->N_bytes = bref.distance_bytes(); @@ -214,7 +205,7 @@ bool s1ap::s1ap_tx_pdu(const asn1::s1ap::s1ap_pdu_c& pdu, struct sctp_sndrcvinfo ssize_t n_sent = sctp_send(m_s1mme, buf->msg, buf->N_bytes, enb_sri, MSG_NOSIGNAL); if (n_sent == -1) { srslte::console("Failed to send S1AP PDU. Error: %s\n", strerror(errno)); - m_s1ap_log->error("Failed to send S1AP PDU. Error: %s \n", strerror(errno)); + m_logger.error("Failed to send S1AP PDU. Error: %s ", strerror(errno)); return false; } @@ -236,25 +227,25 @@ void s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu, struct sctp_sndrcvinfo s1ap_pdu_t rx_pdu; asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (rx_pdu.unpack(bref) != asn1::SRSASN_SUCCESS) { - m_s1ap_log->error("Failed to unpack received PDU\n"); + m_logger.error("Failed to unpack received PDU"); return; } switch (rx_pdu.type().value) { case s1ap_pdu_t::types_opts::init_msg: - m_s1ap_log->info("Received Initiating PDU\n"); + m_logger.info("Received Initiating PDU"); handle_initiating_message(rx_pdu.init_msg(), enb_sri); break; case s1ap_pdu_t::types_opts::successful_outcome: - m_s1ap_log->info("Received Succeseful Outcome PDU\n"); + m_logger.info("Received Succeseful Outcome PDU"); handle_successful_outcome(rx_pdu.successful_outcome()); break; case s1ap_pdu_t::types_opts::unsuccessful_outcome: - m_s1ap_log->info("Received Unsucceseful Outcome PDU\n"); + m_logger.info("Received Unsucceseful Outcome PDU"); // TODO handle_unsuccessfuloutcome(&rx_pdu.choice.unsuccessfulOutcome); break; default: - m_s1ap_log->error("Unhandled PDU type %d\n", rx_pdu.type().value); + m_logger.warning("Unhandled PDU type %d", rx_pdu.type().value); } } @@ -264,24 +255,27 @@ void s1ap::handle_initiating_message(const asn1::s1ap::init_msg_s& msg, struct s switch (msg.value.type().value) { case init_msg_type_opts_t::s1_setup_request: - m_s1ap_log->info("Received S1 Setup Request.\n"); + m_logger.info("Received S1 Setup Request."); m_s1ap_mngmt_proc->handle_s1_setup_request(msg.value.s1_setup_request(), enb_sri); break; case init_msg_type_opts_t::init_ue_msg: - m_s1ap_log->info("Received Initial UE Message.\n"); + m_logger.info("Received Initial UE Message."); m_s1ap_nas_transport->handle_initial_ue_message(msg.value.init_ue_msg(), enb_sri); break; case init_msg_type_opts_t::ul_nas_transport: - m_s1ap_log->info("Received Uplink NAS Transport Message.\n"); + m_logger.info("Received Uplink NAS Transport Message."); m_s1ap_nas_transport->handle_uplink_nas_transport(msg.value.ul_nas_transport(), enb_sri); break; case init_msg_type_opts_t::ue_context_release_request: - m_s1ap_log->info("Received UE Context Release Request Message.\n"); + m_logger.info("Received UE Context Release Request Message."); m_s1ap_ctx_mngmt_proc->handle_ue_context_release_request(msg.value.ue_context_release_request(), enb_sri); break; + case init_msg_type_opts_t::ue_cap_info_ind: + m_logger.info("Ignoring UE capability Info Indication."); + break; default: - m_s1ap_log->error("Unhandled S1AP intiating message: %s\n", msg.value.type().to_string().c_str()); - srslte::console("Unhandled S1APintiating message: %s\n", msg.value.type().to_string().c_str()); + m_logger.error("Unhandled S1AP initiating message: %s", msg.value.type().to_string().c_str()); + srslte::console("Unhandled S1APinitiating message: %s\n", msg.value.type().to_string().c_str()); } } @@ -291,22 +285,22 @@ void s1ap::handle_successful_outcome(const asn1::s1ap::successful_outcome_s& msg switch (msg.value.type().value) { case successful_outcome_type_opts_t::init_context_setup_resp: - m_s1ap_log->info("Received Initial Context Setup Response.\n"); + m_logger.info("Received Initial Context Setup Response."); m_s1ap_ctx_mngmt_proc->handle_initial_context_setup_response(msg.value.init_context_setup_resp()); break; case successful_outcome_type_opts_t::ue_context_release_complete: - m_s1ap_log->info("Received UE Context Release Complete\n"); + m_logger.info("Received UE Context Release Complete"); m_s1ap_ctx_mngmt_proc->handle_ue_context_release_complete(msg.value.ue_context_release_complete()); break; default: - m_s1ap_log->error("Unhandled successful outcome message: %s\n", msg.value.type().to_string().c_str()); + m_logger.error("Unhandled successful outcome message: %s", msg.value.type().to_string().c_str()); } } // eNB Context Managment void s1ap::add_new_enb_ctx(const enb_ctx_t& enb_ctx, const struct sctp_sndrcvinfo* enb_sri) { - m_s1ap_log->info("Adding new eNB context. eNB ID %d\n", enb_ctx.enb_id); + m_logger.info("Adding new eNB context. eNB ID %d", enb_ctx.enb_id); std::set ue_set; enb_ctx_t* enb_ptr = new enb_ctx_t; *enb_ptr = enb_ctx; @@ -332,11 +326,11 @@ void s1ap::delete_enb_ctx(int32_t assoc_id) std::map::iterator it_ctx = m_active_enbs.find(enb_id); if (it_ctx == m_active_enbs.end() || it_assoc == m_sctp_to_enb_id.end()) { - m_s1ap_log->error("Could not find eNB to delete. Association: %d\n", assoc_id); + m_logger.error("Could not find eNB to delete. Association: %d", assoc_id); return; } - m_s1ap_log->info("Deleting eNB context. eNB Id: 0x%x\n", enb_id); + m_logger.info("Deleting eNB context. eNB Id: 0x%x", enb_id); srslte::console("Deleting eNB context. eNB Id: 0x%x\n", enb_id); // Delete connected UEs ctx @@ -354,41 +348,41 @@ bool s1ap::add_nas_ctx_to_imsi_map(nas* nas_ctx) { std::map::iterator ctx_it = m_imsi_to_nas_ctx.find(nas_ctx->m_emm_ctx.imsi); if (ctx_it != m_imsi_to_nas_ctx.end()) { - m_s1ap_log->error("UE Context already exists. IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi); + m_logger.error("UE Context already exists. IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); return false; } if (nas_ctx->m_ecm_ctx.mme_ue_s1ap_id != 0) { std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_nas_ctx.find(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); if (ctx_it2 != m_mme_ue_s1ap_id_to_nas_ctx.end() && ctx_it2->second != nas_ctx) { - m_s1ap_log->error("Context identified with IMSI does not match context identified by MME UE S1AP Id.\n"); + m_logger.error("Context identified with IMSI does not match context identified by MME UE S1AP Id."); return false; } } m_imsi_to_nas_ctx.insert(std::pair(nas_ctx->m_emm_ctx.imsi, nas_ctx)); - m_s1ap_log->debug("Saved UE context corresponding to IMSI %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi); + m_logger.debug("Saved UE context corresponding to IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); return true; } bool s1ap::add_nas_ctx_to_mme_ue_s1ap_id_map(nas* nas_ctx) { if (nas_ctx->m_ecm_ctx.mme_ue_s1ap_id == 0) { - m_s1ap_log->error("Could not add UE context to MME UE S1AP map. MME UE S1AP ID 0 is not valid.\n"); + m_logger.error("Could not add UE context to MME UE S1AP map. MME UE S1AP ID 0 is not valid."); return false; } std::map::iterator ctx_it = m_mme_ue_s1ap_id_to_nas_ctx.find(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); if (ctx_it != m_mme_ue_s1ap_id_to_nas_ctx.end()) { - m_s1ap_log->error("UE Context already exists. MME UE S1AP Id %015" PRIu64 "\n", nas_ctx->m_emm_ctx.imsi); + m_logger.error("UE Context already exists. MME UE S1AP Id %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); return false; } if (nas_ctx->m_emm_ctx.imsi != 0) { std::map::iterator ctx_it2 = m_mme_ue_s1ap_id_to_nas_ctx.find(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); if (ctx_it2 != m_mme_ue_s1ap_id_to_nas_ctx.end() && ctx_it2->second != nas_ctx) { - m_s1ap_log->error("Context identified with MME UE S1AP Id does not match context identified by IMSI.\n"); + m_logger.error("Context identified with MME UE S1AP Id does not match context identified by IMSI."); return false; } } m_mme_ue_s1ap_id_to_nas_ctx.insert(std::pair(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_ctx)); - m_s1ap_log->debug("Saved UE context corresponding to MME UE S1AP Id %d\n", nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); + m_logger.debug("Saved UE context corresponding to MME UE S1AP Id %d", nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); return true; } @@ -396,16 +390,16 @@ bool s1ap::add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id) { std::map >::iterator ues_in_enb = m_enb_assoc_to_ue_ids.find(enb_assoc); if (ues_in_enb == m_enb_assoc_to_ue_ids.end()) { - m_s1ap_log->error("Could not find eNB from eNB SCTP association %d\n", enb_assoc); + m_logger.error("Could not find eNB from eNB SCTP association %d", enb_assoc); return false; } std::set::iterator ue_id = ues_in_enb->second.find(mme_ue_s1ap_id); if (ue_id != ues_in_enb->second.end()) { - m_s1ap_log->error("UE with MME UE S1AP Id already exists %d\n", mme_ue_s1ap_id); + m_logger.error("UE with MME UE S1AP Id already exists %d", mme_ue_s1ap_id); return false; } ues_in_enb->second.insert(mme_ue_s1ap_id); - m_s1ap_log->debug("Added UE with MME-UE S1AP Id %d to eNB with association %d\n", mme_ue_s1ap_id, enb_assoc); + m_logger.debug("Added UE with MME-UE S1AP Id %d to eNB with association %d", mme_ue_s1ap_id, enb_assoc); return true; } @@ -442,8 +436,8 @@ void s1ap::release_ues_ecm_ctx_in_enb(int32_t enb_assoc) emm_ctx_t* emm_ctx = &nas_ctx->second->m_emm_ctx; ecm_ctx_t* ecm_ctx = &nas_ctx->second->m_ecm_ctx; - m_s1ap_log->info( - "Releasing UE context. IMSI: %015" PRIu64 ", UE-MME S1AP Id: %d\n", emm_ctx->imsi, ecm_ctx->mme_ue_s1ap_id); + m_logger.info( + "Releasing UE context. IMSI: %015" PRIu64 ", UE-MME S1AP Id: %d", emm_ctx->imsi, ecm_ctx->mme_ue_s1ap_id); if (emm_ctx->state == EMM_STATE_REGISTERED) { m_mme_gtpc->send_delete_session_request(emm_ctx->imsi); emm_ctx->state = EMM_STATE_DEREGISTERED; @@ -461,7 +455,7 @@ bool s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) { nas* nas_ctx = find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == NULL) { - m_s1ap_log->error("Cannot release UE ECM context, UE not found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_logger.error("Cannot release UE ECM context, UE not found. MME-UE S1AP Id: %d", mme_ue_s1ap_id); return false; } ecm_ctx_t* ecm_ctx = &nas_ctx->m_ecm_ctx; @@ -469,13 +463,13 @@ bool s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) // Delete UE within eNB UE set std::map::iterator it = m_sctp_to_enb_id.find(ecm_ctx->enb_sri.sinfo_assoc_id); if (it == m_sctp_to_enb_id.end()) { - m_s1ap_log->error("Could not find eNB for UE release request.\n"); + m_logger.error("Could not find eNB for UE release request."); return false; } uint16_t enb_id = it->second; std::map >::iterator ue_set = m_enb_assoc_to_ue_ids.find(ecm_ctx->enb_sri.sinfo_assoc_id); if (ue_set == m_enb_assoc_to_ue_ids.end()) { - m_s1ap_log->error("Could not find the eNB's UEs.\n"); + m_logger.error("Could not find the eNB's UEs."); return false; } ue_set->second.erase(mme_ue_s1ap_id); @@ -486,7 +480,7 @@ bool s1ap::release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) ecm_ctx->mme_ue_s1ap_id = 0; ecm_ctx->enb_ue_s1ap_id = 0; - m_s1ap_log->info("Released UE ECM Context.\n"); + m_logger.info("Released UE ECM Context."); return true; } @@ -494,7 +488,7 @@ bool s1ap::delete_ue_ctx(uint64_t imsi) { nas* nas_ctx = find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL) { - m_s1ap_log->info("Cannot delete UE context, UE not found. IMSI: %" PRIu64 "\n", imsi); + m_logger.info("Cannot delete UE context, UE not found. IMSI: %" PRIu64 "", imsi); return false; } @@ -506,7 +500,7 @@ bool s1ap::delete_ue_ctx(uint64_t imsi) // Delete UE context m_imsi_to_nas_ctx.erase(imsi); delete nas_ctx; - m_s1ap_log->info("Deleted UE Context.\n"); + m_logger.info("Deleted UE Context."); return true; } @@ -515,22 +509,22 @@ void s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) { std::map::iterator ue_ctx_it = m_imsi_to_nas_ctx.find(imsi); if (ue_ctx_it == m_imsi_to_nas_ctx.end()) { - m_s1ap_log->error("Could not activate EPS bearer: Could not find UE context\n"); + m_logger.error("Could not activate EPS bearer: Could not find UE context"); return; } // Make sure NAS is active uint32_t mme_ue_s1ap_id = ue_ctx_it->second->m_ecm_ctx.mme_ue_s1ap_id; std::map::iterator it = m_mme_ue_s1ap_id_to_nas_ctx.find(mme_ue_s1ap_id); if (it == m_mme_ue_s1ap_id_to_nas_ctx.end()) { - m_s1ap_log->error("Could not activate EPS bearer: ECM context seems to be missing\n"); + m_logger.error("Could not activate EPS bearer: ECM context seems to be missing"); return; } ecm_ctx_t* ecm_ctx = &ue_ctx_it->second->m_ecm_ctx; esm_ctx_t* esm_ctx = &ue_ctx_it->second->m_esm_ctx[ebi]; if (esm_ctx->state != ERAB_CTX_SETUP) { - m_s1ap_log->error( - "Could not be activate EPS Bearer, bearer in wrong state: MME S1AP Id %d, EPS Bearer id %d, state %d\n", + m_logger.error( + "Could not be activate EPS Bearer, bearer in wrong state: MME S1AP Id %d, EPS Bearer id %d, state %d", mme_ue_s1ap_id, ebi, esm_ctx->state); @@ -544,7 +538,7 @@ void s1ap::activate_eps_bearer(uint64_t imsi, uint8_t ebi) esm_ctx->state = ERAB_ACTIVE; ecm_ctx->state = ECM_STATE_CONNECTED; - m_s1ap_log->info("Activated EPS Bearer: Bearer id %d\n", ebi); + m_logger.info("Activated EPS Bearer: Bearer id %d", ebi); return; } @@ -554,7 +548,7 @@ uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) m_next_m_tmsi = (m_next_m_tmsi + 1) % UINT32_MAX; m_tmsi_to_imsi.insert(std::pair(m_tmsi, imsi)); - m_s1ap_log->debug("Allocated M-TMSI 0x%x to IMSI %015" PRIu64 ",\n", m_tmsi, imsi); + m_logger.debug("Allocated M-TMSI 0x%x to IMSI %015" PRIu64 ",", m_tmsi, imsi); return m_tmsi; } @@ -562,10 +556,10 @@ uint64_t s1ap::find_imsi_from_m_tmsi(uint32_t m_tmsi) { std::map::iterator it = m_tmsi_to_imsi.find(m_tmsi); if (it != m_tmsi_to_imsi.end()) { - m_s1ap_log->debug("Found IMSI %015" PRIu64 " from M-TMSI 0x%x\n", it->second, m_tmsi); + m_logger.debug("Found IMSI %015" PRIu64 " from M-TMSI 0x%x", it->second, m_tmsi); return it->second; } else { - m_s1ap_log->debug("Could not find IMSI from M-TMSI 0x%x\n", m_tmsi); + m_logger.debug("Could not find IMSI from M-TMSI 0x%x", m_tmsi); return 0; } } @@ -576,18 +570,18 @@ void s1ap::print_enb_ctx_info(const std::string& prefix, const enb_ctx_t& enb_ct if (enb_ctx.enb_name_present) { srslte::console("%s - eNB Name: %s, eNB id: 0x%x\n", prefix.c_str(), enb_ctx.enb_name.c_str(), enb_ctx.enb_id); - m_s1ap_log->info("%s - eNB Name: %s, eNB id: 0x%x\n", prefix.c_str(), enb_ctx.enb_name.c_str(), enb_ctx.enb_id); + m_logger.info("%s - eNB Name: %s, eNB id: 0x%x", prefix.c_str(), enb_ctx.enb_name.c_str(), enb_ctx.enb_id); } else { srslte::console("%s - eNB Id 0x%x\n", prefix.c_str(), enb_ctx.enb_id); - m_s1ap_log->info("%s - eNB Id 0x%x\n", prefix.c_str(), enb_ctx.enb_id); + m_logger.info("%s - eNB Id 0x%x", prefix.c_str(), enb_ctx.enb_id); } srslte::mcc_to_string(enb_ctx.mcc, &mcc_str); srslte::mnc_to_string(enb_ctx.mnc, &mnc_str); - m_s1ap_log->info("%s - MCC:%s, MNC:%s, PLMN: %d\n", prefix.c_str(), mcc_str.c_str(), mnc_str.c_str(), enb_ctx.plmn); + m_logger.info("%s - MCC:%s, MNC:%s, PLMN: %d", prefix.c_str(), mcc_str.c_str(), mnc_str.c_str(), enb_ctx.plmn); srslte::console("%s - MCC:%s, MNC:%s\n", prefix.c_str(), mcc_str.c_str(), mnc_str.c_str()); for (int i = 0; i < enb_ctx.nof_supported_ta; i++) { for (int j = 0; i < enb_ctx.nof_supported_ta; i++) { - m_s1ap_log->info("%s - TAC %d, B-PLMN 0x%x\n", prefix.c_str(), enb_ctx.tacs[i], enb_ctx.bplmns[i][j]); + m_logger.info("%s - TAC %d, B-PLMN 0x%x", prefix.c_str(), enb_ctx.tacs[i], enb_ctx.bplmns[i][j]); srslte::console("%s - TAC %d, B-PLMN 0x%x\n", prefix.c_str(), enb_ctx.tacs[i], enb_ctx.bplmns[i][j]); } } @@ -611,7 +605,7 @@ bool s1ap::send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_se { nas* nas_ctx = find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL) { - m_s1ap_log->error("Error finding NAS context when sending initial context Setup Request\n"); + m_logger.error("Error finding NAS context when sending initial context Setup Request"); return false; } m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(nas_ctx, erab_to_setup); @@ -623,7 +617,7 @@ bool s1ap::send_ue_context_release_command(uint32_t mme_ue_s1ap_id) { nas* nas_ctx = find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == NULL) { - m_s1ap_log->error("Error finding NAS context when sending UE Context Setup Release\n"); + m_logger.error("Error finding NAS context when sending UE Context Setup Release"); return false; } m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(nas_ctx); @@ -661,7 +655,7 @@ bool s1ap::expire_nas_timer(enum nas_timer_type type, uint64_t imsi) { nas* nas_ctx = find_nas_ctx_from_imsi(imsi); if (nas_ctx == NULL) { - m_s1ap_log->error("Error finding NAS context to handle timer\n"); + m_logger.error("Error finding NAS context to handle timer"); return false; } bool err = nas_ctx->expire_timer(type); diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index 48de37a5e..4adb91e8e 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -66,14 +66,12 @@ void s1ap_ctx_mngmt_proc::init() { m_s1ap = s1ap::get_instance(); m_mme_gtpc = mme_gtpc::get_instance(); - m_s1ap_log = m_s1ap->m_s1ap_log; m_s1ap_args = m_s1ap->m_s1ap_args; - m_pool = srslte::byte_buffer_pool::get_instance(); } bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint16_t erab_to_setup) { - m_s1ap_log->info("Preparing to send Initial Context Setup request\n"); + m_logger.info("Preparing to send Initial Context Setup request"); // Get UE Context/E-RAB Context to setup emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; @@ -139,13 +137,13 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 for (uint8_t i = 0; i < 32; ++i) { in_ctx_req.security_key.value.data()[31 - i] = sec_ctx->k_enb[i]; } - m_s1ap_log->info_hex(sec_ctx->k_enb, 32, "Initial Context Setup Request -- Key eNB (k_enb)\n"); + m_logger.info(sec_ctx->k_enb, 32, "Initial Context Setup Request -- Key eNB (k_enb)"); - srslte::unique_byte_buffer_t nas_buffer = allocate_unique_buffer(*m_pool); + srslte::unique_byte_buffer_t nas_buffer = srslte::make_byte_buffer(); if (emm_ctx->state == EMM_STATE_DEREGISTERED) { // Attach procedure initiated from an attach request srslte::console("Adding attach accept to Initial Context Setup Request\n"); - m_s1ap_log->info("Adding attach accept to Initial Context Setup Request\n"); + m_logger.info("Adding attach accept to Initial Context Setup Request"); nas_ctx->pack_attach_accept(nas_buffer.get()); // Add nas message to context setup request @@ -155,7 +153,7 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 } if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &ecm_ctx->enb_sri)) { - m_s1ap_log->error("Error sending Initial Context Setup Request.\n"); + m_logger.error("Error sending Initial Context Setup Request."); return false; } @@ -165,19 +163,19 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 struct in_addr addr; addr.s_addr = htonl(erab_ctx_req.transport_layer_address.to_number()); srslte::console("Sent Initial Context Setup Request. E-RAB id %d \n", erab_ctx_req.erab_id); - m_s1ap_log->info( - "Initial Context -- S1-U TEID 0x%" PRIx64 ". IP %s \n", erab_ctx_req.gtp_teid.to_number(), inet_ntoa(addr)); - m_s1ap_log->info("Initial Context Setup Request -- eNB UE S1AP Id %d, MME UE S1AP Id %" PRIu64 "\n", - in_ctx_req.enb_ue_s1ap_id.value.value, - in_ctx_req.mme_ue_s1ap_id.value.value); - m_s1ap_log->info("Initial Context Setup Request -- E-RAB id %d\n", erab_ctx_req.erab_id); - m_s1ap_log->info("Initial Context Setup Request -- S1-U TEID 0x%" PRIu64 ". IP %s \n", - erab_ctx_req.gtp_teid.to_number(), - inet_ntoa(addr)); - m_s1ap_log->info("Initial Context Setup Request -- S1-U TEID 0x%" PRIu64 ". IP %s \n", - erab_ctx_req.gtp_teid.to_number(), - inet_ntoa(addr)); - m_s1ap_log->info("Initial Context Setup Request -- QCI %d\n", erab_ctx_req.erab_level_qos_params.qci); + m_logger.info( + "Initial Context -- S1-U TEID 0x%" PRIx64 ". IP %s ", erab_ctx_req.gtp_teid.to_number(), inet_ntoa(addr)); + m_logger.info("Initial Context Setup Request -- eNB UE S1AP Id %d, MME UE S1AP Id %" PRIu64 "", + in_ctx_req.enb_ue_s1ap_id.value.value, + in_ctx_req.mme_ue_s1ap_id.value.value); + m_logger.info("Initial Context Setup Request -- E-RAB id %d", erab_ctx_req.erab_id); + m_logger.info("Initial Context Setup Request -- S1-U TEID 0x%" PRIu64 ". IP %s ", + erab_ctx_req.gtp_teid.to_number(), + inet_ntoa(addr)); + m_logger.info("Initial Context Setup Request -- S1-U TEID 0x%" PRIu64 ". IP %s ", + erab_ctx_req.gtp_teid.to_number(), + inet_ntoa(addr)); + m_logger.info("Initial Context Setup Request -- QCI %d", erab_ctx_req.erab_level_qos_params.qci); return true; } @@ -187,7 +185,7 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( uint32_t mme_ue_s1ap_id = in_ctxt_resp.protocol_ies.mme_ue_s1ap_id.value.value; nas* nas_ctx = m_s1ap->find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == nullptr) { - m_s1ap_log->error("Could not find UE's context in active UE's map\n"); + m_logger.error("Could not find UE's context in active UE's map"); return false; } @@ -199,7 +197,6 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( // Setup E-RABs for (const asn1::s1ap::protocol_ie_single_container_s& ie_container : in_ctxt_resp.protocol_ies.erab_setup_list_ctxt_su_res.value) { - // Get E-RAB setup context item and E-RAB Id const asn1::s1ap::erab_setup_item_ctxt_su_res_s& erab_setup_item_ctxt = ie_container.value.erab_setup_item_ctxt_su_res(); @@ -208,7 +205,7 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( // Make sure we requested the context setup esm_ctx_t* esm_ctx = &nas_ctx->m_esm_ctx[erab_id]; if (esm_ctx->state != ERAB_CTX_REQUESTED) { - m_s1ap_log->error("E-RAB requested was not previously requested %d\n", erab_id); + m_logger.error("E-RAB requested was not previously requested %d", erab_id); return false; } @@ -224,11 +221,11 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( tmp_addr.s_addr = esm_ctx->enb_fteid.ipv4; const char* err = inet_ntop(AF_INET, &tmp_addr, enb_addr_str, INET_ADDRSTRLEN); if (err == nullptr) { - m_s1ap_log->error("Error converting IP to string\n"); + m_logger.error("Error converting IP to string"); } - m_s1ap_log->info("E-RAB Context Setup. E-RAB id %d\n", esm_ctx->erab_id); - m_s1ap_log->info("E-RAB Context -- eNB TEID 0x%x, eNB Address %s\n", esm_ctx->enb_fteid.teid, enb_addr_str); + m_logger.info("E-RAB Context Setup. E-RAB id %d", esm_ctx->erab_id); + m_logger.info("E-RAB Context -- eNB TEID 0x%x, eNB Address %s", esm_ctx->enb_fteid.teid, enb_addr_str); srslte::console("E-RAB Context Setup. E-RAB id %d\n", esm_ctx->erab_id); srslte::console("E-RAB Context -- eNB TEID 0x%x; eNB GTP-U Address %s\n", esm_ctx->enb_fteid.teid, enb_addr_str); } @@ -245,12 +242,12 @@ bool s1ap_ctx_mngmt_proc::handle_ue_context_release_request(const asn1::s1ap::ue struct sctp_sndrcvinfo* enb_sri) { uint32_t mme_ue_s1ap_id = ue_rel.protocol_ies.mme_ue_s1ap_id.value.value; - m_s1ap_log->info("Received UE Context Release Request. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_logger.info("Received UE Context Release Request. MME-UE S1AP Id: %d", mme_ue_s1ap_id); srslte::console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); nas* nas_ctx = m_s1ap->find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == nullptr) { - m_s1ap_log->info("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_logger.info("No UE context to release found. MME-UE S1AP Id: %d", mme_ue_s1ap_id); srslte::console("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; } @@ -263,7 +260,7 @@ bool s1ap_ctx_mngmt_proc::handle_ue_context_release_request(const asn1::s1ap::ue send_ue_context_release_command(nas_ctx); } else { // No ECM Context to release - m_s1ap_log->info("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d\n", mme_ue_s1ap_id); + m_logger.info("UE is not ECM connected. No need to release S1-U. MME UE S1AP Id %d", mme_ue_s1ap_id); // Make sure E-RABS are marked as DEACTIVATED. for (esm_ctx_t& esm_ctx : nas_ctx->m_esm_ctx) { esm_ctx.state = ERAB_DEACTIVATED; @@ -280,8 +277,8 @@ bool s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas* nas_ctx) ecm_ctx_t* ecm_ctx = &nas_ctx->m_ecm_ctx; if (ecm_ctx->state != ECM_STATE_CONNECTED) { - m_s1ap_log->error("UE is not ECM connected. No send context release command. MME UE S1AP Id %d\n", - ecm_ctx->mme_ue_s1ap_id); + m_logger.error("UE is not ECM connected. No send context release command. MME UE S1AP Id %d", + ecm_ctx->mme_ue_s1ap_id); return false; } @@ -299,7 +296,7 @@ bool s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas* nas_ctx) if (active_erabs) { // There are active E-RABs, send release access mearers request srslte::console("There are active E-RABs, send release access bearers request\n"); - m_s1ap_log->info("There are active E-RABs, send release access bearers request\n"); + m_logger.info("There are active E-RABs, send release access bearers request"); // The handle_release_access_bearers_response function will make sure to mark E-RABS DEACTIVATED // It will release the UEs downstream S1-u and keep the upstream S1-U connection active. @@ -327,7 +324,7 @@ bool s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas* nas_ctx) // Send Reply to eNB if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &nas_ctx->m_ecm_ctx.enb_sri)) { - m_s1ap_log->error("Error sending UE Context Release Command.\n"); + m_logger.error("Error sending UE Context Release Command."); return false; } @@ -337,19 +334,19 @@ bool s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas* nas_ctx) bool s1ap_ctx_mngmt_proc::handle_ue_context_release_complete(const asn1::s1ap::ue_context_release_complete_s& rel_comp) { uint32_t mme_ue_s1ap_id = rel_comp.protocol_ies.mme_ue_s1ap_id.value.value; - m_s1ap_log->info("Received UE Context Release Complete. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_logger.info("Received UE Context Release Complete. MME-UE S1AP Id: %d", mme_ue_s1ap_id); srslte::console("Received UE Context Release Complete. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); nas* nas_ctx = m_s1ap->find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == nullptr) { - m_s1ap_log->info("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); + m_logger.info("No UE context to release found. MME-UE S1AP Id: %d", mme_ue_s1ap_id); srslte::console("No UE context to release found. MME-UE S1AP Id: %d\n", mme_ue_s1ap_id); return false; } // Delete UE context m_s1ap->release_ue_ecm_ctx(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); - m_s1ap_log->info("UE Context Release Completed.\n"); + m_logger.info("UE Context Release Completed."); srslte::console("UE Context Release Completed.\n"); return true; } diff --git a/srsepc/src/mme/s1ap_erab_mngmt_proc.cc b/srsepc/src/mme/s1ap_erab_mngmt_proc.cc index 5014542b4..4e95b42ff 100644 --- a/srsepc/src/mme/s1ap_erab_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_erab_mngmt_proc.cc @@ -65,9 +65,7 @@ void s1ap_erab_mngmt_proc::cleanup() void s1ap_erab_mngmt_proc::init() { m_s1ap = s1ap::get_instance(); - m_s1ap_log = m_s1ap->m_s1ap_log; m_s1ap_args = m_s1ap->m_s1ap_args; - m_pool = srslte::byte_buffer_pool::get_instance(); } bool s1ap_erab_mngmt_proc::send_erab_release_command(uint32_t enb_ue_s1ap_id, @@ -75,7 +73,7 @@ bool s1ap_erab_mngmt_proc::send_erab_release_command(uint32_t enb_ std::vector erabs_to_release, struct sctp_sndrcvinfo enb_sri) { - m_s1ap_log->info("Preparing to send E-RAB Release Command\n"); + m_logger.info("Preparing to send E-RAB Release Command"); // Prepare reply PDU s1ap_pdu_t tx_pdu; @@ -95,11 +93,11 @@ bool s1ap_erab_mngmt_proc::send_erab_release_command(uint32_t enb_ erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().cause.set(asn1::s1ap::cause_c::types::misc); erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().cause.misc() = asn1::s1ap::cause_misc_opts::unspecified; - m_s1ap_log->info("Sending release comman to %d\n", erabs_to_release[i]); + m_logger.info("Sending release comman to %d", erabs_to_release[i]); } if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &enb_sri)) { - m_s1ap_log->error("Error sending Initial Context Setup Request.\n"); + m_logger.error("Error sending Initial Context Setup Request."); return false; } return true; @@ -111,7 +109,7 @@ bool s1ap_erab_mngmt_proc::send_erab_modify_request(uint32_t srslte::byte_buffer_t* nas_msg, struct sctp_sndrcvinfo enb_sri) { - m_s1ap_log->info("Preparing to send E-RAB Modify Command\n"); + m_logger.info("Preparing to send E-RAB Modify Command"); // Prepare reply PDU s1ap_pdu_t tx_pdu; @@ -141,12 +139,12 @@ bool s1ap_erab_mngmt_proc::send_erab_modify_request(uint32_t asn1::s1ap::pre_emption_vulnerability_opts::not_pre_emptable; erab_to_mod.nas_pdu.resize(nas_msg->N_bytes); memcpy(erab_to_mod.nas_pdu.data(), nas_msg->msg, nas_msg->N_bytes); - m_s1ap_log->info("Sending release comman to E-RAB Id %d\n", erab_it->first); + m_logger.info("Sending release comman to E-RAB Id %d", erab_it->first); i++; } if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &enb_sri)) { - m_s1ap_log->error("Error sending Initial Context Setup Request.\n"); + m_logger.error("Error sending Initial Context Setup Request."); return false; } return true; diff --git a/srsepc/src/mme/s1ap_mngmt_proc.cc b/srsepc/src/mme/s1ap_mngmt_proc.cc index 8c38f4674..7783deebd 100644 --- a/srsepc/src/mme/s1ap_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_mngmt_proc.cc @@ -61,7 +61,6 @@ void s1ap_mngmt_proc::cleanup(void) void s1ap_mngmt_proc::init(void) { m_s1ap = s1ap::get_instance(); - m_s1ap_log = m_s1ap->m_s1ap_log; m_s1mme = m_s1ap->get_s1_mme(); m_s1ap_args = m_s1ap->m_s1ap_args; } @@ -70,25 +69,25 @@ bool s1ap_mngmt_proc::handle_s1_setup_request(const asn1::s1ap::s1_setup_request struct sctp_sndrcvinfo* enb_sri) { srslte::console("Received S1 Setup Request.\n"); - m_s1ap_log->info("Received S1 Setup Request.\n"); + m_logger.info("Received S1 Setup Request."); enb_ctx_t enb_ctx = {}; if (!unpack_s1_setup_request(msg, &enb_ctx)) { - m_s1ap_log->error("Malformed S1 Setup Request\n"); + m_logger.error("Malformed S1 Setup Request"); return false; } // Store SCTP sendrecv info memcpy(&enb_ctx.sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - m_s1ap_log->debug("eNB SCTP association Id: %d\n", enb_sri->sinfo_assoc_id); + m_logger.debug("eNB SCTP association Id: %d", enb_sri->sinfo_assoc_id); // Log S1 Setup Request Info m_s1ap->print_enb_ctx_info(std::string("S1 Setup Request"), enb_ctx); // Check for TAC match bool tac_match = false; - for (uint8_t tac : enb_ctx.tacs) { + for (uint16_t tac : enb_ctx.tacs) { if (m_s1ap->get_tac() == tac) { tac_match = true; break; @@ -98,18 +97,18 @@ bool s1ap_mngmt_proc::handle_s1_setup_request(const asn1::s1ap::s1_setup_request // Check matching PLMNs if (enb_ctx.plmn != m_s1ap->get_plmn()) { srslte::console("Sending S1 Setup Failure - Unknown PLMN\n"); - m_s1ap_log->warning("Sending S1 Setup Failure - Unknown PLMN\n"); + m_logger.warning("Sending S1 Setup Failure - Unknown PLMN"); send_s1_setup_failure(asn1::s1ap::cause_misc_opts::unknown_plmn, enb_sri); } else if (!tac_match) { srslte::console("Sending S1 Setup Failure - No matching TAC\n"); - m_s1ap_log->warning("Sending S1 Setup Failure - No matching TAC\n"); + m_logger.warning("Sending S1 Setup Failure - No matching TAC"); send_s1_setup_failure(asn1::s1ap::cause_misc_opts::unspecified, enb_sri); } else { enb_ctx_t* enb_ptr = m_s1ap->find_enb_ctx(enb_ctx.enb_id); if (enb_ptr != nullptr) { // eNB already registered // TODO replace enb_ctx - m_s1ap_log->warning("eNB Already registered\n"); + m_logger.warning("eNB Already registered"); } else { // new eNB m_s1ap->add_new_enb_ctx(enb_ctx, enb_sri); @@ -117,7 +116,7 @@ bool s1ap_mngmt_proc::handle_s1_setup_request(const asn1::s1ap::s1_setup_request send_s1_setup_response(m_s1ap_args, enb_sri); srslte::console("Sending S1 Setup Response\n"); - m_s1ap_log->info("Sending S1 Setup Response\n"); + m_logger.info("Sending S1 Setup Response"); } return true; } @@ -194,7 +193,7 @@ bool s1ap_mngmt_proc::send_s1_setup_failure(asn1::s1ap::cause_misc_opts::options bool s1ap_mngmt_proc::send_s1_setup_response(s1ap_args_t s1ap_args, struct sctp_sndrcvinfo* enb_sri) { - m_s1ap_log->debug("Sending S1 Setup Response\n"); + m_logger.debug("Sending S1 Setup Response"); s1ap_pdu_t tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_S1_SETUP); @@ -228,9 +227,9 @@ bool s1ap_mngmt_proc::send_s1_setup_response(s1ap_args_t s1ap_args, struct sctp_ s1_resp.relative_mme_capacity.value = 255; if (!m_s1ap->s1ap_tx_pdu(tx_pdu, enb_sri)) { - m_s1ap_log->error("Error sending S1 Setup Response.\n"); + m_logger.error("Error sending S1 Setup Response."); } else { - m_s1ap_log->debug("S1 Setup Response sent\n"); + m_logger.debug("S1 Setup Response sent"); } return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index d0ac41219..0801c3281 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -65,9 +65,7 @@ void s1ap_nas_transport::cleanup(void) void s1ap_nas_transport::init() { - m_s1ap = s1ap::get_instance(); - m_s1ap_log = m_s1ap->m_s1ap_log; - m_pool = srslte::byte_buffer_pool::get_instance(); + m_s1ap = s1ap::get_instance(); // Init NAS args m_nas_init.mcc = m_s1ap->m_s1ap_args.mcc; @@ -91,19 +89,19 @@ void s1ap_nas_transport::init() bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg_s& init_ue, struct sctp_sndrcvinfo* enb_sri) { - bool err, mac_valid; - uint8_t pd, msg_type, sec_hdr_type; - srslte::byte_buffer_t* nas_msg = m_pool->allocate(); + bool err, mac_valid; + uint8_t pd, msg_type, sec_hdr_type; + srslte::unique_byte_buffer_t nas_msg = srslte::make_byte_buffer(); memcpy(nas_msg->msg, init_ue.protocol_ies.nas_pdu.value.data(), init_ue.protocol_ies.nas_pdu.value.size()); nas_msg->N_bytes = init_ue.protocol_ies.nas_pdu.value.size(); uint64_t imsi = 0; uint32_t m_tmsi = 0; uint32_t enb_ue_s1ap_id = init_ue.protocol_ies.enb_ue_s1ap_id.value.value; - liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &msg_type); + liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type); srslte::console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); - m_s1ap_log->info("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); + m_logger.info("Initial UE message: %s", liblte_nas_msg_type_to_string(msg_type)); if (init_ue.protocol_ies.s_tmsi_present) { srslte::uint8_to_uint32(init_ue.protocol_ies.s_tmsi.value.m_tmsi.data(), &m_tmsi); @@ -112,33 +110,30 @@ bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: srslte::console("Received Initial UE message -- Attach Request\n"); - m_s1ap_log->info("Received Initial UE message -- Attach Request\n"); - err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); + m_logger.info("Received Initial UE message -- Attach Request"); + err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if); break; case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: srslte::console("Received Initial UE message -- Service Request\n"); - m_s1ap_log->info("Received Initial UE message -- Service Request\n"); - err = nas::handle_service_request( - m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); + m_logger.info("Received Initial UE message -- Service Request"); + err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if); break; case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: srslte::console("Received Initial UE message -- Detach Request\n"); - m_s1ap_log->info("Received Initial UE message -- Detach Request\n"); - err = - nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); + m_logger.info("Received Initial UE message -- Detach Request"); + err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if); break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: srslte::console("Received Initial UE message -- Tracking Area Update Request\n"); - m_s1ap_log->info("Received Initial UE message -- Tracking Area Update Request\n"); + m_logger.info("Received Initial UE message -- Tracking Area Update Request"); err = nas::handle_tracking_area_update_request( - m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, m_nas_init, m_nas_if, m_s1ap->m_nas_log); + m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg.get(), m_nas_init, m_nas_if); break; default: - m_s1ap_log->info("Unhandled Initial UE Message 0x%x \n", msg_type); + m_logger.info("Unhandled Initial UE Message 0x%x ", msg_type); srslte::console("Unhandled Initial UE Message 0x%x \n", msg_type); err = false; } - m_pool->deallocate(nas_msg); return err; } @@ -154,23 +149,23 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr // Get UE NAS context nas* nas_ctx = m_s1ap->find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == nullptr) { - m_s1ap_log->warning("Received uplink NAS, but could not find UE NAS context. MME-UE S1AP id: %d\n", mme_ue_s1ap_id); + m_logger.warning("Received uplink NAS, but could not find UE NAS context. MME-UE S1AP id: %d", mme_ue_s1ap_id); return false; } - m_s1ap_log->debug("Received uplink NAS and found UE NAS context. MME-UE S1AP id: %d\n", mme_ue_s1ap_id); + m_logger.debug("Received uplink NAS and found UE NAS context. MME-UE S1AP id: %d", mme_ue_s1ap_id); emm_ctx_t* emm_ctx = &nas_ctx->m_emm_ctx; ecm_ctx_t* ecm_ctx = &nas_ctx->m_ecm_ctx; sec_ctx_t* sec_ctx = &nas_ctx->m_sec_ctx; // Parse NAS message header - srslte::byte_buffer_t* nas_msg = m_pool->allocate(); + srslte::unique_byte_buffer_t nas_msg = srslte::make_byte_buffer(); memcpy(nas_msg->msg, ul_xport.protocol_ies.nas_pdu.value.data(), ul_xport.protocol_ies.nas_pdu.value.size()); nas_msg->N_bytes = ul_xport.protocol_ies.nas_pdu.value.size(); bool msg_encrypted = false; // Parse the message security header - liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); + liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &sec_hdr_type); // Invalid Security Header Type simply return function if (!(sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS || @@ -178,8 +173,7 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT)) { - m_s1ap_log->error("Unhandled security header type in Uplink NAS Transport: %d\n", sec_hdr_type); - m_pool->deallocate(nas_msg); + m_logger.error("Unhandled security header type in Uplink NAS Transport: %d", sec_hdr_type); return false; } // Todo: Check on count mismatch of uplink count and do resync nas counter... @@ -189,24 +183,24 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { - mac_valid = nas_ctx->integrity_check(nas_msg); + mac_valid = nas_ctx->integrity_check(nas_msg.get()); if (mac_valid == false) { - m_s1ap_log->warning("Invalid MAC message. Even if security header indicates integrity protection (Maybe: " - "Identity Response or Authentication Response)\n"); + m_logger.warning("Invalid MAC message. Even if security header indicates integrity protection (Maybe: " + "Identity Response or Authentication Response)"); } } // Decrypt message if indicated if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { - m_s1ap_log->debug_hex(nas_msg->msg, nas_msg->N_bytes, "Encrypted"); - nas_ctx->cipher_decrypt(nas_msg); + m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Encrypted"); + nas_ctx->cipher_decrypt(nas_msg.get()); msg_encrypted = true; - m_s1ap_log->debug_hex(nas_msg->msg, nas_msg->N_bytes, "Decrypted"); + m_logger.debug(nas_msg->msg, nas_msg->N_bytes, "Decrypted"); } // Now parse message header and handle message - liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &msg_type); + liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type); // Find UE EMM context if message is security protected. if (sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { @@ -216,10 +210,9 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr // This can happen with integrity protected identity reponse messages if (!(msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE && sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { - m_s1ap_log->warning( - "Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %d\n", + m_logger.warning( + "Uplink NAS: could not find security context for integrity protected message. MME-UE S1AP id: %d", mme_ue_s1ap_id); - m_pool->deallocate(nas_msg); return false; } } @@ -236,26 +229,26 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr // - DETACH REQUEST; // - DETACH ACCEPT; // - TRACKING AREA UPDATE REQUEST. - m_s1ap_log->info("UL NAS: sec_hdr_type: %s, mac_vaild: %s, msg_encrypted: %s\n", - liblte_nas_sec_hdr_type_to_string(sec_hdr_type), - mac_valid == true ? "yes" : "no", - msg_encrypted == true ? "yes" : "no"); + m_logger.info("UL NAS: sec_hdr_type: %s, mac_vaild: %s, msg_encrypted: %s", + liblte_nas_sec_hdr_type_to_string(sec_hdr_type), + mac_valid == true ? "yes" : "no", + msg_encrypted == true ? "yes" : "no"); switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: - m_s1ap_log->info("UL NAS: Attach Request\n"); + m_logger.info("UL NAS: Attach Request"); srslte::console("UL NAS: Attach Resquest\n"); - nas_ctx->handle_attach_request(nas_msg); + nas_ctx->handle_attach_request(nas_msg.get()); break; case LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE: - m_s1ap_log->info("UL NAS: Received Identity Response\n"); + m_logger.info("UL NAS: Received Identity Response"); srslte::console("UL NAS: Received Identity Response\n"); - nas_ctx->handle_identity_response(nas_msg); + nas_ctx->handle_identity_response(nas_msg.get()); break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE: - m_s1ap_log->info("UL NAS: Received Authentication Response\n"); + m_logger.info("UL NAS: Received Authentication Response"); srslte::console("UL NAS: Received Authentication Response\n"); - nas_ctx->handle_authentication_response(nas_msg); + nas_ctx->handle_authentication_response(nas_msg.get()); // In case of a successful authentication response, security mode command follows. // Reset counter for incoming security mode complete sec_ctx->ul_nas_count = 0; @@ -264,67 +257,66 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr break; // Authentication failure with the option sync failure can be sent not integrity protected case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_FAILURE: - m_s1ap_log->info("UL NAS: Authentication Failure\n"); + m_logger.info("UL NAS: Authentication Failure"); srslte::console("UL NAS: Authentication Failure\n"); - nas_ctx->handle_authentication_failure(nas_msg); + nas_ctx->handle_authentication_failure(nas_msg.get()); break; // Detach request can be sent not integrity protected when "power off" option is used case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: - m_s1ap_log->info("UL NAS: Detach Request\n"); + m_logger.info("UL NAS: Detach Request"); srslte::console("UL NAS: Detach Request\n"); // TODO: check integrity protection in detach request - nas_ctx->handle_detach_request(nas_msg); + nas_ctx->handle_detach_request(nas_msg.get()); break; case LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMPLETE: - m_s1ap_log->info("UL NAS: Received Security Mode Complete\n"); + m_logger.info("UL NAS: Received Security Mode Complete"); srslte::console("UL NAS: Received Security Mode Complete\n"); if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT && mac_valid == true) { - nas_ctx->handle_security_mode_complete(nas_msg); + nas_ctx->handle_security_mode_complete(nas_msg.get()); } else { // Security Mode Complete was not integrity protected srslte::console("Security Mode Complete %s. Discard message.\n", - (mac_valid ? "not integrity protected" : "invalid integrity")); - m_s1ap_log->warning("Security Mode Complete %s. Discard message.\n", - (mac_valid ? "not integrity protected" : "invalid integrity")); + (mac_valid ? "not integrity protected" : "invalid integrity")); + m_logger.warning("Security Mode Complete %s. Discard message.", + (mac_valid ? "not integrity protected" : "invalid integrity")); increase_ul_nas_cnt = false; } break; case LIBLTE_MME_MSG_TYPE_ATTACH_COMPLETE: - m_s1ap_log->info("UL NAS: Received Attach Complete\n"); + m_logger.info("UL NAS: Received Attach Complete"); srslte::console("UL NAS: Received Attach Complete\n"); if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) { - nas_ctx->handle_attach_complete(nas_msg); + nas_ctx->handle_attach_complete(nas_msg.get()); } else { // Attach Complete was not integrity protected srslte::console("Attach Complete not integrity protected. Discard message.\n"); - m_s1ap_log->warning("Attach Complete not integrity protected. Discard message.\n"); + m_logger.warning("Attach Complete not integrity protected. Discard message."); increase_ul_nas_cnt = false; } break; case LIBLTE_MME_MSG_TYPE_ESM_INFORMATION_RESPONSE: - m_s1ap_log->info("UL NAS: Received ESM Information Response\n"); + m_logger.info("UL NAS: Received ESM Information Response"); srslte::console("UL NAS: Received ESM Information Response\n"); if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && mac_valid == true) { - nas_ctx->handle_esm_information_response(nas_msg); + nas_ctx->handle_esm_information_response(nas_msg.get()); } else { // Attach Complete was not integrity protected srslte::console("ESM Information Response %s. Discard message.\n", - (mac_valid ? "not integrity protected" : "invalid integrity")); - m_s1ap_log->warning("ESM Information Response %s. Discard message.\n", - (mac_valid ? "not integrity protected" : "invalid integrity")); + (mac_valid ? "not integrity protected" : "invalid integrity")); + m_logger.warning("ESM Information Response %s. Discard message.", + (mac_valid ? "not integrity protected" : "invalid integrity")); increase_ul_nas_cnt = false; } break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: - m_s1ap_log->info("UL NAS: Tracking Area Update Request\n"); + m_logger.info("UL NAS: Tracking Area Update Request"); srslte::console("UL NAS: Tracking Area Update Request\n"); - nas_ctx->handle_tracking_area_update_request(nas_msg); + nas_ctx->handle_tracking_area_update_request(nas_msg.get()); break; default: - m_s1ap_log->warning("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type)); + m_logger.warning("Unhandled NAS integrity protected message %s", liblte_nas_msg_type_to_string(msg_type)); srslte::console("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type)); - m_pool->deallocate(nas_msg); return false; } @@ -333,7 +325,6 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr if (increase_ul_nas_cnt == true) { sec_ctx->ul_nas_count++; } - m_pool->deallocate(nas_msg); return true; } @@ -342,10 +333,10 @@ bool s1ap_nas_transport::send_downlink_nas_transport(uint32_t enb_ srslte::byte_buffer_t* nas_msg, struct sctp_sndrcvinfo enb_sri) { - m_s1ap_log->debug("Sending message to eNB with SCTP association %d. MME UE S1AP ID %d, eNB UE S1AP ID %d\n", - enb_sri.sinfo_assoc_id, - mme_ue_s1ap_id, - enb_ue_s1ap_id); + m_logger.debug("Sending message to eNB with SCTP association %d. MME UE S1AP ID %d, eNB UE S1AP ID %d", + enb_sri.sinfo_assoc_id, + mme_ue_s1ap_id, + enb_ue_s1ap_id); // Setup initiating message s1ap_pdu_t tx_pdu; diff --git a/srsepc/src/mme/s1ap_paging.cc b/srsepc/src/mme/s1ap_paging.cc index b13f39b6b..36604d18a 100644 --- a/srsepc/src/mme/s1ap_paging.cc +++ b/srsepc/src/mme/s1ap_paging.cc @@ -37,14 +37,12 @@ void s1ap_paging::init() { m_s1ap = s1ap::get_instance(); m_mme = mme::get_instance(); - m_s1ap_log = m_s1ap->m_s1ap_log; m_s1ap_args = m_s1ap->m_s1ap_args; - m_pool = srslte::byte_buffer_pool::get_instance(); } bool s1ap_paging::send_paging(uint64_t imsi, uint16_t erab_to_setup) { - m_s1ap_log->info("Preparing to Page UE -- IMSI %015" PRIu64 "\n", imsi); + m_logger.info("Preparing to Page UE -- IMSI %015" PRIu64 "", imsi); // Prepare reply PDU s1ap_pdu_t tx_pdu; @@ -54,7 +52,7 @@ bool s1ap_paging::send_paging(uint64_t imsi, uint16_t erab_to_setup) // Getting UE NAS Context nas* nas_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); if (nas_ctx == nullptr) { - m_s1ap_log->error("Could not find UE to page NAS context\n"); + m_logger.error("Could not find UE to page NAS context"); return false; } @@ -82,7 +80,7 @@ bool s1ap_paging::send_paging(uint64_t imsi, uint16_t erab_to_setup) // Start T3413 if (!nas_ctx->start_timer(T_3413)) { - m_s1ap_log->error("Could not start T3413 -- Aborting paging\n"); + m_logger.error("Could not start T3413 -- Aborting paging"); // TODO Send data notification failure to SPGW return false; } @@ -91,7 +89,7 @@ bool s1ap_paging::send_paging(uint64_t imsi, uint16_t erab_to_setup) it++) { enb_ctx_t* enb_ctx = it->second; if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &enb_ctx->sri)) { - m_s1ap_log->error("Error paging to eNB. eNB Id: 0x%x.\n", enb_ctx->enb_id); + m_logger.error("Error paging to eNB. eNB Id: 0x%x.", enb_ctx->enb_id); return false; } } diff --git a/srsepc/src/spgw/gtpc.cc b/srsepc/src/spgw/gtpc.cc index 090a14175..2b543177f 100644 --- a/srsepc/src/spgw/gtpc.cc +++ b/srsepc/src/spgw/gtpc.cc @@ -54,14 +54,9 @@ spgw::gtpc::~gtpc() int spgw::gtpc::init(spgw_args_t* args, spgw* spgw, gtpu_interface_gtpc* gtpu, - srslte::log_filter* gtpc_log, const std::map& ip_to_imsi) { int err; - m_pool = srslte::byte_buffer_pool::get_instance(); - - // Init log - m_gtpc_log = gtpc_log; // Init interfaces m_spgw = spgw; @@ -84,7 +79,7 @@ int spgw::gtpc::init(spgw_args_t* args, // Limit paging queue m_max_paging_queue = args->max_paging_queue; - m_gtpc_log->info("SPGW S11 Initialized.\n"); + m_logger.info("SPGW S11 Initialized."); srslte::console("SPGW S11 Initialized.\n"); return 0; } @@ -93,7 +88,7 @@ void spgw::gtpc::stop() { std::map::iterator it = m_teid_to_tunnel_ctx.begin(); while (it != m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->info("Deleting SP-GW GTP-C Tunnel. IMSI: %015" PRIu64 "\n", it->second->imsi); + m_logger.info("Deleting SP-GW GTP-C Tunnel. IMSI: %015" PRIu64 "", it->second->imsi); srslte::console("Deleting SP-GW GTP-C Tunnel. IMSI: %015" PRIu64 "\n", it->second->imsi); delete it->second; m_teid_to_tunnel_ctx.erase(it++); @@ -108,12 +103,12 @@ int spgw::gtpc::init_s11(spgw_args_t* args) char mme_addr_name[] = "@mme_s11"; // Logs - m_gtpc_log->info("Initializing SPGW S11 interface.\n"); + m_logger.info("Initializing SPGW S11 interface."); // Open Socket m_s11 = socket(AF_UNIX, SOCK_DGRAM, 0); if (m_s11 < 0) { - m_gtpc_log->error("Error opening UNIX socket. Error %s\n", strerror(errno)); + m_logger.error("Error opening UNIX socket. Error %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } @@ -131,7 +126,7 @@ int spgw::gtpc::init_s11(spgw_args_t* args) // Bind socket to address if (bind(m_s11, (const struct sockaddr*)&m_spgw_addr, sizeof(m_spgw_addr)) == -1) { - m_gtpc_log->error("Error binding UNIX socket. Error %s\n", strerror(errno)); + m_logger.error("Error binding UNIX socket. Error %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } return SRSLTE_SUCCESS; @@ -139,16 +134,16 @@ int spgw::gtpc::init_s11(spgw_args_t* args) bool spgw::gtpc::send_s11_pdu(const srslte::gtpc_pdu& pdu) { - m_gtpc_log->debug("SPGW Sending S11 PDU! N_Bytes: %zd\n", sizeof(pdu)); + m_logger.debug("SPGW Sending S11 PDU! N_Bytes: %zd", sizeof(pdu)); // TODO add serialization code here // Send S11 message to MME int n = sendto(m_s11, &pdu, sizeof(pdu), 0, (const sockaddr*)&m_mme_addr, sizeof(m_mme_addr)); if (n < 0) { - m_gtpc_log->error("Error sending to socket. Error %s", strerror(errno)); + m_logger.error("Error sending to socket. Error %s", strerror(errno)); return false; } else { - m_gtpc_log->debug("SPGW S11 Sent %d Bytes.\n", n); + m_logger.debug("SPGW S11 Sent %d Bytes.", n); } return true; } @@ -158,7 +153,7 @@ void spgw::gtpc::handle_s11_pdu(srslte::byte_buffer_t* msg) // TODO add deserialization code here srslte::gtpc_pdu* pdu = (srslte::gtpc_pdu*)msg->msg; srslte::console("Received GTP-C PDU. Message type: %s\n", srslte::gtpc_msg_type_to_str(pdu->header.type)); - m_gtpc_log->debug("Received GTP-C PDU. Message type: %s\n", srslte::gtpc_msg_type_to_str(pdu->header.type)); + m_logger.debug("Received GTP-C PDU. Message type: %s", srslte::gtpc_msg_type_to_str(pdu->header.type)); switch (pdu->header.type) { case srslte::GTPC_MSG_TYPE_CREATE_SESSION_REQUEST: handle_create_session_request(pdu->choice.create_session_request); @@ -180,14 +175,14 @@ void spgw::gtpc::handle_s11_pdu(srslte::byte_buffer_t* msg) pdu->choice.downlink_data_notification_failure_indication); break; default: - m_gtpc_log->error("Unhandled GTP-C message type\n"); + m_logger.error("Unhandled GTP-C message type"); } return; } void spgw::gtpc::handle_create_session_request(const struct srslte::gtpc_create_session_request& cs_req) { - m_gtpc_log->info("SPGW Received Create Session Request\n"); + m_logger.info("SPGW Received Create Session Request"); spgw_tunnel_ctx_t* tunnel_ctx; int default_bearer_id = 5; // Check if IMSI has active GTP-C and/or GTP-U @@ -198,7 +193,7 @@ void spgw::gtpc::handle_create_session_request(const struct srslte::gtpc_create_ srslte::console("SPGW: Deleted previous context.\n"); } - m_gtpc_log->info("Creating new GTP-C context\n"); + m_logger.info("Creating new GTP-C context"); tunnel_ctx = create_gtpc_ctx(cs_req); // Create session response message @@ -232,7 +227,7 @@ void spgw::gtpc::handle_create_session_request(const struct srslte::gtpc_create_ cs_resp->paa.pdn_type = srslte::GTPC_PDN_TYPE_IPV4; cs_resp->paa.ipv4_present = true; cs_resp->paa.ipv4 = tunnel_ctx->ue_ipv4; - m_gtpc_log->info("Sending Create Session Response\n"); + m_logger.info("Sending Create Session Response"); // Send Create session response to MME send_s11_pdu(cs_resp_pdu); @@ -242,13 +237,13 @@ void spgw::gtpc::handle_create_session_request(const struct srslte::gtpc_create_ void spgw::gtpc::handle_modify_bearer_request(const struct srslte::gtpc_header& mb_req_hdr, const struct srslte::gtpc_modify_bearer_request& mb_req) { - m_gtpc_log->info("Received Modified Bearer Request\n"); + m_logger.info("Received Modified Bearer Request"); // Get control tunnel info from mb_req PDU uint32_t ctrl_teid = mb_req_hdr.teid; std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); if (tunnel_it == m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->warning("Could not find TEID %d to modify\n", ctrl_teid); + m_logger.warning("Could not find TEID %d to modify", ctrl_teid); return; } spgw_tunnel_ctx_t* tunnel_ctx = tunnel_it->second; @@ -257,22 +252,21 @@ void spgw::gtpc::handle_modify_bearer_request(const struct srslte::gtpc_header& tunnel_ctx->dw_user_fteid.teid = mb_req.eps_bearer_context_to_modify.s1_u_enb_f_teid.teid; tunnel_ctx->dw_user_fteid.ipv4 = mb_req.eps_bearer_context_to_modify.s1_u_enb_f_teid.ipv4; // Set up actual tunnel - m_gtpc_log->info("Setting Up GTP-U tunnel. Tunnel info: \n"); + m_logger.info("Setting Up GTP-U tunnel. Tunnel info: "); struct in_addr addr; addr.s_addr = tunnel_ctx->ue_ipv4; - m_gtpc_log->info("IMSI: %015" PRIu64 ", UE IP: %s \n", tunnel_ctx->imsi, inet_ntoa(addr)); - m_gtpc_log->info("S-GW Rx Ctrl TEID 0x%x, MME Rx Ctrl TEID 0x%x\n", - tunnel_ctx->up_ctrl_fteid.teid, - tunnel_ctx->dw_ctrl_fteid.teid); - m_gtpc_log->info("S-GW Rx Ctrl IP (NA), MME Rx Ctrl IP (NA)\n"); + m_logger.info("IMSI: %015" PRIu64 ", UE IP: %s ", tunnel_ctx->imsi, inet_ntoa(addr)); + m_logger.info( + "S-GW Rx Ctrl TEID 0x%x, MME Rx Ctrl TEID 0x%x", tunnel_ctx->up_ctrl_fteid.teid, tunnel_ctx->dw_ctrl_fteid.teid); + m_logger.info("S-GW Rx Ctrl IP (NA), MME Rx Ctrl IP (NA)"); struct in_addr addr2; addr2.s_addr = tunnel_ctx->up_user_fteid.ipv4; - m_gtpc_log->info("S-GW Rx User TEID 0x%x, S-GW Rx User IP %s\n", tunnel_ctx->up_user_fteid.teid, inet_ntoa(addr2)); + m_logger.info("S-GW Rx User TEID 0x%x, S-GW Rx User IP %s", tunnel_ctx->up_user_fteid.teid, inet_ntoa(addr2)); struct in_addr addr3; addr3.s_addr = tunnel_ctx->dw_user_fteid.ipv4; - m_gtpc_log->info("eNB Rx User TEID 0x%x, eNB Rx User IP %s\n", tunnel_ctx->dw_user_fteid.teid, inet_ntoa(addr3)); + m_logger.info("eNB Rx User TEID 0x%x, eNB Rx User IP %s", tunnel_ctx->dw_user_fteid.teid, inet_ntoa(addr3)); // Setup IP to F-TEID map m_gtpu->modify_gtpu_tunnel(tunnel_ctx->ue_ipv4, tunnel_ctx->dw_user_fteid, tunnel_ctx->up_ctrl_fteid.teid); @@ -280,7 +274,7 @@ void spgw::gtpc::handle_modify_bearer_request(const struct srslte::gtpc_header& // Mark paging as done & send queued packets if (tunnel_ctx->paging_pending == true) { tunnel_ctx->paging_pending = false; - m_gtpc_log->debug("Modify Bearer Request received after Downling Data Notification was sent\n"); + m_logger.debug("Modify Bearer Request received after Downling Data Notification was sent"); srslte::console("Modify Bearer Request received after Downling Data Notification was sent\n"); m_gtpu->send_all_queued_packets(tunnel_ctx->dw_user_fteid, tunnel_ctx->paging_queue); } @@ -312,7 +306,7 @@ void spgw::gtpc::handle_delete_session_request(const srslte::gtpc_header& uint32_t ctrl_teid = header.teid; std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); if (tunnel_it == m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->warning("Could not find TEID 0x%x to delete session\n", ctrl_teid); + m_logger.warning("Could not find TEID 0x%x to delete session", ctrl_teid); return; } spgw_tunnel_ctx_t* tunnel_ctx = tunnel_it->second; @@ -329,7 +323,7 @@ void spgw::gtpc::handle_release_access_bearers_request(const srslte::gtpc_header uint32_t ctrl_teid = header.teid; std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); if (tunnel_it == m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->warning("Could not find TEID 0x%x to release bearers\n", ctrl_teid); + m_logger.warning("Could not find TEID 0x%x to release bearers", ctrl_teid); return; } spgw_tunnel_ctx_t* tunnel_ctx = tunnel_it->second; @@ -342,7 +336,7 @@ void spgw::gtpc::handle_release_access_bearers_request(const srslte::gtpc_header bool spgw::gtpc::send_downlink_data_notification(uint32_t spgw_ctr_teid) { - m_gtpc_log->debug("Sending Downlink Notification Request\n"); + m_logger.debug("Sending Downlink Notification Request"); struct srslte::gtpc_pdu dl_not_pdu; std::memset(&dl_not_pdu, 0, sizeof(dl_not_pdu)); @@ -352,14 +346,14 @@ bool spgw::gtpc::send_downlink_data_notification(uint32_t spgw_ctr_teid) // Find MME Ctrl TEID std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(spgw_ctr_teid); if (tunnel_it == m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->warning("Could not find TEID 0x%x to send downlink notification.\n", spgw_ctr_teid); + m_logger.warning("Could not find TEID 0x%x to send downlink notification.", spgw_ctr_teid); return false; } spgw_tunnel_ctx_t* tunnel_ctx = tunnel_it->second; // Check if there is no Paging already pending. if (tunnel_ctx->paging_pending == true) { - m_gtpc_log->debug("UE Downlink Data Notification still pending.\n"); + m_logger.debug("UE Downlink Data Notification still pending."); return false; } @@ -385,13 +379,13 @@ void spgw::gtpc::handle_downlink_data_notification_acknowledge( const srslte::gtpc_header& header, const srslte::gtpc_downlink_data_notification_acknowledge& not_ack) { - m_gtpc_log->debug("Handling downlink data notification acknowledge\n"); + m_logger.debug("Handling downlink data notification acknowledge"); // Find tunel ctxt uint32_t ctrl_teid = header.teid; std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); if (tunnel_it == m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->warning("Could not find TEID 0x%x to handle notification acknowldge\n", ctrl_teid); + m_logger.warning("Could not find TEID 0x%x to handle notification acknowldge", ctrl_teid); return; } spgw_tunnel_ctx_t* tunnel_ctx = tunnel_it->second; @@ -399,11 +393,11 @@ void spgw::gtpc::handle_downlink_data_notification_acknowledge( not_ack.cause.cause_value == srslte::GTPC_CAUSE_VALUE_UE_ALREADY_RE_ATTACHED || not_ack.cause.cause_value == srslte::GTPC_CAUSE_VALUE_UNABLE_TO_PAGE_UE || not_ack.cause.cause_value == srslte::GTPC_CAUSE_VALUE_UNABLE_TO_PAGE_UE_DUE_TO_SUSPENSION) { - m_gtpc_log->warning("Downlink Data Notification Acknowledge indicates failure.\n"); + m_logger.warning("Downlink Data Notification Acknowledge indicates failure."); free_all_queued_packets(tunnel_ctx); tunnel_ctx->paging_pending = false; } else if (not_ack.cause.cause_value != srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED) { - m_gtpc_log->warning("Invalid cause in Downlink Data Notification Acknowledge.\n"); + m_logger.warning("Invalid cause in Downlink Data Notification Acknowledge."); free_all_queued_packets(tunnel_ctx); tunnel_ctx->paging_pending = false; } @@ -414,12 +408,12 @@ void spgw::gtpc::handle_downlink_data_notification_failure_indication( const srslte::gtpc_header& header, const srslte::gtpc_downlink_data_notification_failure_indication& not_fail) { - m_gtpc_log->debug("Handling downlink data notification failure indication\n"); + m_logger.debug("Handling downlink data notification failure indication"); // Find tunel ctxt uint32_t ctrl_teid = header.teid; std::map::iterator tunnel_it = m_teid_to_tunnel_ctx.find(ctrl_teid); if (tunnel_it == m_teid_to_tunnel_ctx.end()) { - m_gtpc_log->warning("Could not find TEID 0x%x to handle notification failure indication\n", ctrl_teid); + m_logger.warning("Could not find TEID 0x%x to handle notification failure indication", ctrl_teid); return; } @@ -427,10 +421,9 @@ void spgw::gtpc::handle_downlink_data_notification_failure_indication( if (not_fail.cause.cause_value == srslte::GTPC_CAUSE_VALUE_UE_NOT_RESPONDING || not_fail.cause.cause_value == srslte::GTPC_CAUSE_VALUE_SERVICE_DENIED || not_fail.cause.cause_value == srslte::GTPC_CAUSE_VALUE_UE_ALREADY_RE_ATTACHED) { - m_gtpc_log->debug("Downlink Data Notification failure indication cause: %d.\n", not_fail.cause.cause_value); + m_logger.debug("Downlink Data Notification failure indication cause: %d.", not_fail.cause.cause_value); } else { - m_gtpc_log->warning("Invalid cause in Downlink Data Notification Failure Indication %d\n", - not_fail.cause.cause_value); + m_logger.warning("Invalid cause in Downlink Data Notification Failure Indication %d", not_fail.cause.cause_value); } free_all_queued_packets(tunnel_ctx); tunnel_ctx->paging_pending = false; @@ -480,7 +473,7 @@ bool spgw::gtpc::delete_gtpc_ctx(uint32_t ctrl_teid) { spgw_tunnel_ctx_t* tunnel_ctx; if (!m_teid_to_tunnel_ctx.count(ctrl_teid)) { - m_gtpc_log->error("Could not find GTP context to delete.\n"); + m_logger.error("Could not find GTP context to delete."); return false; } tunnel_ctx = m_teid_to_tunnel_ctx[ctrl_teid]; @@ -500,46 +493,43 @@ bool spgw::gtpc::delete_gtpc_ctx(uint32_t ctrl_teid) /* * Queueing functions */ -bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::byte_buffer_t* msg) +bool spgw::gtpc::queue_downlink_packet(uint32_t ctrl_teid, srslte::unique_byte_buffer_t msg) { spgw_tunnel_ctx_t* tunnel_ctx; if (!m_teid_to_tunnel_ctx.count(ctrl_teid)) { - m_gtpc_log->error("Could not find GTP context to queue.\n"); + m_logger.error("Could not find GTP context to queue."); goto pkt_discard; } tunnel_ctx = m_teid_to_tunnel_ctx[ctrl_teid]; if (!tunnel_ctx->paging_pending) { - m_gtpc_log->error("Paging not pending. Not queueing packet\n"); + m_logger.error("Paging not pending. Not queueing packet"); goto pkt_discard; } if (tunnel_ctx->paging_queue.size() < m_max_paging_queue) { - tunnel_ctx->paging_queue.push(msg); - m_gtpc_log->debug( - "Queued packet. IMSI %" PRIu64 ", Packets in Queue %zd\n", tunnel_ctx->imsi, tunnel_ctx->paging_queue.size()); + tunnel_ctx->paging_queue.push(std::move(msg)); + m_logger.debug( + "Queued packet. IMSI %" PRIu64 ", Packets in Queue %zd", tunnel_ctx->imsi, tunnel_ctx->paging_queue.size()); } else { - m_gtpc_log->debug("Paging queue full. IMSI %" PRIu64 ", Packets in Queue %zd\n", - tunnel_ctx->imsi, - tunnel_ctx->paging_queue.size()); + m_logger.debug( + "Paging queue full. IMSI %" PRIu64 ", Packets in Queue %zd", tunnel_ctx->imsi, tunnel_ctx->paging_queue.size()); goto pkt_discard; } return true; pkt_discard: - m_pool->deallocate(msg); return false; } bool spgw::gtpc::free_all_queued_packets(spgw_tunnel_ctx_t* tunnel_ctx) { if (!tunnel_ctx->paging_pending) { - m_gtpc_log->warning("Freeing queue with paging not pending.\n"); + m_logger.warning("Freeing queue with paging not pending."); } while (!tunnel_ctx->paging_queue.empty()) { - srslte::byte_buffer_t* pkt = tunnel_ctx->paging_queue.front(); - m_gtpc_log->debug("Dropping packet. Bytes %d\n", pkt->N_bytes); - m_pool->deallocate(pkt); + srslte::unique_byte_buffer_t pkt = std::move(tunnel_ctx->paging_queue.front()); + m_logger.debug("Dropping packet. Bytes %d", pkt->N_bytes); tunnel_ctx->paging_queue.pop(); } return true; @@ -551,9 +541,9 @@ int spgw::gtpc::init_ue_ip(spgw_args_t* args, const std::maperror("SPGW: static ip addr %s for imsi %015" PRIu64 ", is reserved for the epc tun interface\n", - iter->first.c_str(), - iter->second); + m_logger.error("SPGW: static ip addr %s for imsi %015" PRIu64 ", is reserved for the epc tun interface", + iter->first.c_str(), + iter->second); return SRSLTE_ERROR_OUT_OF_BOUNDS; } @@ -562,8 +552,8 @@ int spgw::gtpc::init_ue_ip(spgw_args_t* args, const std::mapfirst.c_str()); if (!m_imsi_to_ip.insert(std::make_pair(iter->second, in_addr)).second) { - m_gtpc_log->error( - "SPGW: duplicate imsi %015" PRIu64 " for static ip address %s.\n", iter->second, iter->first.c_str()); + m_logger.error( + "SPGW: duplicate imsi %015" PRIu64 " for static ip address %s.", iter->second, iter->first.c_str()); return SRSLTE_ERROR_OUT_OF_BOUNDS; } } @@ -576,12 +566,12 @@ int spgw::gtpc::init_ue_ip(spgw_args_t* args, const std::map::const_iterator iter = ip_to_imsi.find(inet_ntoa(ue_addr)); if (iter != ip_to_imsi.end()) { - m_gtpc_log->debug("SPGW: init_ue_ip ue ip addr %s is reserved for imsi %015" PRIu64 ", not adding to pool\n", - iter->first.c_str(), - iter->second); + m_logger.debug("SPGW: init_ue_ip ue ip addr %s is reserved for imsi %015" PRIu64 ", not adding to pool", + iter->first.c_str(), + iter->second); } else { m_ue_ip_addr_pool.insert(ue_addr.s_addr); - m_gtpc_log->debug("SPGW: init_ue_ip ue ip addr %s is added to pool\n", inet_ntoa(ue_addr)); + m_logger.debug("SPGW: init_ue_ip ue ip addr %s is added to pool", inet_ntoa(ue_addr)); } } return SRSLTE_SUCCESS; @@ -594,15 +584,15 @@ in_addr_t spgw::gtpc::get_new_ue_ipv4(uint64_t imsi) std::map::const_iterator iter = m_imsi_to_ip.find(imsi); if (iter != m_imsi_to_ip.end()) { ue_addr = iter->second; - m_gtpc_log->info("SPGW: get_new_ue_ipv4 static ip addr %s\n", inet_ntoa(ue_addr)); + m_logger.info("SPGW: get_new_ue_ipv4 static ip addr %s", inet_ntoa(ue_addr)); } else { if (m_ue_ip_addr_pool.empty()) { - m_gtpc_log->error("SPGW: ue address pool is empty\n"); + m_logger.error("SPGW: ue address pool is empty"); ue_addr.s_addr = 0; } else { ue_addr.s_addr = *m_ue_ip_addr_pool.begin(); m_ue_ip_addr_pool.erase(ue_addr.s_addr); - m_gtpc_log->info("SPGW: get_new_ue_ipv4 pool ip addr %s\n", inet_ntoa(ue_addr)); + m_logger.info("SPGW: get_new_ue_ipv4 pool ip addr %s", inet_ntoa(ue_addr)); } } return ue_addr.s_addr; diff --git a/srsepc/src/spgw/gtpu.cc b/srsepc/src/spgw/gtpu.cc index d1bbcf2ef..defe8c5e1 100644 --- a/srsepc/src/spgw/gtpu.cc +++ b/srsepc/src/spgw/gtpu.cc @@ -44,7 +44,6 @@ namespace srsepc { spgw::gtpu::gtpu() : m_sgi_up(false), m_s1u_up(false) { - m_pool = srslte::byte_buffer_pool::get_instance(); return; } @@ -53,13 +52,10 @@ spgw::gtpu::~gtpu() return; } -int spgw::gtpu::init(spgw_args_t* args, spgw* spgw, gtpc_interface_gtpu* gtpc, srslte::log_ref gtpu_log) +int spgw::gtpu::init(spgw_args_t* args, spgw* spgw, gtpc_interface_gtpu* gtpc) { int err; - // Init log - m_gtpu_log = gtpu_log; - // Store interfaces m_spgw = spgw; m_gtpc = gtpc; @@ -78,7 +74,7 @@ int spgw::gtpu::init(spgw_args_t* args, spgw* spgw, gtpc_interface_gtpu* gtpc, s return err; } - m_gtpu_log->info("SPGW GTP-U Initialized.\n"); + m_logger.info("SPGW GTP-U Initialized."); srslte::console("SPGW GTP-U Initialized.\n"); return SRSLTE_SUCCESS; } @@ -106,9 +102,9 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) // Construct the TUN device m_sgi = open("/dev/net/tun", O_RDWR); - m_gtpu_log->info("TUN file descriptor = %d\n", m_sgi); + m_logger.info("TUN file descriptor = %d", m_sgi); if (m_sgi < 0) { - m_gtpu_log->error("Failed to open TUN device: %s\n", strerror(errno)); + m_logger.error("Failed to open TUN device: %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } @@ -119,7 +115,7 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; if (ioctl(m_sgi, TUNSETIFF, &ifr) < 0) { - m_gtpu_log->error("Failed to set TUN device name: %s\n", strerror(errno)); + m_logger.error("Failed to set TUN device name: %s", strerror(errno)); close(m_sgi); return SRSLTE_ERROR_CANT_START; } @@ -127,7 +123,7 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) // Bring up the interface sgi_sock = socket(AF_INET, SOCK_DGRAM, 0); if (ioctl(sgi_sock, SIOCGIFFLAGS, &ifr) < 0) { - m_gtpu_log->error("Failed to bring up socket: %s\n", strerror(errno)); + m_logger.error("Failed to bring up socket: %s", strerror(errno)); close(sgi_sock); close(m_sgi); return SRSLTE_ERROR_CANT_START; @@ -135,7 +131,7 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if (ioctl(sgi_sock, SIOCSIFFLAGS, &ifr) < 0) { - m_gtpu_log->error("Failed to set socket flags: %s\n", strerror(errno)); + m_logger.error("Failed to set socket flags: %s", strerror(errno)); close(sgi_sock); close(m_sgi); return SRSLTE_ERROR_CANT_START; @@ -148,8 +144,8 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) addr->sin_port = 0; if (ioctl(sgi_sock, SIOCSIFADDR, &ifr) < 0) { - m_gtpu_log->error( - "Failed to set TUN interface IP. Address: %s, Error: %s\n", args->sgi_if_addr.c_str(), strerror(errno)); + m_logger.error( + "Failed to set TUN interface IP. Address: %s, Error: %s", args->sgi_if_addr.c_str(), strerror(errno)); close(m_sgi); close(sgi_sock); return SRSLTE_ERROR_CANT_START; @@ -158,7 +154,7 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) ifr.ifr_netmask.sa_family = AF_INET; ((struct sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0"); if (ioctl(sgi_sock, SIOCSIFNETMASK, &ifr) < 0) { - m_gtpu_log->error("Failed to set TUN interface Netmask. Error: %s\n", strerror(errno)); + m_logger.error("Failed to set TUN interface Netmask. Error: %s", strerror(errno)); close(m_sgi); close(sgi_sock); return SRSLTE_ERROR_CANT_START; @@ -166,7 +162,7 @@ int spgw::gtpu::init_sgi(spgw_args_t* args) close(sgi_sock); m_sgi_up = true; - m_gtpu_log->info("Initialized SGi interface\n"); + m_logger.info("Initialized SGi interface"); return SRSLTE_SUCCESS; } @@ -175,7 +171,7 @@ int spgw::gtpu::init_s1u(spgw_args_t* args) // Open S1-U socket m_s1u = socket(AF_INET, SOCK_DGRAM, 0); if (m_s1u == -1) { - m_gtpu_log->error("Failed to open socket: %s\n", strerror(errno)); + m_logger.error("Failed to open socket: %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } m_s1u_up = true; @@ -186,17 +182,17 @@ int spgw::gtpu::init_s1u(spgw_args_t* args) m_s1u_addr.sin_port = htons(GTPU_RX_PORT); if (bind(m_s1u, (struct sockaddr*)&m_s1u_addr, sizeof(struct sockaddr_in))) { - m_gtpu_log->error("Failed to bind socket: %s\n", strerror(errno)); + m_logger.error("Failed to bind socket: %s", strerror(errno)); return SRSLTE_ERROR_CANT_START; } - m_gtpu_log->info("S1-U socket = %d\n", m_s1u); - m_gtpu_log->info("S1-U IP = %s, Port = %d \n", inet_ntoa(m_s1u_addr.sin_addr), ntohs(m_s1u_addr.sin_port)); + m_logger.info("S1-U socket = %d", m_s1u); + m_logger.info("S1-U IP = %s, Port = %d ", inet_ntoa(m_s1u_addr.sin_addr), ntohs(m_s1u_addr.sin_port)); - m_gtpu_log->info("Initialized S1-U interface\n"); + m_logger.info("Initialized S1-U interface"); return SRSLTE_SUCCESS; } -void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg) +void spgw::gtpu::handle_sgi_pdu(srslte::unique_byte_buffer_t msg) { bool usr_found = false; bool ctr_found = false; @@ -206,21 +202,21 @@ void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg) srslte::gtpc_f_teid_ie enb_fteid; uint32_t spgw_teid; struct iphdr* iph = (struct iphdr*)msg->msg; - m_gtpu_log->debug("Received SGi PDU. Bytes %d\n", msg->N_bytes); + m_logger.debug("Received SGi PDU. Bytes %d", msg->N_bytes); if (iph->version != 4) { - m_gtpu_log->info("IPv6 not supported yet.\n"); + m_logger.info("IPv6 not supported yet."); return; } if (ntohs(iph->tot_len) < 20) { - m_gtpu_log->warning("Invalid IP header length. IP length %d.\n", ntohs(iph->tot_len)); + m_logger.warning("Invalid IP header length. IP length %d.", ntohs(iph->tot_len)); return; } // Logging PDU info - m_gtpu_log->debug("SGi PDU -- IP version %d, Total length %d\n", iph->version, ntohs(iph->tot_len)); - m_gtpu_log->debug("SGi PDU -- IP src addr %s\n", srslte::gtpu_ntoa(iph->saddr).c_str()); - m_gtpu_log->debug("SGi PDU -- IP dst addr %s\n", srslte::gtpu_ntoa(iph->daddr).c_str()); + m_logger.debug("SGi PDU -- IP version %d, Total length %d", int(iph->version), ntohs(iph->tot_len)); + m_logger.debug("SGi PDU -- IP src addr %s", srslte::gtpu_ntoa(iph->saddr).c_str()); + m_logger.debug("SGi PDU -- IP dst addr %s", srslte::gtpu_ntoa(iph->daddr).c_str()); // Find user and control tunnel gtpu_fteid_it = m_ip_to_usr_teid.find(iph->daddr); @@ -236,39 +232,32 @@ void spgw::gtpu::handle_sgi_pdu(srslte::byte_buffer_t* msg) // Handle SGi packet if (usr_found == false && ctr_found == false) { - m_gtpu_log->debug("Packet for unknown UE.\n"); - goto pkt_discard_out; + m_logger.debug("Packet for unknown UE."); } else if (usr_found == false && ctr_found == true) { - m_gtpu_log->debug("Packet for attached UE that is not ECM connected.\n"); - m_gtpu_log->debug("Triggering Donwlink Notification Requset.\n"); + m_logger.debug("Packet for attached UE that is not ECM connected."); + m_logger.debug("Triggering Donwlink Notification Requset."); m_gtpc->send_downlink_data_notification(spgw_teid); - m_gtpc->queue_downlink_packet(spgw_teid, msg); + m_gtpc->queue_downlink_packet(spgw_teid, std::move(msg)); return; } else if (usr_found == false && ctr_found == true) { - m_gtpu_log->error("User plane tunnel found without a control plane tunnel present.\n"); - goto pkt_discard_out; + m_logger.error("User plane tunnel found without a control plane tunnel present."); } else { - send_s1u_pdu(enb_fteid, msg); + send_s1u_pdu(enb_fteid, msg.get()); } - return; - -pkt_discard_out: - m_pool->deallocate(msg); - return; } void spgw::gtpu::handle_s1u_pdu(srslte::byte_buffer_t* msg) { srslte::gtpu_header_t header; - srslte::gtpu_read_header(msg, &header, m_gtpu_log); + srslte::gtpu_read_header(msg, &header, m_logger); - m_gtpu_log->debug("Received PDU from S1-U. Bytes=%d\n", msg->N_bytes); - m_gtpu_log->debug("TEID 0x%x. Bytes=%d\n", header.teid, msg->N_bytes); + m_logger.debug("Received PDU from S1-U. Bytes=%d", msg->N_bytes); + m_logger.debug("TEID 0x%x. Bytes=%d", header.teid, msg->N_bytes); int n = write(m_sgi, msg->msg, msg->N_bytes); if (n < 0) { - m_gtpu_log->error("Could not write to TUN interface.\n"); + m_logger.error("Could not write to TUN interface."); } else { - m_gtpu_log->debug("Forwarded packet to TUN interface. Bytes= %d/%d\n", n, msg->N_bytes); + m_logger.debug("Forwarded packet to TUN interface. Bytes= %d/%d", n, msg->N_bytes); } return; } @@ -288,37 +277,36 @@ void spgw::gtpu::send_s1u_pdu(srslte::gtp_fteid_t enb_fteid, srslte::byte_buffer header.length = msg->N_bytes; header.teid = enb_fteid.teid; - m_gtpu_log->debug("User plane tunnel found SGi PDU. Forwarding packet to S1-U.\n"); - m_gtpu_log->debug("eNB F-TEID -- eNB IP %s, eNB TEID 0x%x.\n", inet_ntoa(enb_addr.sin_addr), enb_fteid.teid); + m_logger.debug("User plane tunnel found SGi PDU. Forwarding packet to S1-U."); + m_logger.debug("eNB F-TEID -- eNB IP %s, eNB TEID 0x%x.", inet_ntoa(enb_addr.sin_addr), enb_fteid.teid); // Write header into packet int n; - if (!srslte::gtpu_write_header(&header, msg, m_gtpu_log)) { - m_gtpu_log->error("Error writing GTP-U header on PDU\n"); + if (!srslte::gtpu_write_header(&header, msg, m_logger)) { + m_logger.error("Error writing GTP-U header on PDU"); goto out; } // Send packet to destination n = sendto(m_s1u, msg->msg, msg->N_bytes, 0, (struct sockaddr*)&enb_addr, sizeof(enb_addr)); if (n < 0) { - m_gtpu_log->error("Error sending packet to eNB\n"); + m_logger.error("Error sending packet to eNB"); } else if ((unsigned int)n != msg->N_bytes) { - m_gtpu_log->error("Mis-match between packet bytes and sent bytes: Sent: %d/%d\n", n, msg->N_bytes); + m_logger.error("Mis-match between packet bytes and sent bytes: Sent: %d/%d", n, msg->N_bytes); } out: - m_gtpu_log->debug("Deallocating packet after sending S1-U message\n"); - m_pool->deallocate(msg); + m_logger.debug("Deallocating packet after sending S1-U message"); return; } -void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, - std::queue& pkt_queue) +void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid, + std::queue& pkt_queue) { - m_gtpu_log->debug("Sending all queued packets\n"); + m_logger.debug("Sending all queued packets"); while (!pkt_queue.empty()) { - srslte::byte_buffer_t* msg = pkt_queue.front(); - send_s1u_pdu(dw_user_fteid, msg); + srslte::unique_byte_buffer_t msg = std::move(pkt_queue.front()); + send_s1u_pdu(dw_user_fteid, msg.get()); pkt_queue.pop(); } return; @@ -329,11 +317,10 @@ void spgw::gtpu::send_all_queued_packets(srslte::gtp_fteid_t dw_ */ bool spgw::gtpu::modify_gtpu_tunnel(in_addr_t ue_ipv4, srslte::gtpc_f_teid_ie dw_user_fteid, uint32_t up_ctrl_teid) { - m_gtpu_log->info("Modifying GTP-U Tunnel.\n"); - m_gtpu_log->info("UE IP %s\n", srslte::gtpu_ntoa(ue_ipv4).c_str()); - m_gtpu_log->info( - "Downlink eNB addr %s, U-TEID 0x%x\n", srslte::gtpu_ntoa(dw_user_fteid.ipv4).c_str(), dw_user_fteid.teid); - m_gtpu_log->info("Uplink C-TEID: 0x%x\n", up_ctrl_teid); + m_logger.info("Modifying GTP-U Tunnel."); + m_logger.info("UE IP %s", srslte::gtpu_ntoa(ue_ipv4).c_str()); + m_logger.info("Downlink eNB addr %s, U-TEID 0x%x", srslte::gtpu_ntoa(dw_user_fteid.ipv4).c_str(), dw_user_fteid.teid); + m_logger.info("Uplink C-TEID: 0x%x", up_ctrl_teid); m_ip_to_usr_teid[ue_ipv4] = dw_user_fteid; m_ip_to_ctr_teid[ue_ipv4] = up_ctrl_teid; return true; @@ -345,7 +332,7 @@ bool spgw::gtpu::delete_gtpu_tunnel(in_addr_t ue_ipv4) if (m_ip_to_usr_teid.count(ue_ipv4)) { m_ip_to_usr_teid.erase(ue_ipv4); } else { - m_gtpu_log->error("Could not find GTP-U Tunnel to delete.\n"); + m_logger.error("Could not find GTP-U Tunnel to delete."); return false; } return true; @@ -357,7 +344,7 @@ bool spgw::gtpu::delete_gtpc_tunnel(in_addr_t ue_ipv4) if (m_ip_to_ctr_teid.count(ue_ipv4)) { m_ip_to_ctr_teid.erase(ue_ipv4); } else { - m_gtpu_log->error("Could not find GTP-C Tunnel info to delete.\n"); + m_logger.error("Could not find GTP-C Tunnel info to delete."); return false; } return true; diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index d8a3efb7d..e8c6709aa 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -65,31 +65,23 @@ void spgw::cleanup() pthread_mutex_unlock(&spgw_instance_mutex); } -int spgw::init(spgw_args_t* args, - srslte::log_ref gtpu_log, - srslte::log_filter* gtpc_log, - srslte::log_filter* spgw_log, - const std::map& ip_to_imsi) +int spgw::init(spgw_args_t* args, const std::map& ip_to_imsi) { int err; - m_pool = srslte::byte_buffer_pool::get_instance(); - - // Init log - m_spgw_log = spgw_log; // Init GTP-U - if (m_gtpu->init(args, this, m_gtpc, gtpu_log) != SRSLTE_SUCCESS) { + if (m_gtpu->init(args, this, m_gtpc) != SRSLTE_SUCCESS) { srslte::console("Could not initialize the SPGW's GTP-U.\n"); return SRSLTE_ERROR_CANT_START; } // Init GTP-C - if (m_gtpc->init(args, this, m_gtpu, gtpc_log, ip_to_imsi) != SRSLTE_SUCCESS) { + if (m_gtpc->init(args, this, m_gtpu, ip_to_imsi) != SRSLTE_SUCCESS) { srslte::console("Could not initialize the S1-U interface.\n"); return SRSLTE_ERROR_CANT_START; } - m_spgw_log->info("SP-GW Initialized.\n"); + m_logger.info("SP-GW Initialized."); srslte::console("SP-GW Initialized.\n"); return SRSLTE_SUCCESS; } @@ -111,9 +103,9 @@ void spgw::run_thread() { // Mark the thread as running m_running = true; - srslte::byte_buffer_t *sgi_msg, *s1u_msg, *s11_msg; - s1u_msg = m_pool->allocate("spgw::run_thread::s1u"); - s11_msg = m_pool->allocate("spgw::run_thread::s11"); + srslte::unique_byte_buffer_t sgi_msg, s1u_msg, s11_msg; + s1u_msg = srslte::make_byte_buffer("spgw::run_thread::s1u"); + s11_msg = srslte::make_byte_buffer("spgw::run_thread::s11"); struct sockaddr_in src_addr_in; struct sockaddr_un src_addr_un; @@ -129,7 +121,6 @@ void spgw::run_thread() int max_fd = std::max(s1u, sgi); max_fd = std::max(max_fd, s11); while (m_running) { - s1u_msg->clear(); s11_msg->clear(); @@ -140,7 +131,7 @@ void spgw::run_thread() int n = select(max_fd + 1, &set, NULL, NULL, NULL); if (n == -1) { - m_spgw_log->error("Error from select\n"); + m_logger.error("Error from select"); } else if (n) { if (FD_ISSET(sgi, &set)) { /* @@ -151,29 +142,27 @@ void spgw::run_thread() * procedure fails (see handle_downlink_data_notification_acknowledgment and * handle_downlink_data_notification_failure) */ - m_spgw_log->debug("Message received at SPGW: SGi Message\n"); - sgi_msg = m_pool->allocate("spgw::run_thread::sgi_msg"); + m_logger.debug("Message received at SPGW: SGi Message"); + sgi_msg = srslte::make_byte_buffer("spgw::run_thread::sgi_msg"); sgi_msg->N_bytes = read(sgi, sgi_msg->msg, buf_len); - m_gtpu->handle_sgi_pdu(sgi_msg); + m_gtpu->handle_sgi_pdu(std::move(sgi_msg)); } if (FD_ISSET(s1u, &set)) { - m_spgw_log->debug("Message received at SPGW: S1-U Message\n"); + m_logger.debug("Message received at SPGW: S1-U Message"); socklen_t addrlen = sizeof(src_addr_in); s1u_msg->N_bytes = recvfrom(s1u, s1u_msg->msg, buf_len, 0, (struct sockaddr*)&src_addr_in, &addrlen); - m_gtpu->handle_s1u_pdu(s1u_msg); + m_gtpu->handle_s1u_pdu(s1u_msg.get()); } if (FD_ISSET(s11, &set)) { - m_spgw_log->debug("Message received at SPGW: S11 Message\n"); + m_logger.debug("Message received at SPGW: S11 Message"); socklen_t addrlen = sizeof(src_addr_un); s11_msg->N_bytes = recvfrom(s11, s11_msg->msg, buf_len, 0, (struct sockaddr*)&src_addr_un, &addrlen); - m_gtpc->handle_s11_pdu(s11_msg); + m_gtpc->handle_s11_pdu(s11_msg.get()); } } else { - m_spgw_log->debug("No data from select.\n"); + m_logger.debug("No data from select."); } } - m_pool->deallocate(s1u_msg); - m_pool->deallocate(s11_msg); return; } diff --git a/srsue/hdr/phy/lte/cc_worker.h b/srsue/hdr/phy/lte/cc_worker.h index 248849d0d..d4668f3bc 100644 --- a/srsue/hdr/phy/lte/cc_worker.h +++ b/srsue/hdr/phy/lte/cc_worker.h @@ -32,7 +32,7 @@ namespace lte { class cc_worker { public: - cc_worker(uint32_t cc_idx, uint32_t max_prb, phy_common* phy, srslte::log* log); + cc_worker(uint32_t cc_idx, uint32_t max_prb, phy_common* phy, srslog::basic_logger& logger); ~cc_worker(); /* Functions used by main PHY thread */ @@ -95,8 +95,8 @@ private: uint32_t get_wideband_cqi(); /* Common objects */ - phy_common* phy = nullptr; - srslte::log* log_h = nullptr; + phy_common* phy = nullptr; + srslog::basic_logger& logger; srslte_cell_t cell = {}; srslte_dl_sf_cfg_t sf_cfg_dl = {}; diff --git a/srsue/hdr/phy/lte/sf_worker.h b/srsue/hdr/phy/lte/sf_worker.h index 010671848..052d0d151 100644 --- a/srsue/hdr/phy/lte/sf_worker.h +++ b/srsue/hdr/phy/lte/sf_worker.h @@ -42,7 +42,7 @@ namespace lte { class sf_worker : public srslte::thread_pool::worker { public: - sf_worker(uint32_t max_prb, phy_common* phy, srslte::log* log); + sf_worker(uint32_t max_prb, phy_common* phy_, srslog::basic_logger& logger); virtual ~sf_worker(); void reset_cell_unlocked(uint32_t cc_idx); @@ -88,7 +88,7 @@ private: phy_common* phy = nullptr; - srslte::log* log_h = nullptr; + srslog::basic_logger& logger; srslte_cell_t cell = {}; std::mutex cell_mutex; diff --git a/srsue/hdr/phy/lte/worker_pool.h b/srsue/hdr/phy/lte/worker_pool.h index 1c05264df..d35886269 100644 --- a/srsue/hdr/phy/lte/worker_pool.h +++ b/srsue/hdr/phy/lte/worker_pool.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -30,10 +21,6 @@ namespace lte { class worker_pool { - -private: - std::vector > log_vec; - srslte::thread_pool pool; std::vector > workers; @@ -41,7 +28,7 @@ public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } worker_pool(uint32_t max_workers); - bool init(phy_common* common, srslte::logger* logger, int prio); + bool init(phy_common* common, srslog::sink& log_sink, int prio); sf_worker* wait_worker(uint32_t tti); sf_worker* wait_worker_id(uint32_t id); void start_worker(sf_worker* w); diff --git a/srsue/hdr/phy/nr/cc_worker.h b/srsue/hdr/phy/nr/cc_worker.h index 106fa5b74..f785d11c1 100644 --- a/srsue/hdr/phy/nr/cc_worker.h +++ b/srsue/hdr/phy/nr/cc_worker.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -23,77 +14,50 @@ #define SRSLTE_NR_CC_WORKER_H #include "srslte/common/log.h" -#include "srslte/srslte.h" #include "srsue/hdr/phy/phy_common.h" -#include -#include +#include "state.h" namespace srsue { namespace nr { -typedef struct { - uint32_t nof_carriers; - srslte_ue_dl_nr_args_t dl; -} phy_nr_args_t; - -typedef struct { - srslte_sch_cfg_nr_t pdsch; -} phy_nr_cfg_t; - -class phy_nr_state -{ -public: - phy_nr_args_t args = {}; - phy_nr_cfg_t cfg = {}; - - phy_nr_state() - { - args.nof_carriers = 1; - args.dl.nof_rx_antennas = 1; - args.dl.nof_max_prb = 100; - args.dl.pdsch.measure_evm = true; - args.dl.pdsch.measure_time = true; - args.dl.pdsch.sch.disable_simd = false; - cfg.pdsch.sch_cfg.mcs_table = srslte_mcs_table_256qam; - } -}; - class cc_worker { public: - cc_worker(uint32_t cc_idx, srslte::log* log, phy_nr_state* phy_state_); + cc_worker(uint32_t cc_idx, srslog::basic_logger& log, state* phy_state_); ~cc_worker(); bool set_carrier(const srslte_carrier_nr_t* carrier); void set_tti(uint32_t tti); cf_t* get_rx_buffer(uint32_t antenna_idx); + cf_t* get_tx_buffer(uint32_t antenna_idx); uint32_t get_buffer_len(); bool work_dl(); + bool work_ul(); int read_pdsch_d(cf_t* pdsch_d); private: - srslte_dl_slot_cfg_t dl_slot_cfg = {}; + srslte_slot_cfg_t dl_slot_cfg = {}; + srslte_slot_cfg_t ul_slot_cfg = {}; uint32_t cc_idx = 0; std::array rx_buffer = {}; std::array tx_buffer = {}; uint32_t buffer_sz = 0; - phy_nr_state* phy_state = nullptr; + state* phy = nullptr; srslte_ue_dl_nr_t ue_dl = {}; - srslte::log* log_h = nullptr; + srslte_ue_ul_nr_t ue_ul = {}; + srslog::basic_logger& logger; // Temporal attributes + srslte_softbuffer_tx_t softbuffer_tx = {}; srslte_softbuffer_rx_t softbuffer_rx = {}; - std::vector data; + std::vector tx_data; - // Current rnti - uint16_t rnti = 0; - - // Current coreset and search space - srslte_coreset_t coreset = {}; - srslte_search_space_t search_space = {}; + // Methods for DL... + void decode_pdcch_ul(); + void decode_pdcch_dl(); }; } // namespace nr diff --git a/srsue/hdr/phy/nr/sf_worker.h b/srsue/hdr/phy/nr/sf_worker.h index 110cb4f24..e49768756 100644 --- a/srsue/hdr/phy/nr/sf_worker.h +++ b/srsue/hdr/phy/nr/sf_worker.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -40,7 +31,7 @@ namespace nr { class sf_worker final : public srslte::thread_pool::worker { public: - sf_worker(phy_nr_state* phy_state_, srslte::log* log); + sf_worker(phy_common* phy, state* phy_state_, srslog::basic_logger& logger); ~sf_worker() = default; bool set_carrier_unlocked(uint32_t cc_idx, const srslte_carrier_nr_t* carrier_); @@ -52,14 +43,21 @@ public: int read_pdsch_d(cf_t* pdsch_d); void start_plot(); + void set_prach(cf_t* prach_ptr, float prach_power); + private: /* Inherited from thread_pool::worker. Function called every subframe to run the DL/UL processing */ void work_imp() override; std::vector > cc_workers; - phy_nr_state* phy_state = nullptr; - srslte::log* log_h = nullptr; + phy_common* phy = nullptr; + state* phy_state = nullptr; + srslog::basic_logger& logger; + + uint32_t tti_rx = 0; + cf_t* prach_ptr = nullptr; + float prach_power = 0; }; } // namespace nr diff --git a/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h new file mode 100644 index 000000000..614540363 --- /dev/null +++ b/srsue/hdr/phy/nr/state.h @@ -0,0 +1,247 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSLTE_STATE_H +#define SRSLTE_STATE_H + +#include "srslte/adt/circular_array.h" +#include "srslte/common/common.h" +#include "srslte/interfaces/ue_nr_interfaces.h" +#include "srslte/srslte.h" +#include +#include +#include + +namespace srsue { +namespace nr { + +class state +{ +private: + struct pending_ul_grant_t { + bool enable; + uint32_t pid; + srslte_sch_cfg_nr_t sch_cfg; + }; + srslte::circular_array pending_ul_grant = {}; + mutable std::mutex pending_ul_grant_mutex; + + struct pending_dl_grant_t { + bool enable; + uint32_t pid; + srslte_sch_cfg_nr_t sch_cfg; + srslte_pdsch_ack_resource_nr_t ack_resource; + }; + srslte::circular_array pending_dl_grant = {}; + mutable std::mutex pending_dl_grant_mutex; + + srslte::circular_array pending_ack = {}; + mutable std::mutex pending_ack_mutex; + +public: + mac_interface_phy_nr* stack = nullptr; + srslte_carrier_nr_t carrier = {}; + srslte::phy_cfg_nr_t cfg; + phy_args_nr_t args; + + uint16_t ra_rnti = 0; + uint32_t rar_grant_tti = 0; + + state() + { + carrier.id = 500; + carrier.nof_prb = 100; + carrier.max_mimo_layers = 1; + } + + /** + * @brief Stores a received UL DCI into the pending UL grant list + * @param tti_rx The TTI in which the grant was received + * @param dci_ul The UL DCI message to store + */ + void set_ul_pending_grant(uint32_t tti_rx, const srslte_dci_ul_nr_t& dci_ul) + { + // Convert UL DCI to grant + srslte_sch_cfg_nr_t pusch_cfg = {}; + if (srslte_ra_ul_dci_to_grant_nr(&carrier, &cfg.pusch, &dci_ul, &pusch_cfg, &pusch_cfg.grant)) { + std::array str; + srslte_dci_ul_nr_to_str(&dci_ul, str.data(), str.size()); + ERROR("Computing UL grant %s", str.data()); + return; + } + + // Calculate Transmit TTI + uint32_t tti_tx = TTI_ADD(tti_rx, pusch_cfg.grant.k); + + // Scope mutex to protect read/write the list + std::lock_guard lock(pending_ul_grant_mutex); + + // Save entry + pending_ul_grant_t& pending_grant = pending_ul_grant[tti_tx]; + pending_grant.sch_cfg = pusch_cfg; + pending_grant.pid = dci_ul.pid; + pending_grant.enable = true; + } + + /** + * @brief Checks the UL pending grant list if there is any grant to transmit for the given transmit TTI + * @param tti_tx Current transmit TTI + * @param sch_cfg Provides the Shared Channel configuration for the PUSCH transmission + * @param pid Provides the HARQ process identifier + * @return true if there is a pending grant for the given TX tti, false otherwise + */ + bool get_ul_pending_grant(uint32_t tti_tx, srslte_sch_cfg_nr_t& pusch_cfg, uint32_t& pid) + { + // Scope mutex to protect read/write the list + std::lock_guard lock(pending_ul_grant_mutex); + + // Select entry + pending_ul_grant_t& pending_grant = pending_ul_grant[tti_tx]; + + // If the entry is not active, just return + if (!pending_grant.enable) { + return false; + } + + // Load shared channel configuration + pusch_cfg = pending_grant.sch_cfg; + + // Reset entry + pending_grant.enable = false; + + return true; + } + + /** + * @brief Stores a received DL DCI into the pending DL grant list + * @param tti_rx The TTI in which the grant was received + * @param dci_dl The DL DCI message to store + */ + void set_dl_pending_grant(uint32_t tti_rx, const srslte_dci_dl_nr_t& dci_dl) + { + // Convert DL DCI to grant + srslte_sch_cfg_nr_t pdsch_cfg = {}; + if (srslte_ra_dl_dci_to_grant_nr(&carrier, &cfg.pdsch, &dci_dl, &pdsch_cfg, &pdsch_cfg.grant)) { + ERROR("Computing UL grant"); + return; + } + + // Calculate DL DCI to PDSCH ACK resource + srslte_pdsch_ack_resource_nr_t ack_resource = {}; + if (srslte_ue_dl_nr_pdsch_ack_resource(&cfg.harq_ack, &dci_dl, &ack_resource) < SRSLTE_SUCCESS) { + ERROR("Computing UL ACK resource"); + return; + } + + // Calculate Receive TTI + tti_rx = TTI_ADD(tti_rx, pdsch_cfg.grant.k); + + // Scope mutex to protect read/write the list + std::lock_guard lock(pending_dl_grant_mutex); + + // Save entry + pending_dl_grant_t& pending_grant = pending_dl_grant[tti_rx]; + pending_grant.sch_cfg = pdsch_cfg; + pending_grant.ack_resource = ack_resource; + pending_grant.pid = dci_dl.pid; + pending_grant.enable = true; + } + + /** + * @brief Checks the DL pending grant list if there is any grant to receive for the given receive TTI + * @param tti_rx Current receive TTI + * @param sch_cfg Provides the Shared Channel configuration for the PDSCH transmission + * @param ack_resource Provides the UL ACK resource + * @param pid Provides the HARQ process identifier + * @return true if there is a pending grant for the given TX tti, false otherwise + */ + bool get_dl_pending_grant(uint32_t tti_rx, + srslte_sch_cfg_nr_t& pdsch_cfg, + srslte_pdsch_ack_resource_nr_t& ack_resource, + uint32_t& pid) + { + // Scope mutex to protect read/write the list + std::lock_guard lock(pending_dl_grant_mutex); + + // Select entry + pending_dl_grant_t& pending_grant = pending_dl_grant[tti_rx]; + + // If the entry is not active, just return + if (!pending_grant.enable) { + return false; + } + + // Load shared channel configuration and resource + pdsch_cfg = pending_grant.sch_cfg; + ack_resource = pending_grant.ack_resource; + pid = pending_grant.pid; + + // Reset entry + pending_grant.enable = false; + + return true; + } + + /** + * @brief Stores a pending PDSCH ACK into the pending ACK list + * @param tti_rx The TTI in which the PDSCH transmission was received + * @param dci_dl The DL DCI message to store + */ + void set_pending_ack(const uint32_t& tti_rx, const srslte_pdsch_ack_resource_nr_t& ack_resource, const bool& crc_ok) + { + // Calculate Receive TTI + uint32_t tti_tx = TTI_ADD(tti_rx, ack_resource.k1); + + // Scope mutex to protect read/write the list + std::lock_guard lock(pending_ack_mutex); + + // Select UL transmission time resource + srslte_pdsch_ack_nr_t& ack = pending_ack[tti_tx]; + ack.nof_cc = 1; + + // Select serving cell + srslte_pdsch_ack_cc_nr_t& ack_cc = ack.cc[ack_resource.scell_idx]; + srslte_pdsch_ack_m_nr_t& ack_m = ack_cc.m[ack_cc.M]; + ack_cc.M++; + + // Set PDSCH transmission information + ack_m.resource = ack_resource; + ack_m.value[0] = crc_ok ? 1 : 0; + ack_m.present = true; + } + + bool get_pending_ack(const uint32_t& tti_tx, srslte_pdsch_ack_nr_t& pdsch_ack) + { + // Scope mutex to protect read/write the list + std::lock_guard lock(pending_ack_mutex); + + // Select UL transmission time resource + srslte_pdsch_ack_nr_t& ack = pending_ack[tti_tx]; + + // No pending grant was set + if (ack.nof_cc == 0) { + return false; + } + + // Copy data + pdsch_ack = ack; + + // Reset list entry + ack = {}; + + return true; + } +}; +} // namespace nr +} // namespace srsue + +#endif // SRSLTE_STATE_H diff --git a/srsue/hdr/phy/nr/worker_pool.h b/srsue/hdr/phy/nr/worker_pool.h index 88df74b1d..9dc9f38ca 100644 --- a/srsue/hdr/phy/nr/worker_pool.h +++ b/srsue/hdr/phy/nr/worker_pool.h @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -24,29 +15,32 @@ #include "sf_worker.h" #include "srslte/common/thread_pool.h" +#include "srsue/hdr/phy/prach.h" namespace srsue { namespace nr { class worker_pool { - private: - std::vector > log_vec; - + srslog::sink& log_sink; + srslog::basic_logger& logger; srslte::thread_pool pool; std::vector > workers; - phy_nr_state phy_state; + state phy_state; + std::unique_ptr prach_buffer = nullptr; public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } - worker_pool(uint32_t max_workers); - bool init(phy_common* common, srslte::logger* logger, int prio); + worker_pool(uint32_t max_workers, srslog::sink& log_sink_); + bool init(const phy_args_nr_t& args_, phy_common* common, stack_interface_phy_nr* stack_, int prio); sf_worker* wait_worker(uint32_t tti); - sf_worker* wait_worker_id(uint32_t id); void start_worker(sf_worker* w); void stop(); + void send_prach(uint32_t prach_occasion, uint32_t preamble_index, int preamble_received_target_power); + int set_ul_grant(std::array array, uint16_t rnti, srslte_rnti_type_t rnti_type); + bool set_config(const srslte::phy_cfg_nr_t& cfg); }; } // namespace nr diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index cb2628563..9c02250be 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -32,10 +32,12 @@ #include "srslte/interfaces/radio_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #include "srsue/hdr/phy/lte/worker_pool.h" #include "srsue/hdr/phy/nr/worker_pool.h" #include "srsue/hdr/phy/ue_lte_phy_base.h" +#include "srsue/hdr/phy/ue_nr_phy_base.h" #include "sync.h" namespace srsue { @@ -73,11 +75,23 @@ private: srslte::block_queue > cmd_queue; }; -class phy final : public ue_lte_phy_base, public srslte::thread +class phy final : public ue_lte_phy_base, + public ue_nr_phy_base, + public srslte::thread { public: - explicit phy(srslte::logger* logger_) : - logger(logger_), lte_workers(MAX_WORKERS), nr_workers(MAX_WORKERS), common(), thread("PHY"){}; + explicit phy(srslog::sink& log_sink) : + log_sink(log_sink), + logger_phy(srslog::fetch_basic_logger("PHY", log_sink)), + logger_phy_lib(srslog::fetch_basic_logger("PHY_LIB", log_sink)), + lte_workers(MAX_WORKERS), + nr_workers(MAX_WORKERS, log_sink), + common(logger_phy), + sfsync(logger_phy, logger_phy_lib), + prach_buffer(logger_phy), + thread("PHY") + {} + ~phy() final { stop(); } // Init defined in base class @@ -168,6 +182,18 @@ public: std::string get_type() final { return "lte_soft"; } + int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srslte::radio_interface_phy* radio_) final; + bool set_config(const srslte::phy_cfg_nr_t& cfg) final; + int set_ul_grant(std::array packed_ul_grant, + uint16_t rnti, + srslte_rnti_type_t rnti_type) final; + void send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec = 0.0f) final; + int tx_request(const tx_request_t& request) final; + void set_earfcn(std::vector earfcns) final; + private: void run_thread() final; void configure_prach_params(); @@ -180,12 +206,12 @@ private: const static int SF_RECV_THREAD_PRIO = 0; const static int WORKERS_THREAD_PRIO = 2; - srslte::radio_interface_phy* radio = nullptr; - srslte::logger* logger = nullptr; + srslte::radio_interface_phy* radio = nullptr; + srslog::sink& log_sink; - std::unique_ptr log_h = nullptr; - std::unique_ptr log_phy_lib_h = nullptr; - srsue::stack_interface_phy_lte* stack = nullptr; + srslog::basic_logger& logger_phy; + srslog::basic_logger& logger_phy_lib; + srsue::stack_interface_phy_lte* stack = nullptr; lte::worker_pool lte_workers; nr::worker_pool nr_workers; diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 961f01552..2951638b5 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -30,6 +30,7 @@ #include "srslte/interfaces/radio_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #include "srsue/hdr/phy/scell/scell_state.h" #include "ta_control.h" @@ -74,12 +75,11 @@ public: // Time Aligment Controller, internal thread safe ta_control ta; - phy_common(); + phy_common(srslog::basic_logger& logger); ~phy_common(); void init(phy_args_t* args, - srslte::log* _log, srslte::radio_interface_phy* _radio, stack_interface_phy_lte* _stack, rsrp_insync_itf* rsrp_insync); @@ -132,7 +132,7 @@ public: srslte_pdsch_ack_resource_t resource); bool get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srslte_pdsch_ack_cc_t* ack); - void worker_end(void* h, bool tx_enable, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time); + void worker_end(void* h, bool tx_enable, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time, bool is_nr); void set_cell(const srslte_cell_t& c); @@ -256,8 +256,8 @@ private: bool is_pending_tx_end = false; - srslte::radio_interface_phy* radio_h = nullptr; - srslte::log* log_h = nullptr; + srslte::radio_interface_phy* radio_h = nullptr; + srslog::basic_logger& logger; srslte::channel_ptr ul_channel = nullptr; int rar_grant_tti = -1; @@ -327,6 +327,10 @@ private: bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); bool is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); + + // NR carriers buffering synchronization, LTE workers are in charge of transmitting + srslte::rf_buffer_t nr_tx_buffer; + bool nr_tx_buffer_ready = false; }; } // namespace srsue diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index c00dc23c8..bd28c4005 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -25,6 +25,7 @@ #include "srslte/common/log.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" #include @@ -33,10 +34,10 @@ namespace srsue { class prach { public: - prach() = default; + prach(srslog::basic_logger& logger) : logger(logger) {} ~prach() { stop(); } - void init(uint32_t max_prb, srslte::log* log_h); + void init(uint32_t max_prb); void stop(); bool set_cell(srslte_cell_t cell, srslte_prach_cfg_t prach_cfg); bool prepare_to_send(uint32_t preamble_idx, int allowed_subframe = -1, float target_power_dbm = -1); @@ -64,7 +65,7 @@ private: static constexpr unsigned max_fs = 12; static constexpr unsigned max_preambles = 64; - srslte::log* log_h = nullptr; + srslog::basic_logger& logger; srslte_prach_t prach_obj = {}; srslte_cell_t cell = {}; srslte_cfo_t cfo_h = {}; diff --git a/srsue/hdr/phy/scell/intra_measure.h b/srsue/hdr/phy/scell/intra_measure.h index 22476834a..2da5af70c 100644 --- a/srsue/hdr/phy/scell/intra_measure.h +++ b/srsue/hdr/phy/scell/intra_measure.h @@ -67,7 +67,7 @@ public: /** * Constructor */ - intra_measure(); + intra_measure(srslog::basic_logger& logger); /** * Destructor @@ -78,9 +78,8 @@ public: * Initiation function, necessary to configure main parameters * @param common SRSUE phy_common instance pointer for providing intra_freq_meas_len_ms and intra_freq_meas_period_ms * @param rrc SRSUE PHY->RRC interface for supplying the RRC with the measurements - * @param log_h Physical layer Logging filter pointer */ - void init(uint32_t cc_idx, phy_common* common, meas_itf* new_cell_itf, srslte::log* log_h); + void init(uint32_t cc_idx, phy_common* common, meas_itf* new_cell_itf); /** * Stops the operation of this component @@ -202,19 +201,19 @@ private: ///< Internal Thread priority, low by default const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; - scell_recv scell = {}; - meas_itf* new_cell_itf = nullptr; - srslte::log* log_h = nullptr; - uint32_t cc_idx = 0; - uint32_t current_earfcn = 0; - uint32_t current_sflen = 0; - srslte_cell_t serving_cell = {}; - std::set active_pci = {}; - std::mutex active_pci_mutex = {}; - uint32_t last_measure_tti = 0; - uint32_t intra_freq_meas_len_ms = 20; - uint32_t intra_freq_meas_period_ms = 200; - uint32_t rx_gain_offset_db = 0; + scell_recv scell; + meas_itf* new_cell_itf = nullptr; + srslog::basic_logger& logger; + uint32_t cc_idx = 0; + uint32_t current_earfcn = 0; + uint32_t current_sflen = 0; + srslte_cell_t serving_cell = {}; + std::set active_pci = {}; + std::mutex active_pci_mutex = {}; + uint32_t last_measure_tti = 0; + uint32_t intra_freq_meas_len_ms = 20; + uint32_t intra_freq_meas_period_ms = 200; + uint32_t rx_gain_offset_db = 0; cf_t* search_buffer = nullptr; diff --git a/srsue/hdr/phy/scell/scell_recv.h b/srsue/hdr/phy/scell/scell_recv.h index 5973f4f21..a7e38a5c3 100644 --- a/srsue/hdr/phy/scell/scell_recv.h +++ b/srsue/hdr/phy/scell/scell_recv.h @@ -33,18 +33,20 @@ namespace scell { class scell_recv { public: - void init(srslte::log* log_h, uint32_t max_sf_window); - void deinit(); - void reset(); + explicit scell_recv(srslog::basic_logger& logger) : logger(logger) {} + + void init(uint32_t max_sf_window); + void deinit(); + void reset(); std::set find_cells(const cf_t* input_buffer, const srslte_cell_t serving_cell, const uint32_t nof_sf); private: // 36.133 9.1.2.1 for band 7 constexpr static float ABSOLUTE_RSRP_THRESHOLD_DBM = -125; - cf_t* sf_buffer[SRSLTE_MAX_PORTS]; - srslte::log* log_h; - srslte_sync_t sync_find; + cf_t* sf_buffer[SRSLTE_MAX_PORTS]; + srslog::basic_logger& logger; + srslte_sync_t sync_find; uint32_t current_fft_sz; }; diff --git a/srsue/hdr/phy/scell/scell_state.h b/srsue/hdr/phy/scell/scell_state.h index c9961594b..f57a47d54 100644 --- a/srsue/hdr/phy/scell/scell_state.h +++ b/srsue/hdr/phy/scell/scell_state.h @@ -147,7 +147,7 @@ public: std::unique_lock lock(mutex); if (cc_idx == 0 or cc_idx >= SRSLTE_MAX_CARRIERS) { - ERROR("CC IDX %d out-of-range\n", cc_idx); + ERROR("CC IDX %d out-of-range", cc_idx); return; } @@ -212,7 +212,7 @@ public: std::unique_lock lock(mutex); if (cc_idx == 0 or cc_idx >= SRSLTE_MAX_CARRIERS) { - ERROR("CC IDX %d out-of-range\n", cc_idx); + ERROR("CC IDX %d out-of-range", cc_idx); return 0; } @@ -224,7 +224,7 @@ public: std::unique_lock lock(mutex); if (cc_idx == 0 or cc_idx >= SRSLTE_MAX_CARRIERS) { - ERROR("CC IDX %d out-of-range\n", cc_idx); + ERROR("CC IDX %d out-of-range", cc_idx); return 0; } diff --git a/srsue/hdr/phy/scell/scell_sync.h b/srsue/hdr/phy/scell/scell_sync.h index 84c122229..7503f9f10 100644 --- a/srsue/hdr/phy/scell/scell_sync.h +++ b/srsue/hdr/phy/scell/scell_sync.h @@ -54,13 +54,19 @@ private: */ typedef enum { STATE_IDLE = 0, STATE_SEARCH_PSS, STATE_IN_SYNCH } state_t; - state_t state = STATE_IDLE; - sync_callback* callback = nullptr; - uint32_t channel = 0; - srslte_sync_t find_pss = {}; - int32_t sf_len = 0; - std::array temp = {}; - std::mutex mutex; ///< Used for avoiding reconfiguring (set_cell) while it is searching + /** + * Buffer length in subframes, only 2 subframes are allowed + */ + static const uint32_t BUFFER_LEN = 2; + + state_t state = STATE_IDLE; + sync_callback* callback = nullptr; + uint32_t channel = 0; + srslte_sync_t find_pss = {}; + int32_t sf_len = 0; + int32_t cell_id = -1; + std::array temp = {}; + std::mutex mutex; ///< Used for avoiding reconfiguring (set_cell) while it is searching /** * Executes the PSS search state @@ -80,7 +86,6 @@ private: // Run PSS search switch (srslte_sync_find(&find_pss, temp.data(), 0, &peak_pos)) { - case SRSLTE_SYNC_FOUND: if (callback != nullptr) { // Calculate Sample Offset from TTI difference @@ -96,13 +101,13 @@ private: state = STATE_IN_SYNCH; break; case SRSLTE_SYNC_FOUND_NOSPACE: - ERROR("No space error\n"); + ERROR("No space error"); break; case SRSLTE_SYNC_NOFOUND: // Ignore break; case SRSLTE_SYNC_ERROR: - ERROR("Error finding PSS\n"); + ERROR("Error finding PSS"); break; } @@ -112,6 +117,35 @@ private: } } + /** + * Unprotected internal resize method for a given bandwidth + */ + void resize(uint32_t new_nof_prb) + { + uint32_t symbol_sz = srslte_symbol_sz(new_nof_prb); + int32_t new_sf_len = SRSLTE_SF_LEN_PRB(new_nof_prb); + + // Reset Temporal buffer + srslte_vec_cf_zero(temp.data(), BUFFER_LEN * new_sf_len); + + // Skip if no BW is changed + if (new_sf_len == sf_len) { + return; + } + + // Resizes synchronization object. As the secondary serving cell base-band might be unaligned respect the primary + // serving cell, the PSS may be located away from the primary serving cell PSS time. The secondary serving cell PSS + // could be in the boundary between subframes, so more than a subframe is required to ensure PSS is captured. Two + // subframes is a simple and conservative buffer size. + if (srslte_sync_resize(&find_pss, BUFFER_LEN * new_sf_len, BUFFER_LEN * new_sf_len, symbol_sz) != SRSLTE_SUCCESS) { + ERROR("Error setting cell sync find"); + } + + // Update values + sf_len = new_sf_len; + cell_id = -1; // Force next set_cell to set the ID + } + public: /** * Constructor @@ -126,12 +160,24 @@ public: // Initialise Find PSS object if (srslte_sync_init(&find_pss, 2 * SRSLTE_SF_LEN_MAX, 2 * SRSLTE_SF_LEN_MAX, SRSLTE_SYMBOL_SZ_MAX) != SRSLTE_SUCCESS) { - ERROR("Initiating Synchronizer\n"); + ERROR("Initiating Synchronizer"); } } ~sync() { srslte_sync_free(&find_pss); }; + void set_bw(const uint32_t nof_prb) + { + // Protect DSP objects and buffers; As it is called by asynchronous thread, it can wait to finish current processing + std::unique_lock lock(mutex); + + // Resizes the DSP objects for the given bandwidth + resize(nof_prb); + + // Reset state to idle + state = STATE_IDLE; + } + /** * Sets the cell for the synchronizer */ @@ -140,25 +186,21 @@ public: // Protect DSP objects and buffers; As it is called by asynchronous thread, it can wait to finish current processing std::unique_lock lock(mutex); - uint32_t symbol_sz = srslte_symbol_sz(cell.nof_prb); - sf_len = SRSLTE_SF_LEN_PRB(cell.nof_prb); + // Resize DSP for the new cell bandwidth + resize(cell.nof_prb); - // Resize Sync object - if (srslte_sync_resize(&find_pss, 2 * sf_len, 2 * sf_len, symbol_sz) != SRSLTE_SUCCESS) { - ERROR("Error setting cell sync find\n"); + // Configure only if the cell identifier has changed + int32_t new_cell_id = cell.id; + if (cell_id != new_cell_id) { + srslte_sync_set_frame_type(&find_pss, cell.frame_type); + srslte_sync_set_N_id_2(&find_pss, new_cell_id % SRSLTE_NOF_NID_2); + srslte_sync_set_N_id_1(&find_pss, new_cell_id / SRSLTE_NOF_NID_2); + srslte_sync_set_cfo_ema_alpha(&find_pss, 0.1); + srslte_sync_set_em_alpha(&find_pss, 1); + srslte_sync_set_threshold(&find_pss, 3.0); + cell_id = new_cell_id; } - // Configure - srslte_sync_set_frame_type(&find_pss, cell.frame_type); - srslte_sync_set_N_id_2(&find_pss, cell.id % SRSLTE_NOF_NID_2); - srslte_sync_set_N_id_1(&find_pss, cell.id / SRSLTE_NOF_NID_2); - srslte_sync_set_cfo_ema_alpha(&find_pss, 0.1); - srslte_sync_set_em_alpha(&find_pss, 1); - srslte_sync_set_threshold(&find_pss, 3.0); - - // Reset Temporal buffer - srslte_vec_cf_zero(temp.data(), 2 * sf_len); - // Go to search PSS state = STATE_SEARCH_PSS; } @@ -169,7 +211,7 @@ public: void stop() { state = STATE_IDLE; } /** - * Runs internal FSM, performing Synchronization operations on the provided buffer. It expects data per sub-frame + * Runs internal FSM, performing Synchronization operations on the provided buffer. It expects data per subframe * basis (1 ms). * @param tti Current primary serving cell time * @param buffer Base-band buffer of the given secondary serving cell @@ -177,7 +219,7 @@ public: void run(uint32_t tti, cf_t* buffer) { // Try to get lock. The lock is unsuccessful if the DSP objects are getting configured. In this case, ignore - // the sub-frame. + // the subframe. if (not mutex.try_lock()) { return; } diff --git a/srsue/hdr/phy/search.h b/srsue/hdr/phy/search.h index 4cdaee3a8..b1a0b5f2e 100644 --- a/srsue/hdr/phy/search.h +++ b/srsue/hdr/phy/search.h @@ -24,6 +24,7 @@ #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" namespace srsue { @@ -32,9 +33,9 @@ class search_callback { public: virtual int radio_recv_fnc(srslte::rf_buffer_t&, srslte_timestamp_t* rx_time) = 0; - virtual void set_ue_sync_opts(srslte_ue_sync_t* q, float cfo) = 0; - virtual srslte::radio_interface_phy* get_radio() = 0; - virtual void set_rx_gain(float gain) = 0; + virtual void set_ue_sync_opts(srslte_ue_sync_t* q, float cfo) = 0; + virtual srslte::radio_interface_phy* get_radio() = 0; + virtual void set_rx_gain(float gain) = 0; }; // Class to run cell search @@ -43,16 +44,17 @@ class search public: typedef enum { CELL_NOT_FOUND, CELL_FOUND, ERROR, TIMEOUT } ret_code; + explicit search(srslog::basic_logger& logger) : logger(logger) {} ~search(); - void init(srslte::rf_buffer_t& buffer_, srslte::log* log_h, uint32_t nof_rx_channels, search_callback* parent); + void init(srslte::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search_callback* parent); void reset(); float get_last_cfo(); void set_agc_enable(bool enable); ret_code run(srslte_cell_t* cell, std::array& bch_payload); private: - search_callback* p = nullptr; - srslte::log* log_h = nullptr; + search_callback* p = nullptr; + srslog::basic_logger& logger; srslte::rf_buffer_t buffer = {}; srslte_ue_cellsearch_t cs = {}; srslte_ue_mib_sync_t ue_mib_sync = {}; diff --git a/srsue/hdr/phy/sfn_sync.h b/srsue/hdr/phy/sfn_sync.h index 5fe927f73..0a5a30d22 100644 --- a/srsue/hdr/phy/sfn_sync.h +++ b/srsue/hdr/phy/sfn_sync.h @@ -24,6 +24,7 @@ #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "srslte/srslte.h" namespace srsue { @@ -33,13 +34,12 @@ class sfn_sync { public: typedef enum { IDLE, SFN_FOUND, SFX0_FOUND, SFN_NOFOUND, ERROR } ret_code; - sfn_sync() = default; + explicit sfn_sync(srslog::basic_logger& logger) : logger(logger) {} ~sfn_sync(); void init(srslte_ue_sync_t* ue_sync, const phy_args_t* phy_args_, srslte::rf_buffer_t& buffer, uint32_t buffer_max_samples_, - srslte::log* log_h, uint32_t nof_subframes = SFN_SYNC_NOF_SUBFRAMES); void reset(); bool set_cell(srslte_cell_t cell); @@ -56,14 +56,14 @@ public: private: const static int SFN_SYNC_NOF_SUBFRAMES = 100; - const phy_args_t* phy_args = nullptr; - uint32_t cnt = 0; - uint32_t timeout = 0; - srslte::log* log_h = nullptr; - srslte_ue_sync_t* ue_sync = nullptr; - srslte::rf_buffer_t mib_buffer = {}; - uint32_t buffer_max_samples = 0; - srslte_ue_mib_t ue_mib = {}; + const phy_args_t* phy_args = nullptr; + uint32_t cnt = 0; + uint32_t timeout = 0; + srslog::basic_logger& logger; + srslte_ue_sync_t* ue_sync = nullptr; + srslte::rf_buffer_t mib_buffer = {}; + uint32_t buffer_max_samples = 0; + srslte_ue_mib_t ue_mib = {}; }; }; // namespace srsue diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 3079b359a..9e5f2dafb 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -56,7 +56,14 @@ class sync : public srslte::thread, public scell::intra_measure::meas_itf { public: - sync() : thread("SYNC"), sf_buffer(sync_nof_rx_subframes), dummy_buffer(sync_nof_rx_subframes){}; + sync(srslog::basic_logger& phy_logger, srslog::basic_logger& phy_lib_logger) : + thread("SYNC"), + search_p(phy_logger), + sfn_p(phy_logger), + phy_logger(phy_logger), + phy_lib_logger(phy_lib_logger), + sf_buffer(sync_nof_rx_subframes), + dummy_buffer(sync_nof_rx_subframes){}; ~sync(); void init(srslte::radio_interface_phy* radio_, @@ -65,8 +72,6 @@ public: lte::worker_pool* _lte_workers_pool, nr::worker_pool* _nr_workers_pool, phy_common* _worker_com, - srslte::log* _log_h, - srslte::log* _log_phy_lib_h, uint32_t prio, int sync_cpu_affinity = -1); void stop(); @@ -207,9 +212,9 @@ private: std::vector > intra_freq_meas; // Pointers to other classes - stack_interface_phy_lte* stack = nullptr; - srslte::log* log_h = nullptr; - srslte::log* log_phy_lib_h = nullptr; + stack_interface_phy_lte* stack = nullptr; + srslog::basic_logger& phy_logger; + srslog::basic_logger& phy_lib_logger; lte::worker_pool* lte_worker_pool = nullptr; nr::worker_pool* nr_worker_pool = nullptr; srslte::radio_interface_phy* radio_h = nullptr; diff --git a/srsue/hdr/phy/ta_control.h b/srsue/hdr/phy/ta_control.h index 54149319c..1fd81ecdc 100644 --- a/srsue/hdr/phy/ta_control.h +++ b/srsue/hdr/phy/ta_control.h @@ -31,18 +31,13 @@ namespace srsue { class ta_control { private: - srslte::log* log_h = nullptr; - mutable std::mutex mutex; - uint32_t next_base_nta = 0; - float next_base_sec = 0.0f; + srslog::basic_logger& logger; + mutable std::mutex mutex; + uint32_t next_base_nta = 0; + float next_base_sec = 0.0f; public: - /** - * Sets the logging instance - * - * @param loh_h_ logging instance pointer - */ - void set_logger(srslte::log* log_h_) { log_h = log_h_; } + ta_control(srslog::basic_logger& logger) : logger(logger) {} /** * Sets the next base time in seconds, discarding previous changes. @@ -59,10 +54,7 @@ public: // Update base in nta next_base_nta = static_cast(roundf(next_base_sec / SRSLTE_LTE_TS)); - // Log information information if available - if (log_h) { - log_h->info("PHY: Set TA base: n_ta: %d, ta_usec: %.1f\n", next_base_nta, next_base_sec * 1e6f); - } + logger.info("PHY: Set TA base: n_ta: %d, ta_usec: %.1f", next_base_nta, next_base_sec * 1e6f); } /** @@ -80,13 +72,10 @@ public: // Update base in nta next_base_nta = static_cast(roundf(next_base_sec / SRSLTE_LTE_TS)); - // Log information information if available - if (log_h) { - log_h->info("PHY: Set TA: ta_delta_usec: %.1f, n_ta: %d, ta_usec: %.1f\n", - ta_delta_sec * 1e6f, - next_base_nta, - next_base_sec * 1e6f); - } + logger.info("PHY: Set TA: ta_delta_usec: %.1f, n_ta: %d, ta_usec: %.1f", + ta_delta_sec * 1e6f, + next_base_nta, + next_base_sec * 1e6f); } /** @@ -104,11 +93,7 @@ public: // Update base in seconds next_base_sec = static_cast(next_base_nta) * SRSLTE_LTE_TS; - // Log information information if available - if (log_h) { - log_h->info( - "PHY: Set TA RAR: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, next_base_nta, next_base_sec * 1e6f); - } + logger.info("PHY: Set TA RAR: ta_cmd: %d, n_ta: %d, ta_usec: %.1f", ta_cmd, next_base_nta, next_base_sec * 1e6f); } /** @@ -126,10 +111,7 @@ public: // Update base in seconds next_base_sec = static_cast(next_base_nta) * SRSLTE_LTE_TS; - // Log information information if available - if (log_h) { - log_h->info("PHY: Set TA: ta_cmd: %d, n_ta: %d, ta_usec: %.1f\n", ta_cmd, next_base_nta, next_base_sec * 1e6f); - } + logger.info("PHY: Set TA: ta_cmd: %d, n_ta: %d, ta_usec: %.1f", ta_cmd, next_base_nta, next_base_sec * 1e6f); } /** diff --git a/srsue/hdr/phy/ue_phy_nr_base.h b/srsue/hdr/phy/ue_nr_phy_base.h similarity index 72% rename from srsue/hdr/phy/ue_phy_nr_base.h rename to srsue/hdr/phy/ue_nr_phy_base.h index 9a99e18ab..ba998e01e 100644 --- a/srsue/hdr/phy/ue_phy_nr_base.h +++ b/srsue/hdr/phy/ue_nr_phy_base.h @@ -34,23 +34,20 @@ namespace srsue { -class ue_phy_nr_base : public ue_phy_base, public phy_interface_stack_nr, public srslte::phy_interface_radio +class ue_nr_phy_base : public phy_interface_stack_nr { public: - ue_phy_nr_base(){}; - virtual ~ue_phy_nr_base() {} + ue_nr_phy_base(){}; + virtual ~ue_nr_phy_base() {} virtual std::string get_type() = 0; - virtual int init(const phy_args_t& args_) = 0; - virtual int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srslte::radio_interface_phy* radio_) = 0; - virtual void stop() = 0; + virtual int init(const phy_args_t& args_) = 0; + virtual int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srslte::radio_interface_phy* radio_) = 0; + virtual void stop() = 0; virtual void set_earfcn(std::vector earfcns) = 0; - virtual void wait_initialize() = 0; - virtual void start_plot() = 0; - virtual void get_metrics(phy_metrics_t* m) = 0; }; diff --git a/srsue/hdr/phy/vnf_phy_nr.h b/srsue/hdr/phy/vnf_phy_nr.h index d22e6ac9e..d3a08e32e 100644 --- a/srsue/hdr/phy/vnf_phy_nr.h +++ b/srsue/hdr/phy/vnf_phy_nr.h @@ -30,37 +30,46 @@ #include "srslte/interfaces/radio_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/interfaces/ue_nr_interfaces.h" -#include "srsue/hdr/phy/ue_phy_nr_base.h" +#include "srsue/hdr/phy/ue_nr_phy_base.h" namespace srsue { class vnf_phy_nr : public srsue::ue_phy_base, public srsue::phy_interface_stack_nr { public: - vnf_phy_nr(srslte::logger* logger_); + vnf_phy_nr() = default; ~vnf_phy_nr(); int init(const srsue::phy_args_t& args, srsue::stack_interface_phy_nr* stack_); - int init(const srsue::phy_args_t& args_); + int init(const srsue::phy_args_t& args_) override; void set_earfcn(std::vector earfcns); - void stop(); + void stop() override; - void wait_initialize(); - void get_metrics(phy_metrics_t* m); + void wait_initialize() override; + void get_metrics(phy_metrics_t* m) override; - std::string get_type() { return "vnf_nr"; }; + std::string get_type() override { return "vnf_nr"; }; - void start_plot(); + void start_plot() override; + + // RRC interface + bool set_config(const srslte::phy_cfg_nr_t& cfg) override; // MAC interface - int tx_request(const tx_request_t& request); + int tx_request(const tx_request_t& request) override; + int set_ul_grant(std::array, uint16_t rnti, srslte_rnti_type_t rnti_type) override + { + return SRSLTE_SUCCESS; + }; + void send_prach(const uint32_t preamble_idx, + const int prach_occasion, + const float target_power_dbm, + const float ta_base_sec = 0.0f) override{}; private: - srslte::logger* logger = nullptr; - std::unique_ptr vnf; srsue::stack_interface_phy_nr* stack = nullptr; @@ -70,4 +79,4 @@ private: } // namespace srsue -#endif // SRSUE_VNF_PHY_NR_H \ No newline at end of file +#endif // SRSUE_VNF_PHY_NR_H diff --git a/srsue/hdr/stack/mac/demux.h b/srsue/hdr/stack/mac/demux.h index f77f4bc63..95a3a467f 100644 --- a/srsue/hdr/stack/mac/demux.h +++ b/srsue/hdr/stack/mac/demux.h @@ -27,6 +27,7 @@ #include "srslte/interfaces/ue_interfaces.h" #include "srslte/mac/pdu.h" #include "srslte/mac/pdu_queue.h" +#include "srslte/srslog/srslog.h" /* Logical Channel Demultiplexing and MAC CE dissassemble */ @@ -42,7 +43,7 @@ public: class demux : public srslte::pdu_queue::process_callback { public: - demux(srslte::log_ref log_h_); + explicit demux(srslog::basic_logger& logger); void init(phy_interface_mac_common* phy_h_, rlc_interface_mac* rlc, mac_interface_demux* mac, @@ -70,7 +71,7 @@ private: uint8_t bcch_buffer[MAX_BCCH_PDU_LEN]; // BCCH PID has a dedicated buffer // args - srslte::log_ref log_h; + srslog::basic_logger& logger; phy_interface_mac_common* phy_h = nullptr; rlc_interface_mac* rlc = nullptr; mac_interface_demux* mac = nullptr; diff --git a/srsue/hdr/stack/mac/dl_harq.h b/srsue/hdr/stack/mac/dl_harq.h index 293c8a125..9e3a24888 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -39,7 +39,7 @@ class dl_harq_entity public: dl_harq_entity(uint8_t cc_idx_); - bool init(srslte::log_ref log_h, mac_interface_rrc::ue_rnti_t* rntis, demux* demux_unit); + bool init(mac_interface_rrc::ue_rnti_t* rntis, demux* demux_unit); void reset(); void start_pcap(srslte::mac_pcap* pcap_); @@ -87,9 +87,9 @@ private: std::mutex mutex; - bool is_initiated; - dl_harq_entity* harq_entity; - srslte::log_ref log_h; + bool is_initiated; + dl_harq_entity* harq_entity; + srslog::basic_logger& logger; bool is_first_tb; bool is_new_transmission; @@ -119,7 +119,7 @@ private: std::vector proc; dl_harq_process bcch_proc; demux* demux_unit = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger; srslte::mac_pcap* pcap = nullptr; mac_interface_rrc::ue_rnti_t* rntis = nullptr; uint16_t last_temporal_crnti = 0; @@ -130,7 +130,7 @@ private: uint8_t cc_idx = 0; }; -typedef std::unique_ptr dl_harq_entity_ptr; +typedef std::unique_ptr dl_harq_entity_ptr; typedef std::array dl_harq_entity_vector; } // namespace srsue diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index 046999bc5..2d6728468 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -36,6 +36,7 @@ #include "srslte/common/timers.h" #include "srslte/common/tti_sync_cv.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include "ul_harq.h" #include #include @@ -116,7 +117,7 @@ private: rlc_interface_mac* rlc_h = nullptr; rrc_interface_mac* rrc_h = nullptr; srslte::ext_task_sched_handle task_sched; - srslte::log_ref log_h; + srslog::basic_logger& logger; mac_interface_phy_lte::mac_phy_cfg_mbsfn_t phy_mbsfn_cfg = {}; // RNTI search window scheduling @@ -160,7 +161,6 @@ private: /* Queue to dispatch stack tasks */ srslte::task_multiqueue::queue_handle stack_task_dispatch_queue; - srslte::byte_buffer_pool* pool = nullptr; // pointer to MAC PCAP object srslte::mac_pcap* pcap = nullptr; diff --git a/srsue/hdr/stack/mac/mac_nr.h b/srsue/hdr/stack/mac/mac_nr.h deleted file mode 100644 index 22dddaa7c..000000000 --- a/srsue/hdr/stack/mac/mac_nr.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#ifndef SRSUE_MAC_NR_H -#define SRSUE_MAC_NR_H - -#include "srslte/common/block_queue.h" -#include "srslte/common/logmap.h" -#include "srslte/common/mac_nr_pcap.h" -#include "srslte/interfaces/mac_interface_types.h" -#include "srslte/interfaces/ue_nr_interfaces.h" -#include "srslte/mac/mac_nr_pdu.h" -#include "srsue/hdr/stack/mac/mux.h" -#include "srsue/hdr/stack/ue_stack_base.h" - -namespace srsue { - -struct mac_nr_args_t { - srsue::pcap_args_t pcap; - // TODO: remove temp variable - uint32_t drb_lcid; -}; - -class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr -{ -public: - mac_nr(srslte::ext_task_sched_handle task_sched_); - ~mac_nr(); - - int init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy, rlc_interface_mac* rlc); - void stop(); - - void reset(); - - void run_tti(const uint32_t tti); - - uint16_t get_dl_sched_rnti(uint32_t tti); - uint16_t get_ul_sched_rnti(uint32_t tti); - - void bch_decoded_ok(uint32_t tti, srslte::unique_byte_buffer_t payload); - - int sf_indication(const uint32_t tti); - - void tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant); - - void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant); - - void timer_expired(uint32_t timer_id); - - void get_metrics(mac_metrics_t* metrics); - - /******** Interface for RRC (RRC -> MAC) ****************/ - void setup_lcid(const srslte::logical_channel_config_t& config); - void set_config(const srslte::bsr_cfg_t& bsr_cfg); - void set_config(const srslte::sr_cfg_t& sr_cfg); - - /// stack interface - void process_pdus(); - -private: - - void handle_pdu(srslte::unique_byte_buffer_t pdu); - void get_ul_data(const mac_nr_grant_ul_t& grant, phy_interface_stack_nr::tx_request_t* tx_request); - - /// Interaction with rest of the stack - phy_interface_mac_nr* phy = nullptr; - rlc_interface_mac* rlc = nullptr; - srslte::ext_task_sched_handle task_sched; - - std::unique_ptr pcap = nullptr; - srslte::log_ref log_h; - srslte::byte_buffer_pool* pool = nullptr; - mac_nr_args_t args = {}; - - bool started = false; - - uint16_t crnti = 0xdead; - - static constexpr uint32_t MIN_RLC_PDU_LEN = - 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU - - srslte::block_queue - pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) - - mac_metrics_t metrics[SRSLTE_MAX_CARRIERS] = {}; - - /// Rx buffer - srslte::mac_nr_sch_pdu rx_pdu; - - /// Tx buffer - srslte::mac_nr_sch_pdu tx_pdu; - srslte::unique_byte_buffer_t tx_buffer = nullptr; - srslte::unique_byte_buffer_t rlc_buffer = nullptr; - - srslte::task_multiqueue::queue_handle stack_task_dispatch_queue; -}; - -} // namespace srsue - -#endif // SRSUE_MAC_NR_H diff --git a/srsue/hdr/stack/mac/mux.h b/srsue/hdr/stack/mac/mux.h index 841b63dc2..787204431 100644 --- a/srsue/hdr/stack/mac/mux.h +++ b/srsue/hdr/stack/mac/mux.h @@ -33,6 +33,7 @@ #include "srslte/interfaces/mac_interface_types.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/mac/pdu.h" +#include "srslte/srslog/srslog.h" #include namespace srsue { @@ -40,7 +41,7 @@ namespace srsue { class mux { public: - mux(srslte::log_ref log_); + explicit mux(srslog::basic_logger& logger); ~mux(){}; void reset(); void init(rlc_interface_mac* rlc, bsr_interface_mux* bsr_procedure, phr_proc* phr_procedure_); @@ -66,8 +67,8 @@ public: void print_logical_channel_state(const std::string& info); private: - bool has_logical_channel(const uint32_t& lcid); - bool pdu_move_to_msg3(uint32_t pdu_sz); + bool has_logical_channel(const uint32_t& lcid); + bool pdu_move_to_msg3(uint32_t pdu_sz); uint32_t allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu, int max_sdu_sz); bool sched_sdu(srslte::logical_channel_config_t* ch, int* sdu_space, int max_sdu_sz); @@ -78,11 +79,11 @@ private: // Mutex for exclusive access std::mutex mutex; - srslte::log_ref log_h; - rlc_interface_mac* rlc = nullptr; - bsr_interface_mux* bsr_procedure = nullptr; - phr_proc* phr_procedure = nullptr; - uint16_t pending_crnti_ce = 0; + srslog::basic_logger& logger; + rlc_interface_mac* rlc = nullptr; + bsr_interface_mux* bsr_procedure = nullptr; + phr_proc* phr_procedure = nullptr; + uint16_t pending_crnti_ce = 0; /* Msg3 Buffer */ srslte::byte_buffer_t msg_buff; diff --git a/srsue/hdr/stack/mac/proc_bsr.h b/srsue/hdr/stack/mac/proc_bsr.h index c21822178..944663bbf 100644 --- a/srsue/hdr/stack/mac/proc_bsr.h +++ b/srsue/hdr/stack/mac/proc_bsr.h @@ -29,6 +29,7 @@ #include "srslte/common/logmap.h" #include "srslte/common/timers.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" /* Buffer status report procedure */ @@ -58,9 +59,8 @@ public: class bsr_proc : public srslte::timer_callback, public bsr_interface_mux { public: - bsr_proc(); - void - init(sr_proc* sr_proc, rlc_interface_mac* rlc, srslte::log_ref log_h, srslte::ext_task_sched_handle* task_sched_); + explicit bsr_proc(srslog::basic_logger& logger) : logger(logger) {} + void init(sr_proc* sr_proc, rlc_interface_mac* rlc, srslte::ext_task_sched_handle* task_sched_); void step(uint32_t tti); void reset(); void set_config(srslte::bsr_cfg_t& bsr_cfg); @@ -78,7 +78,7 @@ private: std::mutex mutex; srslte::ext_task_sched_handle* task_sched = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger; rlc_interface_mac* rlc = nullptr; sr_proc* sr = nullptr; diff --git a/srsue/hdr/stack/mac/proc_phr.h b/srsue/hdr/stack/mac/proc_phr.h index aa6e51375..40248ab52 100644 --- a/srsue/hdr/stack/mac/proc_phr.h +++ b/srsue/hdr/stack/mac/proc_phr.h @@ -25,6 +25,7 @@ #include "srslte/common/logmap.h" #include "srslte/common/timers.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include /* Power headroom report procedure */ @@ -34,8 +35,8 @@ namespace srsue { class phr_proc : public srslte::timer_callback { public: - phr_proc(); - void init(phy_interface_mac_lte* phy_h, srslte::log_ref log_h_, srslte::ext_task_sched_handle* task_sched_); + explicit phr_proc(srslog::basic_logger& logger); + void init(phy_interface_mac_lte* phy_h, srslte::ext_task_sched_handle* task_sched_); void set_config(srslte::phr_cfg_t& cfg); void step(); void reset(); @@ -49,7 +50,7 @@ public: private: bool pathloss_changed(); - srslte::log_ref log_h; + srslog::basic_logger& logger; phy_interface_mac_lte* phy_h; srslte::ext_task_sched_handle* task_sched; srslte::phr_cfg_t phr_cfg; diff --git a/srsue/hdr/stack/mac/proc_ra.h b/srsue/hdr/stack/mac/proc_ra.h index f50f12c32..f1fac0b0f 100644 --- a/srsue/hdr/stack/mac/proc_ra.h +++ b/srsue/hdr/stack/mac/proc_ra.h @@ -40,13 +40,12 @@ namespace srsue { class ra_proc : public srslte::timer_callback { public: - ra_proc() : rar_pdu_msg(20){}; + explicit ra_proc(srslog::basic_logger& logger) : rar_pdu_msg(20), logger(logger) {} ~ra_proc(); void init(phy_interface_mac_lte* phy_h, rrc_interface_mac* rrc_, - srslte::log_ref log_h, mac_interface_rrc::ue_rnti_t* rntis, srslte::timer_handler::unique_timer* time_alignment_timer_, mux* mux_unit, @@ -146,7 +145,7 @@ private: void read_params(); phy_interface_mac_lte* phy_h = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger; mux* mux_unit = nullptr; srslte::mac_pcap* pcap = nullptr; rrc_interface_mac* rrc = nullptr; diff --git a/srsue/hdr/stack/mac/proc_sr.h b/srsue/hdr/stack/mac/proc_sr.h index 6afb33653..70e6e1aea 100644 --- a/srsue/hdr/stack/mac/proc_sr.h +++ b/srsue/hdr/stack/mac/proc_sr.h @@ -24,6 +24,7 @@ #include "srslte/common/logmap.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include /* Scheduling Request procedure as defined in 5.4.4 of 36.321 */ @@ -36,8 +37,8 @@ class ra_proc; class sr_proc { public: - sr_proc(); - void init(ra_proc* ra, phy_interface_mac_lte* phy_h, rrc_interface_mac* rrc, srslte::log_ref log_h); + explicit sr_proc(srslog::basic_logger& logger); + void init(ra_proc* ra, phy_interface_mac_lte* phy_h, rrc_interface_mac* rrc); void step(uint32_t tti); void set_config(srslte::sr_cfg_t& cfg); void reset(); @@ -54,7 +55,7 @@ private: ra_proc* ra; rrc_interface_mac* rrc; phy_interface_mac_lte* phy_h; - srslte::log_ref log_h; + srslog::basic_logger& logger; bool initiated; }; diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index c1fdccb27..2531b8bcc 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -40,7 +40,7 @@ class ul_harq_entity public: ul_harq_entity(const uint8_t cc_idx_); - bool init(srslte::log_ref log_h_, mac_interface_rrc_common::ue_rnti_t* rntis_, ra_proc* ra_proc_h_, mux* mux_unit_); + bool init(mac_interface_rrc_common::ue_rnti_t* rntis_, ra_proc* ra_proc_h_, mux* mux_unit_); void reset(); void reset_ndi(); @@ -86,7 +86,7 @@ private: bool is_grant_configured; bool is_initiated; - srslte::log_ref log_h; + srslog::basic_logger& logger; ul_harq_entity* harq_entity; srslte_softbuffer_tx_t softbuffer; @@ -103,9 +103,9 @@ private: std::vector proc; - mux* mux_unit = nullptr; - srslte::mac_pcap* pcap = nullptr; - srslte::log_ref log_h; + mux* mux_unit = nullptr; + srslte::mac_pcap* pcap = nullptr; + srslog::basic_logger& logger; mac_interface_rrc_common::ue_rnti_t* rntis = nullptr; srslte::ul_harq_cfg_t harq_cfg = {}; @@ -117,7 +117,7 @@ private: uint8_t cc_idx = 0; }; -typedef std::unique_ptr ul_harq_entity_ptr; +typedef std::unique_ptr ul_harq_entity_ptr; typedef std::array ul_harq_entity_vector; } // namespace srsue diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h new file mode 100644 index 000000000..582db38da --- /dev/null +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -0,0 +1,147 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSUE_MAC_NR_H +#define SRSUE_MAC_NR_H + +#include "mac_nr_interfaces.h" +#include "proc_ra_nr.h" +#include "srslte/common/block_queue.h" +#include "srslte/common/mac_pcap.h" +#include "srslte/interfaces/mac_interface_types.h" +#include "srslte/interfaces/ue_nr_interfaces.h" +#include "srslte/mac/mac_sch_pdu_nr.h" +#include "srslte/srslog/srslog.h" +#include "srsue/hdr/stack/mac_nr/mux_nr.h" +#include "srsue/hdr/stack/ue_stack_base.h" + +namespace srsue { + +struct mac_nr_args_t { + srsue::pcap_args_t pcap; +}; + +class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_proc_ra_nr +{ +public: + mac_nr(srslte::ext_task_sched_handle task_sched_); + ~mac_nr(); + + int init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy, rlc_interface_mac* rlc); + void stop(); + + void reset(); + void run_tti(const uint32_t tti); + + void bch_decoded_ok(uint32_t tti, srslte::unique_byte_buffer_t payload); + + /// Interface for PHY + sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti); + sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti); + + int sf_indication(const uint32_t tti); + void tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant); + void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* tx_pdu); + void prach_sent(const uint32_t tti, + const uint32_t s_id, + const uint32_t t_id, + const uint32_t f_id, + const uint32_t ul_carrier_id); + + /// Stack interface + void timer_expired(uint32_t timer_id); + void get_metrics(mac_metrics_t* metrics); + + /// Interface for RRC (RRC -> MAC) + void setup_lcid(const srslte::logical_channel_config_t& config); + void set_config(const srslte::bsr_cfg_t& bsr_cfg); + void set_config(const srslte::sr_cfg_t& sr_cfg); + void set_config(const srslte::rach_nr_cfg_t& rach_cfg); + void set_contention_id(const uint64_t ue_identity); + bool set_crnti(const uint16_t crnti); + void start_ra_procedure(); + + /// procedure ra nr interface + uint64_t get_contention_id(); + uint16_t get_c_rnti(); + void set_c_rnti(uint64_t c_rnti_); + + void msg3_flush() { mux.msg3_flush(); } + bool msg3_is_transmitted() { return mux.msg3_is_transmitted(); } + void msg3_prepare() { mux.msg3_prepare(); } + bool msg3_is_pending() { return mux.msg3_is_pending(); } + bool msg3_is_empty() { return mux.msg3_is_empty(); } + + /// stack interface + void process_pdus(); + + static bool is_in_window(uint32_t tti, int* start, int* len); + + // PHY Interface + void prach_sent(const uint32_t tti); + void tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti); + +private: + void write_pcap(const uint32_t cc_idx, mac_nr_grant_dl_t& grant); // If PCAPs are enabled for this MAC + void handle_pdu(srslte::unique_byte_buffer_t pdu); + void get_ul_data(const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* tx_pdu); + + // temporary helper + void handle_rar_pdu(mac_nr_grant_dl_t& grant); + + bool is_si_opportunity(); + bool is_paging_opportunity(); + + bool has_crnti(); + uint16_t get_crnti(); + bool is_valid_crnti(const uint16_t crnti); + + /// Interaction with rest of the stack + phy_interface_mac_nr* phy = nullptr; + rlc_interface_mac* rlc = nullptr; + srslte::ext_task_sched_handle task_sched; + + std::unique_ptr pcap = nullptr; + srslog::basic_logger& logger; + mac_nr_args_t args = {}; + + bool started = false; + + uint16_t c_rnti = SRSLTE_INVALID_RNTI; + uint64_t contention_id = 0; + + static constexpr uint32_t MIN_RLC_PDU_LEN = + 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU + + srslte::block_queue + pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) + + mac_metrics_t metrics[SRSLTE_MAX_CARRIERS] = {}; + + /// Rx buffer + srslte::mac_sch_pdu_nr rx_pdu; + + /// Tx buffer + srslte::mac_sch_pdu_nr tx_pdu; + srslte::unique_byte_buffer_t tx_buffer = nullptr; + srslte::unique_byte_buffer_t rlc_buffer = nullptr; + + srslte::task_multiqueue::queue_handle stack_task_dispatch_queue; + + // MAC Uplink-related procedures + proc_ra_nr proc_ra; + mux_nr mux; +}; + +} // namespace srsue + +#endif // SRSUE_MAC_NR_H diff --git a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h new file mode 100644 index 000000000..94d073bb6 --- /dev/null +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -0,0 +1,39 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 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. + * + */ + +#ifndef SRSUE_MAC_NR_INTERFACES_H +#define SRSUE_MAC_NR_INTERFACES_H + +#include "srslte/common/interfaces_common.h" + +namespace srsue { +/** + * @brief Interface from MAC NR parent class to subclass random access procedure + */ +class mac_interface_proc_ra_nr +{ +public: + // Functions for identity handling, e.g., contention id and c-rnti + virtual uint64_t get_contention_id() = 0; + virtual uint16_t get_c_rnti() = 0; + virtual void set_c_rnti(uint64_t c_rnti) = 0; + + // Functions for msg3 manipulation which shall be transparent to the procedure + virtual bool msg3_is_transmitted() = 0; + virtual void msg3_flush() = 0; + virtual void msg3_prepare() = 0; + virtual bool msg3_is_empty() = 0; +}; + +} // namespace srsue + +#endif // SRSUE_MAC_NR_INTERFACES_H \ No newline at end of file diff --git a/srsue/hdr/stack/mac_nr/mux_nr.h b/srsue/hdr/stack/mac_nr/mux_nr.h new file mode 100644 index 000000000..331822732 --- /dev/null +++ b/srsue/hdr/stack/mac_nr/mux_nr.h @@ -0,0 +1,47 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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. + * + */ + +#ifndef SRSUE_MUX_NR_H +#define SRSUE_MUX_NR_H + +#include "srslte/common/byte_buffer.h" +#include "srslte/common/common.h" +#include "srslte/srslog/srslog.h" +#include "srslte/srslte.h" + +namespace srsue { +class mux_nr +{ +public: + explicit mux_nr(srslog::basic_logger& logger); + ~mux_nr(){}; + void reset(); + void init(); + + void step(); + + void msg3_flush(); + void msg3_prepare(); + void msg3_transmitted(); + bool msg3_is_transmitted(); + bool msg3_is_pending(); + bool msg3_is_empty(); + +private: + srslog::basic_logger& logger; + srslte::unique_byte_buffer_t msg3_buff = nullptr; + typedef enum { none, pending, transmitted } msg3_state_t; + msg3_state_t msg3_state = none; +}; +} // namespace srsue + +#endif // SRSUE_MUX_NR_H diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h new file mode 100644 index 000000000..6541e4aea --- /dev/null +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -0,0 +1,111 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 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. + * + */ + +#ifndef SRSUE_PROC_RA_NR_H +#define SRSUE_PROC_RA_NR_H + +#include +#include +#include + +#include "mac_nr_interfaces.h" +#include "srslte/common/common.h" +#include "srslte/common/task_scheduler.h" +#include "srslte/interfaces/ue_nr_interfaces.h" +#include "srslte/srslog/srslog.h" + +namespace srsue { + +class proc_ra_nr +{ +public: + proc_ra_nr(srslog::basic_logger& logger_); + ~proc_ra_nr(){}; + + void init(phy_interface_mac_nr* phy_h_, mac_interface_proc_ra_nr* mac_, srslte::ext_task_sched_handle* task_sched_); + void set_config(const srslte::rach_nr_cfg_t& rach_cfg); + bool is_contention_resolution(); + + bool is_rar_opportunity(uint32_t tti); + bool has_rar_rnti(); + uint16_t get_rar_rnti(); + bool has_temp_rnti(); + uint16_t get_temp_rnti(); + + // PHY interfaces + void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id); + void handle_rar_pdu(mac_interface_phy_nr::mac_nr_grant_dl_t& grant); + void pdcch_to_crnti(); + + void start_by_rrc(); + void reset(); + +private: + srslog::basic_logger& logger; + phy_interface_mac_nr* phy = nullptr; + mac_interface_proc_ra_nr* mac = nullptr; + srslte::ext_task_sched_handle* task_sched = nullptr; + srslte::task_multiqueue::queue_handle task_queue; + + int ra_window_length = -1, ra_window_start = -1; + uint16_t rar_rnti = SRSLTE_INVALID_RNTI; + uint16_t temp_rnti = SRSLTE_INVALID_RNTI; + + srslte::rach_nr_cfg_t rach_cfg = {}; + bool configured = false; + + enum ra_state_t { + IDLE = 0, + PDCCH_SETUP, + WAITING_FOR_PRACH_SENT, + WAITING_FOR_RESPONSE_RECEPTION, + WAITING_FOR_CONTENTION_RESOLUTION, + WAITING_FOR_COMPLETION, + MAX_RA_STATES, + }; + + std::atomic state = {IDLE}; + + enum initiators_t { MAC, RRC, initiators_t_NULLTYPE }; + std::atomic started_by = {initiators_t_NULLTYPE}; + + srslte::timer_handler::unique_timer prach_send_timer; + srslte::timer_handler::unique_timer rar_timeout_timer; + srslte::timer_handler::unique_timer contention_resolution_timer; + + // 38.321 5.1.1 Variables + uint32_t preamble_index = 0; + uint32_t preamble_transmission_counter = 0; + uint32_t preamble_power_ramping_step = 0; + int preamble_received_target_power = 0; + uint32_t scaling_factor_bi = 0; + // uint32_t temporary_c_rnti; + uint32_t power_offset_2step_ra = 0; + + // not explicty mentioned + uint32_t preambleTransMax = 0; + uint32_t prach_occasion = 0; + + uint32_t current_ta = 0; + void timer_expired(uint32_t timer_id); + // 38.321 Steps 5.1.1 - 5.1.6 + void ra_procedure_initialization(); + void ra_resource_selection(); + void ra_preamble_transmission(); + void ra_response_reception(const mac_interface_phy_nr::mac_nr_grant_dl_t& grant); + void ra_contention_resolution(); + void ra_contention_resolution(uint64_t rx_contention_id); + void ra_completion(); + void ra_error(); +}; +} // namespace srsue +#endif \ No newline at end of file diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 226c107b0..5d3450d36 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -34,6 +34,7 @@ #include "srslte/common/security.h" #include "srslte/common/stack_procedure.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include #include @@ -71,9 +72,7 @@ class rrc : public rrc_interface_nas, public rrc_interface_phy_lte, public rrc_interface_mac, public rrc_interface_pdcp, -#ifdef HAVE_5GNR public rrc_eutra_interface_rrc_nr, -#endif public rrc_interface_rlc, public srslte::timer_callback { @@ -88,9 +87,7 @@ public: nas_interface_rrc* nas_, usim_interface_rrc* usim_, gw_interface_rrc* gw_, -#ifdef HAVE_5GNR rrc_nr_interface_rrc* rrc_nr_, -#endif const rrc_args_t& args_); void stop(); @@ -125,10 +122,8 @@ public: bool has_nr_dc(); // NR interface -#ifdef HAVE_5GNR void new_cell_meas_nr(const std::vector& meas); void nr_rrc_con_reconfig_complete(bool status); -#endif // PHY interface void in_sync() final; @@ -165,9 +160,7 @@ protected: bool is_serving_cell(uint32_t earfcn, uint32_t pci) const; int start_cell_select(); -#ifdef HAVE_5GNR bool has_neighbour_cell_nr(uint32_t earfcn, uint32_t pci) const; -#endif private: typedef struct { @@ -183,8 +176,7 @@ private: stack_interface_rrc* stack = nullptr; srslte::task_sched_handle task_sched; - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref rrc_log; + srslog::basic_logger& logger; phy_interface_rrc_lte* phy = nullptr; mac_interface_rrc* mac = nullptr; rlc_interface_rrc* rlc = nullptr; @@ -192,16 +184,12 @@ private: nas_interface_rrc* nas = nullptr; usim_interface_rrc* usim = nullptr; gw_interface_rrc* gw = nullptr; -#ifdef HAVE_5GNR rrc_nr_interface_rrc* rrc_nr = nullptr; -#endif srslte::unique_byte_buffer_t dedicated_info_nas; void send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg); void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg); - srslte::bit_buffer_t bit_buf; - rrc_state_t state = RRC_STATE_IDLE, last_state = RRC_STATE_IDLE; uint8_t transaction_id = 0; srslte::s_tmsi_t ue_identity; @@ -265,9 +253,7 @@ private: using unique_cell_t = std::unique_ptr; meas_cell_list meas_cells; -#ifdef HAVE_5GNR meas_cell_list meas_cells_nr; -#endif bool initiated = false; asn1::rrc::reest_cause_e m_reest_cause = asn1::rrc::reest_cause_e::nulltype; @@ -283,21 +269,17 @@ private: float get_cell_rsrq(const uint32_t earfcn, const uint32_t pci); meas_cell_eutra* get_serving_cell(); -#ifdef HAVE_5GNR std::set get_cells_nr(const uint32_t arfcn_nr); float get_cell_rsrp_nr(const uint32_t arfcn_nr, const uint32_t pci_nr); float get_cell_rsrq_nr(const uint32_t arfcn_nr, const uint32_t pci_nr); -#endif void process_cell_meas(); void process_new_cell_meas(const std::vector& meas); srslte::block_queue > cell_meas_q; -#ifdef HAVE_5GNR void process_cell_meas_nr(); void process_new_cell_meas_nr(const std::vector& meas); srslte::block_queue > cell_meas_nr_q; -#endif // Cell selection/reselection functions/variables typedef struct { @@ -426,9 +408,7 @@ private: void set_mac_default(); void set_rrc_default(); -#ifdef HAVE_5GNR bool nr_reconfiguration_proc(const asn1::rrc::rrc_conn_recfg_r8_ies_s& rx_recfg); -#endif // Helpers for nr communicaiton asn1::rrc::ue_cap_rat_container_s get_eutra_nr_capabilities(); diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index a286d0fb3..d51f6819f 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -24,11 +24,10 @@ #include "srslte/asn1/rrc.h" #include "srslte/asn1/rrc_utils.h" -#if HAVE_5GNR #include "srslte/asn1/rrc_nr.h" #include "srslte/asn1/rrc_nr_utils.h" -#endif #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" namespace srsue { @@ -114,7 +113,6 @@ protected: std::map sib_info_map; ///< map of sib_index to index of schedInfoList in SIB1 }; -#ifdef HAVE_5GNR class meas_cell_nr : public meas_cell { public: @@ -146,7 +144,6 @@ public: asn1::rrc_nr::sib3_s sib3 = {}; asn1::rrc::mcch_msg_s mcch = {}; }; -#endif class meas_cell_eutra : public meas_cell { @@ -187,7 +184,7 @@ public: asn1::rrc::mcch_msg_s mcch = {}; private: - bool has_valid_sib13 = false; + bool has_valid_sib13 = false; }; //! Universal methods to extract pci/earfcn and compare the two values @@ -201,13 +198,11 @@ inline uint32_t get_pci(const meas_cell_eutra& t) { return t.get_pci(); } -#ifdef HAVE_5GNR template <> inline uint32_t get_pci(const meas_cell_nr& t) { return t.get_pci(); } -#endif template uint32_t get_earfcn(const T& t) { @@ -218,13 +213,11 @@ inline uint32_t get_earfcn(const meas_cell_eutra& t) { return t.get_earfcn(); } -#ifdef HAVE_5GNR template <> inline uint32_t get_earfcn(const meas_cell_nr& t) { return t.get_earfcn(); } -#endif template bool is_same_cell(const T& lhs, const U& rhs) { @@ -251,17 +244,17 @@ public: bool process_new_cell_meas(const std::vector& meas, const std::function& filter_meas); - T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci); - const T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const; - void log_neighbour_cells() const; - std::string print_neighbour_cells() const; - std::set get_neighbour_pcis(uint32_t earfcn) const; - bool has_neighbour_cell(uint32_t earfcn, uint32_t pci) const; - size_t nof_neighbours() const { return neighbour_cells.size(); } - T& operator[](size_t idx) { return *neighbour_cells[idx]; } - const T& operator[](size_t idx) const { return *neighbour_cells[idx]; } - T& at(size_t idx) { return *neighbour_cells.at(idx); } - T* find_cell(uint32_t earfcn, uint32_t pci); + T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci); + const T* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const; + void log_neighbour_cells() const; + std::string print_neighbour_cells() const; + std::set get_neighbour_pcis(uint32_t earfcn) const; + bool has_neighbour_cell(uint32_t earfcn, uint32_t pci) const; + size_t nof_neighbours() const { return neighbour_cells.size(); } + T& operator[](size_t idx) { return *neighbour_cells[idx]; } + const T& operator[](size_t idx) const { return *neighbour_cells[idx]; } + T& at(size_t idx) { return *neighbour_cells.at(idx); } + T* find_cell(uint32_t earfcn, uint32_t pci); // serving cell handling int set_serving_cell(phy_cell_t phy_cell, bool discard_serving); @@ -277,7 +270,7 @@ private: bool add_neighbour_cell_unsorted(unique_meas_cell cell); // args - srslte::log_ref log_h{"RRC"}; + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC"); srslte::task_sched_handle task_sched; unique_meas_cell serv_cell; diff --git a/srsue/hdr/stack/rrc/rrc_meas.h b/srsue/hdr/stack/rrc/rrc_meas.h index 584a866ce..191dd7044 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -44,11 +44,11 @@ meas_obj_to_add_mod_s* find_meas_obj_map(std::map varMeasReportList; }; @@ -113,7 +111,9 @@ private: class var_meas_cfg { public: - var_meas_cfg(var_meas_report_list* meas_report_) : meas_report(meas_report_), log_h(srslte::logmap::get("RRC")) {} + var_meas_cfg(var_meas_report_list* meas_report_) : + meas_report(meas_report_), logger(srslog::fetch_basic_logger("RRC")) + {} void init(rrc* rrc); void reset(); phy_quant_t get_filter_a(); @@ -123,6 +123,7 @@ private: bool parse_meas_config(const meas_cfg_s* meas_config, bool is_ho_reest, uint32_t src_earfcn); void eval_triggers(); void report_triggers(); + private: void remove_varmeas_report(const uint32_t meas_id); @@ -136,7 +137,7 @@ private: void log_debug_trigger_value_eutra(const eutra_event_s::event_id_c_& e); void log_debug_trigger_value_interrat(const report_cfg_inter_rat_s::trigger_type_c_::event_s_::event_id_c_& e); static bool is_rsrp(report_cfg_eutra_s::trigger_quant_opts::options q); - + // Helpers void measObject_addmod_eutra(const meas_obj_to_add_mod_s& l); void measObject_addmod_nr_r15(const meas_obj_to_add_mod_s& l); @@ -155,7 +156,6 @@ private: void report_triggers_eutra_check_new(int32_t meas_id, report_cfg_eutra_s& report_cfg, meas_obj_eutra_s& meas_obj); void report_triggers_eutra_check_leaving(int32_t meas_id, report_cfg_eutra_s& report_cfg); void report_triggers_eutra_removing_trigger(int32_t meas_id); -#ifdef HAVE_5GNR void eval_triggers_interrat_nr(uint32_t meas_id, report_cfg_inter_rat_s& report_cfg, meas_obj_nr_r15_s& meas_obj); void report_triggers_interrat_nr(uint32_t meas_id, report_cfg_inter_rat_s& report_cfg, meas_obj_nr_r15_s& meas_obj); void report_triggers_interrat_check_new(int32_t meas_id, @@ -163,7 +163,6 @@ private: meas_obj_nr_r15_s& meas_obj); void report_triggers_interrat_check_leaving(int32_t meas_id, report_cfg_inter_rat_s& report_cfg); void report_triggers_interrat_removing_trigger(int32_t meas_id); -#endif class cell_trigger_state { @@ -189,20 +188,18 @@ private: // It is safe to use [] operator in this double-map because all members are uint32_t std::map > trigger_state; -#ifdef HAVE_5GNR std::map > trigger_state_nr; -#endif var_meas_report_list* meas_report = nullptr; - srslte::log_ref log_h; + srslog::basic_logger& logger; rrc* rrc_ptr = nullptr; }; - std::mutex meas_cfg_mutex; - var_meas_cfg meas_cfg; - var_meas_report_list meas_report_list; - srslte::log_ref log_h; - rrc* rrc_ptr = nullptr; + std::mutex meas_cfg_mutex; + var_meas_cfg meas_cfg; + var_meas_report_list meas_report_list; + srslog::basic_logger& logger; + rrc* rrc_ptr = nullptr; // Static functions static uint8_t value_to_range(const report_cfg_eutra_s::trigger_quant_opts::options q, float value); diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 68b2aa952..ff85577b8 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -41,9 +41,10 @@ struct core_less_args_t { }; struct rrc_nr_args_t { - core_less_args_t coreless; - std::string log_level; - uint32_t log_hex_limit; + core_less_args_t coreless; + std::vector supported_bands; + std::string log_level; + uint32_t log_hex_limit; }; struct rrc_nr_metrics_t {}; diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index b4fc3b5f6..fc4749401 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -21,6 +21,7 @@ #include "phy_controller.h" #include "srslte/common/log.h" +#include "srslte/srslog/srslog.h" #include "srsue/hdr/stack/rrc/rrc.h" #include #include @@ -86,8 +87,8 @@ private: void start_si_acquire(); // conts - rrc* rrc_ptr; - srslte::log_ref log_h; + rrc* rrc_ptr; + srslog::basic_logger& logger; // state srslte::timer_handler::unique_timer si_acq_timeout, si_acq_retry_timer; @@ -104,8 +105,8 @@ public: static const char* name() { return "Serving Cell Configuration"; } private: - rrc* rrc_ptr; - srslte::log_ref log_h; + rrc* rrc_ptr; + srslog::basic_logger& logger; srslte::proc_outcome_t launch_sib_acquire(); @@ -168,8 +169,8 @@ public: private: // consts - rrc* rrc_ptr; - srslte::log_ref log_h; + rrc* rrc_ptr; + srslog::basic_logger& logger; // state variables found_plmn_t found_plmns[MAX_FOUND_PLMNS]; @@ -189,8 +190,8 @@ public: private: // const - rrc* rrc_ptr; - srslte::log_ref log_h; + rrc* rrc_ptr; + srslog::basic_logger& logger; // args srslte::establishment_cause_t cause; srslte::unique_byte_buffer_t dedicated_info_nas; @@ -234,9 +235,9 @@ public: private: // args - rrc* rrc_ptr; - srslte::log_ref log_h; - asn1::rrc::paging_s paging; + rrc* rrc_ptr; + srslog::basic_logger& logger; + asn1::rrc::paging_s paging; // vars uint32_t paging_idx = 0; diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index 9ced893b5..5e6881010 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -32,7 +32,7 @@ #include #include "mac/mac.h" -#include "mac/mac_nr.h" +#include "mac_nr/mac_nr.h" #include "rrc/rrc.h" #include "srslte/radio/radio.h" #include "srslte/upper/pdcp.h" @@ -55,18 +55,24 @@ namespace srsue { class ue_stack_lte final : public ue_stack_base, public stack_interface_phy_lte, + public stack_interface_phy_nr, public stack_interface_gw, public stack_interface_rrc, public srslte::thread { public: - ue_stack_lte(); + explicit ue_stack_lte(srslog::sink& log_sink); ~ue_stack_lte(); std::string get_type() final; - int init(const stack_args_t& args_, srslte::logger* logger_); - int init(const stack_args_t& args_, srslte::logger* logger_, phy_interface_stack_lte* phy_, gw_interface_stack* gw_); + int init(const stack_args_t& args_, srslte::logger* logger_); + int init(const stack_args_t& args_, srslte::logger* logger_, phy_interface_stack_lte* phy_, gw_interface_stack* gw_); + int init(const stack_args_t& args_, + srslte::logger* logger_, + phy_interface_stack_lte* phy_, + phy_interface_stack_nr* phy_nr_, + gw_interface_stack* gw_); bool switch_on() final; bool switch_off() final; bool is_registered() final; @@ -87,10 +93,13 @@ public: void set_config_complete(bool status) final; void set_scell_complete(bool status) final; - // MAC Interface for PHY + // MAC Interface for EUTRA PHY uint16_t get_dl_sched_rnti(uint32_t tti) final { return mac.get_dl_sched_rnti(tti); } uint16_t get_ul_sched_rnti(uint32_t tti) final { return mac.get_ul_sched_rnti(tti); } + sched_rnti_t get_dl_sched_rnti_nr(uint32_t tti) final { return mac_nr.get_dl_sched_rnti_nr(tti); } + sched_rnti_t get_ul_sched_rnti_nr(uint32_t tti) final { return mac_nr.get_ul_sched_rnti_nr(tti); } + void new_grant_ul(uint32_t cc_idx, mac_grant_ul_t grant, tb_action_ul_t* action) final { mac.new_grant_ul(cc_idx, grant, action); @@ -122,6 +131,22 @@ public: void run_tti(uint32_t tti, uint32_t tti_jump) final; + // MAC Interface for NR PHY + int sf_indication(const uint32_t tti) final { return SRSLTE_SUCCESS; } + void tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) final { mac_nr.tb_decoded(cc_idx, grant); } + + void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* tx_pdu) final { mac_nr.new_grant_ul(cc_idx, grant, tx_pdu); } + + void run_tti(const uint32_t tti) final + { + // ignored, timing will be handled by EUTRA + } + + void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) final + { + mac_nr.prach_sent(tti, s_id, t_id, f_id, ul_carrier_id); + } + // Interface for GW void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) final; @@ -147,19 +172,25 @@ private: srslte::tti_point current_tti; // UE stack logging - srslte::logger* logger = nullptr; - srslte::log_ref stack_log{"STCK"}; ///< our own log filter - srslte::log_ref mac_log{"MAC"}; - srslte::log_ref rlc_log{"RLC"}; - srslte::log_ref pdcp_log{"PDCP"}; - srslte::log_ref rrc_log{"RRC"}; - srslte::log_ref usim_log{"USIM"}; - srslte::log_ref nas_log{"NAS"}; - srslte::log_ref pool_log{"POOL"}; + srslte::logger* logger = nullptr; + srslte::log_ref mac_log{"MAC"}; + srslte::log_ref rlc_log{"RLC"}; + srslte::log_ref pdcp_log{"PDCP"}; + srslte::log_ref rrc_log{"RRC"}; + srslte::log_ref usim_log{"USIM"}; + srslte::log_ref nas_log{"NAS"}; + srslog::basic_logger& stack_logger; + srslog::basic_logger& mac_logger; + srslog::basic_logger& rlc_logger; + srslog::basic_logger& pdcp_logger; + srslog::basic_logger& rrc_logger; + srslog::basic_logger& usim_logger; + srslog::basic_logger& nas_logger; // RAT-specific interfaces phy_interface_stack_lte* phy = nullptr; gw_interface_stack* gw = nullptr; + phy_interface_stack_nr* phy_nr = nullptr; // Thread static const int STACK_MAIN_THREAD_PRIO = 4; // Next lower priority after PHY workers @@ -171,18 +202,19 @@ private: srslte::tprof tti_tprof; // stack components - srsue::mac mac; - srslte::mac_pcap mac_pcap; - srslte::nas_pcap nas_pcap; - srslte::rlc rlc; - srslte::pdcp pdcp; - srsue::rrc rrc; -#ifdef HAVE_5GNR + srsue::mac mac; + srslte::mac_pcap mac_pcap; + srslte::nas_pcap nas_pcap; + srslte::rlc rlc; + srslte::pdcp pdcp; + srsue::rrc rrc; srsue::mac_nr mac_nr; srsue::rrc_nr rrc_nr; -#endif srsue::nas nas; std::unique_ptr usim; + + // Metrics helper + uint32_t ul_dropped_sdus = 0; }; } // namespace srsue diff --git a/srsue/hdr/stack/ue_stack_nr.h b/srsue/hdr/stack/ue_stack_nr.h index 82effab27..3fef732c8 100644 --- a/srsue/hdr/stack/ue_stack_nr.h +++ b/srsue/hdr/stack/ue_stack_nr.h @@ -27,7 +27,7 @@ #include #include -#include "mac/mac_nr.h" +#include "mac_nr/mac_nr.h" #include "rrc/rrc_nr.h" #include "srslte/radio/radio.h" #include "srslte/upper/pdcp.h" @@ -37,7 +37,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log_filter.h" -#include "srslte/common/mac_nr_pcap.h" +#include "srslte/common/mac_pcap.h" #include "srslte/common/multiqueue.h" #include "srslte/common/thread_pool.h" #include "srslte/interfaces/ue_nr_interfaces.h" @@ -71,9 +71,9 @@ public: void stop(); // GW srsue stack_interface_gw dummy interface - bool is_registered(){return true;}; - bool start_service_request(){return true;}; - + bool is_registered() { return true; }; + bool start_service_request() { return true; }; + bool get_metrics(stack_metrics_t* metrics); bool is_rrc_connected(); @@ -83,13 +83,19 @@ public: void run_tti(uint32_t tti) final; // MAC interface for PHY - int sf_indication(const uint32_t tti) + sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) final { return mac->get_dl_sched_rnti_nr(tti); } + sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) final { return mac->get_ul_sched_rnti_nr(tti); } + int sf_indication(const uint32_t tti) { run_tti(tti); return SRSLTE_SUCCESS; } void tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) final { mac->tb_decoded(cc_idx, grant); } - void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant) final { mac->new_grant_ul(cc_idx, grant); } + void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* phy_tx_pdu) final { mac->new_grant_ul(cc_idx, grant, phy_tx_pdu); } + void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) + { + mac->prach_sent(tti, s_id, t_id, f_id, ul_carrier_id); + } // Interface for GW void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) final; @@ -114,7 +120,6 @@ private: srslte::logger* logger = nullptr; srslte::log_ref rlc_log; srslte::log_ref pdcp_log; - srslte::log_ref pool_log; // stack components std::unique_ptr mac; @@ -122,8 +127,6 @@ private: std::unique_ptr rlc; std::unique_ptr pdcp; - std::unique_ptr mac_pcap; - // RAT-specific interfaces phy_interface_stack_nr* phy = nullptr; gw_interface_stack* gw = nullptr; diff --git a/srsue/hdr/stack/upper/gw.h b/srsue/hdr/stack/upper/gw.h index bc1b44705..46cd20cd9 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -30,6 +30,7 @@ #include "srslte/common/log_filter.h" #include "srslte/common/threads.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include "tft_packet_filter.h" #include @@ -59,21 +60,26 @@ public: void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu); // NAS interface - int setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str); - int apply_traffic_flow_template(const uint8_t& eps_bearer_id, - const uint8_t& lcid, - const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); + int setup_if_addr(uint32_t eps_bearer_id, + uint32_t lcid, + uint8_t pdn_type, + uint32_t ip_addr, + uint8_t* ipv6_if_addr, + char* err_str); + int apply_traffic_flow_template(const uint8_t& eps_bearer_id, + const uint8_t& lcid, + const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); void set_test_loop_mode(const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms); // RRC interface void add_mch_port(uint32_t lcid, uint32_t port); + int update_lcid(uint32_t eps_bearer_id, uint32_t new_lcid); private: static const int GW_THREAD_PRIO = -1; - stack_interface_gw* stack = nullptr; - srslte::byte_buffer_pool* pool = nullptr; - srslte::logger* logger = nullptr; + stack_interface_gw* stack = nullptr; + srslte::logger* old_logger = nullptr; gw_args_t args = {}; @@ -86,13 +92,15 @@ private: bool if_up = false; uint32_t default_lcid = 0; - srslte::log_filter log; + srslog::basic_logger& logger; + + std::map eps_lcid; // Mapping between eps bearer ID and LCID uint32_t current_ip_addr = 0; uint8_t current_if_id[8]; - uint32_t ul_tput_bytes = 0; - uint32_t dl_tput_bytes = 0; + uint32_t ul_tput_bytes = 0; + uint32_t dl_tput_bytes = 0; std::chrono::high_resolution_clock::time_point metrics_tp; // stores time when last metrics have been taken void run_thread(); @@ -108,7 +116,7 @@ private: uint32_t mbsfn_ports[SRSLTE_N_MCH_LCIDS] = {}; // Target ports for MBSFN data // TFT - tft_pdu_matcher tft_matcher; + tft_pdu_matcher tft_matcher; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index c59488d54..75414c9d7 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -31,6 +31,7 @@ #include "srslte/common/stack_procedure.h" #include "srslte/common/task_scheduler.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include "srsue/hdr/stack/upper/nas_config.h" #include "srsue/hdr/stack/upper/nas_emm_state.h" #include "srsue/hdr/stack/upper/nas_metrics.h" @@ -81,11 +82,10 @@ public: void start_pcap(srslte::nas_pcap* pcap_) { pcap = pcap_; } private: - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref nas_log; - rrc_interface_nas* rrc = nullptr; - usim_interface_nas* usim = nullptr; - gw_interface_nas* gw = nullptr; + srslog::basic_logger& logger; + rrc_interface_nas* rrc = nullptr; + usim_interface_nas* usim = nullptr; + gw_interface_nas* gw = nullptr; bool running = false; @@ -167,7 +167,7 @@ private: // Airplane mode simulation typedef enum { DISABLED = 0, ENABLED } airplane_mode_state_t; - airplane_mode_state_t airplane_mode_state = {}; + airplane_mode_state_t airplane_mode_state = {}; srslte::timer_handler::unique_timer airplane_mode_sim_timer; // PCAP diff --git a/srsue/hdr/stack/upper/nas_emm_state.h b/srsue/hdr/stack/upper/nas_emm_state.h index 3a9b8f0c0..63689287e 100644 --- a/srsue/hdr/stack/upper/nas_emm_state.h +++ b/srsue/hdr/stack/upper/nas_emm_state.h @@ -23,6 +23,7 @@ #define SRSUE_NAS_EMM_STATE_H #include "srslte/common/logmap.h" +#include "srslte/srslog/srslog.h" #include #include @@ -89,7 +90,7 @@ private: std::atomic state{state_t::null}; // The GW might require to know the NAS state from another thread deregistered_substate_t deregistered_substate = deregistered_substate_t::null; registered_substate_t registered_substate = registered_substate_t::null; - srslte::log_ref nas_log{"NAS"}; + srslog::basic_logger& logger = srslog::fetch_basic_logger("NAS"); }; const char* emm_state_text(emm_state_t::state_t type); diff --git a/srsue/hdr/stack/upper/pcsc_usim.h b/srsue/hdr/stack/upper/pcsc_usim.h index 709765f6a..4f4f52c9c 100644 --- a/srsue/hdr/stack/upper/pcsc_usim.h +++ b/srsue/hdr/stack/upper/pcsc_usim.h @@ -42,7 +42,7 @@ static inline uint16_t to_uint16(const uint8_t* a) class pcsc_usim : public usim_base { public: - pcsc_usim(srslte::log* log_); + explicit pcsc_usim(srslog::basic_logger& logger); ~pcsc_usim(); int init(usim_args_t* args); void stop(); @@ -66,10 +66,10 @@ private: class scard { public: - scard() : log(NULL){}; + explicit scard(srslog::basic_logger& logger) : logger(logger) {} ~scard(){}; - int init(usim_args_t* args, srslte::log* log_); + int init(usim_args_t* args); void deinit(); int select_file(unsigned short file_id, unsigned char* buf, size_t* buf_len); @@ -180,12 +180,12 @@ private: #define SCARD_CHV1_OFFSET 13 #define SCARD_CHV1_FLAG 0x80 - SCARDCONTEXT scard_context; - SCARDHANDLE scard_handle; - long unsigned scard_protocol; - sim_types_t sim_type; - bool pin1_needed; - srslte::log* log; + SCARDCONTEXT scard_context; + SCARDHANDLE scard_handle; + long unsigned scard_protocol; + sim_types_t sim_type; + bool pin1_needed; + srslog::basic_logger& logger; }; scard sc; diff --git a/srsue/hdr/stack/upper/tft_packet_filter.h b/srsue/hdr/stack/upper/tft_packet_filter.h index 8fdbbe030..29dd672cb 100644 --- a/srsue/hdr/stack/upper/tft_packet_filter.h +++ b/srsue/hdr/stack/upper/tft_packet_filter.h @@ -26,6 +26,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/log_filter.h" +#include "srslte/srslog/srslog.h" #include namespace srsue { @@ -71,36 +72,36 @@ public: tft_packet_filter_t(uint8_t eps_bearer_id_, uint8_t lcid_, const LIBLTE_MME_PACKET_FILTER_STRUCT& tft_, - srslte::log* log_); + srslog::basic_logger& logger); bool match(const srslte::unique_byte_buffer_t& pdu); bool filter_contains(uint16_t filtertype); - uint8_t eps_bearer_id {}; - uint8_t lcid = {}; - uint8_t id = {}; - uint8_t eval_precedence = {}; - uint32_t active_filters = {}; - uint32_t ipv4_remote_addr = {}; - uint32_t ipv4_remote_addr_mask = {}; - uint32_t ipv4_local_addr = {}; - uint32_t ipv4_local_addr_mask = {}; - uint8_t ipv6_remote_addr[16] = {}; + uint8_t eps_bearer_id{}; + uint8_t lcid = {}; + uint8_t id = {}; + uint8_t eval_precedence = {}; + uint32_t active_filters = {}; + uint32_t ipv4_remote_addr = {}; + uint32_t ipv4_remote_addr_mask = {}; + uint32_t ipv4_local_addr = {}; + uint32_t ipv4_local_addr_mask = {}; + uint8_t ipv6_remote_addr[16] = {}; uint8_t ipv6_remote_addr_mask[16] = {}; - uint8_t ipv6_remote_addr_length = {}; - uint8_t ipv6_local_addr[16] = {}; - uint8_t ipv6_local_addr_mask[16] = {}; - uint8_t ipv6_local_addr_length = {}; - uint8_t protocol_id = {}; - uint16_t single_local_port = {}; - uint16_t local_port_range[2] = {}; - uint16_t single_remote_port = {}; - uint16_t remote_port_range[2] = {}; - uint32_t security_parameter_index = {}; - uint8_t type_of_service = {}; - uint8_t type_of_service_mask = {}; - uint8_t flow_label[3] = {}; + uint8_t ipv6_remote_addr_length = {}; + uint8_t ipv6_local_addr[16] = {}; + uint8_t ipv6_local_addr_mask[16] = {}; + uint8_t ipv6_local_addr_length = {}; + uint8_t protocol_id = {}; + uint16_t single_local_port = {}; + uint16_t local_port_range[2] = {}; + uint16_t single_remote_port = {}; + uint16_t remote_port_range[2] = {}; + uint32_t security_parameter_index = {}; + uint8_t type_of_service = {}; + uint8_t type_of_service_mask = {}; + uint8_t flow_label[3] = {}; - srslte::log* log; + srslog::basic_logger& logger; bool match_ip(const srslte::unique_byte_buffer_t& pdu); bool match_protocol(const srslte::unique_byte_buffer_t& pdu); @@ -115,7 +116,7 @@ public: class tft_pdu_matcher { public: - tft_pdu_matcher(srslte::log_filter* log_) : log(log_){}; + explicit tft_pdu_matcher(srslog::basic_logger& logger) : logger(logger) {} ~tft_pdu_matcher(){}; void set_default_lcid(const uint8_t lcid); @@ -125,7 +126,7 @@ public: const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); private: - srslte::log_filter* log = nullptr; + srslog::basic_logger& logger; uint8_t default_lcid = 0; std::mutex tft_mutex; typedef std::map tft_filter_map_t; diff --git a/srsue/hdr/stack/upper/usim.h b/srsue/hdr/stack/upper/usim.h index c1db32836..cc7cfc947 100644 --- a/srsue/hdr/stack/upper/usim.h +++ b/srsue/hdr/stack/upper/usim.h @@ -34,7 +34,7 @@ namespace srsue { class usim : public usim_base { public: - usim(srslte::log* log_); + explicit usim(srslog::basic_logger& logger); int init(usim_args_t* args); void stop(); diff --git a/srsue/hdr/stack/upper/usim_base.h b/srsue/hdr/stack/upper/usim_base.h index 0c9d181a9..1f76e9f93 100644 --- a/srsue/hdr/stack/upper/usim_base.h +++ b/srsue/hdr/stack/upper/usim_base.h @@ -26,6 +26,7 @@ #include "srslte/common/log.h" #include "srslte/common/security.h" #include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" #include namespace srsue { @@ -66,9 +67,9 @@ public: class usim_base : public usim_interface_nas, public usim_interface_rrc, public usim_interface_rrc_nr { public: - usim_base(srslte::log* log_); + explicit usim_base(srslog::basic_logger& logger); virtual ~usim_base(); - static std::unique_ptr get_instance(usim_args_t* args, srslte::log* log_); + static std::unique_ptr get_instance(usim_args_t* args, srslog::basic_logger& logger); virtual int init(usim_args_t* args) = 0; virtual void stop() = 0; @@ -113,7 +114,7 @@ protected: bool initiated = false; // Logging - srslte::log* log = nullptr; + srslog::basic_logger& logger; // User data // 3GPP 33.102 v10.0.0 Annex H diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index f6f05fe8b..7f7207b41 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -37,6 +37,7 @@ #include "srslte/common/log_filter.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" +#include "srslte/srslog/srslog.h" #include "stack/ue_stack_base.h" #include "ue_metrics_interface.h" @@ -92,7 +93,7 @@ typedef struct { class ue : public ue_metrics_interface { public: - ue(); + ue(srslog::sink& log_sink); ~ue(); int init(const all_args_t& args_, srslte::logger* logger_); @@ -114,11 +115,11 @@ private: std::unique_ptr gw_inst; // Generic logger members - srslte::logger* logger = nullptr; - srslte::log_filter log; // Own logger for UE + srslte::logger* old_logger = nullptr; + srslog::sink& log_sink; + srslog::basic_logger& logger; - all_args_t args; - srslte::byte_buffer_pool* pool = nullptr; + all_args_t args; // Helper functions int parse_args(const all_args_t& args); // parse and validate arguments diff --git a/srsue/hdr/ue_metrics_interface.h b/srsue/hdr/ue_metrics_interface.h index fa6728061..85d611076 100644 --- a/srsue/hdr/ue_metrics_interface.h +++ b/srsue/hdr/ue_metrics_interface.h @@ -36,6 +36,7 @@ namespace srsue { typedef struct { + uint32_t ul_dropped_sdus; mac_metrics_t mac[SRSLTE_MAX_CARRIERS]; srslte::rlc_metrics_t rlc; nas_metrics_t nas; diff --git a/srsue/src/CMakeLists.txt b/srsue/src/CMakeLists.txt index 6c5940e69..ad18a22d4 100644 --- a/srsue/src/CMakeLists.txt +++ b/srsue/src/CMakeLists.txt @@ -35,10 +35,8 @@ add_executable(srsue main.cc ue.cc metrics_stdout.cc metrics_csv.cc) set(SRSUE_SOURCES srsue_phy srsue_stack srsue_upper srsue_mac srsue_rrc srslog) set(SRSLTE_SOURCES srslte_common srslte_mac srslte_phy srslte_radio srslte_upper rrc_asn1 srslog) -if(ENABLE_5GNR) - set(SRSUE_SOURCES ${SRSUE_SOURCES} srsue_nr_stack srsue_rrc_nr srsue_mac_nr) - set(SRSLTE_SOURCES ${SRSLTE_SOURCES} rrc_nr_asn1 ngap_nr_asn1) -endif() +set(SRSUE_SOURCES ${SRSUE_SOURCES} srsue_nr_stack srsue_rrc_nr srsue_mac_nr) +set(SRSLTE_SOURCES ${SRSLTE_SOURCES} rrc_nr_asn1 ngap_nr_asn1) target_link_libraries(srsue ${SRSUE_SOURCES} ${SRSLTE_SOURCES} diff --git a/srsue/src/main.cc b/srsue/src/main.cc index c3877ff3b..a503270a0 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -76,26 +76,27 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("ue.phy", bpo::value(&args->phy.type)->default_value("lte"), "Type of the PHY [lte]") ("ue.stack", bpo::value(&args->stack.type)->default_value("lte"), "Type of the upper stack [lte, nr]") - ("rf.dl_earfcn", bpo::value(&args->phy.dl_earfcn)->default_value("3400"), "Downlink EARFCN list") - ("rf.ul_earfcn", bpo::value(&args->phy.ul_earfcn), "Uplink EARFCN list. Optional.") - ("rf.srate", bpo::value(&args->rf.srate_hz)->default_value(0.0), "Force Tx and Rx sampling rate in Hz") - ("rf.freq_offset", bpo::value(&args->rf.freq_offset)->default_value(0), "(optional) Frequency offset") - ("rf.dl_freq", bpo::value(&args->phy.dl_freq)->default_value(-1), "Downlink Frequency (if positive overrides EARFCN)") - ("rf.ul_freq", bpo::value(&args->phy.ul_freq)->default_value(-1), "Uplink Frequency (if positive overrides EARFCN)") - ("rf.rx_gain", bpo::value(&args->rf.rx_gain)->default_value(-1), "Front-end receiver gain") - ("rf.tx_gain", bpo::value(&args->rf.tx_gain)->default_value(-1), "Front-end transmitter gain (all channels)") - ("rf.tx_gain[0]", bpo::value(&args->rf.tx_gain_ch[0])->default_value(-1), "Front-end transmitter gain CH0") - ("rf.tx_gain[1]", bpo::value(&args->rf.tx_gain_ch[1])->default_value(-1), "Front-end transmitter gain CH1") - ("rf.tx_gain[2]", bpo::value(&args->rf.tx_gain_ch[2])->default_value(-1), "Front-end transmitter gain CH2") - ("rf.tx_gain[3]", bpo::value(&args->rf.tx_gain_ch[3])->default_value(-1), "Front-end transmitter gain CH3") - ("rf.tx_gain[4]", bpo::value(&args->rf.tx_gain_ch[4])->default_value(-1), "Front-end transmitter gain CH4") - ("rf.rx_gain[0]", bpo::value(&args->rf.rx_gain_ch[0])->default_value(-1), "Front-end receiver gain CH0") - ("rf.rx_gain[1]", bpo::value(&args->rf.rx_gain_ch[1])->default_value(-1), "Front-end receiver gain CH1") - ("rf.rx_gain[2]", bpo::value(&args->rf.rx_gain_ch[2])->default_value(-1), "Front-end receiver gain CH2") - ("rf.rx_gain[3]", bpo::value(&args->rf.rx_gain_ch[3])->default_value(-1), "Front-end receiver gain CH3") - ("rf.rx_gain[4]", bpo::value(&args->rf.rx_gain_ch[4])->default_value(-1), "Front-end receiver gain CH4") - ("rf.nof_carriers", bpo::value(&args->rf.nof_carriers)->default_value(1), "Number of carriers") - ("rf.nof_antennas", bpo::value(&args->rf.nof_antennas)->default_value(1), "Number of antennas per carrier") + ("rf.dl_earfcn", bpo::value(&args->phy.dl_earfcn)->default_value("3400"), "Downlink EARFCN list") + ("rf.ul_earfcn", bpo::value(&args->phy.ul_earfcn), "Uplink EARFCN list. Optional.") + ("rf.dl_nr_arfcn", bpo::value(&args->phy.dl_nr_arfcn)->default_value("632628"), "Downlink NR-ARFCN list") + ("rf.srate", bpo::value(&args->rf.srate_hz)->default_value(0.0), "Force Tx and Rx sampling rate in Hz") + ("rf.freq_offset", bpo::value(&args->rf.freq_offset)->default_value(0), "(optional) Frequency offset") + ("rf.dl_freq", bpo::value(&args->phy.dl_freq)->default_value(-1), "Downlink Frequency (if positive overrides EARFCN)") + ("rf.ul_freq", bpo::value(&args->phy.ul_freq)->default_value(-1), "Uplink Frequency (if positive overrides EARFCN)") + ("rf.rx_gain", bpo::value(&args->rf.rx_gain)->default_value(-1), "Front-end receiver gain") + ("rf.tx_gain", bpo::value(&args->rf.tx_gain)->default_value(-1), "Front-end transmitter gain (all channels)") + ("rf.tx_gain[0]", bpo::value(&args->rf.tx_gain_ch[0])->default_value(-1), "Front-end transmitter gain CH0") + ("rf.tx_gain[1]", bpo::value(&args->rf.tx_gain_ch[1])->default_value(-1), "Front-end transmitter gain CH1") + ("rf.tx_gain[2]", bpo::value(&args->rf.tx_gain_ch[2])->default_value(-1), "Front-end transmitter gain CH2") + ("rf.tx_gain[3]", bpo::value(&args->rf.tx_gain_ch[3])->default_value(-1), "Front-end transmitter gain CH3") + ("rf.tx_gain[4]", bpo::value(&args->rf.tx_gain_ch[4])->default_value(-1), "Front-end transmitter gain CH4") + ("rf.rx_gain[0]", bpo::value(&args->rf.rx_gain_ch[0])->default_value(-1), "Front-end receiver gain CH0") + ("rf.rx_gain[1]", bpo::value(&args->rf.rx_gain_ch[1])->default_value(-1), "Front-end receiver gain CH1") + ("rf.rx_gain[2]", bpo::value(&args->rf.rx_gain_ch[2])->default_value(-1), "Front-end receiver gain CH2") + ("rf.rx_gain[3]", bpo::value(&args->rf.rx_gain_ch[3])->default_value(-1), "Front-end receiver gain CH3") + ("rf.rx_gain[4]", bpo::value(&args->rf.rx_gain_ch[4])->default_value(-1), "Front-end receiver gain CH4") + ("rf.nof_carriers", bpo::value(&args->rf.nof_carriers)->default_value(1), "Number of carriers") + ("rf.nof_antennas", bpo::value(&args->rf.nof_antennas)->default_value(1), "Number of antennas per carrier") ("rf.device_name", bpo::value(&args->rf.device_name)->default_value("auto"), "Front-end device name") ("rf.device_args", bpo::value(&args->rf.device_args)->default_value("auto"), "Front-end device arguments") @@ -649,6 +650,7 @@ int main(int argc, char* argv[]) return SRSLTE_ERROR; } srslte::srslog_wrapper log_wrapper(*chan); + srslog::set_default_sink(*log_sink); // Start the log backend. srslog::init(); @@ -659,7 +661,7 @@ int main(int argc, char* argv[]) srslte::check_scaling_governor(args.rf.device_name); // Create UE instance - srsue::ue ue; + srsue::ue ue(*log_sink); if (ue.init(args, &log_wrapper)) { ue.stop(); return SRSLTE_SUCCESS; diff --git a/srsue/src/phy/CMakeLists.txt b/srsue/src/phy/CMakeLists.txt index 7adc06455..867e17ea6 100644 --- a/srsue/src/phy/CMakeLists.txt +++ b/srsue/src/phy/CMakeLists.txt @@ -25,7 +25,5 @@ if(ENABLE_GUI AND SRSGUI_FOUND) target_link_libraries(srsue_phy ${SRSGUI_LIBRARIES}) endif(ENABLE_GUI AND SRSGUI_FOUND) -if(ENABLE_5GNR) set(SOURCES_NR "../phy/vnf_phy_nr.cc") add_library(srsue_phy_nr STATIC ${SOURCES_NR}) -endif() \ No newline at end of file diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index b3d4e837c..2b649c81a 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -25,16 +25,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) #define CURRENT_TTI (sf_cfg_dl.tti) #define CURRENT_SFIDX (sf_cfg_dl.tti % 10) @@ -49,34 +49,34 @@ namespace lte { * */ -cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_, srslte::log* log_h_) +cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_, srslog::basic_logger& logger) : + logger(logger) { cc_idx = cc_idx_; phy = phy_; - log_h = log_h_; signal_buffer_max_samples = 3 * SRSLTE_SF_LEN_PRB(max_prb); for (uint32_t i = 0; i < phy->args->nof_rx_ant; i++) { signal_buffer_rx[i] = srslte_vec_cf_malloc(signal_buffer_max_samples); if (!signal_buffer_rx[i]) { - Error("Allocating memory\n"); + Error("Allocating memory"); return; } signal_buffer_tx[i] = srslte_vec_cf_malloc(signal_buffer_max_samples); if (!signal_buffer_tx[i]) { - Error("Allocating memory\n"); + Error("Allocating memory"); return; } } if (srslte_ue_dl_init(&ue_dl, signal_buffer_rx, max_prb, phy->args->nof_rx_ant)) { - Error("Initiating UE DL\n"); + Error("Initiating UE DL"); return; } if (srslte_ue_ul_init(&ue_ul, signal_buffer_tx[0], max_prb)) { - Error("Initiating UE UL\n"); + Error("Initiating UE UL"); return; } @@ -134,16 +134,16 @@ bool cc_worker::set_cell_unlocked(srslte_cell_t cell_) cell = cell_; if (srslte_ue_dl_set_cell(&ue_dl, cell)) { - Error("Setting ue_dl cell\n"); + Error("Setting ue_dl cell"); return false; } if (srslte_ue_dl_set_mbsfn_area_id(&ue_dl, 1)) { - Error("Setting mbsfn id\n"); + Error("Setting mbsfn id"); } if (srslte_ue_ul_set_cell(&ue_ul, cell)) { - Error("Initiating UE UL\n"); + Error("Initiating UE UL"); return false; } @@ -221,7 +221,7 @@ bool cc_worker::work_dl_regular() bool found_dl_grant = false; if (!cell_initiated) { - log_h->warning("Trying to access cc_worker=%d while cell not initialized (DL)\n", cc_idx); + logger.warning("Trying to access cc_worker=%d while cell not initialized (DL)", cc_idx); return false; } @@ -251,7 +251,7 @@ bool cc_worker::work_dl_regular() /* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */ if (srslte_ue_dl_decode_fft_estimate(&ue_dl, &sf_cfg_dl, &ue_dl_cfg) < 0) { - Error("Getting PDCCH FFT estimate\n"); + Error("Getting PDCCH FFT estimate"); return false; } @@ -276,7 +276,7 @@ bool cc_worker::work_dl_regular() } // Generate PHY grant if (srslte_ue_dl_dci_to_pdsch_grant(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, &dci_dl, &ue_dl_cfg.cfg.pdsch.grant)) { - Info("Converting DCI message to DL dci\n"); + Info("Converting DCI message to DL dci"); return false; } @@ -316,7 +316,7 @@ bool cc_worker::work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg) mac_interface_phy_lte::tb_action_dl_t dl_action = {}; if (!cell_initiated) { - log_h->warning("Trying to access cc_worker=%d while cell not initialized (MBSFN)\n", cc_idx); + logger.warning("Trying to access cc_worker=%d while cell not initialized (MBSFN)", cc_idx); return false; } @@ -332,7 +332,7 @@ bool cc_worker::work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg) /* Do FFT and extract PDCCH LLR, or quit if no actions are required in this subframe */ if (srslte_ue_dl_decode_fft_estimate(&ue_dl, &sf_cfg_dl, &ue_dl_cfg) < 0) { - Error("Getting PDCCH FFT estimate\n"); + Error("Getting PDCCH FFT estimate"); return false; } @@ -392,12 +392,12 @@ int cc_worker::decode_pdcch_dl() /* Blind search first without cross scheduling then with it if enabled */ for (int i = 0; i < (ue_dl_cfg.cfg.dci.cif_present ? 2 : 1) && !nof_grants; i++) { - Debug("PDCCH looking for rnti=0x%x\n", dl_rnti); + Debug("PDCCH looking for rnti=0x%x", dl_rnti); ue_dl_cfg.cfg.dci.cif_enabled = i > 0; ue_dl_cfg.cfg.dci_common_ss = (cc_idx == 0); nof_grants = srslte_ue_dl_find_dl_dci(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, dl_rnti, dci); if (nof_grants < 0) { - Error("Looking for DL grants\n"); + Error("Looking for DL grants"); return -1; } } @@ -412,10 +412,10 @@ int cc_worker::decode_pdcch_dl() phy->set_dl_pending_grant(CURRENT_TTI, dci[k].cif_present ? dci[k].cif : cc_idx, cc_idx, &dci[k]); // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_dci_dl_info(&dci[k], str, 512); - log_h->info("PDCCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, ue_dl.chest_res.snr_db); + logger.info("PDCCH: cc=%d, %s, snr=%.1f dB", cc_idx, str, ue_dl.chest_res.snr_db); } } } @@ -453,7 +453,7 @@ int cc_worker::decode_pdsch(srslte_pdsch_ack_resource_t ack_resource, // Run PDSCH decoder if (decode_enable) { if (srslte_ue_dl_decode_pdsch(&ue_dl, &sf_cfg_dl, &ue_dl_cfg.cfg.pdsch, pdsch_dec)) { - Error("ERROR: Decoding PDSCH\n"); + Error("ERROR: Decoding PDSCH"); } } @@ -489,10 +489,10 @@ int cc_worker::decode_pdsch(srslte_pdsch_ack_resource_t ack_resource, phy->set_dl_metrics(cc_idx, dl_metrics); // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_pdsch_rx_info(&ue_dl_cfg.cfg.pdsch, pdsch_dec, str, 512); - log_h->info("PDSCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, ue_dl.chest_res.snr_db); + logger.info("PDSCH: cc=%d, %s, snr=%.1f dB", cc_idx, str, ue_dl.chest_res.snr_db); } } @@ -512,7 +512,7 @@ int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srslte srslte_softbuffer_rx_reset_tbs(pmch_cfg.pdsch_cfg.softbuffers.rx[0], pmch_cfg.pdsch_cfg.grant.tb[0].tbs); if (srslte_ue_dl_decode_pmch(&ue_dl, &sf_cfg_dl, &pmch_cfg, &pmch_dec)) { - Error("Decoding PMCH\n"); + Error("Decoding PMCH"); return -1; } @@ -523,7 +523,7 @@ int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srslte dl_metrics.turbo_iters = pmch_dec.avg_iterations_block / 2; phy->set_dl_metrics(cc_idx, dl_metrics); - Info("PMCH: l_crb=%2d, tbs=%d, mcs=%d, crc=%s, snr=%.1f dB, n_iter=%.1f\n", + Info("PMCH: l_crb=%2d, tbs=%d, mcs=%d, crc=%s, snr=%.1f dB, n_iter=%.1f", pmch_cfg.pdsch_cfg.grant.nof_prb, pmch_cfg.pdsch_cfg.grant.tb[0].tbs / 8, pmch_cfg.pdsch_cfg.grant.tb[0].mcs_idx, @@ -536,7 +536,7 @@ int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srslte } } else { - Warning("Received dci for TBS=0\n"); + Warning("Received dci for TBS=0"); } return 0; } @@ -552,10 +552,10 @@ void cc_worker::decode_phich() phich_grant.I_phich = I_phich; if (phy->get_ul_pending_ack(&sf_cfg_dl, cc_idx, &phich_grant, &dci_ul)) { if (srslte_ue_dl_decode_phich(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, &phich_grant, &phich_res)) { - Error("Decoding PHICH\n"); + Error("Decoding PHICH"); } phy->set_ul_received_ack(&sf_cfg_dl, cc_idx, phich_res.ack_value, I_phich, &dci_ul); - Info("PHICH: hi=%d, corr=%.1f, I_lowest=%d, n_dmrs=%d, I_phich=%d\n", + Info("PHICH: hi=%d, corr=%.1f, I_lowest=%d, n_dmrs=%d, I_phich=%d", phich_res.ack_value, phich_res.distance, phich_grant.n_prb_lowest, @@ -587,7 +587,7 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data) uint32_t pid = 0; if (!cell_initiated) { - log_h->warning("Trying to access cc_worker=%d while cell not initialized (UL)\n", cc_idx); + logger.warning("Trying to access cc_worker=%d while cell not initialized (UL)", cc_idx); return false; } @@ -616,14 +616,14 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data) // Generate PHY grant if (srslte_ue_ul_dci_to_pusch_grant(&ue_ul, &sf_cfg_ul, &ue_ul_cfg, &dci_ul, &ue_ul_cfg.ul_cfg.pusch.grant)) { - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[128]; srslte_dci_ul_info(&dci_ul, str, sizeof(str)); - Info("Converting DCI message to UL grant %s\n", str); + Info("Converting DCI message to UL grant %s", str); } ul_grant_available = false; } else if (ue_ul_cfg.ul_cfg.pusch.grant.tb.mod == SRSLTE_MOD_BPSK) { - Error("UL retransmission without valid stored grant.\n"); + Error("UL retransmission without valid stored grant."); ul_grant_available = false; } else { // Save TBS info for next retx @@ -711,7 +711,7 @@ int cc_worker::decode_pdcch_ul() ue_dl_cfg.cfg.dci_common_ss = (cc_idx == 0); nof_grants = srslte_ue_dl_find_ul_dci(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, ul_rnti, dci); if (nof_grants < 0) { - Error("Looking for UL grants\n"); + Error("Looking for UL grants"); return -1; } } @@ -726,10 +726,10 @@ int cc_worker::decode_pdcch_ul() phy->set_ul_pending_grant(&sf_cfg_dl, cc_idx_grant, &dci[k]); // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; srslte_dci_ul_info(&dci[k], str, 512); - log_h->info("PDCCH: cc=%d, %s, snr=%.1f dB\n", cc_idx_grant, str, ue_dl.chest_res.snr_db); + logger.info("PDCCH: cc=%d, %s, snr=%.1f dB", cc_idx_grant, str, ue_dl.chest_res.snr_db); } } } @@ -770,7 +770,7 @@ bool cc_worker::encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srs // Encode signal int ret = srslte_ue_ul_encode(&ue_ul, &sf_cfg_ul, &ue_ul_cfg, &data); if (ret < 0) { - Error("Encoding UL cc=%d\n", cc_idx); + Error("Encoding UL cc=%d", cc_idx); } // Store metrics @@ -782,10 +782,10 @@ bool cc_worker::encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srs } // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { + if (logger.info.enabled()) { char str[512]; if (srslte_ue_ul_info(&ue_ul_cfg, &sf_cfg_ul, &data.uci, str, 512)) { - log_h->info("%s\n", str); + logger.info("%s", str); } } @@ -794,12 +794,12 @@ bool cc_worker::encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srs void cc_worker::set_uci_sr(srslte_uci_data_t* uci_data) { - Debug("set_uci_sr() query: sr_enabled=%d, last_tx_tti=%d\n", phy->sr_enabled, phy->sr_last_tx_tti); + Debug("set_uci_sr() query: sr_enabled=%d, last_tx_tti=%d", phy->sr_enabled, phy->sr_last_tx_tti); if (srslte_ue_ul_gen_sr(&ue_ul_cfg, &sf_cfg_ul, uci_data, phy->sr_enabled)) { if (phy->sr_enabled) { phy->sr_last_tx_tti = CURRENT_TTI_TX; phy->sr_enabled = false; - Debug("set_uci_sr() sending SR: sr_enabled=%d, last_tx_tti=%d\n", phy->sr_enabled, phy->sr_last_tx_tti); + Debug("set_uci_sr() sending SR: sr_enabled=%d, last_tx_tti=%d", phy->sr_enabled, phy->sr_last_tx_tti); } } } @@ -833,7 +833,7 @@ void cc_worker::set_uci_aperiodic_cqi(srslte_uci_data_t* uci_data) if (ue_dl_cfg.cfg.cqi_report.aperiodic_configured) { srslte_ue_dl_gen_cqi_aperiodic(&ue_dl, &ue_dl_cfg, get_wideband_cqi(), uci_data); } else { - Warning("Received CQI request but aperiodic mode is not configured\n"); + Warning("Received CQI request but aperiodic mode is not configured"); } } @@ -886,9 +886,9 @@ void cc_worker::set_config_unlocked(srslte::phy_cfg_t& phy_cfg) // Update signals if (pregen_enabled) { - Info("Pre-generating UL signals...\n"); + Info("Pre-generating UL signals..."); srslte_ue_ul_pregen_signals(&ue_ul, &ue_ul_cfg); - Info("Done pre-generating signals worker...\n"); + Info("Done pre-generating signals worker..."); } } diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index 352b83caa..e11c8a025 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -28,16 +28,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) /* This is to visualize the channel response */ #ifdef ENABLE_GUI @@ -57,14 +57,13 @@ static bool plot_nr_enable = false; namespace srsue { namespace lte { -sf_worker::sf_worker(uint32_t max_prb, phy_common* phy_, srslte::log* log_h_) +sf_worker::sf_worker(uint32_t max_prb, phy_common* phy_, srslog::basic_logger& logger) : logger(logger) { - phy = phy_; - log_h = log_h_; + phy = phy_; // ue_sync in phy.cc requires a buffer for 3 subframes for (uint32_t r = 0; r < phy->args->nof_lte_carriers; r++) { - cc_workers.push_back(new cc_worker(r, max_prb, phy, log_h)); + cc_workers.push_back(new cc_worker(r, max_prb, phy, logger)); } } @@ -84,11 +83,11 @@ bool sf_worker::set_cell_unlocked(uint32_t cc_idx, srslte_cell_t cell_) { if (cc_idx < cc_workers.size()) { if (!cc_workers[cc_idx]->set_cell_unlocked(cell_)) { - Error("Setting cell for cc=%d\n", cc_idx); + Error("Setting cell for cc=%d", cc_idx); return false; } } else { - Error("Setting cell for cc=%d; Not enough CC workers (%zd);\n", cc_idx, cc_workers.size()); + Error("Setting cell for cc=%d; Not enough CC workers (%zd);", cc_idx, cc_workers.size()); } if (cc_idx == 0) { @@ -122,7 +121,7 @@ void sf_worker::set_tti(uint32_t tti_) cc_worker->set_tti(tti); } - log_h->step(tti); + logger.set_context(tti); } void sf_worker::set_tx_time(const srslte::rf_timestamp_t& tx_time_) @@ -172,7 +171,7 @@ void sf_worker::set_config_unlocked(uint32_t cc_idx, srslte::phy_cfg_t phy_cfg) cc_workers[0]->upd_config_dci_unlocked(phy_cfg.dl_cfg.dci); } } else { - Error("Setting config for cc=%d; Invalid cc_idx\n", cc_idx); + Error("Setting config for cc=%d; Invalid cc_idx", cc_idx); } } @@ -181,7 +180,7 @@ void sf_worker::work_imp() srslte::rf_buffer_t tx_signal_ptr = {}; if (!cell_initiated) { - phy->worker_end(this, false, tx_signal_ptr, tx_time); + phy->worker_end(this, false, tx_signal_ptr, tx_time, false); return; } @@ -253,7 +252,7 @@ void sf_worker::work_imp() } // Call worker_end to transmit the signal - phy->worker_end(this, tx_signal_ready, tx_signal_ptr, tx_time); + phy->worker_end(this, tx_signal_ready, tx_signal_ptr, tx_time, false); if (rx_signal_ok) { update_measurements(); @@ -389,15 +388,13 @@ static void* plot_thread_run(void* arg) plot_scatter_setTitle(&pconst, (char*)"LTE - PDSCH - Equalized Symbols"); plot_scatter_setXAxisScale(&pconst, -4, 4); plot_scatter_setYAxisScale(&pconst, -4, 4); - plot_scatter_addToWindowGrid(&pconst, (char*)"srsue", 0, row_count++); - plot_scatter_init(&pconst_nr); - plot_scatter_setTitle(&pconst_nr, (char*)"NR - PDSCH - Equalized Symbols"); - plot_scatter_setXAxisScale(&pconst_nr, -4, 4); - plot_scatter_setYAxisScale(&pconst_nr, -4, 4); - if (plot_nr_enable) { + plot_scatter_init(&pconst_nr); + plot_scatter_setTitle(&pconst_nr, (char*)"NR - PDSCH - Equalized Symbols"); + plot_scatter_setXAxisScale(&pconst_nr, -4, 4); + plot_scatter_setYAxisScale(&pconst_nr, -4, 4); plot_scatter_addToWindowGrid(&pconst_nr, (char*)"srsue", 0, row_count++); pconst_nr_ready = true; } diff --git a/srsue/src/phy/lte/worker_pool.cc b/srsue/src/phy/lte/worker_pool.cc index 3b4af0d0d..17969aaf6 100644 --- a/srsue/src/phy/lte/worker_pool.cc +++ b/srsue/src/phy/lte/worker_pool.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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 "srsue/hdr/phy/lte/worker_pool.h" @@ -25,24 +16,16 @@ namespace lte { worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {} -bool worker_pool::init(phy_common* common, srslte::logger* logger, int prio) +bool worker_pool::init(phy_common* common, srslog::sink& log_sink, int prio) { - // Create logs - // Create array of pointers to phy_logs - for (uint32_t i = 0; i < common->args->nof_phy_threads; i++) { - auto* mylog = new srslte::log_filter; - char tmp[16]; - sprintf(tmp, "PHY%d", i); - mylog->init(tmp, logger, true); - mylog->set_level(common->args->log.phy_level); - mylog->set_hex_limit(common->args->log.phy_hex_limit); - log_vec.push_back(std::unique_ptr(mylog)); - } - // Add workers to workers pool and start threads for (uint32_t i = 0; i < common->args->nof_phy_threads; i++) { + srslog::basic_logger &log = srslog::fetch_basic_logger(fmt::format("PHY{}", i), log_sink); + log.set_level(srslog::str_to_basic_level(common->args->log.phy_level)); + log.set_hex_dump_max_size(common->args->log.phy_hex_limit); + auto w = - std::unique_ptr(new lte::sf_worker(SRSLTE_MAX_PRB, common, (srslte::log*)log_vec[i].get())); + std::unique_ptr(new lte::sf_worker(SRSLTE_MAX_PRB, common, log)); pool.init_worker(i, w.get(), prio, common->args->worker_cpu_mask); workers.push_back(std::move(w)); } diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index c9a6360a1..b4ee3cfaa 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -24,35 +15,52 @@ namespace srsue { namespace nr { -cc_worker::cc_worker(uint32_t cc_idx_, srslte::log* log, phy_nr_state* phy_state_) : - cc_idx(cc_idx_), phy_state(phy_state_), log_h(log) +cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state* phy_state_) : + cc_idx(cc_idx_), phy(phy_state_), logger(log) { - cf_t* buffer_c[SRSLTE_MAX_PORTS] = {}; + cf_t* rx_buffer_c[SRSLTE_MAX_PORTS] = {}; // Allocate buffers - buffer_sz = SRSLTE_SF_LEN_PRB(phy_state->args.dl.nof_max_prb) * 5; + buffer_sz = SRSLTE_SF_LEN_PRB(phy->args.dl.nof_max_prb) * 5; for (uint32_t i = 0; i < phy_state_->args.dl.nof_rx_antennas; i++) { - rx_buffer[i] = srslte_vec_cf_malloc(buffer_sz); - tx_buffer[i] = srslte_vec_cf_malloc(buffer_sz); - buffer_c[i] = rx_buffer[i]; + rx_buffer[i] = srslte_vec_cf_malloc(buffer_sz); + rx_buffer_c[i] = rx_buffer[i]; + tx_buffer[i] = srslte_vec_cf_malloc(buffer_sz); } - if (srslte_ue_dl_nr_init(&ue_dl, buffer_c, &phy_state_->args.dl) < SRSLTE_SUCCESS) { - ERROR("Error initiating UE DL NR\n"); + if (srslte_ue_dl_nr_init(&ue_dl, rx_buffer.data(), &phy_state_->args.dl) < SRSLTE_SUCCESS) { + ERROR("Error initiating UE DL NR"); + return; + } + + if (srslte_ue_ul_nr_init(&ue_ul, tx_buffer[0], &phy_state_->args.ul) < SRSLTE_SUCCESS) { + ERROR("Error initiating UE DL NR"); + return; + } + + if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < + SRSLTE_SUCCESS) { + ERROR("Error init soft-buffer"); return; } if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < SRSLTE_SUCCESS) { - ERROR("Error init soft-buffer\n"); + ERROR("Error init soft-buffer"); return; } - data.resize(SRSLTE_SCH_NR_MAX_NOF_CB_LDPC * SRSLTE_LDPC_MAX_LEN_ENCODED_CB / 8); + + // Initialise data with numbers + tx_data.resize(SRSLTE_SCH_NR_MAX_NOF_CB_LDPC * SRSLTE_LDPC_MAX_LEN_ENCODED_CB / 8); + for (uint32_t i = 0; i < SRSLTE_SCH_NR_MAX_NOF_CB_LDPC * SRSLTE_LDPC_MAX_LEN_ENCODED_CB / 8; i++) { + tx_data[i] = i % 255U; + } } cc_worker::~cc_worker() { srslte_ue_dl_nr_free(&ue_dl); + srslte_ue_ul_nr_free(&ue_ul); srslte_softbuffer_rx_free(&softbuffer_rx); for (cf_t* p : rx_buffer) { if (p != nullptr) { @@ -69,21 +77,22 @@ cc_worker::~cc_worker() bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier) { if (srslte_ue_dl_nr_set_carrier(&ue_dl, carrier) < SRSLTE_SUCCESS) { - ERROR("Error setting carrier\n"); + ERROR("Error setting carrier"); return false; } - coreset.freq_resources[0] = true; // Enable the bottom 6 PRB for PDCCH - coreset.duration = 2; + if (srslte_ue_dl_nr_set_pdcch_config(&ue_dl, &phy->cfg.pdcch) < SRSLTE_SUCCESS) { + ERROR("Error setting carrier"); + return false; + } - if (srslte_ue_dl_nr_set_coreset(&ue_dl, &coreset) < SRSLTE_SUCCESS) { - ERROR("Error setting carrier\n"); + if (srslte_ue_ul_nr_set_carrier(&ue_ul, carrier) < SRSLTE_SUCCESS) { + ERROR("Error setting carrier"); return false; } // Set default PDSCH config - phy_state->cfg.pdsch.rbg_size_cfg_1 = false; - phy_state->cfg.pdsch.pdsch_time_is_default = true; + phy->cfg.pdsch.rbg_size_cfg_1 = false; return true; } @@ -91,77 +100,243 @@ bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier) void cc_worker::set_tti(uint32_t tti) { dl_slot_cfg.idx = tti; + ul_slot_cfg.idx = TTI_TX(tti); } cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx) { - if (antenna_idx >= phy_state->args.dl.nof_rx_antennas) { + if (antenna_idx >= phy->args.dl.nof_rx_antennas) { return nullptr; } return rx_buffer.at(antenna_idx); } +cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx) +{ + if (antenna_idx >= phy->args.dl.nof_rx_antennas) { + return nullptr; + } + + return tx_buffer.at(antenna_idx); +} + uint32_t cc_worker::get_buffer_len() { return buffer_sz; } +void cc_worker::decode_pdcch_dl() +{ + std::array dci_rx = {}; + srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy->stack->get_dl_sched_rnti_nr(dl_slot_cfg.idx); + + // Skip search if no valid RNTI is given + if (rnti.id == SRSLTE_INVALID_RNTI) { + return; + } + + // Search for grants + int n_dl = + srslte_ue_dl_nr_find_dl_dci(&ue_dl, &dl_slot_cfg, rnti.id, rnti.type, dci_rx.data(), (uint32_t)dci_rx.size()); + if (n_dl < SRSLTE_SUCCESS) { + logger.error("Error decoding DL NR-PDCCH"); + return; + } + + // Iterate over all received grants + for (int i = 0; i < n_dl; i++) { + // Log found DCI + if (logger.info.enabled()) { + std::array str; + srslte_dci_dl_nr_to_str(&dci_rx[i], str.data(), str.size()); + logger.info("PDCCH: cc=%d, %s", cc_idx, str.data()); + } + + // Enqueue UL grants + phy->set_dl_pending_grant(dl_slot_cfg.idx, dci_rx[i]); + } +} + +void cc_worker::decode_pdcch_ul() +{ + std::array dci_rx = {}; + srsue::mac_interface_phy_nr::sched_rnti_t rnti = phy->stack->get_ul_sched_rnti_nr(ul_slot_cfg.idx); + + // Skip search if no valid RNTI is given + if (rnti.id == SRSLTE_INVALID_RNTI) { + return; + } + + // Search for grants + int n_dl = + srslte_ue_dl_nr_find_ul_dci(&ue_dl, &dl_slot_cfg, rnti.id, rnti.type, dci_rx.data(), (uint32_t)dci_rx.size()); + if (n_dl < SRSLTE_SUCCESS) { + logger.error("Error decoding UL NR-PDCCH"); + return; + } + + // Iterate over all received grants + for (int i = 0; i < n_dl; i++) { + // Log found DCI + if (logger.info.enabled()) { + std::array str; + srslte_dci_ul_nr_to_str(&dci_rx[i], str.data(), str.size()); + logger.info("PDCCH: cc=%d, %s", cc_idx, str.data()); + } + + // Enqueue UL grants + phy->set_ul_pending_grant(dl_slot_cfg.idx, dci_rx[i]); + } +} + bool cc_worker::work_dl() { - srslte_dci_dl_nr_t dci_dl = {}; - srslte_sch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; - std::array pdsch_res = {}; - // Run FFT srslte_ue_dl_nr_estimate_fft(&ue_dl, &dl_slot_cfg); - // Set rnti - rnti = 0x1234; + // Decode PDCCH DL first + decode_pdcch_dl(); - // Configure Search space - search_space.type = srslte_search_space_type_ue; - for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - search_space.nof_candidates[L] = srslte_pdcch_nr_max_candidates_coreset(&coreset, L); + // Decode PDCCH UL after + decode_pdcch_ul(); + + // Get DL grant for this TTI, if available + uint32_t pid = 0; + srslte_sch_cfg_nr_t pdsch_cfg = {}; + srslte_pdsch_ack_resource_nr_t ack_resource = {}; + if (phy->get_dl_pending_grant(dl_slot_cfg.idx, pdsch_cfg, ack_resource, pid)) { + // Get data buffer + srslte::unique_byte_buffer_t data = srslte::make_byte_buffer(); + data->N_bytes = pdsch_cfg.grant.tb[0].tbs / 8U; + + // Get soft-buffer from MAC + // ... + srslte_softbuffer_rx_reset(&softbuffer_rx); + + // Initialise PDSCH Result + std::array pdsch_res = {}; + pdsch_res[0].payload = data->msg; + pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer_rx; + + // Decode actual PDSCH transmission + if (srslte_ue_dl_nr_decode_pdsch(&ue_dl, &dl_slot_cfg, &pdsch_cfg, pdsch_res.data()) < SRSLTE_SUCCESS) { + ERROR("Error decoding PDSCH"); + return false; + } + + // Logging + if (logger.info.enabled()) { + std::array str; + srslte_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, pdsch_res.data(), str.data(), str.size()); + logger.info(pdsch_res[0].payload, pdsch_cfg.grant.tb[0].tbs / 8, "PDSCH: cc=%d, %s", cc_idx, str.data()); + } + + // Enqueue PDSCH ACK information only if the RNTI is type C + if (pdsch_cfg.grant.rnti_type == srslte_rnti_type_c) { + phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res[0].crc); + } + + // Notify MAC about PDSCH decoding result + if (pdsch_res[0].crc) { + // Prepare grant + mac_interface_phy_nr::mac_nr_grant_dl_t mac_nr_grant = {}; + mac_nr_grant.tb[0] = std::move(data); + mac_nr_grant.pid = pid; + mac_nr_grant.rnti = pdsch_cfg.grant.rnti; + mac_nr_grant.tti = dl_slot_cfg.idx; + + if (pdsch_cfg.grant.rnti_type == srslte_rnti_type_ra) { + phy->rar_grant_tti = dl_slot_cfg.idx; + } + + // Send data to MAC + phy->stack->tb_decoded(cc_idx, mac_nr_grant); + } } - srslte_dci_dl_nr_t dci_dl_rx = {}; - int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(&ue_dl, &search_space, &dl_slot_cfg, rnti, &dci_dl_rx, 1); - if (nof_found_dci < SRSLTE_SUCCESS) { - ERROR("Error decoding\n"); - return SRSLTE_ERROR; + return true; +} + +bool cc_worker::work_ul() +{ + srslte_uci_data_nr_t uci_data = {}; + uint32_t pid = 0; + + // Gather PDSCH ACK information + srslte_pdsch_ack_nr_t pdsch_ack = {}; + bool has_ul_ack = phy->get_pending_ack(ul_slot_cfg.idx, pdsch_ack); + + // Request grant to PHY state for this transmit TTI + srslte_sch_cfg_nr_t pusch_cfg = {}; + bool has_pusch_grant = phy->get_ul_pending_grant(ul_slot_cfg.idx, pusch_cfg, pid); + + // If PDSCH UL AKC is available, load into UCI + if (has_ul_ack) { + pdsch_ack.use_pusch = has_pusch_grant; + if (srslte_ue_dl_nr_gen_ack(&phy->cfg.harq_ack, &pdsch_ack, &uci_data) < SRSLTE_SUCCESS) { + ERROR("Filling UCI ACK bits"); + return false; + } } - if (nof_found_dci < 1) { - ERROR("Error DCI not found\n"); - } + if (has_pusch_grant) { + // Notify MAC about PUSCH found grant + mac_interface_phy_nr::mac_nr_grant_ul_t mac_ul_grant = {}; + mac_ul_grant.pid = pid; + mac_ul_grant.rnti = pusch_cfg.grant.rnti; + mac_ul_grant.tti = ul_slot_cfg.idx; + mac_ul_grant.tbs = pusch_cfg.grant.tb[0].tbs; + srslte::unique_byte_buffer_t tx_pdu = srslte::make_byte_buffer(); + phy->stack->new_grant_ul(0, mac_ul_grant, tx_pdu.get()); + // Provisional reset and assign Tx softbuffer + srslte_softbuffer_tx_reset(&softbuffer_tx); + pusch_cfg.grant.tb[0].softbuffer.tx = &softbuffer_tx; - dci_dl.rnti = 0x1234; - dci_dl.format = srslte_dci_format_nr_1_0; + // TODO: Use here PDU, after that, remove tx_data attribute + uint8_t* tx_data_ptr = tx_pdu.get()->msg; - dci_dl.freq_domain_assigment = 0x1FFF; - dci_dl.time_domain_assigment = 0; - dci_dl.mcs = 27; + // Encode PUSCH transmission + if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, tx_data_ptr) < SRSLTE_SUCCESS) { + ERROR("Encoding PUSCH"); + return false; + } - // Compute DL grant - if (srslte_ra_dl_dci_to_grant_nr(&ue_dl.carrier, &pdsch_cfg, &dci_dl, &pdsch_cfg.grant)) { - ERROR("Computing DL grant\n"); - } + // PUSCH Logging + if (logger.info.enabled()) { + std::array str; + srslte_ue_ul_nr_pusch_info(&ue_ul, &pusch_cfg, str.data(), str.size()); + logger.info(tx_data_ptr, + pusch_cfg.grant.tb[0].tbs / 8, + "PUSCH (NR): cc=%d, %s, tti_tx=%d", + cc_idx, + str.data(), + ul_slot_cfg.idx); + } + } else if (srslte_uci_nr_total_bits(&uci_data.cfg) > 0) { + // Get PUCCH resource + srslte_pucch_nr_resource_t resource = {}; + if (srslte_ra_ul_nr_pucch_resource(&phy->cfg.pucch, &uci_data.cfg, &resource) < SRSLTE_SUCCESS) { + ERROR("Selecting PUCCH resource"); + return false; + } - pdsch_res[0].payload = data.data(); - pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer_rx; - srslte_softbuffer_rx_reset(pdsch_cfg.grant.tb[0].softbuffer.rx); + // Encode PUCCH message + if (srslte_ue_ul_nr_encode_pucch(&ue_ul, &ul_slot_cfg, &phy->cfg.pucch.common, &resource, &uci_data) < + SRSLTE_SUCCESS) { + ERROR("Encoding PUCCH"); + return false; + } - if (srslte_ue_dl_nr_decode_pdsch(&ue_dl, &dl_slot_cfg, &pdsch_cfg, pdsch_res.data()) < SRSLTE_SUCCESS) { - ERROR("Error decoding PDSCH\n"); - return false; - } - - // Logging - if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { - char str[512]; - srslte_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, pdsch_res.data(), str, sizeof(str)); - log_h->info("PDSCH: cc=%d, %s\n", cc_idx, str); + // PUCCH Logging + if (logger.info.enabled()) { + std::array str; + srslte_ue_ul_nr_pucch_info(&resource, &uci_data, str.data(), str.size()); + logger.info("PUCCH: cc=%d, %s, tti_tx=%d", cc_idx, str.data(), ul_slot_cfg.idx); + } + } else { + // No NR signal shall be transmitted + srslte_vec_cf_zero(tx_buffer[0], ue_ul.ifft.sf_sz); } return true; diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index 103ee6d69..fea8876d2 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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. * */ @@ -35,7 +26,8 @@ static int plot_worker_id = -1; namespace srsue { namespace nr { -sf_worker::sf_worker(phy_nr_state* phy_state_, srslte::log* log) : phy_state(phy_state_), log_h(log) +sf_worker::sf_worker(phy_common* phy_, state* phy_state_, srslog::basic_logger& log) : + phy_state(phy_state_), phy(phy_), logger(log) { for (uint32_t i = 0; i < phy_state->args.nof_carriers; i++) { cc_worker* w = new cc_worker(i, log, phy_state); @@ -68,7 +60,8 @@ uint32_t sf_worker::get_buffer_len() void sf_worker::set_tti(uint32_t tti) { - log_h->step(tti); + tti_rx = tti; + logger.set_context(tti); for (auto& w : cc_workers) { w->set_tti(tti); } @@ -76,11 +69,45 @@ void sf_worker::set_tti(uint32_t tti) void sf_worker::work_imp() { + srslte::rf_buffer_t tx_buffer = {}; + srslte::rf_timestamp_t dummy_ts = {}; + + // Perform DL processing for (auto& w : cc_workers) { w->work_dl(); } - /* Tell the plotting thread to draw the plots */ + // Check if PRACH is available + if (prach_ptr != nullptr) { + // PRACH is available, set buffer, transmit and return + tx_buffer.set(0, prach_ptr); + + // Notify MAC about PRACH transmission + phy_state->stack->prach_sent(TTI_TX(tti_rx), 7, 1, 0, 0); + + // Transmit NR PRACH + phy->worker_end(this, false, tx_buffer, dummy_ts, true); + + // Reset PRACH pointer + prach_ptr = nullptr; + + return; + } + + // Perform UL processing + for (auto& w : cc_workers) { + w->work_ul(); + } + + // Set Tx buffers + for (uint32_t i = 0; i < (uint32_t)cc_workers.size(); i++) { + tx_buffer.set(i, cc_workers[i]->get_tx_buffer(0)); + } + + // Always call worker_end before returning + phy->worker_end(this, false, tx_buffer, dummy_ts, true); + + // Tell the plotting thread to draw the plots #ifdef ENABLE_GUI if ((int)get_id() == plot_worker_id) { sem_post(&plot_sem); @@ -108,6 +135,12 @@ void sf_worker::start_plot() #endif } +void sf_worker::set_prach(cf_t* prach_ptr_, float prach_power_) +{ + prach_ptr = prach_ptr_; + prach_power = prach_power_; +} + } // namespace nr } // namespace srsue @@ -120,7 +153,7 @@ extern bool plot_quit; static void* plot_thread_run(void* arg) { - auto worker = (srsue::nr::sf_worker*)arg; + auto worker = (srsue::nr::sf_worker*)arg; int pdsch_re_count = 0; while (!plot_quit) { sem_wait(&plot_sem); @@ -157,4 +190,4 @@ static void init_plots(srsue::nr::sf_worker* worker) exit(-1); } } -#endif \ No newline at end of file +#endif diff --git a/lib/src/radio/radio_null.cc b/srsue/src/phy/nr/state.cc similarity index 81% rename from lib/src/radio/radio_null.cc rename to srsue/src/phy/nr/state.cc index 093404b76..0e849375f 100644 --- a/lib/src/radio/radio_null.cc +++ b/srsue/src/phy/nr/state.cc @@ -19,11 +19,8 @@ * */ -#include "srslte/radio/radio_null.h" -#include +#include "srsue/hdr/phy/nr/state.h" -namespace srslte { - -radio_null::radio_null(srslte::logger* logger_) : log("RF"), radio_base(logger_) {} - -} // namespace srslte +namespace srsue { +namespace nr {} +} // namespace srsue \ No newline at end of file diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 65c7ab4bc..9043c5a41 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -1,21 +1,12 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited * - * This file is part of srsLTE. + * \section COPYRIGHT * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. + * Copyright 2013-2020 Software Radio Systems Limited * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. + * 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 "srsue/hdr/phy/nr/worker_pool.h" @@ -23,46 +14,58 @@ namespace srsue { namespace nr { -worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {} +worker_pool::worker_pool(uint32_t max_workers, srslog::sink& log_sink_) : + pool(max_workers), log_sink(log_sink_), logger(srslog::fetch_basic_logger("NR-PHY", log_sink)) +{} -bool worker_pool::init(phy_common* common, srslte::logger* logger, int prio) +bool worker_pool::init(const phy_args_nr_t& args, phy_common* common, stack_interface_phy_nr* stack_, int prio) { + phy_state.stack = stack_; + phy_state.args = args; + + // Set carrier attributes + phy_state.carrier.id = 500; + phy_state.carrier.nof_prb = args.nof_prb; + // Set NR arguments - phy_state.args.nof_carriers = common->args->nof_nr_carriers; - phy_state.args.dl.nof_max_prb = common->args->nr_nof_prb; + phy_state.args.nof_carriers = args.nof_carriers; + phy_state.args.dl.nof_max_prb = args.nof_prb; // Skip init of workers if no NR carriers if (phy_state.args.nof_carriers == 0) { return true; } - // Create logs - // Create array of pointers to phy_logs - for (uint32_t i = 0; i < common->args->nof_phy_threads; i++) { - auto* mylog = new srslte::log_filter; - char tmp[16]; - sprintf(tmp, "PHY%d", i); - mylog->init(tmp, logger, true); - mylog->set_level(common->args->log.phy_level); - mylog->set_hex_limit(common->args->log.phy_hex_limit); - log_vec.push_back(std::unique_ptr(mylog)); - } - // Add workers to workers pool and start threads - for (uint32_t i = 0; i < common->args->nof_phy_threads; i++) { - auto w = new sf_worker(&phy_state, (srslte::log*)log_vec[i].get()); - pool.init_worker(i, w, prio, common->args->worker_cpu_mask); + for (uint32_t i = 0; i < args.nof_phy_threads; i++) { + auto& log = srslog::fetch_basic_logger(fmt::format("PHY{}", i), log_sink); + log.set_level(srslog::str_to_basic_level(args.log.phy_level)); + log.set_hex_dump_max_size(args.log.phy_hex_limit); + + auto w = new sf_worker(common, &phy_state, log); + pool.init_worker(i, w, prio, args.worker_cpu_mask); workers.push_back(std::unique_ptr(w)); - srslte_carrier_nr_t c = {}; - c.nof_prb = phy_state.args.dl.nof_max_prb; - c.max_mimo_layers = 1; - - if (not w->set_carrier_unlocked(0, &c)) { + if (not w->set_carrier_unlocked(0, &phy_state.carrier)) { return false; } } + // Initialise PRACH + auto& prach_log = srslog::fetch_basic_logger("NR-PRACH", log_sink); + prach_log.set_level(srslog::str_to_basic_level(args.log.phy_level)); + prach_buffer = std::unique_ptr(new prach(prach_log)); + prach_buffer->init(phy_state.args.dl.nof_max_prb); + + // Set PRACH hard-coded cell + srslte_cell_t cell = {}; + cell.nof_prb = 50; + cell.id = phy_state.carrier.id; + if (not prach_buffer->set_cell(cell, phy_state.cfg.prach)) { + prach_log.error("Setting PRACH cell"); + return false; + } + return true; } @@ -73,12 +76,17 @@ void worker_pool::start_worker(sf_worker* w) sf_worker* worker_pool::wait_worker(uint32_t tti) { - return (sf_worker*)pool.wait_worker(tti); -} + sf_worker* worker = (sf_worker*)pool.wait_worker(tti); -sf_worker* worker_pool::wait_worker_id(uint32_t id) -{ - return (sf_worker*)pool.wait_worker_id(id); + // Generate PRACH if ready + if (prach_buffer->is_ready_to_send(tti, phy_state.carrier.id)) { + uint32_t nof_prach_sf = 0; + float prach_target_power = 0.0f; + cf_t* prach_ptr = prach_buffer->generate(0.0f, &nof_prach_sf, &prach_target_power); + worker->set_prach(prach_ptr, prach_target_power); + } + + return worker; } void worker_pool::stop() @@ -86,5 +94,45 @@ void worker_pool::stop() pool.stop(); } +void worker_pool::send_prach(uint32_t prach_occasion, uint32_t preamble_index, int preamble_received_target_power) +{ + prach_buffer->prepare_to_send(preamble_index); +} + +int worker_pool::set_ul_grant(std::array packed_ul_grant, + uint16_t rnti, + srslte_rnti_type_t rnti_type) +{ + // Copy DCI bits and setup DCI context + srslte_dci_msg_nr_t dci_msg = {}; + dci_msg.format = srslte_dci_format_nr_0_0; // MAC RAR grant shall be unpacked as DCI 0_0 format + dci_msg.rnti_type = rnti_type; + dci_msg.search_space = srslte_search_space_type_rar; // This indicates it is a MAC RAR + dci_msg.rnti = rnti; + dci_msg.nof_bits = SRSLTE_RAR_UL_GRANT_NBITS; + srslte_vec_u8_copy(dci_msg.payload, packed_ul_grant.data(), SRSLTE_RAR_UL_GRANT_NBITS); + + srslte_dci_ul_nr_t dci_ul = {}; + + if (srslte_dci_nr_rar_unpack(&dci_msg, &dci_ul) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + + if (logger.info.enabled()) { + std::array str; + srslte_dci_ul_nr_to_str(&dci_ul, str.data(), str.size()); + logger.set_context(phy_state.rar_grant_tti); + logger.info("Setting RAR Grant %s", str.data()); + } + + phy_state.set_ul_pending_grant(phy_state.rar_grant_tti, dci_ul); + + return SRSLTE_SUCCESS; +} +bool worker_pool::set_config(const srslte::phy_cfg_nr_t& cfg) +{ + phy_state.cfg = cfg; + return true; +} } // namespace nr -} // namespace srsue \ No newline at end of file +} // namespace srsue diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index f48b7f409..6a310b9ed 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -34,16 +34,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger_phy.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger_phy.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger_phy.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger_phy.debug(fmt, ##__VA_ARGS__) using namespace std; @@ -57,22 +57,18 @@ static void srslte_phy_handler(phy_logger_level_t log_level, void* ctx, char* st void phy::srslte_phy_logger(phy_logger_level_t log_level, char* str) { - if (log_phy_lib_h) { - switch (log_level) { - case LOG_LEVEL_INFO_S: - log_phy_lib_h->info(" %s", str); - break; - case LOG_LEVEL_DEBUG_S: - log_phy_lib_h->debug(" %s", str); - break; - case LOG_LEVEL_ERROR_S: - log_phy_lib_h->error(" %s", str); - break; - default: - break; - } - } else { - printf("[PHY_LIB]: %s\n", str); + switch (log_level) { + case LOG_LEVEL_INFO_S: + logger_phy_lib.info(" %s", str); + break; + case LOG_LEVEL_DEBUG_S: + logger_phy_lib.debug(" %s", str); + break; + case LOG_LEVEL_ERROR_S: + logger_phy_lib.error(" %s", str); + break; + default: + break; } } @@ -132,21 +128,16 @@ int phy::init(const phy_args_t& args_) } // Add PHY lib log - if (srslte::log::get_level_from_string(args.log.phy_lib_level) != srslte::LOG_LEVEL_NONE) { - log_phy_lib_h = std::unique_ptr(new srslte::log_filter); - log_phy_lib_h->init("PHY_LIB", logger, true); - log_phy_lib_h->set_level(args.log.phy_lib_level); - log_phy_lib_h->set_hex_limit(args.log.phy_hex_limit); + auto lib_log_level = srslog::str_to_basic_level(args.log.phy_lib_level); + logger_phy_lib.set_level(lib_log_level); + logger_phy_lib.set_hex_dump_max_size(args.log.phy_hex_limit); + if (lib_log_level != srslog::basic_levels::none) { srslte_phy_log_register_handler(this, srslte_phy_handler); } // set default logger - { - log_h = std::unique_ptr(new srslte::log_filter); - log_h->init("PHY", logger, true); - log_h->set_level(args.log.phy_level); - log_h->set_hex_limit(args.log.phy_hex_limit); - } + logger_phy.set_level(srslog::str_to_basic_level(args.log.phy_level)); + logger_phy.set_hex_dump_max_size(args.log.phy_hex_limit); if (!check_args(args)) { return false; @@ -161,24 +152,15 @@ int phy::init(const phy_args_t& args_) void phy::run_thread() { std::unique_lock lock(config_mutex); - prach_buffer.init(SRSLTE_MAX_PRB, log_h.get()); - common.init(&args, log_h.get(), radio, stack, &sfsync); + prach_buffer.init(SRSLTE_MAX_PRB); + common.init(&args, radio, stack, &sfsync); // Initialise workers - lte_workers.init(&common, logger, WORKERS_THREAD_PRIO); - nr_workers.init(&common, logger, WORKERS_THREAD_PRIO); + lte_workers.init(&common, log_sink, WORKERS_THREAD_PRIO); // Warning this must be initialized after all workers have been added to the pool - sfsync.init(radio, - stack, - &prach_buffer, - <e_workers, - &nr_workers, - &common, - log_h.get(), - log_phy_lib_h.get(), - SF_RECV_THREAD_PRIO, - args.sync_cpu_affinity); + sfsync.init( + radio, stack, &prach_buffer, <e_workers, &nr_workers, &common, SF_RECV_THREAD_PRIO, args.sync_cpu_affinity); // Disable UL signal pregeneration until the attachment enable_pregen_signals(false); @@ -259,12 +241,12 @@ void phy::set_activation_deactivation_scell(uint32_t cmd, uint32_t tti) void phy::configure_prach_params() { - Debug("Configuring PRACH parameters\n"); + Debug("Configuring PRACH parameters"); prach_cfg.tdd_config = tdd_config; if (!prach_buffer.set_cell(selected_cell, prach_cfg)) { - Error("Configuring PRACH parameters\n"); + Error("Configuring PRACH parameters"); } } @@ -334,7 +316,7 @@ bool phy::cell_select(phy_cell_t cell) }); return true; } else { - log_h->warning("Could not start Cell Selection procedure\n"); + logger_phy.warning("Could not start Cell Selection procedure"); return false; } } @@ -353,7 +335,7 @@ bool phy::cell_search() stack->cell_search_complete(ret, found_cell); }); } else { - log_h->warning("Could not start Cell Search procedure\n"); + logger_phy.warning("Could not start Cell Search procedure"); } return true; } @@ -379,7 +361,7 @@ void phy::prach_send(uint32_t preamble_idx, int allowed_subframe, float target_p common.ta.set_base_sec(ta_base_sec); common.reset_radio(); if (!prach_buffer.prepare_to_send(preamble_idx, allowed_subframe, target_power_dbm)) { - Error("Preparing PRACH to send\n"); + Error("Preparing PRACH to send"); } } @@ -397,12 +379,12 @@ void phy::radio_overflow() void phy::radio_failure() { // TODO: handle failure - Error("Radio failure.\n"); + Error("Radio failure."); } void phy::reset() { - Info("Resetting PHY...\n"); + Info("Resetting PHY..."); common.ta.set_base_sec(0); common.reset(); } @@ -416,7 +398,7 @@ void phy::sr_send() { common.sr_enabled = true; common.sr_last_tx_tti = -1; - Debug("sr_send(): sr_enabled=%d, last_tx_tti=%d\n", common.sr_enabled, common.sr_last_tx_tti); + Debug("sr_send(): sr_enabled=%d, last_tx_tti=%d", common.sr_enabled, common.sr_last_tx_tti); } int phy::sr_last_tx_tti() @@ -433,7 +415,7 @@ void phy::set_crnti(uint16_t rnti) { // set_crnti() is an operation that takes time, run in background worker cmd_worker.add_cmd([this, rnti]() { - log_h->info("Configuring sequences for C-RNTI=0x%x...\n", rnti); + logger_phy.info("Configuring sequences for C-RNTI=0x%x...", rnti); for (uint32_t i = 0; i < args.nof_phy_threads; i++) { // set_crnti is not protected so run when worker is finished lte::sf_worker* w = lte_workers.wait_worker_id(i); @@ -442,7 +424,7 @@ void phy::set_crnti(uint16_t rnti) w->release(); } } - log_h->info("Finished configuring sequences for C-RNTI=0x%x.\n", rnti); + logger_phy.info("Finished configuring sequences for C-RNTI=0x%x.", rnti); }); } @@ -476,7 +458,7 @@ bool phy::set_config(srslte::phy_cfg_t config_, uint32_t cc_idx) return false; } - Info("Setting configuration\n"); + Info("Setting configuration"); // The PRACH configuration shall be updated only if: // - The new configuration belongs to the primary cell @@ -487,7 +469,7 @@ bool phy::set_config(srslte::phy_cfg_t config_, uint32_t cc_idx) // Apply configuration after the worker is finished to avoid race conditions cmd_worker.add_cmd([this, config_, cc_idx]() { - log_h->info("Setting new PHY configuration cc_idx=%d...\n", cc_idx); + logger_phy.info("Setting new PHY configuration cc_idx=%d...", cc_idx); for (uint32_t i = 0; i < args.nof_phy_threads; i++) { // set_cell is not protected so run when worker is finished lte::sf_worker* w = lte_workers.wait_worker_id(i); @@ -496,11 +478,10 @@ bool phy::set_config(srslte::phy_cfg_t config_, uint32_t cc_idx) w->release(); } } - log_h->info("Finished setting new PHY configuration cc_idx=%d\n", cc_idx); + logger_phy.info("Finished setting new PHY configuration cc_idx=%d", cc_idx); // It is up to the PRACH component to detect whether the cell or the configuration have changed to reconfigure configure_prach_params(); - stack->set_config_complete(true); }); return true; @@ -514,7 +495,7 @@ bool phy::set_scell(srslte_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) } if (cc_idx == 0) { - log_h->error("Received SCell configuration for invalid cc_idx=0\n"); + logger_phy.error("Received SCell configuration for invalid cc_idx=0"); return false; } @@ -527,7 +508,7 @@ bool phy::set_scell(srslte_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) // First of all check validity of parameters if (!srslte_cell_isvalid(&cell_info)) { - log_h->error("Received SCell configuration for an invalid cell\n"); + logger_phy.error("Received SCell configuration for an invalid cell"); return false; } @@ -547,7 +528,7 @@ bool phy::set_scell(srslte_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) // Component carrier index zero should be reserved for PCell // Send configuration to workers cmd_worker.add_cmd([this, cell_info, cc_idx, earfcn, earfcn_is_different]() { - log_h->info("Setting new SCell configuration cc_idx=%d, earfcn=%d...\n", cc_idx, earfcn); + logger_phy.info("Setting new SCell configuration cc_idx=%d, earfcn=%d...", cc_idx, earfcn); for (uint32_t i = 0; i < args.nof_phy_threads; i++) { // set_cell is not protected so run when worker is finished lte::sf_worker* w = lte_workers.wait_worker_id(i); @@ -568,7 +549,7 @@ bool phy::set_scell(srslte_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) // Set secondary serving cell synchronization sfsync.scell_sync_set(cc_idx, cell_info); - log_h->info("Finished setting new SCell configuration cc_idx=%d, earfcn=%d\n", cc_idx, earfcn); + logger_phy.info("Finished setting new SCell configuration cc_idx=%d, earfcn=%d", cc_idx, earfcn); stack->set_scell_complete(true); }); @@ -600,7 +581,7 @@ void phy::set_config_tdd(srslte_tdd_config_t& tdd_config_) void phy::set_config_mbsfn_sib2(srslte::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) { if (nof_cfgs > 1) { - Warning("SIB2 has %d MBSFN subframe configs - only 1 supported\n", nof_cfgs); + Warning("SIB2 has %d MBSFN subframe configs - only 1 supported", nof_cfgs); } if (nof_cfgs > 0) { common.mbsfn_config.mbsfn_subfr_cnfg = cfg_list[0]; @@ -612,7 +593,7 @@ void phy::set_config_mbsfn_sib13(const srslte::sib13_t& sib13) { common.mbsfn_config.mbsfn_notification_cnfg = sib13.notif_cfg; if (sib13.nof_mbsfn_area_info > 1) { - Warning("SIB13 has %d MBSFN area info elements - only 1 supported\n", sib13.nof_mbsfn_area_info); + Warning("SIB13 has %d MBSFN area info elements - only 1 supported", sib13.nof_mbsfn_area_info); } if (sib13.nof_mbsfn_area_info > 0) { common.mbsfn_config.mbsfn_area_info = sib13.mbsfn_area_info_list[0]; @@ -633,4 +614,43 @@ void phy::set_mch_period_stop(uint32_t stop) common.set_mch_period_stop(stop); } +int phy::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srslte::radio_interface_phy* radio_) +{ + if (!nr_workers.init(args_, &common, stack_, WORKERS_THREAD_PRIO)) { + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int phy::set_ul_grant(std::array packed_ul_grant, + uint16_t rnti, + srslte_rnti_type_t rnti_type) +{ + return nr_workers.set_ul_grant(packed_ul_grant, rnti, rnti_type); +} + +void phy::send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec) +{ + nr_workers.send_prach(prach_occasion, preamble_index, preamble_received_target_power); +} + +int phy::tx_request(const phy_interface_mac_nr::tx_request_t& request) +{ + return 0; +} + +void phy::set_earfcn(std::vector earfcns) +{ + // Do nothing +} + +bool phy::set_config(const srslte::phy_cfg_nr_t& cfg) +{ + return nr_workers.set_config(cfg); +} + } // namespace srsue diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 591eedcb1..831d4114a 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -27,22 +27,22 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) namespace srsue { static srslte::rf_buffer_t zeros_multi(1); -phy_common::phy_common() +phy_common::phy_common(srslog::basic_logger& logger) : logger(logger), ta(logger) { reset(); } @@ -50,24 +50,20 @@ phy_common::phy_common() phy_common::~phy_common() = default; void phy_common::init(phy_args_t* _args, - srslte::log* _log, srslte::radio_interface_phy* _radio, stack_interface_phy_lte* _stack, rsrp_insync_itf* _chest_loop) { - log_h = _log; radio_h = _radio; stack = _stack; args = _args; insync_itf = _chest_loop; sr_last_tx_tti = -1; - ta.set_logger(_log); - // Instantiate UL channel emulator if (args->ul_channel_args.enable) { - ul_channel = - srslte::channel_ptr(new srslte::channel(args->ul_channel_args, args->nof_lte_carriers * args->nof_rx_ant)); + ul_channel = srslte::channel_ptr( + new srslte::channel(args->ul_channel_args, args->nof_lte_carriers * args->nof_rx_ant, logger)); } } @@ -136,13 +132,12 @@ void phy_common::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRAN uint16_t rnti, srslte_tdd_config_t tdd_config) { - #if MSG3_DELAY_MS < 0 #error "Error MSG3_DELAY_MS can't be negative" #endif /* MSG3_DELAY_MS < 0 */ if (rar_grant_tti < 0) { - Error("Must call set_rar_grant_tti before set_rar_grant\n"); + Error("Must call set_rar_grant_tti before set_rar_grant"); } srslte_dci_ul_t dci_ul; @@ -150,7 +145,7 @@ void phy_common::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRAN srslte_dci_rar_unpack(grant_payload, &rar_grant); if (srslte_dci_rar_to_ul_dci(&cell, &rar_grant, &dci_ul)) { - Error("Converting RAR message to UL dci\n"); + Error("Converting RAR message to UL dci"); return; } @@ -174,12 +169,12 @@ void phy_common::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRAN std::lock_guard lock(pending_ul_grant_mutex); pending_ul_grant_t& pending_grant = pending_ul_grant[0][msg3_tx_tti]; if (!pending_grant.enable) { - Debug("RAR grant rar_grant=%d, msg3_tti=%d, stored in index=%d\n", rar_grant_tti, msg3_tx_tti, TTIMOD(msg3_tx_tti)); + Debug("RAR grant rar_grant=%d, msg3_tti=%d, stored in index=%d", rar_grant_tti, msg3_tx_tti, TTIMOD(msg3_tx_tti)); pending_grant.pid = ul_pidof(msg3_tx_tti, &tdd_config); pending_grant.dci = dci_ul; pending_grant.enable = true; } else { - Warning("set_rar_grant: sf->tti=%d, cc=%d already in use\n", msg3_tx_tti, 0); + Warning("set_rar_grant: sf->tti=%d, cc=%d already in use", msg3_tx_tti, 0); } rar_grant_tti = -1; @@ -206,7 +201,6 @@ const static uint32_t k_phich[7][10] = {{0, 0, 4, 7, 6, 0, 0, 4, 7, 6}, uint32_t phy_common::ul_pidof(uint32_t tti, srslte_tdd_config_t* tdd_config) { - if (tdd_config->configured) { /* In TDD modes 1-5, each PID is associated with a unique subframe and the number of harq processes equals the * number of UL subframes Modes 0 and 6 have more processes than UL subframes and PID depends on sfn @@ -246,7 +240,7 @@ uint32_t phy_common::ul_pidof(uint32_t tti, srslte_tdd_config_t* tdd_config) return (cycle_idx + sf_idx - 4) % 6; } default: - Error("Invalid SF configuration %d\n", tdd_config->sf_config); + Error("Invalid SF configuration %d", tdd_config->sf_config); } } else { return tti % SRSLTE_FDD_NOF_HARQ; @@ -273,13 +267,13 @@ void phy_common::set_ul_pending_ack(srslte_ul_sf_cfg_t* sf, pending_ack.dci_ul = *dci_ul; pending_ack.phich_grant = phich_grant; pending_ack.enable = true; - Debug("Set pending ACK for sf->tti=%d n_dmrs=%d, I_phich=%d, cc_idx=%d\n", + Debug("Set pending ACK for sf->tti=%d n_dmrs=%d, I_phich=%d, cc_idx=%d", sf->tti, phich_grant.n_dmrs, phich_grant.I_phich, cc_idx); } else { - Warning("set_ul_pending_ack: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx); + Warning("set_ul_pending_ack: sf->tti=%d, cc=%d already in use", sf->tti, cc_idx); } } @@ -297,7 +291,7 @@ bool phy_common::get_ul_pending_ack(srslte_dl_sf_cfg_t* sf, *dci_ul = pending_ack.dci_ul; ret = true; pending_ack.enable = false; - Debug("Get pending ACK for sf->tti=%d n_dmrs=%d, I_phich=%d\n", sf->tti, phich_grant->n_dmrs, phich_grant->I_phich); + Debug("Get pending ACK for sf->tti=%d n_dmrs=%d, I_phich=%d", sf->tti, phich_grant->n_dmrs, phich_grant->I_phich); } return ret; } @@ -342,9 +336,9 @@ void phy_common::set_ul_pending_grant(srslte_dl_sf_cfg_t* sf, uint32_t cc_idx, s pending_grant.pid = pid; pending_grant.dci = *dci; pending_grant.enable = true; - Debug("Set ul pending grant for sf->tti=%d current_tti=%d, pid=%d\n", tti_pusch_gr(sf), sf->tti, pid); + Debug("Set ul pending grant for sf->tti=%d current_tti=%d, pid=%d", tti_pusch_gr(sf), sf->tti, pid); } else { - Warning("set_ul_pending_grant: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx); + Warning("set_ul_pending_grant: sf->tti=%d, cc=%d already in use", sf->tti, cc_idx); } } @@ -356,7 +350,7 @@ bool phy_common::get_ul_pending_grant(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, u pending_ul_grant_t& pending_grant = pending_ul_grant[cc_idx][sf->tti]; if (pending_grant.enable) { - Debug("Reading grant sf->tti=%d idx=%d\n", sf->tti, TTIMOD(sf->tti)); + Debug("Reading grant sf->tti=%d idx=%d", sf->tti, TTIMOD(sf->tti)); if (pid) { *pid = pending_grant.pid; } @@ -395,7 +389,7 @@ void phy_common::set_ul_received_ack(srslte_dl_sf_cfg_t* sf, received_ack.hi_present = true; received_ack.hi_value = ack_value; received_ack.dci_ul = *dci_ul; - Debug("Set ul received ack for sf->tti=%d, current_tti=%d\n", tti_pusch_hi(sf), sf->tti); + Debug("Set ul received ack for sf->tti=%d, current_tti=%d", tti_pusch_hi(sf), sf->tti); } // SF->TTI at which PUSCH will be transmitted @@ -412,7 +406,7 @@ bool phy_common::get_ul_received_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, bo if (dci_ul) { *dci_ul = received_ack.dci_ul; } - Debug("Get ul received ack for current_tti=%d\n", sf->tti); + Debug("Get ul received ack for current_tti=%d", sf->tti); received_ack.hi_present = false; ret = true; } @@ -433,9 +427,9 @@ void phy_common::set_dl_pending_ack(srslte_dl_sf_cfg_t* sf, pending_ack.enable = true; pending_ack.resource = resource; memcpy(pending_ack.value, value, SRSLTE_MAX_CODEWORDS * sizeof(uint8_t)); - Debug("Set dl pending ack for sf->tti=%d, value=%d, ncce=%d\n", sf->tti, value[0], resource.n_cce); + Debug("Set dl pending ack for sf->tti=%d, value=%d, ncce=%d", sf->tti, value[0], resource.n_cce); } else { - Warning("pending_dl_ack: sf->tti=%d, cc=%d already in use\n", sf->tti, cc_idx); + Warning("pending_dl_ack: sf->tti=%d, cc=%d already in use", sf->tti, cc_idx); } } @@ -455,7 +449,7 @@ void phy_common::set_dl_pending_grant(uint32_t tti, pending_dl_grant[tti % FDD_HARQ_DELAY_UL_MS][cc_idx].grant_cc_idx = grant_cc_idx; pending_dl_grant[tti % FDD_HARQ_DELAY_UL_MS][cc_idx].enable = true; } else { - Warning("set_dl_pending_grant: cc=%d already exists\n", cc_idx); + Info("set_dl_pending_grant: cc=%d already exists", cc_idx); } } @@ -514,7 +508,6 @@ bool phy_common::get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srs M = das_table[sf->tdd_config.sf_config][sf->tti % 10].M; } for (uint32_t i = 0; i < M; i++) { - uint32_t k = (cell.frame_type == SRSLTE_FDD) ? FDD_HARQ_DELAY_UL_MS : das_table[sf->tdd_config.sf_config][sf->tti % 10].K[i]; uint32_t pdsch_tti = TTI_SUB(sf->tti, k + (FDD_HARQ_DELAY_DL_MS - FDD_HARQ_DELAY_UL_MS)); @@ -524,7 +517,7 @@ bool phy_common::get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srs ack->m[i].k = k; ack->m[i].resource = pending_ack.resource; memcpy(ack->m[i].value, pending_ack.value, SRSLTE_MAX_CODEWORDS * sizeof(uint8_t)); - Debug("Get dl pending ack for sf->tti=%d, i=%d, k=%d, pdsch_tti=%d, value=%d, ncce=%d, v_dai=%d\n", + Debug("Get dl pending ack for sf->tti=%d, i=%d, k=%d, pdsch_tti=%d, value=%d, ncce=%d, v_dai=%d", sf->tti, i, k, @@ -550,17 +543,40 @@ bool phy_common::get_dl_pending_ack(srslte_ul_sf_cfg_t* sf, uint32_t cc_idx, srs void phy_common::worker_end(void* tx_sem_id, bool tx_enable, srslte::rf_buffer_t& buffer, - srslte::rf_timestamp_t& tx_time) + srslte::rf_timestamp_t& tx_time, + bool is_nr) { // Wait for the green light to transmit in the current TTI semaphore.wait(tx_sem_id); + // If this is for NR, save Tx buffers... + if (is_nr) { + nr_tx_buffer = buffer; + nr_tx_buffer_ready = true; + semaphore.release(); + return; + } + + // ... otherwise, append NR base-band from saved buffer if available + if (nr_tx_buffer_ready) { + // Load NR carrier base-band + for (uint32_t i = 0; i < args->nof_nr_carriers * args->nof_rx_ant; i++) { + uint32 channel_idx = args->nof_lte_carriers * args->nof_rx_ant + i; + buffer.set(channel_idx, nr_tx_buffer.get(i)); + } + + // Remove NR buffer flag + nr_tx_buffer_ready = false; + + // Make sure it transmits in this TTI + tx_enable = true; + } + // Add Time Alignment tx_time.sub((double)ta.get_sec()); // For each radio, transmit if (tx_enable) { - if (ul_channel) { ul_channel->run(buffer.to_cf_t(), buffer.to_cf_t(), buffer.get_nof_samples(), tx_time.get(0)); } @@ -573,7 +589,6 @@ void phy_common::worker_end(void* tx_sem_id, is_pending_tx_end = false; } else { if (!radio_h->get_is_start_of_burst()) { - if (ul_channel) { srslte_vec_cf_zero(zeros_multi.get(0), buffer.get_nof_samples()); ul_channel->run(zeros_multi.to_cf_t(), zeros_multi.to_cf_t(), buffer.get_nof_samples(), tx_time.get(0)); @@ -630,7 +645,6 @@ void phy_common::update_measurements(uint32_t cc_idx, // Only worker 0 reads the RSSI sensor if (rssi_power_buffer) { - if (!rssi_read_cnt) { // Average RSSI over all symbols in antenna port 0 (make sure SF length is non-zero) float rssi_dbm = SRSLTE_SF_LEN_PRB(cell.nof_prb) > 0 @@ -741,9 +755,9 @@ void phy_common::update_measurements(uint32_t cc_idx, bool active = cell_state.is_configured(cc_idx); if (active && ((sf_cfg_dl.tti % pcell_report_period) == pcell_report_period - 1)) { phy_meas_t meas = {}; - meas.rsrp = avg_rsrp_dbm[cc_idx]; - meas.rsrq = avg_rsrq_db[cc_idx]; - meas.cfo_hz = avg_cfo_hz[cc_idx]; + meas.rsrp = avg_rsrp_dbm[cc_idx]; + meas.rsrq = avg_rsrq_db[cc_idx]; + meas.cfo_hz = avg_cfo_hz[cc_idx]; // Save PCI and EARFCN (if available) if (cc_idx == 0) { @@ -758,11 +772,10 @@ void phy_common::update_measurements(uint32_t cc_idx, // Check in-sync / out-sync conditions. Use SNR instead of SINR for RLF threshold if (cc_idx == 0) { if (avg_rsrp_dbm[0] > args->in_sync_rsrp_dbm_th && avg_snr_db[0] > args->in_sync_snr_db_th) { - log_h->debug( - "SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n", avg_snr_db[0], avg_rsrp_dbm[0]); + logger.debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator", avg_snr_db[0], avg_rsrp_dbm[0]); } else { - log_h->warning( - "SNR=%.1f dB RSRP=%.1f dBm, sync=out-of-sync from channel estimator\n", avg_snr_db[0], avg_rsrp_dbm[0]); + logger.warning( + "SNR=%.1f dB RSRP=%.1f dBm, sync=out-of-sync from channel estimator", avg_snr_db[0], avg_rsrp_dbm[0]); insync = false; } } @@ -951,7 +964,7 @@ void phy_common::build_mch_table() } else if (mbsfn_config.mbsfn_subfr_cnfg.nof_alloc_subfrs == srslte::mbsfn_sf_cfg_t::sf_alloc_type_t::four_frames) { generate_mch_table(&mch_table[0], (uint32_t)mbsfn_config.mbsfn_subfr_cnfg.sf_alloc, 4u); } else { - log_h->error("The subframe config has not been set for MBSFN\n"); + logger.error("The subframe config has not been set for MBSFN"); } // Debug @@ -960,7 +973,7 @@ void phy_common::build_mch_table() for (uint32_t j = 0; j < 40; j++) { ss << (int)mch_table[j] << "|"; } - Info("MCH table: %s\n", ss.str().c_str()); + Info("MCH table: %s", ss.str().c_str()); } void phy_common::build_mcch_table() @@ -974,7 +987,7 @@ void phy_common::build_mcch_table() for (uint32_t j = 0; j < 10; j++) { ss << (int)mcch_table[j] << "|"; } - Info("MCCH table: %s\n", ss.str().c_str()); + Info("MCCH table: %s", ss.str().c_str()); sib13_configured = true; } @@ -1065,7 +1078,7 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) // have_mtch_stop = false; } } - Debug("MCH subframe TTI:%d\n", phy_tti); + Debug("MCH subframe TTI:%d", phy_tti); } return true; } @@ -1080,7 +1093,7 @@ bool phy_common::is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) } } } else { - log_h->error("The subframe allocation type is not yet configured\n"); + logger.error("The subframe allocation type is not yet configured"); } } @@ -1109,7 +1122,7 @@ bool phy_common::is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti) cfg->mbsfn_mcs = enum_to_number(area_info.mcch_cfg.sig_mcs); cfg->enable = true; have_mtch_stop = false; - Debug("MCCH subframe TTI:%d\n", phy_tti); + Debug("MCCH subframe TTI:%d", phy_tti); return true; } } diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index eaf70289f..259ec5ac0 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -27,23 +27,21 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) using namespace srsue; -void prach::init(uint32_t max_prb, srslte::log* log_h_) +void prach::init(uint32_t max_prb) { - log_h = log_h_; - for (auto& i : buffer) { for (auto& j : i) { j = srslte_vec_cf_malloc(SRSLTE_PRACH_MAX_LEN); @@ -55,7 +53,7 @@ void prach::init(uint32_t max_prb, srslte::log* log_h_) } if (srslte_cfo_init(&cfo_h, SRSLTE_PRACH_MAX_LEN)) { - ERROR("PRACH: Error initiating CFO\n"); + ERROR("PRACH: Error initiating CFO"); return; } @@ -68,7 +66,7 @@ void prach::init(uint32_t max_prb, srslte::log* log_h_) } if (srslte_prach_init(&prach_obj, srslte_symbol_sz(max_prb))) { - Error("Initiating PRACH library\n"); + Error("Initiating PRACH library"); return; } @@ -96,7 +94,7 @@ void prach::stop() bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) { if (!mem_initiated) { - ERROR("PRACH: Error must call init() first\n"); + ERROR("PRACH: Error must call init() first"); return false; } @@ -110,11 +108,11 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) if (6 + prach_cfg.freq_offset > cell.nof_prb) { srslte::console("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", prach_cfg.freq_offset, cell.nof_prb); - log_h->error("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d\n", prach_cfg.freq_offset, cell.nof_prb); + logger.error("Error no space for PRACH: frequency offset=%d, N_rb_ul=%d", prach_cfg.freq_offset, cell.nof_prb); return false; } - Info("PRACH: cell.id=%d, configIdx=%d, rootSequence=%d, zeroCorrelationConfig=%d, freqOffset=%d\n", + Info("PRACH: cell.id=%d, configIdx=%d, rootSequence=%d, zeroCorrelationConfig=%d, freqOffset=%d", cell.id, prach_cfg.config_idx, prach_cfg.root_seq_idx, @@ -122,7 +120,7 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) prach_cfg.freq_offset); if (srslte_prach_set_cfg(&prach_obj, &prach_cfg, cell.nof_prb)) { - Error("Initiating PRACH library\n"); + Error("Initiating PRACH library"); return false; } @@ -131,7 +129,7 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) transmitted_tti = -1; cell_initiated = true; - log_h->info("Finished setting new PRACH configuration.\n"); + logger.info("Finished setting new PRACH configuration."); return true; } @@ -148,7 +146,7 @@ bool prach::generate_buffer(uint32_t f_idx) cfg.config_idx, cfg.tdd_config.sf_config, (f_idx / 6) * 10, f_idx % 6, cfg.freq_offset, cell.nof_prb); } if (srslte_prach_gen(&prach_obj, preamble_idx, freq_offset, buffer[f_idx][preamble_idx])) { - Error("Generating PRACH preamble %d\n", preamble_idx); + Error("Generating PRACH preamble %d", preamble_idx); return false; } @@ -160,7 +158,7 @@ bool prach::generate_buffer(uint32_t f_idx) bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm_) { if (preamble_idx_ >= max_preambles) { - Error("PRACH: Invalid preamble %d\n", preamble_idx_); + Error("PRACH: Invalid preamble %d", preamble_idx_); return false; } @@ -168,7 +166,7 @@ bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm = target_power_dbm_; allowed_subframe = allowed_subframe_; transmitted_tti = -1; - Debug("PRACH: prepare to send preamble %d\n", preamble_idx); + Debug("PRACH: prepare to send preamble %d", preamble_idx); return true; } @@ -184,7 +182,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_, uint32_t current_pci) // consider the number of subframes the transmission must be anticipated uint32_t tti_tx = TTI_TX(current_tti_); if (srslte_prach_tti_opportunity(&prach_obj, tti_tx, allowed_subframe)) { - Debug("PRACH Buffer: Ready to send at tti: %d (now is %d)\n", tti_tx, current_tti_); + Debug("PRACH Buffer: Ready to send at tti: %d (now is %d)", tti_tx, current_tti_); transmitted_tti = tti_tx; return true; } @@ -214,7 +212,7 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) { if (!cell_initiated || preamble_idx < 0 || !nof_sf || unsigned(preamble_idx) >= max_preambles || !srslte_cell_isvalid(&cell) || len >= MAX_LEN_SF * 30720 || len == 0) { - Error("PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d\n", + Error("PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d", cell_initiated, preamble_idx, cell.nof_prb, @@ -230,7 +228,7 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) f_idx += 6; } if (f_idx >= max_fs) { - Error("PRACH Buffer: Invalid f_idx=%d\n", f_idx); + Error("PRACH Buffer: Invalid f_idx=%d", f_idx); f_idx = 0; } } @@ -240,7 +238,7 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) } if (!is_buffer_generated(f_idx, preamble_idx)) { - Error("PRACH Buffer not generated: f_idx=%d preamble_idx=%d\n", f_idx, preamble_idx); + Error("PRACH Buffer not generated: f_idx=%d preamble_idx=%d", f_idx, preamble_idx); return nullptr; } @@ -257,7 +255,7 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) *target_power = target_power_dbm; } - Info("PRACH: Transmitted preamble=%d, tti_tx=%d, CFO=%.2f KHz, nof_sf=%d, target_power=%.1f dBm\n", + Info("PRACH: Transmitted preamble=%d, tti_tx=%d, CFO=%.2f KHz, nof_sf=%d, target_power=%.1f dBm", preamble_idx, transmitted_tti, cfo * 15, diff --git a/srsue/src/phy/scell/intra_measure.cc b/srsue/src/phy/scell/intra_measure.cc index 0e8822597..214b0e590 100644 --- a/srsue/src/phy/scell/intra_measure.cc +++ b/srsue/src/phy/scell/intra_measure.cc @@ -21,22 +21,23 @@ #include "srsue/hdr/phy/scell/intra_measure.h" #define Error(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \ - log_h->error(fmt, ##__VA_ARGS__) + if (SRSLTE_DEBUG_ENABLED) \ + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \ - log_h->warning(fmt, ##__VA_ARGS__) + if (SRSLTE_DEBUG_ENABLED) \ + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \ - log_h->info(fmt, ##__VA_ARGS__) + if (SRSLTE_DEBUG_ENABLED) \ + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ - if (SRSLTE_DEBUG_ENABLED and log_h != nullptr) \ - log_h->debug(fmt, ##__VA_ARGS__) + if (SRSLTE_DEBUG_ENABLED) \ + logger.debug(fmt, ##__VA_ARGS__) namespace srsue { namespace scell { -intra_measure::intra_measure() : scell(), thread("SYNC_INTRA_MEASURE") {} +intra_measure::intra_measure(srslog::basic_logger& logger) : scell(logger), logger(logger), thread("SYNC_INTRA_MEASURE") +{} intra_measure::~intra_measure() { @@ -45,11 +46,10 @@ intra_measure::~intra_measure() free(search_buffer); } -void intra_measure::init(uint32_t cc_idx_, phy_common* common, meas_itf* new_cell_itf_, srslte::log* log_h_) +void intra_measure::init(uint32_t cc_idx_, phy_common* common, meas_itf* new_cell_itf_) { cc_idx = cc_idx_; new_cell_itf = new_cell_itf_; - log_h = log_h_; if (common) { intra_freq_meas_len_ms = common->args->intra_freq_meas_len_ms; @@ -61,7 +61,7 @@ void intra_measure::init(uint32_t cc_idx_, phy_common* common, meas_itf* new_cel srslte_refsignal_dl_sync_init(&refsignal_dl_sync); // Start scell - scell.init(log_h, intra_freq_meas_len_ms); + scell.init(intra_freq_meas_len_ms); search_buffer = srslte_vec_cf_malloc(intra_freq_meas_len_ms * SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)); @@ -105,7 +105,7 @@ void intra_measure::meas_stop() // Transition state to idle // Ring-buffer shall not be reset, it will automatically be reset as soon as the FSM transitions to receive state.set_state(internal_state::idle); - Info("INTRA: Disabled neighbour cell search for EARFCN %d\n", get_earfcn()); + Info("INTRA: Disabled neighbour cell search for EARFCN %d", get_earfcn()); } void intra_measure::set_cells_to_meas(const std::set& pci) @@ -114,7 +114,7 @@ void intra_measure::set_cells_to_meas(const std::set& pci) active_pci = pci; active_pci_mutex.unlock(); state.set_state(internal_state::receive); - log_h->info("INTRA: Received list of %zd neighbour cells to measure in EARFCN %d.\n", pci.size(), current_earfcn); + logger.info("INTRA: Received list of %zd neighbour cells to measure in EARFCN %d.", pci.size(), current_earfcn); } void intra_measure::write(uint32_t tti, cf_t* data, uint32_t nsamples) @@ -143,7 +143,7 @@ void intra_measure::write(uint32_t tti, cf_t* data, uint32_t nsamples) // Try writing in the buffer if (srslte_ringbuffer_write(&ring_buffer, data, nbytes) < nbytes) { - Warning("INTRA: Error writing to ringbuffer (EARFCN=%d)\n", current_earfcn); + Warning("INTRA: Error writing to ringbuffer (EARFCN=%d)", current_earfcn); // Transition to wait, so it can keep receiving without stopping the component operation state.set_state(internal_state::wait); @@ -210,7 +210,7 @@ void intra_measure::measure_proc() neighbour_cells.push_back(m); Info("INTRA: Found neighbour cell: EARFCN=%d, PCI=%03d, RSRP=%5.1f dBm, RSRQ=%5.1f, peak_idx=%5d, " - "CFO=%+.1fHz\n", + "CFO=%+.1fHz", m.earfcn, m.pci, m.rsrp, diff --git a/srsue/src/phy/scell/scell_recv.cc b/srsue/src/phy/scell/scell_recv.cc index c679530fb..642b3ea1d 100644 --- a/srsue/src/phy/scell/scell_recv.cc +++ b/srsue/src/phy/scell/scell_recv.cc @@ -28,10 +28,8 @@ namespace scell { * Secondary cell receiver */ -void scell_recv::init(srslte::log* _log_h, uint32_t max_sf_window) +void scell_recv::init(uint32_t max_sf_window) { - log_h = _log_h; - // and a separate ue_sync instance uint32_t max_fft_sz = (uint32_t)srslte_symbol_sz(100); @@ -39,13 +37,13 @@ void scell_recv::init(srslte::log* _log_h, uint32_t max_sf_window) sf_buffer[0] = srslte_vec_cf_malloc(max_sf_size); if (!sf_buffer[0]) { - log_h->error("Error allocating %d samples for scell\n", max_sf_size); + logger.error("Error allocating %d samples for scell", max_sf_size); return; } // do this different we don't need all this search window. if (srslte_sync_init(&sync_find, max_sf_window * max_sf_size, 5 * max_sf_size, max_fft_sz)) { - log_h->error("Error initiating sync_find\n"); + logger.error("Error initiating sync_find"); return; } srslte_sync_set_sss_algorithm(&sync_find, SSS_FULL); @@ -89,14 +87,14 @@ scell_recv::find_cells(const cf_t* input_buffer, const srslte_cell_t serving_cel if (fft_sz != current_fft_sz) { if (srslte_sync_resize(&sync_find, nof_sf * sf_len, 5 * sf_len, fft_sz)) { - log_h->error("Error resizing sync nof_sf=%d, sf_len=%d, fft_sz=%d\n", nof_sf, sf_len, fft_sz); + logger.error("Error resizing sync nof_sf=%d, sf_len=%d, fft_sz=%d", nof_sf, sf_len, fft_sz); return found_cell_ids; } current_fft_sz = fft_sz; } - uint32_t peak_idx = 0; - int cell_id = 0; + uint32_t peak_idx = 0; + int cell_id = 0; for (uint32_t n_id_2 = 0; n_id_2 < 3; n_id_2++) { @@ -118,7 +116,7 @@ scell_recv::find_cells(const cf_t* input_buffer, const srslte_cell_t serving_cel for (uint32_t sf5_cnt = 0; sf5_cnt < nof_sf / 5; sf5_cnt++) { sync_res = srslte_sync_find(&sync_find, input_buffer, sf5_cnt * 5 * sf_len, &peak_idx); if (sync_res == SRSLTE_SYNC_ERROR) { - log_h->error("INTRA: Error calling sync_find()\n"); + logger.error("INTRA: Error calling sync_find()"); return found_cell_ids; } @@ -135,8 +133,8 @@ scell_recv::find_cells(const cf_t* input_buffer, const srslte_cell_t serving_cel sss_detected = true; } - log_h->debug("INTRA: n_id_2=%d, cnt=%d/%d, sync_res=%d, cell_id=%d, sf_idx=%d, peak_idx=%d, peak_value=%f, " - "sss_detected=%d\n", + logger.debug("INTRA: n_id_2=%d, cnt=%d/%d, sync_res=%d, cell_id=%d, sf_idx=%d, peak_idx=%d, peak_value=%f, " + "sss_detected=%d", n_id_2, sf5_cnt, nof_sf / 5, @@ -152,7 +150,7 @@ scell_recv::find_cells(const cf_t* input_buffer, const srslte_cell_t serving_cel if (sync_res == SRSLTE_SYNC_FOUND && sss_detected && cell_id >= 0) { // We have found a new cell, add to the list found_cell_ids.insert((uint32_t)cell_id); - log_h->debug("INTRA: Detected new cell_id=%d using PSS/SSS\n", cell_id); + logger.debug("INTRA: Detected new cell_id=%d using PSS/SSS", cell_id); } } } diff --git a/srsue/src/phy/search.cc b/srsue/src/phy/search.cc index 07a8ea710..bff861a1d 100644 --- a/srsue/src/phy/search.cc +++ b/srsue/src/phy/search.cc @@ -23,16 +23,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) namespace srsue { @@ -54,20 +54,19 @@ search::~search() srslte_ue_cellsearch_free(&cs); } -void search::init(srslte::rf_buffer_t& buffer_, srslte::log* log_h_, uint32_t nof_rx_channels, search_callback* parent) +void search::init(srslte::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search_callback* parent) { - log_h = log_h_; - p = parent; + p = parent; buffer = buffer_; if (srslte_ue_cellsearch_init_multi(&cs, 8, radio_recv_callback, nof_rx_channels, parent)) { - Error("SYNC: Initiating UE cell search\n"); + Error("SYNC: Initiating UE cell search"); } srslte_ue_cellsearch_set_nof_valid_frames(&cs, 4); if (srslte_ue_mib_sync_init_multi(&ue_mib_sync, radio_recv_callback, nof_rx_channels, parent)) { - Error("SYNC: Initiating UE MIB synchronization\n"); + Error("SYNC: Initiating UE MIB synchronization"); } // Set options defined in expert section @@ -96,7 +95,7 @@ void search::set_agc_enable(bool enable) rf_info->max_rx_gain, p->get_radio()->get_rx_gain()); } else { - ERROR("Error stop AGC not implemented\n"); + ERROR("Error stop AGC not implemented"); } } @@ -112,7 +111,7 @@ search::ret_code search::run(srslte_cell_t* cell_, std::array= 0 && force_N_id_2 < 3) { @@ -123,10 +122,10 @@ search::ret_code search::run(srslte_cell_t* cell_, std::arrayerror(fmt, ##__VA_ARGS__) + logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + logger.debug(fmt, ##__VA_ARGS__) namespace srsue { @@ -45,10 +45,8 @@ void sfn_sync::init(srslte_ue_sync_t* ue_sync_, const phy_args_t* phy_args_, srslte::rf_buffer_t& buffer, uint32_t buffer_max_samples_, - srslte::log* log_h_, uint32_t nof_subframes) { - log_h = log_h_; ue_sync = ue_sync_; phy_args = phy_args_; timeout = nof_subframes; @@ -58,14 +56,14 @@ void sfn_sync::init(srslte_ue_sync_t* ue_sync_, // MIB decoder uses a single receiver antenna in logical channel 0 if (srslte_ue_mib_init(&ue_mib, buffer.get(0), SRSLTE_MAX_PRB)) { - Error("SYNC: Initiating UE MIB decoder\n"); + Error("SYNC: Initiating UE MIB decoder"); } } bool sfn_sync::set_cell(srslte_cell_t cell_) { if (srslte_ue_mib_set_cell(&ue_mib, cell_)) { - Error("SYNC: Setting cell: initiating ue_mib\n"); + Error("SYNC: Setting cell: initiating ue_mib"); return false; } reset(); @@ -85,7 +83,7 @@ sfn_sync::ret_code sfn_sync::run_subframe(srslte_cell_t* { int ret = srslte_ue_sync_zerocopy(ue_sync, mib_buffer.to_cf_t(), buffer_max_samples); if (ret < 0) { - Error("SYNC: Error calling ue_sync_get_buffer.\n"); + Error("SYNC: Error calling ue_sync_get_buffer."); return ERROR; } @@ -95,7 +93,7 @@ sfn_sync::ret_code sfn_sync::run_subframe(srslte_cell_t* return ret2; } } else { - Info("SYNC: Waiting for PSS while trying to decode MIB (%d/%d)\n", cnt, timeout); + Info("SYNC: Waiting for PSS while trying to decode MIB (%d/%d)", cnt, timeout); } cnt++; @@ -144,19 +142,19 @@ sfn_sync::ret_code sfn_sync::decode_mib(srslte_cell_t* // Check if SNR is below the minimum threshold if (ue_mib.chest_res.snr_db < phy_args->in_sync_snr_db_th) { - Info("SYNC: MIB decoded, SNR is too low (%+.1f < %+.1f)\n", + Info("SYNC: MIB decoded, SNR is too low (%+.1f < %+.1f)", ue_mib.chest_res.snr_db, phy_args->in_sync_snr_db_th); return SFN_NOFOUND; } - Info("SYNC: DONE, SNR=%.1f dB, TTI=%d, sfn_offset=%d\n", ue_mib.chest_res.snr_db, *tti_cnt, sfn_offset); + Info("SYNC: DONE, SNR=%.1f dB, TTI=%d, sfn_offset=%d", ue_mib.chest_res.snr_db, *tti_cnt, sfn_offset); } reset(); return SFN_FOUND; case SRSLTE_UE_MIB_NOTFOUND: - Info("SYNC: Found PSS but could not decode MIB. SNR=%.1f dB (%d/%d)\n", ue_mib.chest_res.snr_db, cnt, timeout); + Info("SYNC: Found PSS but could not decode MIB. SNR=%.1f dB (%d/%d)", ue_mib.chest_res.snr_db, cnt, timeout); return SFN_NOFOUND; } } diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index b3d5f96fd..eb0891748 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -29,16 +29,16 @@ #define Error(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->error(fmt, ##__VA_ARGS__) + phy_logger.error(fmt, ##__VA_ARGS__) #define Warning(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->warning(fmt, ##__VA_ARGS__) + phy_logger.warning(fmt, ##__VA_ARGS__) #define Info(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->info(fmt, ##__VA_ARGS__) + phy_logger.info(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) \ if (SRSLTE_DEBUG_ENABLED) \ - log_h->debug(fmt, ##__VA_ARGS__) + phy_logger.debug(fmt, ##__VA_ARGS__) namespace srsue { @@ -60,14 +60,10 @@ void sync::init(srslte::radio_interface_phy* _radio, lte::worker_pool* _lte_workers_pool, nr::worker_pool* _nr_workers_pool, phy_common* _worker_com, - srslte::log* _log_h, - srslte::log* _log_phy_lib_h, uint32_t prio, int sync_cpu_affinity) { radio_h = _radio; - log_h = _log_h; - log_phy_lib_h = _log_phy_lib_h; stack = _stack; lte_worker_pool = _lte_workers_pool; nr_worker_pool = _nr_workers_pool; @@ -77,30 +73,31 @@ void sync::init(srslte::radio_interface_phy* _radio, nof_rf_channels = (worker_com->args->nof_lte_carriers + worker_com->args->nof_nr_carriers) * worker_com->args->nof_rx_ant; if (nof_rf_channels == 0 || nof_rf_channels > SRSLTE_MAX_CHANNELS) { - Error("SYNC: Invalid number of RF channels (%d)\n", nof_rf_channels); + Error("SYNC: Invalid number of RF channels (%d)", nof_rf_channels); return; } if (srslte_ue_sync_init_multi(&ue_sync, SRSLTE_MAX_PRB, false, radio_recv_callback, nof_rf_channels, this) != SRSLTE_SUCCESS) { - Error("SYNC: Initiating ue_sync\n"); + Error("SYNC: Initiating ue_sync"); return; } if (worker_com->args->dl_channel_args.enable) { - channel_emulator = srslte::channel_ptr(new srslte::channel(worker_com->args->dl_channel_args, nof_rf_channels)); + channel_emulator = + srslte::channel_ptr(new srslte::channel(worker_com->args->dl_channel_args, nof_rf_channels, phy_logger)); } // Initialize cell searcher - search_p.init(sf_buffer, log_h, nof_rf_channels, this); + search_p.init(sf_buffer, nof_rf_channels, this); // Initialize SFN synchronizer, it uses only pcell buffer - sfn_p.init(&ue_sync, worker_com->args, sf_buffer, sf_buffer.size(), log_h); + sfn_p.init(&ue_sync, worker_com->args, sf_buffer, sf_buffer.size()); // Start intra-frequency measurement for (uint32_t i = 0; i < worker_com->args->nof_lte_carriers; i++) { - scell::intra_measure* q = new scell::intra_measure; - q->init(i, worker_com, this, log_h); + scell::intra_measure* q = new scell::intra_measure(phy_logger); + q->init(i, worker_com, this); intra_freq_meas.push_back(std::unique_ptr(q)); } @@ -190,12 +187,12 @@ bool sync::cell_search_init() std::unique_lock ul(rrc_mutex); if (rrc_proc_state != PROC_IDLE) { - Error("Cell Search: Can't start procedure. SYNC already running a procedure (%d)\n", (uint32_t)rrc_proc_state); + Error("Cell Search: Can't start procedure. SYNC already running a procedure (%d)", (uint32_t)rrc_proc_state); return false; } // Move state to IDLE - Info("Cell Search: Start EARFCN index=%u/%zd\n", cellsearch_earfcn_index, worker_com->args->dl_earfcn_list.size()); + Info("Cell Search: Start EARFCN index=%u/%zd", cellsearch_earfcn_index, worker_com->args->dl_earfcn_list.size()); phy_state.go_idle(); worker_com->reset(); @@ -216,7 +213,7 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou ret.last_freq = rrc_interface_phy_lte::cell_search_ret_t::NO_MORE_FREQS; if (rrc_proc_state != PROC_SEARCH_START) { - Error("Cell Search: Can't run procedure. Must call cell_search_init() first (%d)\n", (uint32_t)rrc_proc_state); + Error("Cell Search: Can't run procedure. Must call cell_search_init() first (%d)", (uint32_t)rrc_proc_state); return ret; } @@ -226,28 +223,28 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou srate_mode = SRATE_FIND; radio_h->set_rx_srate(1.92e6); radio_h->set_tx_srate(1.92e6); - Info("SYNC: Setting Cell Search sampling rate\n"); + Info("SYNC: Setting Cell Search sampling rate"); } try { if (current_earfcn != (int)worker_com->args->dl_earfcn_list.at(cellsearch_earfcn_index)) { current_earfcn = (int)worker_com->args->dl_earfcn_list[cellsearch_earfcn_index]; - Info("Cell Search: changing frequency to EARFCN=%d\n", current_earfcn); + Info("Cell Search: changing frequency to EARFCN=%d", current_earfcn); set_frequency(); } } catch (const std::out_of_range& oor) { - Error("Index %d is not a valid EARFCN element.\n", cellsearch_earfcn_index); + Error("Index %d is not a valid EARFCN element.", cellsearch_earfcn_index); return ret; } // Move to CELL SEARCH and wait to finish - Info("Cell Search: Setting Cell search state\n"); + Info("Cell Search: Setting Cell search state"); phy_state.run_cell_search(); // Check return state switch (cell_search_ret) { case search::CELL_FOUND: - log_h->info("Cell Search: Found cell with PCI=%d with %d PRB\n", cell.id, cell.nof_prb); + phy_logger.info("Cell Search: Found cell with PCI=%d with %d PRB", cell.id, cell.nof_prb); if (found_cell) { found_cell->earfcn = current_earfcn; found_cell->pci = cell.id; @@ -256,18 +253,18 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou ret.found = rrc_interface_phy_lte::cell_search_ret_t::CELL_FOUND; break; case search::CELL_NOT_FOUND: - Info("Cell Search: No cell found in this frequency\n"); + Info("Cell Search: No cell found in this frequency"); ret.found = rrc_interface_phy_lte::cell_search_ret_t::CELL_NOT_FOUND; break; default: - Error("Cell Search: while receiving samples\n"); + Error("Cell Search: while receiving samples"); radio_error(); break; } cellsearch_earfcn_index++; if (cellsearch_earfcn_index >= worker_com->args->dl_earfcn_list.size()) { - Info("Cell Search: No more frequencies in the current EARFCN set\n"); + Info("Cell Search: No more frequencies in the current EARFCN set"); cellsearch_earfcn_index = 0; ret.last_freq = rrc_interface_phy_lte::cell_search_ret_t::NO_MORE_FREQS; } else { @@ -291,17 +288,17 @@ bool sync::cell_select_init(phy_cell_t new_cell) std::unique_lock ul(rrc_mutex); if (rrc_proc_state != PROC_IDLE) { - Error("Cell Select: Can't start procedure. SYNC already running a procedure (%d)\n", (uint32_t)rrc_proc_state); + Error("Cell Select: Can't start procedure. SYNC already running a procedure (%d)", (uint32_t)rrc_proc_state); return false; } // Move state to IDLE if (!srslte_cellid_isvalid(new_cell.pci)) { - Error("Cell Select: Invalid cell_id=%d\n", new_cell.pci); + Error("Cell Select: Invalid cell_id=%d", new_cell.pci); return false; } - Info("Cell Select: Going to IDLE\n"); + Info("Cell Select: Going to IDLE"); phy_state.go_idle(); worker_com->reset(); @@ -321,7 +318,7 @@ bool sync::cell_select_start(phy_cell_t new_cell) bool ret = false; if (rrc_proc_state != PROC_SELECT_START) { - Error("Cell Select: Can't run procedure. Must call cell_select_init() first (%d)\n", (uint32_t)rrc_proc_state); + Error("Cell Select: Can't run procedure. Must call cell_select_init() first (%d)", (uint32_t)rrc_proc_state); goto clean_exit; } @@ -334,7 +331,7 @@ bool sync::cell_select_start(phy_cell_t new_cell) /* Reconfigure cell if necessary */ cell.id = new_cell.pci; if (not set_cell(new_cell.cfo_hz)) { - Error("Cell Select: Reconfiguring cell\n"); + Error("Cell Select: Reconfiguring cell"); goto clean_exit; } @@ -342,9 +339,9 @@ bool sync::cell_select_start(phy_cell_t new_cell) if ((int)new_cell.earfcn != current_earfcn) { current_earfcn = new_cell.earfcn; - Info("Cell Select: Setting new frequency EARFCN=%d\n", new_cell.earfcn); + Info("Cell Select: Setting new frequency EARFCN=%d", new_cell.earfcn); if (!set_frequency()) { - Error("Cell Select: Setting new frequency EARFCN=%d\n", new_cell.earfcn); + Error("Cell Select: Setting new frequency EARFCN=%d", new_cell.earfcn); goto clean_exit; } } @@ -352,20 +349,26 @@ bool sync::cell_select_start(phy_cell_t new_cell) // Reconfigure first intra-frequency measurement intra_freq_meas[0]->set_primary_cell(current_earfcn, cell); + // Reconfigure secondary serving cell synchronization assuming the same BW than the primary + // The secondary serving cell synchronization will not resize again when the SCell gets configured + for (auto& e : scell_sync) { + e.second->set_bw(cell.nof_prb); + } + // Change sampling rate if necessary if (srate_mode != SRATE_CAMP) { - log_h->info("Cell Select: Setting CAMPING sampling rate\n"); + phy_logger.info("Cell Select: Setting CAMPING sampling rate"); set_sampling_rate(); } // SFN synchronization phy_state.run_sfn_sync(); if (phy_state.is_camping()) { - Info("Cell Select: SFN synchronized. CAMPING...\n"); + Info("Cell Select: SFN synchronized. CAMPING..."); stack->in_sync(); ret = true; } else { - Info("Cell Select: Could not synchronize SFN\n"); + Info("Cell Select: Could not synchronize SFN"); } clean_exit: @@ -395,8 +398,8 @@ void sync::run_sfn_sync_state() if (memcmp(&cell, &temp_cell, sizeof(srslte_cell_t)) != 0) { srslte_cell_fprint(stdout, &cell, 0); srslte_cell_fprint(stdout, &temp_cell, 0); - log_h->error("Detected cell during SFN synchronization differs from configured cell. Cell reselection to " - "cells with different MIB is not supported\n"); + phy_logger.error("Detected cell during SFN synchronization differs from configured cell. Cell reselection to " + "cells with different MIB is not supported"); srslte::console("Detected cell during SFN synchronization differs from configured cell. Cell reselection " "to cells with different MIB is not supported\n"); phy_state.state_exit(false); @@ -417,10 +420,8 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, srslte::rf_buffer_t& sync_buffer) { // Update logging TTI - log_h->step(tti); - if (log_phy_lib_h != nullptr) { - log_phy_lib_h->step(tti); - } + phy_lib_logger.set_context(tti); + phy_logger.set_context(tti); // Check tti is synched with ue_sync if (srslte_ue_sync_get_sfidx(&ue_sync) != tti % 10) { @@ -439,7 +440,7 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, if (is_overflow) { force_camping_sfn_sync = true; is_overflow = false; - log_h->info("Detected overflow, trying to resync SFN\n"); + phy_logger.info("Detected overflow, trying to resync SFN"); } // Force decode MIB if required @@ -456,19 +457,19 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, force_camping_sfn_sync = false; if (memcmp(&cell, &temp_cell, sizeof(srslte_cell_t)) != 0) { - log_h->error("Detected cell during SFN synchronization differs from configured cell. Cell " - "reselection to cells with different MIB is not supported\n"); + phy_logger.error("Detected cell during SFN synchronization differs from configured cell. Cell " + "reselection to cells with different MIB is not supported"); srslte::console("Detected cell during SFN synchronization differs from configured cell. Cell " "reselection to cells with different MIB is not supported\n"); } else { - log_h->info("SFN resynchronized successfully\n"); + phy_logger.info("SFN resynchronized successfully"); } } else { - log_h->warning("SFN not yet synchronized, sending out-of-sync\n"); + phy_logger.warning("SFN not yet synchronized, sending out-of-sync"); } } - Debug("SYNC: Worker %d synchronized\n", lte_worker->get_id()); + Debug("SYNC: Worker %d synchronized", lte_worker->get_id()); metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); @@ -481,7 +482,7 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, if (prach_buffer->is_ready_to_send(tti, cell.id)) { prach_ptr = prach_buffer->generate(get_tx_cfo(), &prach_nof_sf, &prach_power); if (prach_ptr == nullptr) { - Error("Generating PRACH\n"); + Error("Generating PRACH"); } } @@ -511,15 +512,17 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, } } + // Start NR worker only if present + if (nr_worker != nullptr) { + // NR worker needs to be launched first, phy_common::worker_end expects first the NR worker and the LTE worker. + nr_worker->set_tti(tti); + worker_com->semaphore.push(nr_worker); + nr_worker_pool->start_worker(nr_worker); + } + // Start LTE worker worker_com->semaphore.push(lte_worker); lte_worker_pool->start_worker(lte_worker); - - // Start NR worker only if present - if (nr_worker != nullptr) { - nr_worker->set_tti(tti); - nr_worker_pool->start_worker(nr_worker); - } } void sync::run_camping_state() { @@ -560,7 +563,7 @@ void sync::run_camping_state() run_camping_in_sync_state(lte_worker, nr_worker, sync_buffer); break; case 0: - Warning("SYNC: Out-of-sync detected in PSS/SSS\n"); + Warning("SYNC: Out-of-sync detected in PSS/SSS"); out_of_sync(); lte_worker->release(); @@ -577,7 +580,7 @@ void sync::run_camping_state() } // Run stack - Debug("run_stack_tti: from main\n"); + Debug("run_stack_tti: from main"); run_stack_tti(); } @@ -588,7 +591,7 @@ void sync::run_idle_state() if (std::isnormal(current_srate) and current_srate > 0.0f) { nsamples = current_srate / 1000; } - Debug("Discarding %d samples\n", nsamples); + Debug("Discarding %d samples", nsamples); srslte_timestamp_t rx_time = {}; dummy_buffer.set_nof_samples(nsamples); if (radio_recv_fnc(dummy_buffer, &rx_time) == SRSLTE_SUCCESS) { @@ -600,7 +603,7 @@ void sync::run_idle_state() } radio_h->tx_end(); } else { - Debug("Sleeping\n"); + Debug("Sleeping"); usleep(1000); } } @@ -608,11 +611,9 @@ void sync::run_idle_state() void sync::run_thread() { while (running) { - if (log_phy_lib_h) { - log_phy_lib_h->step(tti); - } + phy_lib_logger.set_context(tti); - Debug("SYNC: state=%s, tti=%d\n", phy_state.to_string(), tti); + Debug("SYNC: state=%s, tti=%d", phy_state.to_string(), tti); // If not camping, clear SFN sync if (!phy_state.is_camping()) { @@ -651,7 +652,7 @@ void sync::radio_overflow() void sync::radio_error() { - log_h->error("SYNC: Receiving from radio.\n"); + phy_logger.error("SYNC: Receiving from radio."); // Need to find a method to effectively reset radio, reloading the driver does not work radio_h->reset(); } @@ -671,10 +672,10 @@ void sync::in_sync() void sync::out_of_sync() { // Send RRC out-of-sync signal after NOF_OUT_OF_SYNC_SF consecutive subframes - Info("Out-of-sync %d/%d\n", out_of_sync_cnt, worker_com->args->nof_out_of_sync_events); + Info("Out-of-sync %d/%d", out_of_sync_cnt, worker_com->args->nof_out_of_sync_events); out_of_sync_cnt++; if (out_of_sync_cnt == worker_com->args->nof_out_of_sync_events) { - Info("Sending to RRC\n"); + Info("Sending to RRC"); stack->out_of_sync(); out_of_sync_cnt = 0; in_sync_cnt = 0; @@ -701,14 +702,14 @@ void sync::set_agc_enable(bool enable) // PHY and radio must have been initialised if (not running or radio_h == nullptr) { - ERROR("Error setting AGC: PHY not initiated\n"); + ERROR("Error setting AGC: PHY not initiated"); return; } // Get radio info and check it is valid srslte_rf_info_t* rf_info = radio_h->get_info(); if (rf_info == nullptr) { - Error("Error: Radio does not provide RF information\n"); + Error("Error: Radio does not provide RF information"); return; } @@ -774,7 +775,7 @@ void sync::set_ue_sync_opts(srslte_ue_sync_t* q, float cfo) } else if (!worker_com->args->sss_algorithm.compare("full")) { sss_alg = SSS_FULL; } else { - Warning("SYNC: Invalid SSS algorithm %s. Using 'full'\n", worker_com->args->sss_algorithm.c_str()); + Warning("SYNC: Invalid SSS algorithm %s. Using 'full'", worker_com->args->sss_algorithm.c_str()); } srslte_sync_set_sss_algorithm(&q->strack, (sss_alg_t)sss_alg); srslte_sync_set_sss_algorithm(&q->sfind, (sss_alg_t)sss_alg); @@ -785,23 +786,23 @@ bool sync::set_cell(float cfo) // Wait for SYNC thread to transition to IDLE (max. 2000ms) uint32_t cnt = 0; while (!phy_state.is_idle() && cnt <= 4000) { - Info("SYNC: PHY state is_idle=%d, cnt=%d\n", phy_state.is_idle(), cnt); + Info("SYNC: PHY state is_idle=%d, cnt=%d", phy_state.is_idle(), cnt); usleep(500); cnt++; } if (!phy_state.is_idle()) { - Error("Can not change Cell while not in IDLE\n"); + Error("Can not change Cell while not in IDLE"); return false; } if (!srslte_cell_isvalid(&cell)) { - Error("SYNC: Setting cell: invalid cell (nof_prb=%d, pci=%d, ports=%d)\n", cell.nof_prb, cell.id, cell.nof_ports); + Error("SYNC: Setting cell: invalid cell (nof_prb=%d, pci=%d, ports=%d)", cell.nof_prb, cell.id, cell.nof_ports); return false; } // Set cell in all objects if (srslte_ue_sync_set_cell(&ue_sync, cell)) { - Error("SYNC: Setting cell: initiating ue_sync\n"); + Error("SYNC: Setting cell: initiating ue_sync"); return false; } sfn_p.set_cell(cell); @@ -821,7 +822,7 @@ bool sync::set_cell(float cfo) } } if (!success) { - Error("SYNC: Setting cell: initiating PHCH worker\n"); + Error("SYNC: Setting cell: initiating PHCH worker"); return false; } @@ -857,10 +858,8 @@ bool sync::set_frequency() } } if (set_dl_freq > 0 && set_ul_freq > 0) { - log_h->info("SYNC: Set DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz\n", - current_earfcn, - set_dl_freq / 1e6, - set_ul_freq / 1e6); + phy_logger.info( + "SYNC: Set DL EARFCN=%d, f_dl=%.1f MHz, f_ul=%.1f MHz", current_earfcn, set_dl_freq / 1e6, set_ul_freq / 1e6); // Logical channel is 0 radio_h->set_rx_freq(0, set_dl_freq); @@ -868,7 +867,7 @@ bool sync::set_frequency() for (uint32_t i = 0; i < worker_com->args->nof_nr_carriers; i++) { radio_h->set_rx_freq(i + worker_com->args->nof_lte_carriers, worker_com->args->nr_freq_hz); - // radio_h->set_tx_freq(0, set_ul_freq); + radio_h->set_tx_freq(i + worker_com->args->nof_lte_carriers, worker_com->args->nr_freq_hz); } ul_dl_factor = (float)(set_ul_freq / set_dl_freq); @@ -877,7 +876,7 @@ bool sync::set_frequency() return true; } else { - log_h->error("SYNC: Cell Search: Invalid EARFCN=%d\n", current_earfcn); + phy_logger.error("SYNC: Cell Search: Invalid EARFCN=%d", current_earfcn); return false; } } @@ -886,19 +885,19 @@ void sync::set_sampling_rate() { float new_srate = (float)srslte_sampling_freq_hz(cell.nof_prb); if (new_srate < 0.0) { - Error("Invalid sampling rate for %d PRBs. keeping same.\n", cell.nof_prb); + Error("Invalid sampling rate for %d PRBs. keeping same.", cell.nof_prb); return; } if (current_srate != new_srate || srate_mode != SRATE_CAMP) { current_srate = new_srate; - Info("SYNC: Setting sampling rate %.2f MHz\n", current_srate / 1000000); + Info("SYNC: Setting sampling rate %.2f MHz", current_srate / 1000000); srate_mode = SRATE_CAMP; radio_h->set_rx_srate(current_srate); radio_h->set_tx_srate(current_srate); } else { - Error("Error setting sampling rate for cell with %d PRBs\n", cell.nof_prb); + Error("Error setting sampling rate for cell with %d PRBs", cell.nof_prb); } } @@ -942,7 +941,7 @@ int sync::radio_recv_fnc(srslte::rf_buffer_t& data, srslte_timestamp_t* rx_time) // Run stack if the sync state is not in camping if (not phy_state.is_camping()) { - Debug("run_stack_tti: from recv\n"); + Debug("run_stack_tti: from recv"); run_stack_tti(); } @@ -963,7 +962,7 @@ int sync::radio_recv_fnc(srslte::rf_buffer_t& data, srslte_timestamp_t* rx_time) } } - log_h->debug("SYNC: received %d samples from radio\n", data.get_nof_samples()); + phy_logger.debug("SYNC: received %d samples from radio", data.get_nof_samples()); return data.get_nof_samples(); } @@ -974,14 +973,14 @@ void sync::run_stack_tti() if (forced_rx_time_init || srslte_timestamp_iszero(&stack_tti_ts) || srslte_timestamp_compare(&stack_tti_ts_new, &stack_tti_ts) < 0) { if (srslte_timestamp_compare(&stack_tti_ts_new, &stack_tti_ts) < 0) { - log_h->warning("SYNC: radio time seems to be going backwards (rx_time=%f, tti_ts=%f)\n", - srslte_timestamp_real(&stack_tti_ts_new), - srslte_timestamp_real(&stack_tti_ts)); + phy_logger.warning("SYNC: radio time seems to be going backwards (rx_time=%f, tti_ts=%f)", + srslte_timestamp_real(&stack_tti_ts_new), + srslte_timestamp_real(&stack_tti_ts)); // time-stamp will be set to rx time below and run_tti() will be called with MIN_TTI_JUMP } // init tti_ts with last rx time - log_h->debug("SYNC: Setting initial TTI time to %f\n", srslte_timestamp_real(&stack_tti_ts_new)); + phy_logger.debug("SYNC: Setting initial TTI time to %f", srslte_timestamp_real(&stack_tti_ts_new)); srslte_timestamp_copy(&stack_tti_ts, &stack_tti_ts_new); forced_rx_time_init = false; } @@ -994,14 +993,14 @@ void sync::run_stack_tti() int32_t tti_jump = static_cast(srslte_timestamp_uint64(&temp, 1e3)); tti_jump = SRSLTE_MAX(tti_jump, MIN_TTI_JUMP); if (tti_jump > MAX_TTI_JUMP) { - log_h->warning("SYNC: TTI jump of %d limited to %d\n", tti_jump, MAX_TTI_JUMP); + phy_logger.warning("SYNC: TTI jump of %d limited to %d", tti_jump, int(MAX_TTI_JUMP)); tti_jump = SRSLTE_MIN(tti_jump, MAX_TTI_JUMP); } // Run stack - Debug("run_stack_tti: calling stack tti=%d, tti_jump=%d\n", tti, tti_jump); + Debug("run_stack_tti: calling stack tti=%d, tti_jump=%d", tti, tti_jump); stack->run_tti(tti, tti_jump); - Debug("run_stack_tti: stack called\n"); + Debug("run_stack_tti: stack called"); } // update timestamp @@ -1034,7 +1033,7 @@ void sync::set_cells_to_meas(uint32_t earfcn_, const std::set& pci) } } if (!found) { - log_h->error("Neighbour cell measurement not supported in secondary carrier. EARFCN=%d\n", earfcn_); + phy_logger.error("Neighbour cell measurement not supported in secondary carrier. EARFCN=%d", earfcn_); } } diff --git a/srsue/src/phy/vnf_phy_nr.cc b/srsue/src/phy/vnf_phy_nr.cc index b433ab3ce..74fa792e8 100644 --- a/srsue/src/phy/vnf_phy_nr.cc +++ b/srsue/src/phy/vnf_phy_nr.cc @@ -37,8 +37,6 @@ using namespace std; namespace srsue { -vnf_phy_nr::vnf_phy_nr(srslte::logger* logger_) : logger(logger_) {} - vnf_phy_nr::~vnf_phy_nr() { stop(); @@ -53,7 +51,7 @@ int vnf_phy_nr::init(const srsue::phy_args_t& args_, srsue::stack_interface_phy_ int vnf_phy_nr::init(const srsue::phy_args_t& args_) { // create VNF - vnf = std::unique_ptr(new srslte::srslte_basic_vnf(args_.vnf_args, logger, stack)); + vnf = std::unique_ptr(new srslte::srslte_basic_vnf(args_.vnf_args, stack)); initialized = true; return SRSLTE_SUCCESS; } @@ -80,5 +78,9 @@ int vnf_phy_nr::tx_request(const tx_request_t& request) // send Tx request over basic API return vnf->tx_request(request); } +bool vnf_phy_nr::set_config(const srslte::phy_cfg_nr_t& cfg) +{ + return false; +} } // namespace srsue \ No newline at end of file diff --git a/srsue/src/stack/CMakeLists.txt b/srsue/src/stack/CMakeLists.txt index 59a2b097d..099092121 100644 --- a/srsue/src/stack/CMakeLists.txt +++ b/srsue/src/stack/CMakeLists.txt @@ -25,7 +25,6 @@ add_subdirectory(upper) set(SOURCES ue_stack_lte.cc) add_library(srsue_stack STATIC ${SOURCES}) -if(ENABLE_5GNR) - set(SOURCES ue_stack_nr.cc) - add_library(srsue_nr_stack STATIC ${SOURCES}) -endif() +add_subdirectory(mac_nr) +set(SOURCES ue_stack_nr.cc) +add_library(srsue_nr_stack STATIC ${SOURCES}) diff --git a/srsue/src/stack/mac/CMakeLists.txt b/srsue/src/stack/mac/CMakeLists.txt index c53b2e605..59be40744 100644 --- a/srsue/src/stack/mac/CMakeLists.txt +++ b/srsue/src/stack/mac/CMakeLists.txt @@ -19,9 +19,4 @@ # set(SOURCES demux.cc dl_harq.cc mac.cc mux.cc proc_bsr.cc proc_phr.cc proc_ra.cc proc_sr.cc ul_harq.cc) -add_library(srsue_mac STATIC ${SOURCES}) - -if(ENABLE_5GNR) - set(SOURCES mac_nr.cc) - add_library(srsue_mac_nr STATIC ${SOURCES}) -endif() +add_library(srsue_mac STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsue/src/stack/mac/demux.cc b/srsue/src/stack/mac/demux.cc index 83a4257f9..bc89fa300 100644 --- a/srsue/src/stack/mac/demux.cc +++ b/srsue/src/stack/mac/demux.cc @@ -19,10 +19,10 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/demux.h" #include "srslte/interfaces/ue_interfaces.h" @@ -30,7 +30,8 @@ namespace srsue { -demux::demux(log_ref log_h_) : log_h(log_h_), mac_msg(20, log_h_), mch_mac_msg(20, log_h_), pending_mac_msg(20, log_h_) +demux::demux(srslog::basic_logger& logger) : + logger(logger), mac_msg(20, logger), mch_mac_msg(20, logger), pending_mac_msg(20, logger), pdus(logger) {} void demux::init(phy_interface_mac_common* phy_, @@ -42,7 +43,7 @@ void demux::init(phy_interface_mac_common* phy_, rlc = rlc_; mac = mac_; time_alignment_timer = time_alignment_timer_; - pdus.init(this, log_h); + pdus.init(this); } void demux::reset() @@ -98,7 +99,7 @@ void demux::push_pdu_temp_crnti(uint8_t* buff, uint32_t nof_bytes) switch (pending_mac_msg.get()->dl_sch_ce_type()) { case srslte::dl_sch_lcid::CON_RES_ID: if (!is_uecrid_successful) { - Debug("Found Contention Resolution ID CE\n"); + Debug("Found Contention Resolution ID CE"); is_uecrid_successful = mac->contention_resolution_id_rcv(pending_mac_msg.get()->get_con_res_id()); } break; @@ -111,13 +112,13 @@ void demux::push_pdu_temp_crnti(uint8_t* buff, uint32_t nof_bytes) } pending_mac_msg.reset(); if (is_uecrid_successful) { - Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n"); + Debug("Saved MAC PDU with Temporal C-RNTI in buffer"); pdus.push(buff, nof_bytes, srslte::pdu_queue::DCH); } else { pdus.deallocate(buff); } } else { - Warning("Trying to push PDU with payload size zero\n"); + Warning("Trying to push PDU with payload size zero"); } } @@ -127,7 +128,6 @@ void demux::push_pdu_temp_crnti(uint8_t* buff, uint32_t nof_bytes) */ void demux::push_pdu(uint8_t* buff, uint32_t nof_bytes, uint32_t tti) { - // Process Real-Time PDUs process_sch_pdu_rt(buff, nof_bytes, tti); @@ -157,13 +157,13 @@ bool demux::process_pdus() void demux::process_pdu(uint8_t* mac_pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel) { - Debug("Processing MAC PDU channel %d\n", channel); + Debug("Processing MAC PDU channel %d", channel); switch (channel) { case srslte::pdu_queue::DCH: // Unpack DLSCH MAC PDU mac_msg.init_rx(nof_bytes); mac_msg.parse_packet(mac_pdu); - Info("%s\n", mac_msg.to_string().c_str()); + Info("%s", mac_msg.to_string().c_str()); process_sch_pdu(&mac_msg); pdus.deallocate(mac_pdu); break; @@ -182,7 +182,7 @@ void demux::process_pdu(uint8_t* mac_pdu, uint32_t nof_bytes, srslte::pdu_queue: void demux::process_sch_pdu_rt(uint8_t* buff, uint32_t nof_bytes, uint32_t tti) { - srslte::sch_pdu mac_msg_rt(20, log_h); + srslte::sch_pdu mac_msg_rt(20, logger); mac_msg_rt.init_rx(nof_bytes); mac_msg_rt.parse_packet(buff); @@ -193,7 +193,7 @@ void demux::process_sch_pdu_rt(uint8_t* buff, uint32_t nof_bytes, uint32_t tti) } else { // Process MAC Control Element if (!process_ce(mac_msg_rt.get(), tti)) { - Warning("Received Subheader with invalid or unknown LCID\n"); + Warning("Received Subheader with invalid or unknown LCID"); } } } @@ -212,21 +212,20 @@ void demux::process_sch_pdu(srslte::sch_pdu* pdu_msg) } if (sum == 0) { route_pdu = false; - Warning("Received all zero PDU\n"); + Warning("Received all zero PDU"); } } // Route logical channel if (route_pdu) { - Debug("Delivering PDU for lcid=%d, %d bytes\n", - pdu_msg->get()->get_sdu_lcid(), - pdu_msg->get()->get_payload_size()); + Debug( + "Delivering PDU for lcid=%d, %d bytes", pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_payload_size()); if (pdu_msg->get()->get_payload_size() < MAX_PDU_LEN) { rlc->write_pdu( pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); } else { char tmp[1024]; srslte_vec_sprint_hex(tmp, sizeof(tmp), pdu_msg->get()->get_sdu_ptr(), 32); - Error("PDU size %d exceeds maximum PDU buffer size, lcid=%d, hex=[%s]\n", + Error("PDU size %d exceeds maximum PDU buffer size, lcid=%d, hex=[%s]", pdu_msg->get()->get_payload_size(), pdu_msg->get()->get_sdu_lcid(), tmp); @@ -241,22 +240,21 @@ void demux::process_mch_pdu(srslte::mch_pdu* mch_msg) { // disgarding headers that have already been processed while (mch_msg->next()) { - if (srslte::mch_lcid::MCH_SCHED_INFO == mch_msg->get()->mch_ce_type()) { uint16_t stop; uint8_t lcid; if (mch_msg->get()->get_next_mch_sched_info(&lcid, &stop)) { - Info("MCH Sched Info: LCID: %d, Stop: %d, tti is %d \n", lcid, stop, phy_h->get_current_tti()); + Info("MCH Sched Info: LCID: %d, Stop: %d, tti is %d ", lcid, stop, phy_h->get_current_tti()); } } if (mch_msg->get()->is_sdu()) { uint32_t lcid = mch_msg->get()->get_sdu_lcid(); if (lcid >= SRSLTE_N_MCH_LCIDS) { - Error("Radio bearer id must be in [0:%d] - %d\n", SRSLTE_N_MCH_LCIDS, lcid); + Error("Radio bearer id must be in [0:%d] - %d", SRSLTE_N_MCH_LCIDS, lcid); return; } - Debug("Wrote MCH LCID=%d to RLC\n", lcid); + Debug("Wrote MCH LCID=%d to RLC", lcid); if (1 == mch_lcids[lcid]) { rlc->write_pdu_mch(lcid, mch_msg->get()->get_sdu_ptr(), mch_msg->get()->get_payload_size()); } @@ -267,10 +265,10 @@ void demux::process_mch_pdu(srslte::mch_pdu* mch_msg) void demux::mch_start_rx(uint32_t lcid) { if (lcid < 32) { - Info("MCH Channel Setup: LCID=%d\n", lcid); + Info("MCH Channel Setup: LCID=%d", lcid); mch_lcids[lcid] = 1; } else { - Error("MCH Channel Setup: invalid LCID=%d\n", lcid); + Error("MCH Channel Setup: invalid LCID=%d", lcid); } } @@ -286,14 +284,14 @@ bool demux::process_ce(srslte::sch_subh* subh, uint32_t tti) case srslte::dl_sch_lcid::SCELL_ACTIVATION: { uint32_t cmd = (uint32_t)subh->get_activation_deactivation_cmd(); srslte::console("SCELL Activation / Deactivation CMD: %x\n", cmd); - log_h->info("SCELL Activation / Deactivation CMD: %x\n", cmd); + logger.info("SCELL Activation / Deactivation CMD: %x", cmd); phy_h->set_activation_deactivation_scell(cmd, tti); break; } case srslte::dl_sch_lcid::PADDING: break; default: - Error("MAC CE 0x%x not supported\n", subh->lcid_value()); + Error("MAC CE 0x%x not supported", subh->lcid_value()); break; } return true; @@ -302,7 +300,7 @@ bool demux::process_ce(srslte::sch_subh* subh, uint32_t tti) void demux::parse_ta_cmd(srslte::sch_subh* subh) { phy_h->set_timeadv(subh->get_ta_cmd()); - Info("Received TA=%d (%d/%d) \n", + Info("Received TA=%d (%d/%d) ", subh->get_ta_cmd(), time_alignment_timer->time_elapsed(), time_alignment_timer->duration()); diff --git a/srsue/src/stack/mac/dl_harq.cc b/srsue/src/stack/mac/dl_harq.cc index fbfff3a65..9a9cb7849 100644 --- a/srsue/src/stack/mac/dl_harq.cc +++ b/srsue/src/stack/mac/dl_harq.cc @@ -19,10 +19,10 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/dl_harq.h" #include "srslte/common/log.h" @@ -32,12 +32,13 @@ namespace srsue { -dl_harq_entity::dl_harq_entity(uint8_t cc_idx_) : proc(SRSLTE_MAX_HARQ_PROC), cc_idx(cc_idx_) {} +dl_harq_entity::dl_harq_entity(uint8_t cc_idx_) : + proc(SRSLTE_MAX_HARQ_PROC), logger(srslog::fetch_basic_logger("MAC")), cc_idx(cc_idx_) +{} -bool dl_harq_entity::init(srslte::log_ref log_h_, mac_interface_rrc::ue_rnti_t* rntis_, demux* demux_unit_) +bool dl_harq_entity::init(mac_interface_rrc::ue_rnti_t* rntis_, demux* demux_unit_) { demux_unit = demux_unit_; - log_h = log_h_; rntis = rntis_; for (uint32_t i = 0; i < SRSLTE_MAX_HARQ_PROC; i++) { @@ -62,7 +63,7 @@ void dl_harq_entity::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, proc_ptr = &bcch_proc; } else { if (grant.pid >= SRSLTE_MAX_HARQ_PROC) { - Error("Invalid PID: %d\n", grant.pid); + Error("Invalid PID: %d", grant.pid); return; } proc_ptr = &proc[grant.pid]; @@ -71,11 +72,11 @@ void dl_harq_entity::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, if (grant.rnti == rntis->temp_rnti && last_temporal_crnti != rntis->temp_rnti) { last_temporal_crnti = rntis->temp_rnti; proc_ptr->reset_ndi(); - Info("Considering NDI in pid=%d to be toggled for first Temporal C-RNTI\n", grant.pid); + Info("Considering NDI in pid=%d to be toggled for first Temporal C-RNTI", grant.pid); } proc_ptr->new_grant_dl(grant, action); } else { - Error("SPS not supported\n"); + Error("SPS not supported"); } } @@ -85,7 +86,7 @@ void dl_harq_entity::tb_decoded(mac_interface_phy_lte::mac_grant_dl_t grant, boo bcch_proc.tb_decoded(grant, ack); } else { if (grant.pid >= SRSLTE_MAX_HARQ_PROC) { - Error("Invalid PID: %d\n", grant.pid); + Error("Invalid PID: %d", grant.pid); return; } proc[grant.pid].tb_decoded(grant, ack); @@ -168,7 +169,7 @@ bool dl_harq_entity::dl_harq_process::is_sps() return false; } -dl_harq_entity::dl_harq_process::dl_tb_process::dl_tb_process() +dl_harq_entity::dl_harq_process::dl_tb_process::dl_tb_process() : logger(srslog::fetch_basic_logger("MAC")) { is_initiated = false; ack = false; @@ -187,7 +188,7 @@ dl_harq_entity::dl_harq_process::dl_tb_process::~dl_tb_process() bool dl_harq_entity::dl_harq_process::dl_tb_process::init(int pid, dl_harq_entity* parent, uint32_t tb_idx) { if (srslte_softbuffer_rx_init(&softbuffer, 110)) { - Error("Error initiating soft buffer\n"); + Error("Error initiating soft buffer"); return false; } @@ -203,7 +204,6 @@ bool dl_harq_entity::dl_harq_process::dl_tb_process::init(int pid, dl_harq_entit is_first_tb = true; is_initiated = true; harq_entity = parent; - log_h = harq_entity->log_h; return true; } @@ -258,7 +258,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::new_grant_dl(mac_interface_ // If this is a new transmission or the size of the TB has changed if (is_new_transmission || (cur_grant.tb[tid].tbs != grant.tb[tid].tbs)) { if (!is_new_transmission) { - Debug("DL PID %d: Size of dci changed during a retransmission %d!=%d\n", + Debug("DL PID %d: Size of dci changed during a retransmission %d!=%d", pid, cur_grant.tb[tid].tbs, grant.tb[tid].tbs); @@ -277,7 +277,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::new_grant_dl(mac_interface_ cur_grant = grant; if (payload_buffer_ptr) { - Warning("DL PID %d: Allocating buffer already allocated. Deallocating.\n", pid); + Warning("DL PID %d: Allocating buffer already allocated. Deallocating.", pid); if (!is_bcch) { harq_entity->demux_unit->deallocate(payload_buffer_ptr); } @@ -292,7 +292,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::new_grant_dl(mac_interface_ action->tb[tid].payload = payload_buffer_ptr; if (!action->tb[tid].payload) { - Error("Can't get a buffer for TBS=%d\n", cur_grant.tb[tid].tbs); + Error("Can't get a buffer for TBS=%d", cur_grant.tb[tid].tbs); return; } @@ -300,7 +300,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::new_grant_dl(mac_interface_ action->tb[tid].rv = cur_grant.tb[tid].rv; action->tb[tid].softbuffer.rx = &softbuffer; } else { - Info("DL PID %d: Received duplicate TB%d. Discarding and retransmitting ACK (n_retx=%d, reset=%s)\n", + Info("DL PID %d: Received duplicate TB%d. Discarding and retransmitting ACK (n_retx=%d, reset=%s)", pid, tid, n_retx, @@ -325,7 +325,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::tb_decoded(mac_interface_ph harq_entity->pcap->write_dl_sirnti( payload_buffer_ptr, cur_grant.tb[tid].tbs, ack, cur_grant.tti, harq_entity->cc_idx); } - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.tb[tid].tbs); + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)", cur_grant.tb[tid].tbs); harq_entity->demux_unit->push_pdu_bcch(payload_buffer_ptr, cur_grant.tb[tid].tbs); } else { if (harq_entity->pcap) { @@ -333,14 +333,14 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::tb_decoded(mac_interface_ph payload_buffer_ptr, cur_grant.tb[tid].tbs, cur_grant.rnti, ack, cur_grant.tti, harq_entity->cc_idx); } if (cur_grant.rnti == harq_entity->rntis->temp_rnti) { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", cur_grant.tb[tid].tbs); + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)", cur_grant.tb[tid].tbs); harq_entity->demux_unit->push_pdu_temp_crnti(payload_buffer_ptr, cur_grant.tb[tid].tbs); // If T-CRNTI, update ack value with result from contention resolution *ack_ptr = harq_entity->demux_unit->get_uecrid_successful(); } else { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.tb[tid].tbs); + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit", cur_grant.tb[tid].tbs); harq_entity->demux_unit->push_pdu(payload_buffer_ptr, cur_grant.tb[tid].tbs, grant.tti); // Compute average number of retransmissions per packet @@ -354,7 +354,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::tb_decoded(mac_interface_ph payload_buffer_ptr = NULL; - Info("DL %d (TB %d): %s tbs=%d, rv=%d, ack=%s, ndi=%d\n", + Info("DL %d (TB %d): %s tbs=%d, rv=%d, ack=%s, ndi=%d", pid, tid, is_new_transmission ? "newTX" : "reTX ", @@ -386,7 +386,7 @@ bool dl_harq_entity::dl_harq_process::dl_tb_process::calc_is_new_transmission( is_new_transmission = false; } - Debug("Set HARQ for %stransmission\n", is_new_transmission ? "new " : "re"); + Debug("Set HARQ for %stransmission", is_new_transmission ? "new " : "re"); return is_new_transmission; } diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index b5ff6b91a..64b1ad599 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -19,10 +19,10 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include #include @@ -36,10 +36,14 @@ namespace srsue { mac::mac(const char* logname, ext_task_sched_handle task_sched_) : - log_h(srslte::logmap::get(logname)), - mch_msg(10, log_h), - mux_unit(log_h), - demux_unit(log_h), + logger(srslog::fetch_basic_logger(logname)), + mch_msg(10, logger), + mux_unit(logger), + demux_unit(logger), + ra_procedure(logger), + sr_procedure(logger), + bsr_procedure(logger), + phr_procedure(logger), pcap(nullptr), task_sched(task_sched_) { @@ -50,8 +54,6 @@ mac::mac(const char* logname, ext_task_sched_handle task_sched_) : srslte_softbuffer_rx_init(&pch_softbuffer, 100); srslte_softbuffer_rx_init(&mch_softbuffer, 100); - pool = srslte::byte_buffer_pool::get_instance(); - // Keep initialising members bzero(&metrics, sizeof(mac_metrics_t)); clear_rntis(); @@ -76,16 +78,16 @@ bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface // Create Stack task dispatch queue stack_task_dispatch_queue = task_sched.make_task_queue(); - bsr_procedure.init(&sr_procedure, rlc_h, log_h, &task_sched); - phr_procedure.init(phy_h, log_h, &task_sched); + bsr_procedure.init(&sr_procedure, rlc_h, &task_sched); + phr_procedure.init(phy_h, &task_sched); mux_unit.init(rlc_h, &bsr_procedure, &phr_procedure); demux_unit.init(phy_h, rlc_h, this, &timer_alignment); - ra_procedure.init(phy_h, rrc, log_h, &uernti, &timer_alignment, &mux_unit, &task_sched); - sr_procedure.init(&ra_procedure, phy_h, rrc, log_h); + ra_procedure.init(phy_h, rrc, &uernti, &timer_alignment, &mux_unit, &task_sched); + sr_procedure.init(&ra_procedure, phy_h, rrc); // Create UL/DL unique HARQ pointers - ul_harq.at(PCELL_CC_IDX)->init(log_h, &uernti, &ra_procedure, &mux_unit); - dl_harq.at(PCELL_CC_IDX)->init(log_h, &uernti, &demux_unit); + ul_harq.at(PCELL_CC_IDX)->init(&uernti, &ra_procedure, &mux_unit); + dl_harq.at(PCELL_CC_IDX)->init(&uernti, &demux_unit); reset(); @@ -129,7 +131,7 @@ void mac::reconfiguration(const uint32_t& cc_idx, const bool& enable) if (cc_idx < SRSLTE_MAX_CARRIERS) { if (enable and ul_harq.at(cc_idx) == nullptr) { ul_harq_entity_ptr ul = ul_harq_entity_ptr(new ul_harq_entity(cc_idx)); - ul->init(log_h, &uernti, &ra_procedure, &mux_unit); + ul->init(&uernti, &ra_procedure, &mux_unit); ul->set_config(ul_harq_cfg); if (pcap != nullptr) { @@ -141,7 +143,7 @@ void mac::reconfiguration(const uint32_t& cc_idx, const bool& enable) if (enable and dl_harq.at(cc_idx) == nullptr) { dl_harq_entity_ptr dl = dl_harq_entity_ptr(new dl_harq_entity(cc_idx)); - dl->init(log_h, &uernti, &demux_unit); + dl->init(&uernti, &demux_unit); if (pcap != nullptr) { dl->start_pcap(pcap); @@ -157,7 +159,7 @@ void mac::reset() { bzero(&metrics, sizeof(mac_metrics_t)); - Info("Resetting MAC\n"); + Info("Resetting MAC"); timer_alignment.stop(); @@ -196,12 +198,12 @@ void mac::reset() void mac::run_tti(const uint32_t tti) { - log_h->step(tti); + logger.set_context(tti); /* Warning: Here order of invocation of procedures is important!! */ // Step all procedures (must follow this order) - Debug("Running MAC tti=%d\n", tti); + Debug("Running MAC tti=%d", tti); mux_unit.step(); bsr_procedure.step(tti); sr_procedure.step(tti); @@ -225,7 +227,7 @@ void mac::bcch_start_rx(int si_window_start_, int si_window_length_) si_window_length = 0; si_window_start = 0; } - Info("SCHED: Searching for DL dci for SI-RNTI window_st=%d, window_len=%d\n", si_window_start, si_window_length); + Info("SCHED: Searching for DL dci for SI-RNTI window_st=%d, window_len=%d", si_window_start, si_window_length); } void mac::bcch_stop_rx() @@ -311,25 +313,25 @@ uint16_t mac::get_dl_sched_rnti(uint32_t tti) return SRSLTE_INVALID_RNTI; } } - Debug("SCHED: Searching SI-RNTI, tti=%d, window start=%d, length=%d\n", tti, si_window_start, si_window_length); + Debug("SCHED: Searching SI-RNTI, tti=%d, window start=%d, length=%d", tti, si_window_start, si_window_length); return SRSLTE_SIRNTI; } } if (uernti.rar_rnti && ra_window_start > 0 && ra_window_length > 0 && is_in_window(tti, &ra_window_start, &ra_window_length)) { - Debug("SCHED: Searching RAR-RNTI=0x%x, tti=%d\n", uernti.rar_rnti, tti); + Debug("SCHED: Searching RAR-RNTI=0x%x, tti=%d", uernti.rar_rnti, tti); return uernti.rar_rnti; } if (uernti.temp_rnti && !uernti.crnti) { - Debug("SCHED: Searching Temp-RNTI=0x%x\n", uernti.temp_rnti); + Debug("SCHED: Searching Temp-RNTI=0x%x", uernti.temp_rnti); return uernti.temp_rnti; } if (uernti.crnti) { - Debug("SCHED: Searching C-RNTI=0x%x\n", uernti.crnti); + Debug("SCHED: Searching C-RNTI=0x%x", uernti.crnti); return uernti.crnti; } if (p_window_start > 0) { - Debug("SCHED: Searching P-RNTI\n"); + Debug("SCHED: Searching P-RNTI"); return SRSLTE_PRNTI; } @@ -340,7 +342,7 @@ uint16_t mac::get_dl_sched_rnti(uint32_t tti) void mac::bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) { // Send MIB to RLC - unique_byte_buffer_t buf = allocate_unique_buffer(*pool); + unique_byte_buffer_t buf = make_byte_buffer(); if (buf != nullptr) { memcpy(buf->msg, payload, len); buf->N_bytes = len; @@ -348,10 +350,10 @@ void mac::bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) auto p = stack_task_dispatch_queue.try_push(std::bind( [this](srslte::unique_byte_buffer_t& buf) { rlc_h->write_pdu_bcch_bch(std::move(buf)); }, std::move(buf))); if (not p.first) { - Warning("Failed to dispatch rlc::write_pdu_bcch_bch task to stack\n"); + Warning("Failed to dispatch rlc::write_pdu_bcch_bch task to stack"); } } else { - log_h->error("Fatal error: Out of buffers from the pool in write_pdu_bcch_bch()\n"); + logger.error("Fatal error: Out of buffers from the pool in write_pdu_bcch_bch()"); } if (pcap) { @@ -372,7 +374,7 @@ void mac::mch_decoded(uint32_t len, bool crc) uint8_t lcid; if (mch_msg.get()->get_next_mch_sched_info(&lcid, &stop)) { phy_h->set_mch_period_stop(stop); - Info("MCH Sched Info: LCID: %d, Stop: %d, tti is %d \n", lcid, stop, phy_h->get_current_tti()); + Info("MCH Sched Info: LCID: %d, Stop: %d, tti is %d ", lcid, stop, phy_h->get_current_tti()); } } } @@ -400,7 +402,7 @@ void mac::tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSLTE_MAX_ } } else if (grant.rnti == SRSLTE_PRNTI) { // Send PCH payload to RLC - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (pdu != nullptr) { memcpy(pdu->msg, pch_payload_buffer, grant.tb[0].tbs); pdu->N_bytes = grant.tb[0].tbs; @@ -409,20 +411,19 @@ void mac::tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSLTE_MAX_ auto ret = stack_task_dispatch_queue.try_push(std::bind( [this](srslte::unique_byte_buffer_t& pdu) { rlc_h->write_pdu_pcch(std::move(pdu)); }, std::move(pdu))); if (not ret.first) { - Warning("Failed to dispatch rlc::write_pdu_pcch task to stack\n"); + Warning("Failed to dispatch rlc::write_pdu_pcch task to stack"); } } else { - log_h->error("Fatal error: Out of buffers from the pool in write_pdu_pcch()\n"); + logger.error("Fatal error: Out of buffers from the pool in write_pdu_pcch()"); } if (pcap) { pcap->write_dl_pch(pch_payload_buffer, grant.tb[0].tbs, true, grant.tti, cc_idx); } } else { - // Assert DL HARQ entity if (dl_harq.at(cc_idx) == nullptr) { - Error("HARQ entity %d has not been created\n", cc_idx); + Error("HARQ entity %d has not been created", cc_idx); return; } @@ -449,10 +450,9 @@ void mac::new_grant_dl(uint32_t cc_idx, if (SRSLTE_RNTI_ISRAR(grant.rnti)) { ra_procedure.new_grant_dl(grant, action); } else if (grant.rnti == SRSLTE_PRNTI) { - bzero(action, sizeof(mac_interface_phy_lte::tb_action_dl_t)); if (grant.tb[0].tbs > pch_payload_buffer_sz) { - Error("Received dci for PCH (%d bytes) exceeds buffer (%d bytes)\n", grant.tb[0].tbs, pch_payload_buffer_sz); + Error("Received dci for PCH (%d bytes) exceeds buffer (%d bytes)", grant.tb[0].tbs, int(pch_payload_buffer_sz)); action->tb[0].enabled = false; } else { action->tb[0].enabled = true; @@ -468,14 +468,14 @@ void mac::new_grant_dl(uint32_t cc_idx, } // Assert DL HARQ entity if (dl_harq.at(cc_idx) == nullptr) { - Error("HARQ entity %d has not been created\n", cc_idx); + Error("HARQ entity %d has not been created", cc_idx); return; } dl_harq.at(cc_idx)->new_grant_dl(grant, action); } else { /* Discard */ - Info("Discarding dci in CC %d, RNTI=0x%x\n", cc_idx, grant.rnti); + Info("Discarding dci in CC %d, RNTI=0x%x", cc_idx, grant.rnti); } } @@ -489,7 +489,7 @@ void mac::process_pdus() } }); if (not ret.first) { - Warning("Failed to dispatch mac::%s task to stack thread\n", __func__); + Warning("Failed to dispatch mac::%s task to stack thread", __func__); } } @@ -526,7 +526,7 @@ void mac::new_grant_ul(uint32_t cc_idx, // Assert UL HARQ entity if (ul_harq.at(cc_idx) == nullptr) { - Error("HARQ entity %d has not been created\n", cc_idx); + Error("HARQ entity %d has not been created", cc_idx); return; } @@ -566,10 +566,10 @@ void mac::setup_timers(int time_alignment_timer) void mac::timer_expired(uint32_t timer_id) { if (timer_id == timer_alignment.id()) { - Info("Time Alignment Timer expired\n"); + Info("Time Alignment Timer expired"); timer_alignment_expire(); } else { - Warning("Received callback from unknown timer_id=%d\n", timer_id); + Warning("Received callback from unknown timer_id=%d", timer_id); } } @@ -608,13 +608,13 @@ void mac::set_mbsfn_config(uint32_t nof_mbsfn_services) // Only reset SR config void mac::set_config(sr_cfg_t& sr_cfg) { - Info("Setting SR configuration\n"); + Info("Setting SR configuration"); sr_procedure.set_config(sr_cfg); } void mac::set_config(mac_cfg_t& mac_cfg) { - Info("Setting configuration\n"); + Info("Setting configuration"); // Set configuration for each module in MAC bsr_procedure.set_config(mac_cfg.bsr_cfg); phr_procedure.set_config(mac_cfg.phr_cfg); @@ -643,7 +643,7 @@ void mac::setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_t void mac::setup_lcid(const logical_channel_config_t& config) { - Info("Logical Channel Setup: LCID=%d, LCG=%d, priority=%d, PBR=%d, BSD=%dms, bucket_size=%d\n", + Info("Logical Channel Setup: LCID=%d, LCG=%d, priority=%d, PBR=%d, BSD=%dms, bucket_size=%d", config.lcid, config.lcg, config.priority, @@ -690,7 +690,7 @@ void mac::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]) dl_avg_ret /= dl_avg_ret_count; } - Info("DL retx: %.2f \%%, perpkt: %.2f, UL retx: %.2f \%% perpkt: %.2f\n", + Info("DL retx: %.2f \%%, perpkt: %.2f, UL retx: %.2f \%% perpkt: %.2f", rx_pkts ? ((float)100 * rx_errors / rx_pkts) : 0.0f, dl_avg_ret, tx_pkts ? ((float)100 * tx_errors / tx_pkts) : 0.0f, diff --git a/srsue/src/stack/mac/mac_nr.cc b/srsue/src/stack/mac/mac_nr.cc deleted file mode 100644 index b4f754a4d..000000000 --- a/srsue/src/stack/mac/mac_nr.cc +++ /dev/null @@ -1,268 +0,0 @@ -/** - * Copyright 2013-2021 Software Radio Systems Limited - * - * This file is part of srsLTE. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include "srsue/hdr/stack/mac/mac_nr.h" -#include "srslte/common/log_helper.h" - -using namespace asn1::rrc; - -namespace srsue { - -mac_nr::mac_nr(srslte::ext_task_sched_handle task_sched_) : - pool(srslte::byte_buffer_pool::get_instance()), - log_h("MAC"), - task_sched(task_sched_) -{ - tx_buffer = srslte::allocate_unique_buffer(*pool); - rlc_buffer = srslte::allocate_unique_buffer(*pool); -} - -mac_nr::~mac_nr() -{ - stop(); -} - -int mac_nr::init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy_, rlc_interface_mac* rlc_) -{ - args = args_; - phy = phy_; - rlc = rlc_; - - // Create Stack task dispatch queue - stack_task_dispatch_queue = task_sched.make_task_queue(); - - // Set up pcap - if (args.pcap.enable) { - pcap.reset(new srslte::mac_nr_pcap()); - pcap->open(args.pcap.filename.c_str()); - } - - started = true; - - return SRSLTE_SUCCESS; -} - -void mac_nr::stop() -{ - if (started) { - if (pcap != nullptr) { - pcap->close(); - } - - started = false; - } -} - -// Implement Section 5.9 -void mac_nr::reset() -{ - Info("Resetting MAC\n"); -} - -void mac_nr::run_tti(const uint32_t tti) -{ - log_h->step(tti); - - // Step all procedures - Debug("Running MAC tti=%d\n", tti); -} - -uint16_t mac_nr::get_ul_sched_rnti(uint32_t tti) -{ - return crnti; -} - -uint16_t mac_nr::get_dl_sched_rnti(uint32_t tti) -{ - return crnti; -} - -void mac_nr::bch_decoded_ok(uint32_t tti, srslte::unique_byte_buffer_t payload) -{ - // Send MIB to RLC - rlc->write_pdu_bcch_bch(std::move(payload)); - - if (pcap) { - // pcap->write_dl_bch(payload, len, true, tti); - } -} - -int mac_nr::sf_indication(const uint32_t tti) -{ - run_tti(tti); - return SRSLTE_SUCCESS; -} - -/** - * \brief Called from PHY after decoding a TB - * - * The TB can directly be used - * - * @param cc_idx - * @param grant structure - */ -void mac_nr::tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) -{ - if (SRSLTE_RNTI_ISRAR(grant.rnti)) { - // TODO: deliver to RA procedure - } else if (grant.rnti == SRSLTE_PRNTI) { - // Send PCH payload to RLC - // rlc->write_pdu_pcch(pch_payload_buffer, grant.tb[0].tbs); - - if (pcap) { - // pcap->write_dl_pch(pch_payload_buffer, grant.tb[0].tbs, true, grant.tti); - } - } else { - for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; ++i) { - if (grant.tb[i] != nullptr) { - if (pcap) { - pcap->write_dl_crnti(grant.tb[i]->msg, grant.tb[i]->N_bytes, grant.rnti, true, grant.tti); - } - pdu_queue.push(std::move(grant.tb[i])); - - metrics[cc_idx].rx_pkts++; - } - } - - stack_task_dispatch_queue.push([this]() { process_pdus(); }); - } -} - -void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant) -{ - phy_interface_stack_nr::tx_request_t tx_request = {}; - - get_ul_data(grant, &tx_request); - - // send TX.request - phy->tx_request(tx_request); - - metrics[cc_idx].tx_pkts++; -} - -void mac_nr::get_ul_data(const mac_nr_grant_ul_t& grant, phy_interface_stack_nr::tx_request_t* tx_request) -{ - // Todo: delegate to mux class - tx_request->tb_len = grant.tbs; - - // initialize MAC PDU - tx_buffer->clear(); - tx_pdu.init_tx(tx_buffer.get(), grant.tbs, true); - - while (tx_pdu.get_remaing_len() >= MIN_RLC_PDU_LEN) { - // read RLC PDU - rlc_buffer->clear(); - uint8_t* rd = rlc_buffer->msg; - int pdu_len = rlc->read_pdu(args.drb_lcid, rd, tx_pdu.get_remaing_len() - 2); - - // Add SDU if RLC has something to tx - if (pdu_len > 0) { - rlc_buffer->N_bytes = pdu_len; - log_h->info_hex(rlc_buffer->msg, rlc_buffer->N_bytes, "Read %d B from RLC\n", rlc_buffer->N_bytes); - - // add to MAC PDU and pack - if (tx_pdu.add_sdu(args.drb_lcid, rlc_buffer->msg, rlc_buffer->N_bytes) != SRSLTE_SUCCESS) { - log_h->error("Error packing MAC PDU\n"); - } - } else { - break; - } - } - - // Pack PDU - tx_pdu.pack(); - - log_h->info_hex(tx_buffer->msg, tx_buffer->N_bytes, "Generated MAC PDU (%d B)\n", tx_buffer->N_bytes); - - tx_request->data = tx_buffer->msg; - tx_request->tb_len = tx_buffer->N_bytes; - - if (pcap) { - pcap->write_ul_crnti(tx_request->data, tx_request->tb_len, grant.rnti, grant.pid, grant.tti); - } -} - -void mac_nr::timer_expired(uint32_t timer_id) -{ - // not implemented -} - -void mac_nr::setup_lcid(const srslte::logical_channel_config_t& config) -{ - Info("Logical Channel Setup: LCID=%d, LCG=%d, priority=%d, PBR=%d, BSD=%dms, bucket_size=%d\n", - config.lcid, - config.lcg, - config.priority, - config.PBR, - config.BSD, - config.bucket_size); - // mux_unit.setup_lcid(config); - // bsr_procedure.setup_lcid(config.lcid, config.lcg, config.priority); -} - -void mac_nr::set_config(const srslte::bsr_cfg_t& bsr_cfg) -{ - Info("BSR config periodic timer %d retx timer %d\n", bsr_cfg.periodic_timer, bsr_cfg.retx_timer); - Warning("Not handling BSR config yet\n"); -} - -void mac_nr::set_config(const srslte::sr_cfg_t& sr_cfg) -{ - Info("Scheduling Request Config DSR tansmax %d\n", sr_cfg.dsr_transmax); - Warning("Not Scheduling Request Config yet\n"); -} - -void mac_nr::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]) {} - -/** - * Called from the main stack thread to process received PDUs - */ -void mac_nr::process_pdus() -{ - while (started and not pdu_queue.empty()) { - srslte::unique_byte_buffer_t pdu = pdu_queue.wait_pop(); - // TODO: delegate to demux class - handle_pdu(std::move(pdu)); - } -} - -void mac_nr::handle_pdu(srslte::unique_byte_buffer_t pdu) -{ - log_h->info_hex(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)\n", pdu->N_bytes); - - rx_pdu.init_rx(); - rx_pdu.unpack(pdu->msg, pdu->N_bytes); - - for (uint32_t i = 0; i < rx_pdu.get_num_subpdus(); ++i) { - srslte::mac_nr_sch_subpdu subpdu = rx_pdu.get_subpdu(i); - log_h->info("Handling subPDU %d/%d: lcid=%d, sdu_len=%d\n", - i, - rx_pdu.get_num_subpdus(), - subpdu.get_lcid(), - subpdu.get_sdu_length()); - - if (subpdu.get_lcid() == args.drb_lcid) { - rlc->write_pdu(subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); - } - } -} - -} // namespace srsue diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 3768fb5a2..98d7212a7 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -19,10 +19,10 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/mux.h" #include "srsue/hdr/stack/mac/mac.h" @@ -32,10 +32,7 @@ namespace srsue { -mux::mux(srslte::log_ref log_) : pdu_msg(MAX_NOF_SUBHEADERS, log_), log_h(log_) -{ - msg3_flush(); -} +mux::mux(srslog::basic_logger& logger) : logger(logger), pdu_msg(MAX_NOF_SUBHEADERS, logger) {} void mux::init(rlc_interface_mac* rlc_, bsr_interface_mux* bsr_procedure_, phr_proc* phr_procedure_) { @@ -67,7 +64,7 @@ void mux::step() channel.Bj += channel.PBR; // PBR is in kByte/s, conversion in Byte and ms not needed } channel.Bj = SRSLTE_MIN((uint32_t)channel.Bj, channel.bucket_size); - Debug("Update Bj: lcid=%d, Bj=%d\n", channel.lcid, channel.Bj); + Debug("Update Bj: lcid=%d, Bj=%d", channel.lcid, channel.Bj); } } @@ -112,7 +109,7 @@ void mux::setup_lcid(const logical_channel_config_t& config) // warn user if there is another LCID with same prio for (auto& channel : logical_channels) { if (channel.priority == config.priority && channel.lcid != config.lcid) { - log_h->warning("LCID %d and %d have same priority.\n", channel.lcid, config.lcid); + logger.warning("LCID %d and %d have same priority.", channel.lcid, config.lcid); } } } else { @@ -148,7 +145,7 @@ void mux::print_logical_channel_state(const std::string& info) logline += ", sched_len="; logline += std::to_string(channel.sched_len); } - log_h->debug("%s\n", logline.c_str()); + logger.debug("%s", logline.c_str()); } srslte::ul_sch_lcid bsr_format_convert(bsr_proc::bsr_format_t format) @@ -178,13 +175,13 @@ uint8_t* mux::pdu_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) if (pending_crnti_ce) { if (pdu_msg.new_subh()) { if (!pdu_msg.get()->set_c_rnti(pending_crnti_ce)) { - Warning("Pending C-RNTI CE could not be inserted in MAC PDU\n"); + Warning("Pending C-RNTI CE could not be inserted in MAC PDU"); } } } } else { if (pending_crnti_ce) { - Warning("Pending C-RNTI CE was not inserted because message was for CCCH\n"); + Warning("Pending C-RNTI CE was not inserted because message was for CCCH"); } } pending_crnti_ce = 0; @@ -297,9 +294,9 @@ uint8_t* mux::pdu_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) bsr_procedure->update_bsr_tti_end(&bsr); // Generate MAC PDU and save to buffer - uint8_t* ret = pdu_msg.write_packet(log_h); - Info("%s\n", pdu_msg.to_string().c_str()); - Debug("Assembled MAC PDU msg size %d/%d bytes\n", pdu_msg.get_pdu_len() - pdu_msg.rem_size(), pdu_sz); + uint8_t* ret = pdu_msg.write_packet(logger); + Info("%s", pdu_msg.to_string().c_str()); + Debug("Assembled MAC PDU msg size %d/%d bytes", pdu_msg.get_pdu_len() - pdu_msg.rem_size(), pdu_sz); return ret; } @@ -324,7 +321,7 @@ bool mux::sched_sdu(logical_channel_config_t* ch, int* sdu_space, int max_sdu_sz *sdu_space -= sched_len; // UL-SCH subheader size is accounted for in the calling function - Debug("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d\n", ch->lcid, ch->buffer_len, sched_len); + Debug("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d", ch->lcid, ch->buffer_len, sched_len); ch->buffer_len -= sched_len; ch->sched_len += sched_len; @@ -347,7 +344,7 @@ uint32_t mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_ int sdu_len = pdu_msg->get()->set_sdu(lcid, requested_sdu_len, rlc); if (sdu_len > 0) { // new SDU could be added Debug("SDU: allocated lcid=%d, buffer_state=%d, request_sdu_len=%d, allocated=%d/%d, max_sdu_sz=%d, " - "remaining=%d\n", + "remaining=%d", lcid, buffer_state, requested_sdu_len, @@ -361,7 +358,7 @@ uint32_t mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_ buffer_state = rlc->get_buffer_state(lcid); } else { Debug("Couldn't allocate new SDU (buffer_state=%d, requested_sdu_len=%d, sdu_len=%d, sdu_space=%d, " - "remaining=%d, get_sdu_space=%d)\n", + "remaining=%d, get_sdu_space=%d)", buffer_state, requested_sdu_len, sdu_len, @@ -373,7 +370,7 @@ uint32_t mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_ break; } } else { - Debug("Couldn't add new MAC subheader (buffer_state=%d, requested_sdu_len=%d, sdu_space=%d, remaining=%d)\n", + Debug("Couldn't add new MAC subheader (buffer_state=%d, requested_sdu_len=%d, sdu_space=%d, remaining=%d)", buffer_state, requested_sdu_len, sdu_space, @@ -387,9 +384,7 @@ uint32_t mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_ void mux::msg3_flush() { - if (log_h) { - Debug("Msg3 buffer flushed\n"); - } + Debug("Msg3 buffer flushed"); msg3_buff.clear(); msg3_has_been_transmitted = false; msg3_pending = false; @@ -422,7 +417,7 @@ uint8_t* mux::msg3_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) if (pdu_sz < msg3_buff.get_tailroom()) { if (msg3_is_empty()) { if (!pdu_get(&msg3_buff, pdu_sz)) { - Error("Moving PDU from Mux unit to Msg3 buffer\n"); + Error("Moving PDU from Mux unit to Msg3 buffer"); return NULL; } msg3_pending = false; @@ -431,7 +426,7 @@ uint8_t* mux::msg3_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) msg3_has_been_transmitted = true; return payload->msg; } else { - Error("Msg3 size exceeds buffer\n"); + Error("Msg3 size exceeds buffer"); return nullptr; } } diff --git a/srsue/src/stack/mac/proc_bsr.cc b/srsue/src/stack/mac/proc_bsr.cc index 004865dd3..757b39e59 100644 --- a/srsue/src/stack/mac/proc_bsr.cc +++ b/srsue/src/stack/mac/proc_bsr.cc @@ -20,19 +20,12 @@ */ #include "srsue/hdr/stack/mac/proc_bsr.h" -#include "srslte/common/log_helper.h" #include "srsue/hdr/stack/mac/mux.h" namespace srsue { -bsr_proc::bsr_proc() {} - -void bsr_proc::init(sr_proc* sr_, - rlc_interface_mac* rlc_, - srslte::log_ref log_h_, - srslte::ext_task_sched_handle* task_sched_) +void bsr_proc::init(sr_proc* sr_, rlc_interface_mac* rlc_, srslte::ext_task_sched_handle* task_sched_) { - log_h = log_h_; rlc = rlc_; sr = sr_; task_sched = task_sched_; @@ -64,7 +57,7 @@ void bsr_proc::print_state() n = srslte_print_check(str, 128, n, "%d: %d ", iter.first, iter.second.old_buffer); } } - Info("BSR: triggered_bsr_type=%s, LCID QUEUE status: %s\n", bsr_type_tostring(triggered_bsr_type), str); + logger.info("BSR: triggered_bsr_type=%s, LCID QUEUE status: %s", bsr_type_tostring(triggered_bsr_type), str); } void bsr_proc::set_trigger(srsue::bsr_proc::triggered_bsr_type_t new_trigger) @@ -73,7 +66,7 @@ void bsr_proc::set_trigger(srsue::bsr_proc::triggered_bsr_type_t new_trigger) // Trigger SR always when Regular BSR is triggered in the current TTI. Will be cancelled if a grant is received if (triggered_bsr_type == REGULAR) { - Debug("BSR: Triggering SR procedure\n"); + logger.debug("BSR: Triggering SR procedure"); sr->start(); } } @@ -94,11 +87,11 @@ void bsr_proc::set_config(srslte::bsr_cfg_t& bsr_cfg_) if (bsr_cfg_.periodic_timer > 0) { timer_periodic.set(bsr_cfg_.periodic_timer, [this](uint32_t tid) { timer_expired(tid); }); - Info("BSR: Configured timer periodic %d ms\n", bsr_cfg_.periodic_timer); + logger.info("BSR: Configured timer periodic %d ms", bsr_cfg_.periodic_timer); } if (bsr_cfg_.retx_timer > 0) { timer_retx.set(bsr_cfg_.retx_timer, [this](uint32_t tid) { timer_expired(tid); }); - Info("BSR: Configured timer reTX %d ms\n", bsr_cfg_.retx_timer); + logger.info("BSR: Configured timer reTX %d ms", bsr_cfg_.retx_timer); } } @@ -111,16 +104,16 @@ void bsr_proc::timer_expired(uint32_t timer_id) if (timer_id == timer_periodic.id()) { if (triggered_bsr_type == NONE) { set_trigger(PERIODIC); - Debug("BSR: Triggering Periodic BSR\n"); + logger.debug("BSR: Triggering Periodic BSR"); } // retxBSR-Timer } else if (timer_id == timer_retx.id()) { // Enable reTx of SR only if periodic timer is not infinity - Debug("BSR: Timer BSR reTX expired, periodic=%d, channel=%d\n", bsr_cfg.periodic_timer, check_any_channel()); + logger.debug("BSR: Timer BSR reTX expired, periodic=%d, channel=%d", bsr_cfg.periodic_timer, check_any_channel()); // Triger Regular BSR if UE has available data for transmission on any channel if (check_any_channel()) { set_trigger(REGULAR); - Debug("BSR: Triggering BSR reTX\n"); + logger.debug("BSR: Triggering BSR reTX"); } } } @@ -153,7 +146,7 @@ bool bsr_proc::check_highest_channel() } } if (is_max_priority) { - Debug("BSR: New data for lcid=%d with maximum priority in lcg=%d\n", iter->first, i); + logger.debug("BSR: New data for lcid=%d with maximum priority in lcg=%d", iter->first, i); return true; } } @@ -180,7 +173,7 @@ bool bsr_proc::check_new_data() if (get_buffer_state_lcg(i) == 0) { for (std::map::iterator iter = lcgs[i].begin(); iter != lcgs[i].end(); ++iter) { if (iter->second.new_buffer > 0) { - Debug("BSR: New data available for lcid=%d\n", iter->first); + logger.debug("BSR: New data available for lcid=%d", iter->first); return true; } } @@ -260,7 +253,7 @@ bool bsr_proc::generate_bsr(bsr_t* bsr, uint32_t pdu_space) // Restart or Start Periodic timer every time a BSR is generated and transmitted in an UL grant if (timer_periodic.duration() && bsr->format != TRUNC_BSR) { timer_periodic.run(); - Debug("BSR: Started periodicBSR-Timer\n"); + logger.debug("BSR: Started periodicBSR-Timer"); } // reset trigger to avoid another BSR in the next UL grant triggered_bsr_type = NONE; @@ -308,7 +301,7 @@ void bsr_proc::step(uint32_t tti) // Regular BSR triggered if new data arrives or channel with high priority has new data if (check_new_data() || check_highest_channel()) { - Debug("BSR: Triggering Regular BSR tti=%d\n", tti); + logger.debug("BSR: Triggering Regular BSR tti=%d", tti); set_trigger(REGULAR); } @@ -359,13 +352,13 @@ bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t grant_size, uint32_t total_ } // Cancel SR if an Uplink grant is received - Debug("BSR: Cancelling SR procedure due to uplink grant\n"); + logger.debug("BSR: Cancelling SR procedure due to uplink grant"); sr->reset(); // Restart or Start ReTX timer upon indication of a grant if (timer_retx.duration()) { timer_retx.run(); - Debug("BSR: Started retxBSR-Timer\n"); + logger.debug("BSR: Started retxBSR-Timer"); } return send_bsr; } @@ -401,7 +394,7 @@ void bsr_proc::setup_lcid(uint32_t lcid, uint32_t new_lcg, uint32_t priority) lcgs[new_lcg][lcid].priority = priority; lcgs[new_lcg][lcid].old_buffer = 0; } else { - Error("BSR: Invalid lcg=%d for lcid=%d\n", new_lcg, lcid); + logger.error("BSR: Invalid lcg=%d for lcid=%d", new_lcg, lcid); } } diff --git a/srsue/src/stack/mac/proc_phr.cc b/srsue/src/stack/mac/proc_phr.cc index d3f4743ab..0b76958c4 100644 --- a/srsue/src/stack/mac/proc_phr.cc +++ b/srsue/src/stack/mac/proc_phr.cc @@ -19,10 +19,10 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/proc_phr.h" #include "srslte/interfaces/ue_interfaces.h" @@ -31,17 +31,16 @@ namespace srsue { -phr_proc::phr_proc() +phr_proc::phr_proc(srslog::basic_logger& logger) : logger(logger) { initiated = false; last_pathloss_db = 0; phr_cfg = {}; } -void phr_proc::init(phy_interface_mac_lte* phy_h_, srslte::log_ref log_h_, srslte::ext_task_sched_handle* task_sched_) +void phr_proc::init(phy_interface_mac_lte* phy_h_, srslte::ext_task_sched_handle* task_sched_) { phy_h = phy_h_; - log_h = log_h_; task_sched = task_sched_; initiated = true; @@ -72,13 +71,13 @@ void phr_proc::set_config(srslte::phr_cfg_t& cfg) timer_periodic.set(phr_cfg.periodic_timer, [this](uint32_t tid) { timer_expired(tid); }); timer_periodic.run(); phr_is_triggered = true; - Info("PHR: Configured timer periodic %d ms\n", phr_cfg.periodic_timer); + Info("PHR: Configured timer periodic %d ms", phr_cfg.periodic_timer); } if (phr_cfg.prohibit_timer > 0) { timer_prohibit.set(phr_cfg.prohibit_timer, [this](uint32_t tid) { timer_expired(tid); }); timer_prohibit.run(); - Info("PHR: Configured timer prohibit %d ms\n", phr_cfg.prohibit_timer); + Info("PHR: Configured timer prohibit %d ms", phr_cfg.prohibit_timer); phr_is_triggered = true; } } @@ -111,21 +110,21 @@ void phr_proc::start_periodic_timer() void phr_proc::timer_expired(uint32_t timer_id) { if (!phr_cfg.enabled) { - Warning("PHR: %s timer triggered but PHR has been disabled\n", + Warning("PHR: %s timer triggered but PHR has been disabled", timer_id == timer_periodic.id() ? "Periodic" : "Prohibit"); return; } if (timer_id == timer_periodic.id()) { timer_periodic.run(); - Debug("PHR: Triggered by timer periodic (timer expired).\n"); + Debug("PHR: Triggered by timer periodic (timer expired)."); phr_is_triggered = true; } else if (timer_id == timer_prohibit.id()) { if (pathloss_changed()) { - Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d (timer expired)\n", last_pathloss_db); + Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d (timer expired)", last_pathloss_db); phr_is_triggered = true; } } else { - log_h->warning("Received timer callback from unknown timer_id=%d\n", timer_id); + logger.warning("Received timer callback from unknown timer_id=%d", timer_id); } } @@ -133,7 +132,7 @@ void phr_proc::step() { if (phr_cfg.enabled && initiated) { if (pathloss_changed() && timer_prohibit.is_expired()) { - Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d\n", last_pathloss_db); + Info("PHR: Triggered by pathloss difference. cur_pathloss_db=%d", last_pathloss_db); phr_is_triggered = true; } } @@ -147,7 +146,7 @@ bool phr_proc::generate_phr_on_ul_grant(float* phr) *phr = phy_h->get_phr(); } - Debug("PHR: Generating PHR=%f\n", phr ? *phr : 0.0); + Debug("PHR: Generating PHR=%f", phr ? *phr : 0.0); timer_periodic.run(); timer_prohibit.run(); diff --git a/srsue/src/stack/mac/proc_ra.cc b/srsue/src/stack/mac/proc_ra.cc index 7f4df7a68..10d16fe3f 100644 --- a/srsue/src/stack/mac/proc_ra.cc +++ b/srsue/src/stack/mac/proc_ra.cc @@ -38,9 +38,10 @@ const char* state_str[] = {"RA: INIT: ", "RA: WaitComplt: ", "RA: Complt: "}; -#define rError(fmt, ...) Error("%s" fmt, state_str[state], ##__VA_ARGS__) -#define rInfo(fmt, ...) Info("%s" fmt, state_str[state], ##__VA_ARGS__) -#define rDebug(fmt, ...) Debug("%s" fmt, state_str[state], ##__VA_ARGS__) +#define rError(fmt, ...) logger.error("%s" fmt, state_str[state], ##__VA_ARGS__) +#define rInfo(fmt, ...) logger.info("%s" fmt, state_str[state], ##__VA_ARGS__) +#define rDebug(fmt, ...) logger.debug("%s" fmt, state_str[state], ##__VA_ARGS__) +#define rWarning(fmt, ...) logger.warning("%s" fmt, state_str[state], ##__VA_ARGS__) // Table 7.2-1. Backoff Parameter values uint32_t backoff_table[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480, 960, 960, 960, 960}; @@ -51,14 +52,12 @@ int delta_preamble_db_table[5] = {0, 0, -3, -3, 8}; // Initializes memory and pointers to other objects void ra_proc::init(phy_interface_mac_lte* phy_h_, rrc_interface_mac* rrc_, - srslte::log_ref log_h_, mac_interface_rrc::ue_rnti_t* rntis_, srslte::timer_handler::unique_timer* time_alignment_timer_, mux* mux_unit_, srslte::ext_task_sched_handle* task_sched_) { phy_h = phy_h_; - log_h = log_h_; rntis = rntis_; mux_unit = mux_unit_; rrc = rrc_; @@ -167,14 +166,14 @@ void ra_proc::state_pdcch_setup() if (info.is_transmitted) { ra_tti = info.tti_ra; ra_rnti = 1 + (ra_tti % 10) + (10 * info.f_id); - rInfo("seq=%d, ra-rnti=0x%x, ra-tti=%d, f_id=%d\n", sel_preamble.load(), ra_rnti, info.tti_ra, info.f_id); + rInfo("seq=%d, ra-rnti=0x%x, ra-tti=%d, f_id=%d", sel_preamble.load(), ra_rnti, info.tti_ra, info.f_id); srslte::console( "Random Access Transmission: seq=%d, tti=%d, ra-rnti=0x%x\n", sel_preamble.load(), info.tti_ra, ra_rnti); rar_window_st = ra_tti + 3; rntis->rar_rnti = ra_rnti; state = RESPONSE_RECEPTION; } else { - rDebug("preamble not yet transmitted\n"); + rDebug("preamble not yet transmitted"); } } @@ -187,7 +186,7 @@ void ra_proc::state_response_reception(uint32_t tti) if (!rar_received) { uint32_t interval = srslte_tti_interval(tti, ra_tti + 3 + rach_cfg.responseWindowSize - 1); if (interval > 0 && interval < 100) { - Error("RA response not received within the response window\n"); + logger.error("RA response not received within the response window"); response_error(); } } @@ -224,7 +223,7 @@ void ra_proc::state_contention_resolution() // Once Msg3 is transmitted, start contention resolution timer if (mux_unit->msg3_is_transmitted() && !contention_resolution_timer.is_running()) { // Start contention resolution timer - rInfo("Starting ContentionResolutionTimer=%d ms\n", contention_resolution_timer.duration()); + rInfo("Starting ContentionResolutionTimer=%d ms", contention_resolution_timer.duration()); contention_resolution_timer.run(); } } @@ -248,15 +247,14 @@ void ra_proc::notify_ra_completed(uint32_t task_id) { if (current_task_id == task_id) { if (state != WAITING_COMPLETION) { - rError("Received unexpected notification of RA completion\n"); + rError("Received unexpected notification of RA completion"); } else { - rInfo("RA waiting procedure completed\n"); + rInfo("RA waiting procedure completed"); } state = IDLE; } else { - rError("Received old notification of RA completition (old task_id=%d, current_task_id=%d)\n", - task_id, - current_task_id); + rError( + "Received old notification of RA completition (old task_id=%d, current_task_id=%d)", task_id, current_task_id); } } @@ -304,7 +302,7 @@ void ra_proc::resource_selection() // randomly choose preamble from [0 nof_groupA_preambles) sel_preamble = rand() % rach_cfg.nof_groupA_preambles; } else { - rError("Selected group preamble A but nof_groupA_preambles=0\n"); + rError("Selected group preamble A but nof_groupA_preambles=0"); state = IDLE; return; } @@ -313,7 +311,7 @@ void ra_proc::resource_selection() // randomly choose preamble from [nof_groupA_preambles nof_groupB_preambles) sel_preamble = rach_cfg.nof_groupA_preambles + rand() % nof_groupB_preambles; } else { - rError("Selected group preamble B but nof_groupA_preambles=0\n"); + rError("Selected group preamble B but nof_groupA_preambles=0"); state = IDLE; return; } @@ -321,7 +319,7 @@ void ra_proc::resource_selection() sel_maskIndex = 0; } - rDebug("Selected preambleIndex=%d maskIndex=%d GroupA=%d, GroupB=%d\n", + rDebug("Selected preambleIndex=%d maskIndex=%d GroupA=%d, GroupB=%d", sel_preamble.load(), sel_maskIndex, rach_cfg.nof_groupA_preambles, @@ -356,16 +354,16 @@ void ra_proc::process_timeadv_cmd(uint32_t ta) if (time_alignment_timer->is_running()) { time_alignment_timer->run(); } - Debug("Applying RAR TA CMD %d\n", ta); + logger.debug("Applying RAR TA CMD %d", ta); } else { // Preamble selected by UE MAC if (!time_alignment_timer->is_running()) { phy_h->set_timeadv_rar(ta); time_alignment_timer->run(); - Debug("Applying RAR TA CMD %d\n", ta); + logger.debug("Applying RAR TA CMD %d", ta); } else { // Ignore TA CMD - Warning("Ignoring RAR TA CMD because timeAlignmentTimer still running\n"); + logger.warning("Ignoring RAR TA CMD because timeAlignmentTimer still running"); } } } @@ -378,7 +376,7 @@ void ra_proc::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_inte bzero(action, sizeof(mac_interface_phy_lte::tb_action_dl_t)); if (grant.tb[0].tbs < MAX_RAR_PDU_LEN) { - rDebug("DL dci found RA-RNTI=%d\n", ra_rnti); + rDebug("DL dci found RA-RNTI=%d", ra_rnti); action->tb[0].enabled = true; action->tb[0].payload = rar_pdu_buffer; action->tb[0].rv = grant.tb[0].rv; @@ -388,7 +386,7 @@ void ra_proc::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_inte srslte_softbuffer_rx_reset(&softbuffer_rar); } } else { - rError("Received RAR dci exceeds buffer length (%d>%d)\n", grant.tb[0].tbs, MAX_RAR_PDU_LEN); + rError("Received RAR dci exceeds buffer length (%d>%d)", grant.tb[0].tbs, int(MAX_RAR_PDU_LEN)); } } @@ -405,10 +403,10 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) rar_pdu_msg.init_rx(rar_grant_nbytes); if (rar_pdu_msg.parse_packet(rar_pdu_buffer) != SRSLTE_SUCCESS) { - rError("Error decoding RAR PDU\n"); + rError("Error decoding RAR PDU"); } - rDebug("RAR decoded successfully TBS=%d\n", rar_grant_nbytes); + rDebug("RAR decoded successfully TBS=%d", rar_grant_nbytes); // Set Backoff parameter if (rar_pdu_msg.has_backoff()) { @@ -436,7 +434,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) current_ta = rar_pdu_msg.get()->get_ta_cmd(); - rInfo("RAPID=%d, TA=%d, T-CRNTI=0x%x\n", + rInfo("RAPID=%d, TA=%d, T-CRNTI=0x%x", sel_preamble.load(), rar_pdu_msg.get()->get_ta_cmd(), rar_pdu_msg.get()->get_temp_crnti()); @@ -454,7 +452,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) // If we have a C-RNTI, tell Mux unit to append C-RNTI CE if no CCCH SDU transmission if (transmitted_crnti) { - rInfo("Appending C-RNTI MAC CE 0x%x in next transmission\n", transmitted_crnti.load()); + rInfo("Appending C-RNTI MAC CE 0x%x in next transmission", transmitted_crnti.load()); mux_unit->append_crnti_ce_next_tx(transmitted_crnti); } } @@ -463,7 +461,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) transmitted_contention_id = rntis->contention_id; task_queue.push([this]() { - rDebug("Waiting for Contention Resolution\n"); + rDebug("Waiting for Contention Resolution"); state = CONTENTION_RESOLUTION; }); } else { @@ -472,7 +470,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) } } else { if (rar_pdu_msg.get()->has_rapid()) { - rInfo("Found RAR for preamble %d\n", rar_pdu_msg.get()->get_rapid()); + rInfo("Found RAR for preamble %d", rar_pdu_msg.get()->get_rapid()); } } } @@ -487,7 +485,7 @@ void ra_proc::response_error() preambleTransmissionCounter++; contention_resolution_timer.stop(); if (preambleTransmissionCounter >= rach_cfg.preambleTransMax + 1) { - rError("Maximum number of transmissions reached (%d)\n", rach_cfg.preambleTransMax); + rError("Maximum number of transmissions reached (%d)", rach_cfg.preambleTransMax); rrc->ra_problem(); state = IDLE; } else { @@ -498,10 +496,10 @@ void ra_proc::response_error() backoff_interval = 0; } if (backoff_interval) { - rDebug("Backoff wait interval %d\n", backoff_interval); + rDebug("Backoff wait interval %d", backoff_interval); state = BACKOFF_WAIT; } else { - rInfo("Transmitting new preamble immediately (%d/%d)\n", preambleTransmissionCounter, rach_cfg.preambleTransMax); + rInfo("Transmitting new preamble immediately (%d/%d)", preambleTransmissionCounter, rach_cfg.preambleTransMax); resource_selection(); } } @@ -526,7 +524,7 @@ void ra_proc::complete() rrc->ra_completed(); srslte::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta); - rInfo("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta); + rInfo("Random Access Complete. c-rnti=0x%x, ta=%d", rntis->crnti, current_ta); state = START_WAIT_COMPLETION; } @@ -536,10 +534,10 @@ void ra_proc::start_mac_order(uint32_t msg_len_bits) if (state == IDLE) { started_by_pdcch = false; new_ra_msg_len = msg_len_bits; - rInfo("Starting PRACH by MAC order\n"); + rInfo("Starting PRACH by MAC order"); initialization(); } else { - Warning("Trying to start PRACH by MAC order in invalid state (%s)\n", state_str[state]); + logger.warning("Trying to start PRACH by MAC order in invalid state (%s)", state_str[state]); } } @@ -547,17 +545,17 @@ void ra_proc::start_pdcch_order() { if (state == IDLE) { started_by_pdcch = true; - rInfo("Starting PRACH by PDCCH order\n"); + rInfo("Starting PRACH by PDCCH order"); initialization(); } else { - Warning("Trying to start PRACH by MAC order in invalid state (%s)\n", state_str[state]); + logger.warning("Trying to start PRACH by MAC order in invalid state (%s)", state_str[state]); } } // Contention Resolution Timer is expired (Section 5.1.5) void ra_proc::timer_expired(uint32_t timer_id) { - rInfo("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error\n"); + rInfo("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error"); response_error(); } @@ -581,10 +579,10 @@ bool ra_proc::contention_resolution_id_received_unsafe(uint64_t rx_contention_id { bool uecri_successful = false; - rDebug("MAC PDU Contains Contention Resolution ID CE\n"); + rDebug("MAC PDU Contains Contention Resolution ID CE"); if (state != CONTENTION_RESOLUTION) { - rError("Received contention resolution in wrong state. Aborting.\n"); + rError("Received contention resolution in wrong state. Aborting."); response_error(); } @@ -596,7 +594,7 @@ bool ra_proc::contention_resolution_id_received_unsafe(uint64_t rx_contention_id uecri_successful = true; complete(); } else { - rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%" PRIx64 " != 0x%" PRIx64 ")\n", + rInfo("Transmitted UE Contention Id differs from received Contention ID (0x%" PRIx64 " != 0x%" PRIx64 ")", transmitted_contention_id.load(), rx_contention_id); @@ -615,9 +613,9 @@ void ra_proc::pdcch_to_crnti(bool is_new_uplink_transmission) { task_queue.push([this, is_new_uplink_transmission]() { // TS 36.321 Section 5.1.5 - rDebug("PDCCH to C-RNTI received %s new UL transmission\n", is_new_uplink_transmission ? "with" : "without"); + rDebug("PDCCH to C-RNTI received %s new UL transmission", is_new_uplink_transmission ? "with" : "without"); if ((!started_by_pdcch && is_new_uplink_transmission) || started_by_pdcch) { - rDebug("PDCCH for C-RNTI received\n"); + rDebug("PDCCH for C-RNTI received"); contention_resolution_timer.stop(); complete(); } @@ -635,14 +633,14 @@ void ra_proc::update_rar_window(int& rar_window_start, int& rar_window_length) rar_window_length = rach_cfg.responseWindowSize; rar_window_start = rar_window_st; } - rDebug("rar_window_start=%d, rar_window_length=%d\n", rar_window_start, rar_window_length); + rDebug("rar_window_start=%d, rar_window_length=%d", rar_window_start, rar_window_length); } // Restart timer at each Msg3 HARQ retransmission (5.1.5) void ra_proc::harq_retx() { task_queue.push([this]() { - rInfo("Restarting ContentionResolutionTimer=%d ms\n", contention_resolution_timer.duration()); + rInfo("Restarting ContentionResolutionTimer=%d ms", contention_resolution_timer.duration()); contention_resolution_timer.run(); }); } @@ -651,7 +649,7 @@ void ra_proc::harq_retx() void ra_proc::harq_max_retx() { task_queue.push([this]() { - Warning("Contention Resolution is considered not successful. Stopping PDCCH Search and going to Response Error\n"); + rWarning("Contention Resolution is considered not successful. Stopping PDCCH Search and going to Response Error"); response_error(); }); } diff --git a/srsue/src/stack/mac/proc_sr.cc b/srsue/src/stack/mac/proc_sr.cc index 72aaf6686..4c8c36006 100644 --- a/srsue/src/stack/mac/proc_sr.cc +++ b/srsue/src/stack/mac/proc_sr.cc @@ -19,24 +19,23 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/proc_sr.h" #include "srsue/hdr/stack/mac/proc_ra.h" namespace srsue { -sr_proc::sr_proc() +sr_proc::sr_proc(srslog::basic_logger& logger) : logger(logger) { initiated = false; } -void sr_proc::init(ra_proc* ra_, phy_interface_mac_lte* phy_h_, rrc_interface_mac* rrc_, srslte::log_ref log_h_) +void sr_proc::init(ra_proc* ra_, phy_interface_mac_lte* phy_h_, rrc_interface_mac* rrc_) { - log_h = log_h_; rrc = rrc_; ra = ra_; phy_h = phy_h_; @@ -52,7 +51,7 @@ void sr_proc::reset() bool sr_proc::need_tx(uint32_t tti) { int last_tx_tti = phy_h->sr_last_tx_tti(); - Debug("SR: need_tx(): last_tx_tti=%d, tti=%d\n", last_tx_tti, tti); + Debug("SR: need_tx(): last_tx_tti=%d, tti=%d", last_tx_tti, tti); if (last_tx_tti >= 0) { if (tti > (uint32_t)last_tx_tti) { if (tti - last_tx_tti > 8) { @@ -71,11 +70,11 @@ bool sr_proc::need_tx(uint32_t tti) void sr_proc::set_config(srslte::sr_cfg_t& cfg) { if (cfg.enabled && cfg.dsr_transmax == 0) { - Error("Zero is an invalid value for dsr-TransMax (n4, n8, n16, n32, n64 are supported). Disabling SR.\n"); + Error("Zero is an invalid value for dsr-TransMax (n4, n8, n16, n32, n64 are supported). Disabling SR."); return; } if (cfg.enabled) { - Info("SR: Set dsr_transmax=%d\n", sr_cfg.dsr_transmax); + Info("SR: Set dsr_transmax=%d", sr_cfg.dsr_transmax); } sr_cfg = cfg; } @@ -88,12 +87,12 @@ void sr_proc::step(uint32_t tti) if (sr_counter < sr_cfg.dsr_transmax) { if (sr_counter == 0 || need_tx(tti)) { sr_counter++; - Info("SR: Signalling PHY sr_counter=%d\n", sr_counter); + Info("SR: Signalling PHY sr_counter=%d", sr_counter); phy_h->sr_send(); } } else { if (need_tx(tti)) { - Info("SR: Releasing PUCCH/SRS resources, sr_counter=%d, dsr_transmax=%d\n", + Info("SR: Releasing PUCCH/SRS resources, sr_counter=%d, dsr_transmax=%d", sr_counter, sr_cfg.dsr_transmax); srslte::console("Scheduling request failed: releasing RRC connection...\n"); @@ -103,7 +102,7 @@ void sr_proc::step(uint32_t tti) } } } else if (ra->is_idle()) { - Info("SR: PUCCH not configured. Starting RA procedure\n"); + Info("SR: PUCCH not configured. Starting RA procedure"); ra->start_mac_order(); reset(); } diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index a6201fb32..fefd5c8d9 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -19,10 +19,10 @@ * */ -#define Error(fmt, ...) log_h->error(fmt, ##__VA_ARGS__) -#define Warning(fmt, ...) log_h->warning(fmt, ##__VA_ARGS__) -#define Info(fmt, ...) log_h->info(fmt, ##__VA_ARGS__) -#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) +#define Error(fmt, ...) logger.error(fmt, ##__VA_ARGS__) +#define Warning(fmt, ...) logger.warning(fmt, ##__VA_ARGS__) +#define Info(fmt, ...) logger.info(fmt, ##__VA_ARGS__) +#define Debug(fmt, ...) logger.debug(fmt, ##__VA_ARGS__) #include "srsue/hdr/stack/mac/ul_harq.h" #include "srslte/common/interfaces_common.h" @@ -33,14 +33,12 @@ namespace srsue { -ul_harq_entity::ul_harq_entity(const uint8_t cc_idx_) : proc(SRSLTE_MAX_HARQ_PROC), cc_idx(cc_idx_) {} +ul_harq_entity::ul_harq_entity(const uint8_t cc_idx_) : + proc(SRSLTE_MAX_HARQ_PROC), logger(srslog::fetch_basic_logger("MAC")), cc_idx(cc_idx_) +{} -bool ul_harq_entity::init(srslte::log_ref log_h_, - mac_interface_rrc_common::ue_rnti_t* rntis_, - ra_proc* ra_procedure_, - mux* mux_unit_) +bool ul_harq_entity::init(mac_interface_rrc_common::ue_rnti_t* rntis_, ra_proc* ra_procedure_, mux* mux_unit_) { - log_h = log_h_; mux_unit = mux_unit_; ra_procedure = ra_procedure_; rntis = rntis_; @@ -85,7 +83,7 @@ void ul_harq_entity::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t grant, bzero(action, sizeof(mac_interface_phy_lte::tb_action_ul_t)); if (grant.pid >= SRSLTE_MAX_HARQ_PROC) { - Error("Invalid PID: %d\n", grant.pid); + Error("Invalid PID: %d", grant.pid); return; } if (grant.rnti == rntis->crnti || grant.rnti == rntis->temp_rnti || SRSLTE_RNTI_ISRAR(grant.rnti)) { @@ -98,17 +96,17 @@ void ul_harq_entity::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t grant, grant.tb.ndi = proc[grant.pid].get_ndi(); proc[grant.pid].new_grant_ul(grant, action); } else { - Info("Not implemented\n"); + Info("Not implemented"); } } else { - Info("Received grant for unknown rnti=0x%x\n", grant.rnti); + Info("Received grant for unknown rnti=0x%x", grant.rnti); } } int ul_harq_entity::get_current_tbs(uint32_t pid) { if (pid >= SRSLTE_MAX_HARQ_PROC) { - Error("Invalid PID: %d\n", pid); + Error("Invalid PID: %d", pid); return 0; } return proc[pid].get_current_tbs(); @@ -119,7 +117,7 @@ float ul_harq_entity::get_average_retx() return average_retx; } -ul_harq_entity::ul_harq_process::ul_harq_process() +ul_harq_entity::ul_harq_process::ul_harq_process() : logger(srslog::fetch_basic_logger("MAC")) { pdu_ptr = NULL; payload_buffer = NULL; @@ -145,18 +143,17 @@ ul_harq_entity::ul_harq_process::~ul_harq_process() bool ul_harq_entity::ul_harq_process::init(uint32_t pid_, ul_harq_entity* parent) { if (srslte_softbuffer_tx_init(&softbuffer, 110)) { - ERROR("Error initiating soft buffer\n"); + ERROR("Error initiating soft buffer"); return false; } harq_entity = parent; - log_h = harq_entity->log_h; is_initiated = true; pid = pid_; payload_buffer = std::unique_ptr(new byte_buffer_t); if (!payload_buffer) { - Error("Allocating memory\n"); + Error("Allocating memory"); return false; } pdu_ptr = payload_buffer->msg; @@ -196,7 +193,7 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Check maximum retransmissions, do not consider last retx ACK if (current_tx_nb >= max_retx && !grant.hi_value) { - Info("UL %d: Maximum number of ReTX reached (%d). Discarding TB.\n", pid, max_retx); + Info("UL %d: Maximum number of ReTX reached (%d). Discarding TB.", pid, max_retx); if (grant.rnti == harq_entity->rntis->temp_rnti) { harq_entity->ra_procedure->harq_max_retx(); } @@ -209,8 +206,7 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Reset HARQ process if TB has changed if (harq_feedback && has_grant() && grant.tb.ndi_present) { if (grant.tb.tbs != cur_grant.tb.tbs && cur_grant.tb.tbs > 0 && grant.tb.tbs > 0) { - Debug( - "UL %d: Reset due to change of dci size last_grant=%d, new_grant=%d\n", pid, cur_grant.tb.tbs, grant.tb.tbs); + Debug("UL %d: Reset due to change of dci size last_grant=%d, new_grant=%d", pid, cur_grant.tb.tbs, grant.tb.tbs); reset(); } } @@ -232,22 +228,22 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Check buffer size if (grant.tb.tbs > payload_buffer_len) { - Error("Grant size exceeds payload buffer size (%d > %d)\n", grant.tb.tbs, payload_buffer_len); + Error("Grant size exceeds payload buffer size (%d > %d)", grant.tb.tbs, int(payload_buffer_len)); return; } // Uplink dci in a RAR and there is a PDU in the Msg3 buffer if (grant.is_rar) { if (harq_entity->mux_unit->msg3_is_pending()) { - Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant.tb.tbs); + Debug("Getting Msg3 buffer payload, grant size=%d bytes", grant.tb.tbs); pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer.get(), grant.tb.tbs); if (pdu_ptr) { generate_new_tx(grant, action); } else { - Warning("UL RAR dci available but no Msg3 on buffer\n"); + Warning("UL RAR dci available but no Msg3 on buffer"); } } else { - Warning("UL RAR available but no Msg3 pending on buffer\n"); + Warning("UL RAR available but no Msg3 pending on buffer"); } // Normal UL dci } else { @@ -256,7 +252,7 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr if (pdu_ptr) { generate_new_tx(grant, action); } else { - Warning("Uplink dci but no MAC PDU in Multiplex Unit buffer\n"); + Warning("Uplink dci but no MAC PDU in Multiplex Unit buffer"); } } @@ -267,7 +263,7 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Adaptive Re-TX generate_retx(grant, action); } else { - Warning("UL %d: Received retransmission but no previous dci available for this PID.\n", pid); + Warning("UL %d: Received retransmission but no previous dci available for this PID.", pid); } if (harq_entity->pcap) { uint16_t rnti; @@ -327,7 +323,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g current_irv = irv_of_rv[grant.tb.rv % 4]; } - Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d, HI=%s, ndi=%d, prev_ndi=%d\n", + Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d, HI=%s, ndi=%d, prev_ndi=%d", pid, current_tx_nb, get_rv(), @@ -347,7 +343,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g // HARQ entity requests a non-adaptive transmission } else if (!harq_feedback) { // Non-adaptive retx are only sent if HI=NACK. If HI=ACK but no dci was received do not reset PID - Info("UL %d: Non-Adaptive retx=%d, RV=%d, TBS=%d, HI=%s\n", + Info("UL %d: Non-Adaptive retx=%d, RV=%d, TBS=%d, HI=%s", pid, current_tx_nb, get_rv(), @@ -372,7 +368,7 @@ void ul_harq_entity::ul_harq_process::generate_new_tx(mac_interface_phy_lte::mac action->is_rar = grant.is_rar || (grant.rnti == harq_entity->rntis->temp_rnti); - Info("UL %d: New TX%s, RV=%d, TBS=%d\n", + Info("UL %d: New TX%s, RV=%d, TBS=%d", pid, grant.rnti == harq_entity->rntis->temp_rnti ? " for Msg3" : "", get_rv(), diff --git a/srsue/src/stack/mac_nr/CMakeLists.txt b/srsue/src/stack/mac_nr/CMakeLists.txt new file mode 100644 index 000000000..2003bb81b --- /dev/null +++ b/srsue/src/stack/mac_nr/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright 2013-2020 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 mac_nr.cc proc_ra_nr.cc mux_nr.cc) +add_library(srsue_mac_nr STATIC ${SOURCES}) +target_link_libraries(srsue_mac_nr srslte_mac) \ No newline at end of file diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc new file mode 100644 index 000000000..eea143fe6 --- /dev/null +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -0,0 +1,406 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srsue/hdr/stack/mac_nr/mac_nr.h" +#include "srslte/mac/mac_rar_pdu_nr.h" +#include "srsue/hdr/stack/mac_nr/proc_ra_nr.h" + +namespace srsue { + +mac_nr::mac_nr(srslte::ext_task_sched_handle task_sched_) : + task_sched(task_sched_), logger(srslog::fetch_basic_logger("MAC")), proc_ra(logger), mux(logger) +{ + tx_buffer = srslte::make_byte_buffer(); + rlc_buffer = srslte::make_byte_buffer(); +} + +mac_nr::~mac_nr() +{ + stop(); +} + +int mac_nr::init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy_, rlc_interface_mac* rlc_) +{ + args = args_; + phy = phy_; + rlc = rlc_; + + // Create Stack task dispatch queue + stack_task_dispatch_queue = task_sched.make_task_queue(); + + // Set up pcap + if (args.pcap.enable) { + pcap.reset(new srslte::mac_pcap(srslte::srslte_rat_t::nr)); + pcap->open(args.pcap.filename.c_str()); + } + + proc_ra.init(phy, this, &task_sched); + + mux.init(); + + started = true; + + return SRSLTE_SUCCESS; +} + +void mac_nr::stop() +{ + if (started) { + if (pcap != nullptr) { + pcap->close(); + } + + started = false; + } +} + +// Implement Section 5.9 +void mac_nr::reset() +{ + logger.info("Resetting MAC-NR"); +} + +void mac_nr::run_tti(const uint32_t tti) +{ + // Step all procedures + logger.debug("Running MAC tti=%d", tti); +} + +mac_interface_phy_nr::sched_rnti_t mac_nr::get_ul_sched_rnti_nr(const uint32_t tti) +{ + return {c_rnti, srslte_rnti_type_c}; +} + +bool mac_nr::is_si_opportunity() +{ + // TODO: ask RRC if we need SI + return false; +} + +bool mac_nr::is_paging_opportunity() +{ + return false; +} + +mac_interface_phy_nr::sched_rnti_t mac_nr::get_dl_sched_rnti_nr(const uint32_t tti) +{ + // Priority: SI-RNTI, P-RNTI, RA-RNTI, Temp-RNTI, CRNTI + if (is_si_opportunity()) { + return {SRSLTE_SIRNTI, srslte_rnti_type_si}; + } + + if (is_paging_opportunity()) { + return {SRSLTE_PRNTI, srslte_rnti_type_si}; + } + + if (proc_ra.is_rar_opportunity(tti)) { + return {proc_ra.get_rar_rnti(), srslte_rnti_type_ra}; + } + + if (proc_ra.has_temp_rnti() && has_crnti() == false) { + logger.debug("SCHED: Searching temp C-RNTI=0x%x (proc_ra)", proc_ra.get_temp_rnti()); + return {proc_ra.get_temp_rnti(), srslte_rnti_type_c}; + } + + if (has_crnti()) { + logger.debug("SCHED: Searching C-RNTI=0x%x", get_crnti()); + return {get_crnti(), srslte_rnti_type_c}; + } + + // turn off DCI search for this TTI + return {SRSLTE_INVALID_RNTI, srslte_rnti_type_c}; +} + +bool mac_nr::has_crnti() +{ + return c_rnti != SRSLTE_INVALID_RNTI; +} + +uint16_t mac_nr::get_crnti() +{ + return c_rnti; +} + +void mac_nr::bch_decoded_ok(uint32_t tti, srslte::unique_byte_buffer_t payload) +{ + // Send MIB to RLC + rlc->write_pdu_bcch_bch(std::move(payload)); + + if (pcap) { + // pcap->write_dl_bch(payload, len, true, tti); + } +} + +int mac_nr::sf_indication(const uint32_t tti) +{ + run_tti(tti); + return SRSLTE_SUCCESS; +} + +void mac_nr::prach_sent(const uint32_t tti, + const uint32_t s_id, + const uint32_t t_id, + const uint32_t f_id, + const uint32_t ul_carrier_id) +{ + proc_ra.prach_sent(tti, s_id, t_id, f_id, ul_carrier_id); +} + +// This function handles all PCAP writing for a decoded DL TB +void mac_nr::write_pcap(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) +{ + if (pcap) { + for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; ++i) { + if (grant.tb[i] != nullptr) { + if (proc_ra.has_rar_rnti() && grant.rnti == proc_ra.get_rar_rnti()) { + pcap->write_dl_ra_rnti_nr(grant.tb[i]->msg, grant.tb[i]->N_bytes, grant.rnti, true, grant.tti); + } else if (grant.rnti == SRSLTE_PRNTI) { + pcap->write_dl_pch_nr(grant.tb[i]->msg, grant.tb[i]->N_bytes, grant.rnti, true, grant.tti); + } else { + pcap->write_dl_crnti_nr(grant.tb[i]->msg, grant.tb[i]->N_bytes, grant.rnti, true, grant.tti); + } + } + } + } +} + +/** + * \brief Called from PHY after decoding a TB + * + * The TB can directly be used + * + * @param cc_idx + * @param grant structure + */ +void mac_nr::tb_decoded(const uint32_t cc_idx, mac_nr_grant_dl_t& grant) +{ + write_pcap(cc_idx, grant); + // handle PDU + if (proc_ra.has_rar_rnti() && grant.rnti == proc_ra.get_rar_rnti()) { + proc_ra.handle_rar_pdu(grant); + } else { + // Push DL PDUs to queue for back-ground processing + for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; ++i) { + if (grant.tb[i] != nullptr) { + pdu_queue.push(std::move(grant.tb[i])); + } + } + } + + metrics[cc_idx].rx_pkts++; + stack_task_dispatch_queue.push([this]() { process_pdus(); }); +} + +void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* phy_tx_pdu) +{ + // if proc ra is in contention resolution and c_rnti == grant.c_rnti resolve contention resolution + if (proc_ra.is_contention_resolution() && grant.rnti == c_rnti) { + proc_ra.pdcch_to_crnti(); + } + get_ul_data(grant, phy_tx_pdu); + + metrics[cc_idx].tx_pkts++; +} + +void mac_nr::get_ul_data(const mac_nr_grant_ul_t& grant, srslte::byte_buffer_t* phy_tx_pdu) +{ + // initialize MAC PDU + tx_buffer->clear(); + tx_pdu.init_tx(tx_buffer.get(), grant.tbs / 8U, true); + + if (mux.msg3_is_pending()) { + // If message 3 is pending pack message 3 for uplink transmission + // Use the CRNTI which is provided in the RRC reconfiguration (only for DC mode maybe other) + tx_pdu.add_crnti_ce(c_rnti); + srslte::mac_sch_subpdu_nr::lcg_bsr_t sbsr = {}; + sbsr.lcg_id = 0; + sbsr.buffer_size = 1; + tx_pdu.add_sbsr_ce(sbsr); + logger.info("Generated msg3 with RNTI 0x%x", c_rnti); + mux.msg3_transmitted(); + } else { + // Pack normal UL data PDU + while (tx_pdu.get_remaing_len() >= MIN_RLC_PDU_LEN) { + // read RLC PDU + rlc_buffer->clear(); + uint8_t* rd = rlc_buffer->msg; + int pdu_len = 0; + // pdu_len = rlc->read_pdu(args.drb_lcid, rd, tx_pdu.get_remaing_len() - 2); + + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + // rlc_buffer->N_bytes = pdu_len; + // logger.info(rlc_buffer->msg, rlc_buffer->N_bytes, "Read %d B from RLC", rlc_buffer->N_bytes); + + // // add to MAC PDU and pack + // if (tx_pdu.add_sdu(args.drb_lcid, rlc_buffer->msg, rlc_buffer->N_bytes) != SRSLTE_SUCCESS) { + // logger.error("Error packing MAC PDU"); + // } + } else { + break; + } + } + } + + // Pack PDU + tx_pdu.pack(); + + logger.info(tx_buffer->msg, tx_buffer->N_bytes, "Generated MAC PDU (%d B)", tx_buffer->N_bytes); + + memcpy(phy_tx_pdu->msg, tx_buffer->msg, tx_buffer->N_bytes); + phy_tx_pdu->N_bytes = tx_buffer->N_bytes; + + if (pcap) { + pcap->write_ul_crnti_nr(tx_buffer->msg, tx_buffer->N_bytes, grant.rnti, grant.pid, grant.tti); + } +} + +void mac_nr::timer_expired(uint32_t timer_id) +{ + // not implemented +} + +void mac_nr::setup_lcid(const srslte::logical_channel_config_t& config) +{ + logger.info("Logical Channel Setup: LCID=%d, LCG=%d, priority=%d, PBR=%d, BSD=%dms, bucket_size=%d", + config.lcid, + config.lcg, + config.priority, + config.PBR, + config.BSD, + config.bucket_size); + // mux_unit.setup_lcid(config); + // bsr_procedure.setup_lcid(config.lcid, config.lcg, config.priority); +} + +void mac_nr::set_config(const srslte::bsr_cfg_t& bsr_cfg) +{ + logger.info("BSR config periodic timer %d retx timer %d", bsr_cfg.periodic_timer, bsr_cfg.retx_timer); + logger.warning("Not handling BSR config yet"); +} + +void mac_nr::set_config(const srslte::sr_cfg_t& sr_cfg) +{ + logger.info("Scheduling Request Config DSR tansmax %d", sr_cfg.dsr_transmax); + logger.warning("Not Scheduling Request Config yet"); +} + +void mac_nr::set_config(const srslte::rach_nr_cfg_t& rach_cfg){ + proc_ra.set_config(rach_cfg); +} + +void mac_nr::set_contention_id(uint64_t ue_identity) +{ + contention_id = ue_identity; +} + +bool mac_nr::set_crnti(const uint16_t c_rnti_) +{ + if (is_valid_crnti(c_rnti_)) { + logger.info("Setting C-RNTI to 0x%X", c_rnti_); + c_rnti = c_rnti_; + return true; + } else { + logger.warning("Failed to set C-RNTI, 0x%X is not valid.", c_rnti_); + return false; + } +} + +void mac_nr::start_ra_procedure() +{ + proc_ra.start_by_rrc(); +} + +bool mac_nr::is_valid_crnti(const uint16_t crnti) +{ + // TS 38.321 15.3.0 Table 7.1-1 + return (crnti >= 0x0001 && crnti <= 0xFFEF); +} + +void mac_nr::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]) {} + +/** + * Called from the main stack thread to process received PDUs + */ +void mac_nr::process_pdus() +{ + while (started and not pdu_queue.empty()) { + srslte::unique_byte_buffer_t pdu = pdu_queue.wait_pop(); + // TODO: delegate to demux class + handle_pdu(std::move(pdu)); + } +} + +void mac_nr::handle_pdu(srslte::unique_byte_buffer_t pdu) +{ + logger.info(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)", pdu->N_bytes); + + rx_pdu.init_rx(); + rx_pdu.unpack(pdu->msg, pdu->N_bytes); + + for (uint32_t i = 0; i < rx_pdu.get_num_subpdus(); ++i) { + srslte::mac_sch_subpdu_nr subpdu = rx_pdu.get_subpdu(i); + logger.info("Handling subPDU %d/%d: rnti=0x%x lcid=%d, sdu_len=%d", + i, + rx_pdu.get_num_subpdus(), + subpdu.get_c_rnti(), + subpdu.get_lcid(), + subpdu.get_sdu_length()); + + // rlc->write_pdu(subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); + } +} + +uint64_t mac_nr::get_contention_id() +{ + return 0xdeadbeef; // TODO when rebased on PR +} + +uint16_t mac_nr::get_c_rnti() +{ + return c_rnti; +} + +void mac_nr::set_c_rnti(uint64_t c_rnti_) +{ + c_rnti = c_rnti_; +} + +// TODO same function as for mac_eutra +bool mac_nr::is_in_window(uint32_t tti, int* start, int* len) +{ + uint32_t st = (uint32_t)*start; + uint32_t l = (uint32_t)*len; + + if (srslte_tti_interval(tti, st) < l + 5) { + if (tti > st) { + if (tti <= st + l) { + return true; + } else { + *start = 0; + *len = 0; + return false; + } + } else { + if (tti <= (st + l) % 10240) { + return true; + } else { + *start = 0; + *len = 0; + return false; + } + } + } + return false; +} + +} // namespace srsue diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc new file mode 100644 index 000000000..084ee457c --- /dev/null +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -0,0 +1,56 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srsue/hdr/stack/mac_nr/mux_nr.h" +#include "srslte/common/buffer_pool.h" + +namespace srsue { + +mux_nr::mux_nr(srslog::basic_logger& logger_) : logger(logger_) +{ + msg3_buff = srslte::make_byte_buffer(); +}; + +void mux_nr::init() {} + +void mux_nr::msg3_flush() +{ + msg3_buff->clear(); + msg3_state = msg3_state_t::none; +} + +void mux_nr::msg3_prepare() +{ + msg3_state = msg3_state_t::pending; +} + +void mux_nr::msg3_transmitted() +{ + msg3_state = msg3_state_t::transmitted; +} + +bool mux_nr::msg3_is_transmitted() +{ + return msg3_state == msg3_state_t::transmitted; +} + +bool mux_nr::msg3_is_pending() +{ + return msg3_state == msg3_state_t::pending; +} + +bool mux_nr::msg3_is_empty() +{ + return msg3_buff->N_bytes == 0; +} + +} // namespace srsue diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc new file mode 100644 index 000000000..6d568058f --- /dev/null +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -0,0 +1,327 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 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 "srsue/hdr/stack/mac_nr/proc_ra_nr.h" +#include "srslte/mac/mac_rar_pdu_nr.h" +#include "srsue/hdr/stack/mac_nr/mac_nr.h" + +namespace srsue { + +const char* state_str_nr[] = {"RA: IDLE: ", + "RA: PDCCH_SETUP: ", + "RA: WAITING_FOR_PRACH_SENT: ", + "RA: WAITING_FOR_RESPONSE_RECEPTION: ", + "RA: WAITING_FOR_COMPLETION: ", + "RA: MAX_RA_STATES: "}; + +// Table 7.2-1. Backoff Parameter values +uint32_t backoff_table_nr[16] = {0, 10, 20, 30, 40, 60, 80, 120, 160, 240, 320, 480, 960, 1920, 1920, 1920}; + +// Table 7.6-1: DELTA_PREAMBLE values long +int delta_preamble_db_table_nr[5] = {0, -3, -6, 0}; + +proc_ra_nr::proc_ra_nr(srslog::basic_logger& logger_) : logger(logger_) {} + +void proc_ra_nr::init(phy_interface_mac_nr* phy_, + mac_interface_proc_ra_nr* mac_, + srslte::ext_task_sched_handle* task_sched_) +{ + phy = phy_; + mac = mac_; + task_sched = task_sched_; + task_queue = task_sched->make_task_queue(); + prach_send_timer = task_sched->get_unique_timer(); + rar_timeout_timer = task_sched->get_unique_timer(); + contention_resolution_timer = task_sched->get_unique_timer(); +} + +/* Sets a new configuration. The configuration is applied by initialization() function */ +void proc_ra_nr::set_config(const srslte::rach_nr_cfg_t& rach_cfg_) +{ + if (state != IDLE) { + logger.warning("Wrong state for ra reponse reception %s (expected state %s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, IDLE)); + return; + } + rach_cfg = rach_cfg_; + configured = true; + logger.info("Set RACH common config (Config Index %d, preambleTransMax %d, Repsonse Window %d)", + rach_cfg.prach_ConfigurationIndex, + rach_cfg.preambleTransMax, + rach_cfg.ra_responseWindow); +} + +void proc_ra_nr::start_by_rrc() +{ + if (state != IDLE || configured == false) { + logger.warning("Trying to start PRACH by RRC order in invalid state (%s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state)); + return; + } + started_by = initiators_t::RRC; + logger.info("Starting PRACH by RRC order"); + ra_procedure_initialization(); +} + +bool proc_ra_nr::is_rar_opportunity(uint32_t tti) +{ + // TODO replace second "&&"" by rar_timeout_timer.running if timer thread safe and delayed starting (tti+3) + if (state == WAITING_FOR_RESPONSE_RECEPTION && ra_window_start > 0 && ra_window_length > 0 && + mac_nr::is_in_window(tti, &ra_window_start, &ra_window_length)) { + logger.debug("SCHED: Searching RAR-RNTI=0x%x, tti=%d", rar_rnti, tti); + return true; + } + return false; +} + +uint16_t proc_ra_nr::get_rar_rnti() +{ + if (rar_rnti == SRSLTE_INVALID_RNTI || state != WAITING_FOR_RESPONSE_RECEPTION) { + logger.error("Requested ra rnti is invalid. Anyway we return an invalid ra rnti"); + return SRSLTE_INVALID_RNTI; + } + return rar_rnti; +} + +bool proc_ra_nr::has_rar_rnti() +{ + if (rar_rnti != SRSLTE_INVALID_RNTI) { + return true; + } + return false; +} + +bool proc_ra_nr::has_temp_rnti() +{ + return temp_rnti != SRSLTE_INVALID_RNTI; +} + +uint16_t proc_ra_nr::get_temp_rnti() +{ + return temp_rnti; +} + +void proc_ra_nr::timer_expired(uint32_t timer_id) +{ + if (prach_send_timer.id() == timer_id) { + logger.error("PRACH Send timer expired. PRACH was not transmitted within %d ttis by phy. (TODO)", + prach_send_timer.duration()); + ra_error(); + } else if (rar_timeout_timer.id() == timer_id) { + logger.error("RAR Timer expired. RA response not received within the response window Response Error (TODO)"); + ra_error(); + } else if (contention_resolution_timer.id() == timer_id) { + logger.error("Contention Resolution Timer expired. Stopping PDCCH Search and going to Response Error (TODO)"); + ra_error(); + } else { + logger.error("Timer not implemented"); + } +} + +// 5.1.2 Random Access Resource selection +void proc_ra_nr::ra_procedure_initialization() +{ + mac->msg3_flush(); + preamble_power_ramping_step = rach_cfg.powerRampingStep; + scaling_factor_bi = 1; + preambleTransMax = rach_cfg.preambleTransMax; + ra_resource_selection(); +} + +// 5.1.2 Random Access Resource selection (TODO) +void proc_ra_nr::ra_resource_selection() +{ + ra_preamble_transmission(); +} + +// 5.1.3 Random Access Preamble transmission +void proc_ra_nr::ra_preamble_transmission() +{ + uint32_t delta_preamble = 0; // TODO calulate the delta preamble based on delta_preamble_db_table_nr + preamble_received_target_power = rach_cfg.PreambleReceivedTargetPower + delta_preamble + + (preamble_transmission_counter - 1) * rach_cfg.powerRampingStep + + power_offset_2step_ra; + preamble_index = 0; + prach_occasion = 0; + // instruct the physical layer to transmit the Random Access Preamble using the selected PRACH occasion, corresponding + // RA-RNTI (if available), PREAMBLE_INDEX, and PREAMBLE_RECEIVED_TARGET_POWER. + phy->send_prach(prach_occasion, preamble_index, preamble_received_target_power); + prach_send_timer.set(100, [this](uint32_t tid) { timer_expired(tid); }); // TODO find a suitable 100? + prach_send_timer.run(); + state = WAITING_FOR_PRACH_SENT; +} + +// 5.1.4 Random Access Preamble transmission +void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::mac_nr_grant_dl_t& grant) +{ + if (state != WAITING_FOR_RESPONSE_RECEPTION) { + logger.warning( + "Wrong state for ra reponse reception %s (expected state %s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_RESPONSE_RECEPTION)); + return; + } + + // Stop rar timer + rar_timeout_timer.stop(); + for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; ++i) { + if (grant.tb[i] != nullptr) { + srslte::mac_rar_pdu_nr pdu; + if (!pdu.unpack(grant.tb[i]->msg, grant.tb[i]->N_bytes)) { + logger.warning("Error unpacking RAR PDU (%d)", i); + return; + } + logger.info(pdu.to_string()); + + for (auto& subpdu : pdu.get_subpdus()) { + if (subpdu.has_rapid() && subpdu.get_rapid() == preamble_index) { + logger.info("PROC RA NR: Setting ul grant and prepare msg3"); + temp_rnti = subpdu.get_temp_crnti(); + + // Set Temporary-C-RNTI if provided, otherwise C-RNTI is ok + phy->set_ul_grant(subpdu.get_ul_grant(), temp_rnti, srslte_rnti_type_c); + + // reset all parameters that are used before rar + rar_rnti = SRSLTE_INVALID_RNTI; + mac->msg3_prepare(); + current_ta = subpdu.get_ta(); + } + } + } + } + contention_resolution_timer.set(rach_cfg.ra_ContentionResolutionTimer, [this](uint32_t tid) { timer_expired(tid); }); + contention_resolution_timer.run(); + logger.debug("Waiting for Contention Resolution"); + state = WAITING_FOR_CONTENTION_RESOLUTION; +} + +// TS 38.321 Section 5.1.5 2 ways to resolve contention resolution +// if the C-RNTI MAC CE was included in Msg3: (only this one is implemented) +void proc_ra_nr::ra_contention_resolution() +{ + if (state != WAITING_FOR_CONTENTION_RESOLUTION) { + logger.warning( + "Wrong state for ra contention resolution by phy %s (expected state %s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION)); + return; + } + if (started_by == initiators_t::RRC || started_by == initiators_t::MAC) { + logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + contention_resolution_timer.stop(); + state = WAITING_FOR_COMPLETION; + ra_completion(); + } else { + logger.error("Not started by the correct initiator MAC or RRC"); + } +} + +// or else if the CCCH SDU was included in Msg3 and the PDCCH transmission is addressed to its TEMPORARY_C-RNTI: +void proc_ra_nr::ra_contention_resolution(uint64_t rx_contention_id) +{ + if (state != WAITING_FOR_CONTENTION_RESOLUTION) { + logger.warning( + "Wrong state for ra contention resolution by phy %s (expected state %s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION)); + return; + } + // TODO +} + +void proc_ra_nr::ra_completion() +{ + if (state != WAITING_FOR_COMPLETION) { + logger.warning("Wrong state for ra completion by phy %s (expected state %s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_COMPLETION)); + return; + } + srslte::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", mac->get_c_rnti(), current_ta); + logger.info("Random Access Complete. c-rnti=0x%x, ta=%d", mac->get_c_rnti(), current_ta); + temp_rnti = SRSLTE_INVALID_RNTI; + reset(); +} + +void proc_ra_nr::ra_error() +{ + logger.error("NR random access procedure error recovery not implemented yet"); +} + +// Is called by PHY once it has transmitted the prach transmitted, than configure RA-RNTI and wait for RAR reception +void proc_ra_nr::prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) +{ + task_queue.push([this, tti, s_id, t_id, f_id, ul_carrier_id]() { + if (state != WAITING_FOR_PRACH_SENT) { + logger.warning("Wrong state for prach sent notification by phy %s (expected state %s)", + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), + srslte::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_PRACH_SENT)); + return; + } + prach_send_timer.stop(); + rar_rnti = 1 + s_id + 14 * t_id + 14 * 80 * f_id + 14 * 80 * 8 * ul_carrier_id; + logger.info( + "prach_occasion=%d, preamble_index=%d, ra-rnti=0x%x, ra-tti=%d, s_id=%d, t_id=%d, f_id=%d, ul_carrier_id=%d", + prach_occasion, + preamble_index, + rar_rnti, + tti, + s_id, + t_id, + f_id, + ul_carrier_id); + srslte::console("Random Access Transmission: prach_occasion=%d, preamble_index=%d, ra-rnti=0x%x, tti=%d\n", + prach_occasion, + preamble_index, + rar_rnti, + tti); + uint32_t rar_window_st = TTI_ADD(tti, 3); + // TODO check ra_response window (delayed start)? // last 3 check if needed when we have a delayed start + rar_timeout_timer.set(rach_cfg.ra_responseWindow + 3 + 3, [this](uint32_t tid) { timer_expired(tid); }); + rar_timeout_timer.run(); + // Wait for RAR reception + ra_window_length = rach_cfg.ra_responseWindow; + ra_window_start = TTI_ADD(tti, 3); + logger.debug("Calculated ra_window_start=%d, ra_window_length=%d", ra_window_start, ra_window_length); + state = WAITING_FOR_RESPONSE_RECEPTION; + }); +} + +// Called by PHY thread through MAC parent +void proc_ra_nr::handle_rar_pdu(mac_interface_phy_nr::mac_nr_grant_dl_t& grant) +{ + // Defer the handling of the grant to main stack thread in ra_response_reception + auto task_handler = [this](const mac_interface_phy_nr::mac_nr_grant_dl_t& t) { ra_response_reception(std::move(t)); }; + task_queue.push(std::bind(task_handler, std::move(grant))); +} + +// Called from PHY thread, defer actions therefore. +void proc_ra_nr::pdcch_to_crnti() +{ + task_queue.push([this]() { ra_contention_resolution(); }); +} + +bool proc_ra_nr::is_contention_resolution() +{ + return state == WAITING_FOR_CONTENTION_RESOLUTION; +} + +void proc_ra_nr::reset() +{ + state = IDLE; + started_by = initiators_t::initiators_t_NULLTYPE; + prach_send_timer.stop(); + rar_timeout_timer.stop(); + contention_resolution_timer.stop(); +} +} // namespace srsue diff --git a/srsue/src/stack/rrc/CMakeLists.txt b/srsue/src/stack/rrc/CMakeLists.txt index 6881b3d72..76f2e3df8 100644 --- a/srsue/src/stack/rrc/CMakeLists.txt +++ b/srsue/src/stack/rrc/CMakeLists.txt @@ -18,15 +18,8 @@ # and at http://www.gnu.org/licenses/. # -set(SOURCES rrc.cc rrc_procedures.cc rrc_meas.cc rrc_cell.cc phy_controller.cc) - -if(ENABLE_5GNR) - set(SOURCES ${SOURCES} rrc_nr.cc) -endif() +set(SOURCES rrc.cc rrc_nr.cc rrc_procedures.cc rrc_meas.cc rrc_cell.cc phy_controller.cc) add_library(srsue_rrc STATIC ${SOURCES}) +add_library(srsue_rrc_nr STATIC ${SOURCES}) -if(ENABLE_5GNR) - set(SOURCES rrc_nr.cc) - add_library(srsue_rrc_nr STATIC ${SOURCES}) -endif() diff --git a/srsue/src/stack/rrc/phy_controller.cc b/srsue/src/stack/rrc/phy_controller.cc index ed15c8c57..6ad55eb32 100644 --- a/srsue/src/stack/rrc/phy_controller.cc +++ b/srsue/src/stack/rrc/phy_controller.cc @@ -33,7 +33,7 @@ std::string to_string(const phy_cell_t& cell) phy_controller::phy_controller(srsue::phy_interface_rrc_lte* phy_, srslte::task_sched_handle task_sched_, std::function on_cell_selection) : - base_t(srslte::log_ref{"RRC"}), + base_t(srslog::fetch_basic_logger("RRC")), phy(phy_), task_sched(task_sched_), cell_selection_always_observer(std::move(on_cell_selection)) @@ -46,13 +46,13 @@ void phy_controller::in_sync() bool phy_controller::set_cell_config(const srslte::phy_cfg_t& config, uint32_t cc_idx) { - log_h->info("Setting PHY config for cc_idx=%d\n", cc_idx); + logger.info("Setting PHY config for cc_idx=%d", cc_idx); return set_cell_config(config, cc_idx, true); } void phy_controller::set_phy_to_default() { - log_h->info("Setting default PHY config (common and dedicated)\n"); + logger.info("Setting default PHY config (common and dedicated)"); srslte::phy_cfg_t& default_cfg = current_cells_cfg[0]; default_cfg.set_defaults(); @@ -64,7 +64,7 @@ void phy_controller::set_phy_to_default() /// Apply default PHY config for all SCells as specified in TS 36.331 9.2.4 void phy_controller::set_phy_to_default_dedicated() { - log_h->info("Setting default dedicated PHY config\n"); + logger.info("Setting default dedicated PHY config"); srslte::phy_cfg_t& default_cfg = current_cells_cfg[0]; default_cfg.set_defaults_dedicated(); @@ -75,7 +75,7 @@ void phy_controller::set_phy_to_default_dedicated() void phy_controller::set_phy_to_default_pucch_srs() { - log_h->info("Setting default PHY config dedicated\n"); + logger.info("Setting default PHY config dedicated"); srslte::phy_cfg_t& default_cfg_ded = current_cells_cfg[0]; default_cfg_ded.set_defaults_pucch_sr(); @@ -100,7 +100,7 @@ bool phy_controller::set_cell_config(const srslte::phy_cfg_t& cfg, uint32_t cc_i void phy_controller::set_config_complete() { if (nof_pending_configs == 0) { - log_h->warning("Received more phy config complete signals than the ones scheduled\n"); + logger.warning("Received more phy config complete signals than the ones scheduled"); return; } nof_pending_configs--; @@ -113,12 +113,12 @@ void phy_controller::set_config_complete() bool phy_controller::start_cell_select(const phy_cell_t& phy_cell, srslte::event_observer observer) { if (is_in_state()) { - log_h->warning("Failed to launch cell selection as it is already running\n"); + logger.warning("Failed to launch cell selection as it is already running"); return false; } trigger(cell_sel_cmd{phy_cell}); if (not is_in_state()) { - log_h->warning("Failed to launch cell selection. Current state: %s\n", current_state_name().c_str()); + logger.warning("Failed to launch cell selection. Current state: %s", current_state_name().c_str()); return false; } cell_selection_notifier = std::move(observer); @@ -140,7 +140,7 @@ void phy_controller::selecting_cell::enter(phy_controller* f, const cell_sel_cmd target_cell = ev.phy_cell; csel_res.result = false; - fsmInfo("Starting for pci=%d, earfcn=%d\n", target_cell.pci, target_cell.earfcn); + fsmInfo("Starting for pci=%d, earfcn=%d", target_cell.pci, target_cell.earfcn); if (not f->phy->cell_select(target_cell)) { trigger(srslte::failure_ev{}); } @@ -151,9 +151,9 @@ void phy_controller::selecting_cell::exit(phy_controller* f) wait_in_sync_timer.stop(); if (csel_res.result) { - fsmInfo("Cell %s successfully selected\n", to_string(target_cell).c_str()); + fsmInfo("Cell %s successfully selected", to_string(target_cell).c_str()); } else { - fsmWarning("Failed to select cell %s\n", to_string(target_cell).c_str()); + fsmWarning("Failed to select cell %s", to_string(target_cell).c_str()); } // Signal result back to FSM that called cell selection @@ -178,12 +178,12 @@ void phy_controller::selecting_cell::wait_in_sync::enter(selecting_cell* f) bool phy_controller::start_cell_search(srslte::event_observer observer) { if (is_in_state()) { - fsmInfo("Cell search already launched.\n"); + fsmInfo("Cell search already launched."); return true; } trigger(cell_search_cmd{}); if (not is_in_state()) { - fsmWarning("Failed to launch cell search\n"); + fsmWarning("Failed to launch cell search"); return false; } cell_search_observers.subscribe(observer); @@ -197,7 +197,7 @@ void phy_controller::cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t void phy_controller::searching_cell::enter(phy_controller* f) { - otherfsmInfo(f, "Initiating Cell search\n"); + otherfsmInfo(f, "Initiating Cell search"); f->phy->cell_search(); } @@ -205,13 +205,13 @@ void phy_controller::handle_cell_search_res(searching_cell& s, const cell_srch_r { switch (result.cs_ret.found) { case cell_search_ret_t::CELL_FOUND: - fsmInfo("PHY cell search completed. Found cell %s\n", to_string(result.found_cell).c_str()); + fsmInfo("PHY cell search completed. Found cell %s", to_string(result.found_cell).c_str()); break; case cell_search_ret_t::CELL_NOT_FOUND: - fsmWarning("PHY cell search completed. No cells found.\n"); + fsmWarning("PHY cell search completed. No cells found."); break; default: - fsmError("Invalid cell search result\n"); + fsmError("Invalid cell search result"); // TODO: check what errors can happen (currently not handled in our code) } diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 29e336a85..038237f63 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -56,7 +56,7 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) : state(RRC_STATE_IDLE), last_state(RRC_STATE_CONNECTED), drb_up(false), - rrc_log("RRC"), + logger(srslog::fetch_basic_logger("RRC")), measurements(new rrc_meas()), cell_searcher(this), si_acquirer(this), @@ -70,9 +70,7 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) : connection_reest(this), ho_handler(this), conn_recfg_proc(this), -#ifdef HAVE_5GNR meas_cells_nr(task_sched_), -#endif meas_cells(task_sched_) {} @@ -85,19 +83,19 @@ void rrc::log_rrc_message(const std::string source, const T& msg, const std::string& msg_type) { - if (rrc_log->get_level() == srslte::LOG_LEVEL_INFO) { - rrc_log->info("%s - %s %s (%d B)\n", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); - } else if (rrc_log->get_level() >= srslte::LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { asn1::json_writer json_writer; msg.to_json(json_writer); - rrc_log->debug_hex(pdu->msg, - pdu->N_bytes, - "%s - %s %s (%d B)\n", - source.c_str(), - (dir == Rx) ? "Rx" : "Tx", - msg_type.c_str(), - pdu->N_bytes); - rrc_log->debug_long("Content:\n%s\n", json_writer.to_string().c_str()); + logger.debug(pdu->msg, + pdu->N_bytes, + "%s - %s %s (%d B)", + source.c_str(), + (dir == Rx) ? "Rx" : "Tx", + msg_type.c_str(), + pdu->N_bytes); + logger.debug("Content:\n%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); } } @@ -108,12 +106,9 @@ void rrc::init(phy_interface_rrc_lte* phy_, nas_interface_rrc* nas_, usim_interface_rrc* usim_, gw_interface_rrc* gw_, -#ifdef HAVE_5GNR rrc_nr_interface_rrc* rrc_nr_, -#endif const rrc_args_t& args_) { - pool = byte_buffer_pool::get_instance(); phy = phy_; mac = mac_; rlc = rlc_; @@ -121,9 +116,7 @@ void rrc::init(phy_interface_rrc_lte* phy_, nas = nas_; usim = usim_; gw = gw_; -#ifdef HAVE_5GNR rrc_nr = rrc_nr_; -#endif args = args_; auto on_every_cell_selection = [this](uint32_t earfcn, uint32_t pci, bool csel_result) { @@ -161,7 +154,7 @@ void rrc::init(phy_interface_rrc_lte* phy_, struct timeval tv; gettimeofday(&tv, NULL); - rrc_log->info("using srand seed of %ld\n", tv.tv_usec); + logger.info("using srand seed of %ld", tv.tv_usec); // set seed (used in CHAP auth and attach) srand(tv.tv_usec); @@ -225,16 +218,14 @@ void rrc::run_tti() // Process pending PHY measurements in IDLE/CONNECTED process_cell_meas(); -#ifdef HAVE_5GNR process_cell_meas_nr(); -#endif // Process on-going callbacks, and clear finished callbacks callback_list.run(); // Log state changes if (state != last_state) { - rrc_log->debug("State %s\n", rrc_state_text[state]); + logger.debug("State %s", rrc_state_text[state]); last_state = state; } @@ -309,7 +300,7 @@ uint16_t rrc::get_mnc() bool rrc::plmn_search() { if (not plmn_searcher.launch()) { - rrc_log->error("Unable to initiate PLMN search\n"); + logger.error("Unable to initiate PLMN search"); return false; } callback_list.add_proc(plmn_searcher); @@ -324,7 +315,7 @@ void rrc::plmn_select(srslte::plmn_id_t plmn_id) plmn_is_selected = true; selected_plmn_id = plmn_id; - rrc_log->info("PLMN Selected %s\n", plmn_id.to_string().c_str()); + logger.info("PLMN Selected %s", plmn_id.to_string().c_str()); } /* 5.3.3.2 Initiation of RRC Connection Establishment procedure @@ -338,7 +329,7 @@ void rrc::plmn_select(srslte::plmn_id_t plmn_id) bool rrc::connection_request(srslte::establishment_cause_t cause, srslte::unique_byte_buffer_t dedicated_info_nas_) { if (not conn_req_proc.launch(cause, std::move(dedicated_info_nas_))) { - rrc_log->error("Failed to initiate connection request procedure\n"); + logger.error("Failed to initiate connection request procedure"); return false; } callback_list.add_proc(conn_req_proc); @@ -349,8 +340,8 @@ void rrc::set_ue_identity(srslte::s_tmsi_t s_tmsi) { ue_identity_configured = true; ue_identity = s_tmsi; - rrc_log->info( - "Set ue-Identity to 0x%" PRIu64 ":0x%" PRIu64 "\n", (uint64_t)ue_identity.mmec, (uint64_t)ue_identity.m_tmsi); + logger.info( + "Set ue-Identity to 0x%" PRIu64 ":0x%" PRIu64 "", (uint64_t)ue_identity.mmec, (uint64_t)ue_identity.m_tmsi); } /******************************************************************************* @@ -384,7 +375,6 @@ void rrc::set_config_complete(bool status) void rrc::set_scell_complete(bool status) {} -#ifdef HAVE_5GNR /* This function is called from a NR PHY worker thus must return very quickly. * Queue the values of the measurements and process them from the RRC thread */ @@ -400,7 +390,7 @@ void rrc::process_cell_meas_nr() std::vector m; while (cell_meas_nr_q.try_pop(&m)) { if (cell_meas_nr_q.size() > 0) { - rrc_log->debug("MEAS: Processing measurement. %zd measurements in queue\n", cell_meas_q.size()); + logger.debug("MEAS: Processing measurement. %zd measurements in queue", cell_meas_q.size()); } process_new_cell_meas_nr(m); } @@ -408,7 +398,6 @@ void rrc::process_cell_meas_nr() void rrc::process_new_cell_meas_nr(const std::vector& meas) { - // Convert vector std::vector meas_lte; for (const auto& m : meas) { @@ -426,7 +415,7 @@ void rrc::process_new_cell_meas_nr(const std::vector& meas) c.set_cfo(m.cfo_hz); }; - rrc_log->debug("MEAS: Processing measurement of %zd cells\n", meas.size()); + logger.debug("MEAS: Processing measurement of %zd cells", meas.size()); bool neighbour_added = meas_cells_nr.process_new_cell_meas(meas_lte, filter); } @@ -437,7 +426,6 @@ void rrc::nr_rrc_con_reconfig_complete(bool status) conn_recfg_proc.trigger(status); } } -#endif /* This function is called from a PHY worker thus must return very quickly. * Queue the values of the measurements and process them from the RRC thread @@ -453,7 +441,7 @@ void rrc::process_cell_meas() std::vector m; while (cell_meas_q.try_pop(&m)) { if (cell_meas_q.size() > 0) { - rrc_log->debug("MEAS: Processing measurement. %zd measurements in queue\n", cell_meas_q.size()); + logger.debug("MEAS: Processing measurement. %zd measurements in queue", cell_meas_q.size()); } process_new_cell_meas(m); } @@ -468,7 +456,7 @@ void rrc::process_new_cell_meas(const std::vector& meas) c.set_cfo(m.cfo_hz); }; - rrc_log->debug("MEAS: Processing measurement of %zd cells\n", meas.size()); + logger.debug("MEAS: Processing measurement of %zd cells", meas.size()); bool neighbour_added = meas_cells.process_new_cell_meas(meas, filter); @@ -482,7 +470,7 @@ void rrc::process_new_cell_meas(const std::vector& meas) void rrc::out_of_sync() { // CAUTION: We do not lock in this function since they are called from real-time threads - if (meas_cells.serving_cell().is_valid() && rrc_log) { + if (meas_cells.serving_cell().is_valid()) { phy_ctrl->out_sync(); // upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300, @@ -492,15 +480,15 @@ void rrc::out_of_sync() // nor T311 is running bool t311_running = t311.is_running() || connection_reest.is_busy(); if (!t300.is_running() and !t301.is_running() and !t304.is_running() and !t310.is_running() and !t311_running) { - rrc_log->info("Received out-of-sync while in state %s. n310=%d, t311=%s, t310=%s\n", - rrc_state_text[state], - n310_cnt, - t311.is_running() ? "running" : "stop", - t310.is_running() ? "running" : "stop"); + logger.info("Received out-of-sync while in state %s. n310=%d, t311=%s, t310=%s", + rrc_state_text[state], + n310_cnt, + t311.is_running() ? "running" : "stop", + t310.is_running() ? "running" : "stop"); n310_cnt++; if (n310_cnt == N310) { - rrc_log->info( - "Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n", N310, t310.duration()); + logger.info( + "Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms", N310, t310.duration()); t310.run(); n310_cnt = 0; } @@ -519,7 +507,7 @@ void rrc::in_sync() if (n311_cnt == N311) { t310.stop(); n311_cnt = 0; - rrc_log->info("Detected %d in-sync from PHY. Stopping T310 timer\n", N311); + logger.info("Detected %d in-sync from PHY. Stopping T310 timer", N311); } } } @@ -578,7 +566,7 @@ void rrc::set_serving_cell(phy_cell_t phy_cell, bool discard_serving) int rrc::start_cell_select() { if (not cell_selector.launch()) { - rrc_log->error("Failed to initiate a Cell Selection procedure...\n"); + logger.error("Failed to initiate a Cell Selection procedure..."); return SRSLTE_ERROR; } callback_list.add_proc(cell_selector); @@ -590,12 +578,10 @@ bool rrc::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const return meas_cells.has_neighbour_cell(earfcn, pci); } -#ifdef HAVE_5GNR bool rrc::has_neighbour_cell_nr(uint32_t earfcn, uint32_t pci) const { return meas_cells_nr.has_neighbour_cell(earfcn, pci); } -#endif bool rrc::is_serving_cell(uint32_t earfcn, uint32_t pci) const { @@ -640,11 +626,11 @@ bool rrc::mbms_service_start(uint32_t serv, uint32_t port) { bool ret = false; if (!meas_cells.serving_cell().has_mcch) { - rrc_log->error("MCCH not available at MBMS Service Start\n"); + logger.error("MCCH not available at MBMS Service Start"); return ret; } - rrc_log->info("%s\n", print_mbms().c_str()); + logger.info("%s", print_mbms().c_str()); mcch_msg_type_c msg = meas_cells.serving_cell().mcch.msg; for (uint32_t i = 0; i < msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9.size(); i++) { @@ -696,14 +682,14 @@ void rrc::radio_link_failure_process() if (state == RRC_STATE_CONNECTED) { if (security_is_activated) { - rrc_log->info("Detected Radio-Link Failure with active AS security. Starting ConnectionReestablishment...\n"); + logger.info("Detected Radio-Link Failure with active AS security. Starting ConnectionReestablishment..."); start_con_restablishment(reest_cause_e::other_fail); } else { - rrc_log->info("Detected Radio-Link Failure with AS security deactivated. Going to IDLE...\n"); + logger.info("Detected Radio-Link Failure with AS security deactivated. Going to IDLE..."); start_go_idle(); } } else { - rrc_log->info("Detected Radio-Link Failure while RRC_IDLE. Ignoring it.\n"); + logger.info("Detected Radio-Link Failure while RRC_IDLE. Ignoring it."); } } @@ -719,29 +705,29 @@ void rrc::release_pucch_srs() void rrc::ra_problem() { if (not t300.is_running() and not t301.is_running() and not t304.is_running() and not t311.is_running()) { - rrc_log->warning("MAC indicated RA problem. Starting RLF\n"); + logger.warning("MAC indicated RA problem. Starting RLF"); radio_link_failure_push_cmd(); } else { - rrc_log->warning("MAC indicated RA problem but either T300, T301, T304 or T311 is running. Ignoring it.\n"); + logger.warning("MAC indicated RA problem but either T300, T301, T304 or T311 is running. Ignoring it."); } } void rrc::max_retx_attempted() { // TODO: Handle the radio link failure - rrc_log->warning("Max RLC reTx attempted. Starting RLF\n"); + logger.warning("Max RLC reTx attempted. Starting RLF"); radio_link_failure_push_cmd(); } void rrc::timer_expired(uint32_t timeout_id) { if (timeout_id == t310.id()) { - rrc_log->info("Timer T310 expired: Radio Link Failure\n"); + logger.info("Timer T310 expired: Radio Link Failure"); radio_link_failure_push_cmd(); } else if (timeout_id == t311.id()) { srslte::console("Timer T311 expired: Going to RRC IDLE\n"); if (connection_reest.is_idle()) { - rrc_log->info("Timer T311 expired: Going to RRC IDLE\n"); + logger.info("Timer T311 expired: Going to RRC IDLE"); start_go_idle(); } else { // Do nothing, this is handled by the procedure @@ -749,26 +735,25 @@ void rrc::timer_expired(uint32_t timeout_id) } } else if (timeout_id == t301.id()) { if (state == RRC_STATE_IDLE) { - rrc_log->info("Timer T301 expired: Already in IDLE.\n"); + logger.info("Timer T301 expired: Already in IDLE."); } else { - rrc_log->info("Timer T301 expired: Going to RRC IDLE\n"); + logger.info("Timer T301 expired: Going to RRC IDLE"); connection_reest.trigger(connection_reest_proc::t301_expiry{}); } } else if (timeout_id == t302.id()) { - rrc_log->info("Timer T302 expired. Informing NAS about barrier alleviation\n"); + logger.info("Timer T302 expired. Informing NAS about barrier alleviation"); nas->set_barring(srslte::barring_t::none); } else if (timeout_id == t300.id()) { // Do nothing, handled in connection_request() } else if (timeout_id == t304.id()) { srslte::console("Timer t304 expired: Handover failed\n"); - rrc_log->info("Timer t304 expired: Handover failed\n"); + logger.info("Timer t304 expired: Handover failed"); ho_failed(); } else { - rrc_log->error("Timeout from unknown timer id %d\n", timeout_id); + logger.error("Timeout from unknown timer id %d", timeout_id); } } -#ifdef HAVE_5GNR bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg) { if (!(rx_recfg.non_crit_ext_present && rx_recfg.non_crit_ext.non_crit_ext_present && @@ -823,7 +808,6 @@ bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg) nr_radio_bearer_cfg1_r15_present, nr_radio_bearer_cfg1_r15); } -#endif /******************************************************************************* * * @@ -836,7 +820,7 @@ bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg) void rrc::send_con_request(srslte::establishment_cause_t cause) { - rrc_log->debug("Preparing RRC Connection Request\n"); + logger.debug("Preparing RRC Connection Request"); // Prepare ConnectionRequest packet ul_ccch_msg_s ul_ccch_msg; @@ -886,8 +870,8 @@ void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint1 uint32_t N_bits = (uint32_t)bref.distance(varShortMAC_packed); uint32_t N_bytes = ((N_bits - 1) / 8 + 1); - rrc_log->info( - "Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes, %d bits)\n", cellid, pci, crnti, N_bytes, N_bits); + logger.info( + "Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes, %d bits)", cellid, pci, crnti, N_bytes, N_bits); // Compute MAC-I uint8_t mac_key[4] = {}; @@ -920,7 +904,7 @@ void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint1 mac_key); break; default: - rrc_log->info("Unsupported integrity algorithm during reestablishment\n"); + logger.info("Unsupported integrity algorithm during reestablishment"); } // Prepare ConnectionRestalishmentRequest packet @@ -937,17 +921,16 @@ void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint1 meas_cells.serving_cell().phy_cell.pci, meas_cells.serving_cell().phy_cell.earfcn, cause.to_string().c_str()); - rrc_log->info("RRC Connection Reestablishment to PCI=%d, EARFCN=%d (Cause: \"%s\")\n", - meas_cells.serving_cell().phy_cell.pci, - meas_cells.serving_cell().phy_cell.earfcn, - cause.to_string().c_str()); + logger.info("RRC Connection Reestablishment to PCI=%d, EARFCN=%d (Cause: \"%s\")", + meas_cells.serving_cell().phy_cell.pci, + meas_cells.serving_cell().phy_cell.earfcn, + cause.to_string().c_str()); send_ul_ccch_msg(ul_ccch_msg); } void rrc::send_con_restablish_complete() { - - rrc_log->debug("Preparing RRC Connection Reestablishment Complete\n"); + logger.debug("Preparing RRC Connection Reestablishment Complete"); srslte::console("RRC Connected\n"); // Prepare ConnectionSetupComplete packet @@ -962,7 +945,7 @@ void rrc::send_con_restablish_complete() void rrc::send_con_setup_complete(srslte::unique_byte_buffer_t nas_msg) { - rrc_log->debug("Preparing RRC Connection Setup Complete\n"); + logger.debug("Preparing RRC Connection Setup Complete"); // Prepare ConnectionSetupComplete packet asn1::rrc::ul_dcch_msg_s ul_dcch_msg; @@ -996,7 +979,7 @@ void rrc::send_ul_info_transfer(unique_byte_buffer_t nas_msg) void rrc::send_security_mode_complete() { - rrc_log->debug("Preparing Security Mode Complete\n"); + logger.debug("Preparing Security Mode Complete"); // Prepare Security Mode Command Complete ul_dcch_msg_s ul_dcch_msg; @@ -1008,15 +991,15 @@ void rrc::send_security_mode_complete() void rrc::send_rrc_con_reconfig_complete(bool contains_nr_complete) { - rrc_log->debug("Preparing RRC Connection Reconfig Complete\n"); + logger.debug("Preparing RRC Connection Reconfig Complete"); - ul_dcch_msg_s ul_dcch_msg; - ul_dcch_msg.msg.c1().rrc_conn_recfg_complete().rrc_transaction_id = transaction_id; + ul_dcch_msg_s ul_dcch_msg; rrc_conn_recfg_complete_r8_ies_s* rrc_conn_recfg_complete_r8 = &ul_dcch_msg.msg.set_c1().set_rrc_conn_recfg_complete().crit_exts.set_rrc_conn_recfg_complete_r8(); + ul_dcch_msg.msg.c1().rrc_conn_recfg_complete().rrc_transaction_id = transaction_id; if (contains_nr_complete == true) { - rrc_log->debug("Preparing RRC Connection Reconfig Complete with NR Complete\n"); + logger.debug("Preparing RRC Connection Reconfig Complete with NR Complete"); rrc_conn_recfg_complete_r8->non_crit_ext_present = true; rrc_conn_recfg_complete_r8->non_crit_ext.non_crit_ext_present = true; @@ -1045,7 +1028,7 @@ void rrc::ra_completed() bool rrc::con_reconfig_ho(const rrc_conn_recfg_s& reconfig) { if (not ho_handler.launch(reconfig)) { - rrc_log->error("Unable to launch Handover Preparation procedure\n"); + logger.error("Unable to launch Handover Preparation procedure"); return false; } callback_list.add_proc(ho_handler); @@ -1055,7 +1038,7 @@ bool rrc::con_reconfig_ho(const rrc_conn_recfg_s& reconfig) void rrc::start_go_idle() { if (not idle_setter.launch()) { - rrc_log->info("Failed to set RRC to IDLE\n"); + logger.info("Failed to set RRC to IDLE"); return; } callback_list.add_proc(idle_setter); @@ -1096,7 +1079,7 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, const rrc_conn_recfg_s& reconfi con_reconfig_ho(reconfig); } else { if (not conn_recfg_proc.launch(reconfig)) { - rrc_log->error("Unable to launch Handover Preparation procedure\n"); + logger.error("Unable to launch Handover Preparation procedure"); return; } callback_list.add_proc(conn_recfg_proc); @@ -1115,7 +1098,7 @@ void rrc::rrc_connection_release(const std::string& cause) void rrc::leave_connected() { srslte::console("RRC IDLE\n"); - rrc_log->info("Leaving RRC_CONNECTED state\n"); + logger.info("Leaving RRC_CONNECTED state"); state = RRC_STATE_IDLE; drb_up = false; security_is_activated = false; @@ -1138,7 +1121,7 @@ void rrc::leave_connected() // 1> if leaving RRC_CONNECTED was not triggered by reception of the MobilityFromEUTRACommand message: // 2> enter RRC_IDLE by performing cell selection in accordance with the cell selection process, defined for the // case of leaving RRC_CONNECTED, as specified in TS 36.304 [4]; - rrc_log->info("Going RRC_IDLE\n"); + logger.info("Going RRC_IDLE"); if (phy->cell_is_camping()) { // Receive paging mac->pcch_start_rx(); @@ -1168,7 +1151,7 @@ void rrc::stop_timers() void rrc::start_con_restablishment(reest_cause_e cause) { if (not connection_reest.launch(cause)) { - rrc_log->info("Failed to launch connection re-establishment procedure\n"); + logger.info("Failed to launch connection re-establishment procedure"); } callback_list.add_proc(connection_reest); @@ -1227,7 +1210,6 @@ meas_cell_eutra* rrc::get_serving_cell() return &meas_cells.serving_cell(); } -#ifdef HAVE_5GNR std::set rrc::get_cells_nr(const uint32_t arfcn_nr) { return meas_cells_nr.get_neighbour_pcis(arfcn_nr); @@ -1244,7 +1226,6 @@ float rrc::get_cell_rsrq_nr(const uint32_t arfcn_nr, const uint32_t pci_nr) meas_cell_nr* c = meas_cells_nr.get_neighbour_cell_handle(arfcn_nr, pci_nr); return (c != nullptr) ? c->get_rsrq() : NAN; } -#endif /******************************************************************************* * @@ -1262,7 +1243,7 @@ void rrc::write_pdu_bcch_bch(unique_byte_buffer_t pdu) asn1::SRSASN_CODE err = bch_msg.unpack(bch_bref); if (err != asn1::SRSASN_SUCCESS) { - rrc_log->error("Could not unpack BCCH-BCH message.\n"); + logger.error("Could not unpack BCCH-BCH message."); return; } @@ -1286,14 +1267,14 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref); if (err != asn1::SRSASN_SUCCESS or dlsch_msg.msg.type().value != bcch_dl_sch_msg_type_c::types_opts::c1) { - rrc_log->error_hex(pdu->msg, pdu->N_bytes, "Could not unpack BCCH DL-SCH message (%d B).\n", pdu->N_bytes); + logger.error(pdu->msg, pdu->N_bytes, "Could not unpack BCCH DL-SCH message (%d B).", pdu->N_bytes); return; } log_rrc_message("BCCH-DLSCH", Rx, pdu.get(), dlsch_msg, dlsch_msg.msg.c1().type().to_string()); if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_c::c1_c_::types::sib_type1) { - rrc_log->info("Processing SIB1 (1/1)\n"); + logger.info("Processing SIB1 (1/1)"); meas_cells.serving_cell().set_sib1(dlsch_msg.msg.c1().sib_type1()); si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); handle_sib1(); @@ -1301,7 +1282,7 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) sys_info_r8_ies_s::sib_type_and_info_l_& sib_list = dlsch_msg.msg.c1().sys_info().crit_exts.sys_info_r8().sib_type_and_info; for (uint32_t i = 0; i < sib_list.size(); ++i) { - rrc_log->info("Processing SIB%d (%d/%d)\n", sib_list[i].type().to_number(), i, sib_list.size()); + logger.info("Processing SIB%d (%d/%d)", sib_list[i].type().to_number(), i, sib_list.size()); switch (sib_list[i].type().value) { case sib_info_item_c::types::sib2: if (not meas_cells.serving_cell().has_sib2()) { @@ -1325,7 +1306,7 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); break; default: - rrc_log->warning("SIB%d is not supported\n", sib_list[i].type().to_number()); + logger.warning("SIB%d is not supported", sib_list[i].type().to_number()); } } } @@ -1334,17 +1315,17 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) void rrc::handle_sib1() { const sib_type1_s* sib1 = meas_cells.serving_cell().sib1ptr(); - rrc_log->info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d\n", - meas_cells.serving_cell().get_cell_id() & 0xfff, - sib1->si_win_len.to_number(), - sib1->sched_info_list[0].si_periodicity.to_number()); + logger.info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d", + meas_cells.serving_cell().get_cell_id() & 0xfff, + sib1->si_win_len.to_number(), + sib1->sched_info_list[0].si_periodicity.to_number()); // Print SIB scheduling info for (uint32_t i = 0; i < sib1->sched_info_list.size(); ++i) { si_periodicity_r12_e p = sib1->sched_info_list[i].si_periodicity; for (uint32_t j = 0; j < sib1->sched_info_list[i].sib_map_info.size(); ++j) { sib_type_e t = sib1->sched_info_list[i].sib_map_info[j]; - rrc_log->debug("SIB scheduling info, sib_type=%d, si_periodicity=%d\n", t.to_number(), p.to_number()); + logger.debug("SIB scheduling info, sib_type=%d, si_periodicity=%d", t.to_number(), p.to_number()); } } @@ -1359,7 +1340,7 @@ void rrc::handle_sib1() void rrc::handle_sib2() { - rrc_log->info("SIB2 received\n"); + logger.info("SIB2 received"); const sib_type2_s* sib2 = meas_cells.serving_cell().sib2ptr(); @@ -1417,18 +1398,18 @@ void rrc::handle_sib2() N310 = sib2->ue_timers_and_consts.n310.to_number(); N311 = sib2->ue_timers_and_consts.n311.to_number(); - rrc_log->info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d\n", - N310, - N311, - t300.duration(), - t301.duration(), - t310.duration(), - t311.duration()); + logger.info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d", + N310, + N311, + t300.duration(), + t301.duration(), + t310.duration(), + t311.duration()); } void rrc::handle_sib3() { - rrc_log->info("SIB3 received\n"); + logger.info("SIB3 received"); const sib_type3_s* sib3 = meas_cells.serving_cell().sib3ptr(); @@ -1449,7 +1430,7 @@ void rrc::handle_sib3() void rrc::handle_sib13() { - rrc_log->info("SIB13 received\n"); + logger.info("SIB13 received"); const sib_type13_r9_s* sib13 = meas_cells.serving_cell().sib13ptr(); @@ -1482,21 +1463,21 @@ void rrc::paging_completed(bool outcome) void rrc::process_pcch(unique_byte_buffer_t pdu) { if (pdu->N_bytes <= 0 or pdu->N_bytes >= SRSLTE_MAX_BUFFER_SIZE_BITS) { - rrc_log->error_hex(pdu->msg, pdu->N_bytes, "Dropping PCCH message with %d B\n", pdu->N_bytes); + logger.error(pdu->msg, pdu->N_bytes, "Dropping PCCH message with %d B", pdu->N_bytes); return; } pcch_msg_s pcch_msg; asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (pcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or pcch_msg.msg.type().value != pcch_msg_type_c::types_opts::c1) { - rrc_log->error_hex(pdu->msg, pdu->N_bytes, "Failed to unpack PCCH message (%d B)\n", pdu->N_bytes); + logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack PCCH message (%d B)", pdu->N_bytes); return; } log_rrc_message("PCCH", Rx, pdu.get(), pcch_msg, pcch_msg.msg.c1().type().to_string()); if (not ue_identity_configured) { - rrc_log->warning("Received paging message but no ue-Identity is configured\n"); + logger.warning("Received paging message but no ue-Identity is configured"); return; } @@ -1506,7 +1487,7 @@ void rrc::process_pcch(unique_byte_buffer_t pdu) } if (not pcch_processor.launch(*paging)) { - rrc_log->error("Failed to launch process PCCH procedure\n"); + logger.error("Failed to launch process PCCH procedure"); return; } @@ -1531,7 +1512,7 @@ void rrc::parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (meas_cells.serving_cell().mcch.unpack(bref) != asn1::SRSASN_SUCCESS or meas_cells.serving_cell().mcch.msg.type().value != mcch_msg_type_c::types_opts::c1) { - rrc_log->error("Failed to unpack MCCH message\n"); + logger.error("Failed to unpack MCCH message"); return; } meas_cells.serving_cell().has_mcch = true; @@ -1539,7 +1520,7 @@ void rrc::parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) log_rrc_message( "MCH", Rx, pdu.get(), meas_cells.serving_cell().mcch, meas_cells.serving_cell().mcch.msg.c1().type().to_string()); if (args.mbms_service_id >= 0) { - rrc_log->info("Attempting to auto-start MBMS service %d\n", args.mbms_service_id); + logger.info("Attempting to auto-start MBMS service %d", args.mbms_service_id); mbms_service_start(args.mbms_service_id, args.mbms_service_port); } } @@ -1555,9 +1536,9 @@ void rrc::parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) void rrc::send_ul_ccch_msg(const ul_ccch_msg_s& msg) { // Reset and reuse sdu buffer if provided - unique_byte_buffer_t pdcp_buf = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdcp_buf = srslte::make_byte_buffer(); if (not pdcp_buf.get()) { - rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack()."); return; } @@ -1575,7 +1556,7 @@ void rrc::send_ul_ccch_msg(const ul_ccch_msg_s& msg) ue_cri_ptr[nbytes - i - 1] = pdcp_buf->msg[i]; } - rrc_log->debug("Setting UE contention resolution ID: %" PRIu64 "\n", uecri); + logger.debug("Setting UE contention resolution ID: %" PRIu64 "", uecri); mac->set_contention_id(uecri); uint32_t lcid = RB_ID_SRB0; @@ -1587,9 +1568,9 @@ void rrc::send_ul_ccch_msg(const ul_ccch_msg_s& msg) void rrc::send_ul_dcch_msg(uint32_t lcid, const ul_dcch_msg_s& msg) { // Reset and reuse sdu buffer if provided - unique_byte_buffer_t pdcp_buf = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdcp_buf = srslte::make_byte_buffer(); if (not pdcp_buf.get()) { - rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack()."); return; } @@ -1607,7 +1588,7 @@ void rrc::send_ul_dcch_msg(uint32_t lcid, const ul_dcch_msg_s& msg) void rrc::write_sdu(srslte::unique_byte_buffer_t sdu) { if (state == RRC_STATE_IDLE) { - rrc_log->warning("Received ULInformationTransfer SDU when in IDLE\n"); + logger.warning("Received ULInformationTransfer SDU when in IDLE"); return; } send_ul_info_transfer(std::move(sdu)); @@ -1620,7 +1601,7 @@ void rrc::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) void rrc::process_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { - rrc_log->debug("RX PDU, LCID: %d\n", lcid); + logger.debug("RX PDU, LCID: %d", lcid); switch (lcid) { case RB_ID_SRB0: parse_dl_ccch(std::move(pdu)); @@ -1630,7 +1611,7 @@ void rrc::process_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) parse_dl_dcch(lcid, std::move(pdu)); break; default: - rrc_log->error("RX PDU with invalid bearer id: %d\n", lcid); + logger.error("RX PDU with invalid bearer id: %d", lcid); break; } } @@ -1641,7 +1622,7 @@ void rrc::parse_dl_ccch(unique_byte_buffer_t pdu) asn1::rrc::dl_ccch_msg_s dl_ccch_msg; if (dl_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or dl_ccch_msg.msg.type().value != dl_ccch_msg_type_c::types_opts::c1) { - rrc_log->error_hex(pdu->msg, pdu->N_bytes, "Failed to unpack DL-CCCH message (%d B)\n", pdu->N_bytes); + logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack DL-CCCH message (%d B)", pdu->N_bytes); return; } log_rrc_message(get_rb_name(RB_ID_SRB0).c_str(), Rx, pdu.get(), dl_ccch_msg, dl_ccch_msg.msg.c1().type().to_string()); @@ -1651,7 +1632,7 @@ void rrc::parse_dl_ccch(unique_byte_buffer_t pdu) case dl_ccch_msg_type_c::c1_c_::types::rrc_conn_reject: { // 5.3.3.8 rrc_conn_reject_r8_ies_s* reject_r8 = &c1->rrc_conn_reject().crit_exts.c1().rrc_conn_reject_r8(); - rrc_log->info("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time); + logger.info("Received ConnectionReject. Wait time: %d", reject_r8->wait_time); srslte::console("Received ConnectionReject. Wait time: %d\n", reject_r8->wait_time); t300.stop(); @@ -1684,7 +1665,7 @@ void rrc::parse_dl_ccch(unique_byte_buffer_t pdu) connection_reest.trigger(c1->rrc_conn_reest_reject()); break; default: - rrc_log->error("The provided DL-CCCH message type is not recognized\n"); + logger.error("The provided DL-CCCH message type is not recognized"); break; } } @@ -1695,7 +1676,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) asn1::rrc::dl_dcch_msg_s dl_dcch_msg; if (dl_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or dl_dcch_msg.msg.type().value != dl_dcch_msg_type_c::types_opts::c1) { - rrc_log->error_hex(pdu->msg, pdu->N_bytes, "Failed to unpack DL-DCCH message (%d B)\n", pdu->N_bytes); + logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack DL-DCCH message (%d B)", pdu->N_bytes); return; } log_rrc_message(get_rb_name(lcid).c_str(), Rx, pdu.get(), dl_dcch_msg, dl_dcch_msg.msg.c1().type().to_string()); @@ -1703,9 +1684,9 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1(); switch (dl_dcch_msg.msg.c1().type().value) { case dl_dcch_msg_type_c::c1_c_::types::dl_info_transfer: - pdu = srslte::allocate_unique_buffer(*pool, true); + pdu = srslte::make_byte_buffer(); if (!pdu.get()) { - rrc_log->error("Fatal error: out of buffers in pool\n"); + logger.error("Fatal error: out of buffers in pool"); return; } pdu->N_bytes = c1->dl_info_transfer().crit_exts.c1().dl_info_transfer_r8().ded_info_type.ded_info_nas().size(); @@ -1726,9 +1707,9 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) .security_mode_cmd_r8() .security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm.value; - rrc_log->info("Received Security Mode Command eea: %s, eia: %s\n", - ciphering_algorithm_id_text[sec_cfg.cipher_algo], - integrity_algorithm_id_text[sec_cfg.integ_algo]); + logger.info("Received Security Mode Command eea: %s, eia: %s", + ciphering_algorithm_id_text[sec_cfg.cipher_algo], + integrity_algorithm_id_text[sec_cfg.integ_algo]); // Generate AS security keys generate_as_keys(); @@ -1754,7 +1735,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) rrc_connection_release(c1->rrc_conn_release().crit_exts.c1().rrc_conn_release_r8().release_cause.to_string()); break; default: - rrc_log->error("The provided DL-CCCH message type is not recognized or supported\n"); + logger.error("The provided DL-CCCH message type is not recognized or supported"); break; } } @@ -1764,12 +1745,12 @@ void rrc::generate_as_keys(void) { uint8_t k_asme[32] = {}; nas->get_k_asme(k_asme, 32); - rrc_log->debug_hex(k_asme, 32, "UE K_asme"); - rrc_log->debug("Generating K_enb with UL NAS COUNT: %d\n", nas->get_k_enb_count()); + logger.debug(k_asme, 32, "UE K_asme"); + logger.debug("Generating K_enb with UL NAS COUNT: %d", nas->get_k_enb_count()); usim->generate_as_keys(k_asme, nas->get_k_enb_count(), &sec_cfg); - rrc_log->info_hex(sec_cfg.k_rrc_enc.data(), 32, "RRC encryption key - k_rrc_enc"); - rrc_log->info_hex(sec_cfg.k_rrc_int.data(), 32, "RRC integrity key - k_rrc_int"); - rrc_log->info_hex(sec_cfg.k_up_enc.data(), 32, "UP encryption key - k_up_enc"); + logger.info(sec_cfg.k_rrc_enc.data(), 32, "RRC encryption key - k_rrc_enc"); + logger.info(sec_cfg.k_rrc_int.data(), 32, "RRC integrity key - k_rrc_int"); + logger.info(sec_cfg.k_up_enc.data(), 32, "UP encryption key - k_up_enc"); } /******************************************************************************* @@ -1785,12 +1766,12 @@ void rrc::enable_capabilities() { bool enable_ul_64 = args.ue_category >= 5 && meas_cells.serving_cell().sib2ptr()->rr_cfg_common.pusch_cfg_common.pusch_cfg_basic.enable64_qam; - rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); + logger.info("%s 64QAM PUSCH", enable_ul_64 ? "Enabling" : "Disabling"); } void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) { - rrc_log->debug("Preparing UE Capability Info\n"); + logger.debug("Preparing UE Capability Info"); ul_dcch_msg_s ul_dcch_msg; ue_cap_info_r8_ies_s* info = &ul_dcch_msg.msg.set_c1().set_ue_cap_info().crit_exts.set_c1().set_ue_cap_info_r8(); @@ -1808,11 +1789,11 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) // Check UE config arguments bounds if (args.release < SRSLTE_RELEASE_MIN || args.release > SRSLTE_RELEASE_MAX) { uint32_t new_release = SRSLTE_MIN(SRSLTE_RELEASE_MAX, SRSLTE_MAX(SRSLTE_RELEASE_MIN, args.release)); - rrc_log->error("Release is %d. It is out of bounds (%d ... %d), setting it to %d\n", - args.release, - SRSLTE_RELEASE_MIN, - SRSLTE_RELEASE_MAX, - new_release); + logger.error("Release is %d. It is out of bounds (%d ... %d), setting it to %d", + args.release, + SRSLTE_RELEASE_MIN, + SRSLTE_RELEASE_MAX, + new_release); args.release = new_release; } @@ -1820,11 +1801,11 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) if (args.ue_category < SRSLTE_UE_CATEGORY_MIN || args.ue_category > SRSLTE_UE_CATEGORY_MAX) { uint32_t new_category = SRSLTE_MIN(SRSLTE_UE_CATEGORY_MAX, SRSLTE_MAX(SRSLTE_UE_CATEGORY_MIN, args.ue_category)); - rrc_log->error("UE Category is %d. It is out of bounds (%d ... %d), setting it to %d\n", - args.ue_category, - SRSLTE_UE_CATEGORY_MIN, - SRSLTE_UE_CATEGORY_MAX, - new_category); + logger.error("UE Category is %d. It is out of bounds (%d ... %d), setting it to %d", + args.ue_category, + SRSLTE_UE_CATEGORY_MIN, + SRSLTE_UE_CATEGORY_MAX, + new_category); args.ue_category = new_category; } @@ -1880,7 +1861,6 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) } if (args.release > 9) { - phy_layer_params_v1020_s phy_layer_params_v1020; phy_layer_params_v1020.two_ant_ports_for_pucch_r10_present = false; phy_layer_params_v1020.tm9_with_minus8_tx_fdd_r10_present = false; @@ -2087,27 +2067,24 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) rat_idx++; } -#ifdef HAVE_5GNR else if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request[i] == rat_type_e::eutra_nr && has_nr_dc()) { info->ue_cap_rat_container_list[rat_idx] = get_eutra_nr_capabilities(); - rrc_log->info("Including EUTRA-NR capabilities in UE Capability Info (%d B)\n", - info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.size()); + logger.info("Including EUTRA-NR capabilities in UE Capability Info (%d B)", + info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.size()); rat_idx++; } else if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request[i] == rat_type_e::nr && has_nr_dc()) { info->ue_cap_rat_container_list[rat_idx] = get_nr_capabilities(); - rrc_log->info("Including NR capabilities in UE Capability Info (%d B)\n", - info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.size()); + logger.info("Including NR capabilities in UE Capability Info (%d B)", + info->ue_cap_rat_container_list[rat_idx].ue_cap_rat_container.size()); rat_idx++; } -#endif else { - rrc_log->error("RAT Type of UE Cap request not supported or not configured\n"); + logger.error("RAT Type of UE Cap request not supported or not configured"); } } // resize container back to the actually filled items info->ue_cap_rat_container_list.resize(rat_idx); -#ifdef HAVE_5GNR if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext_present) { if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext.non_crit_ext_present) { if (enquiry.crit_exts.c1().ue_cap_enquiry_r8().non_crit_ext.non_crit_ext.non_crit_ext_present) { @@ -2119,14 +2096,13 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) .ue_cap_enquiry_r8() .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext .requested_freq_bands_nr_mrdc_r15_present) { - rrc_log->debug("Requested Freq Bands NR MRDC R15 present\n"); + logger.debug("Requested Freq Bands NR MRDC R15 present"); } } } } } } -#endif send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg); } @@ -2143,42 +2119,42 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) void rrc::log_rr_config_common() { - rrc_log->info("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n", - current_mac_cfg.rach_cfg.nof_preambles, - current_mac_cfg.rach_cfg.responseWindowSize, - current_mac_cfg.rach_cfg.contentionResolutionTimer); + logger.info("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms", + current_mac_cfg.rach_cfg.nof_preambles, + current_mac_cfg.rach_cfg.responseWindowSize, + current_mac_cfg.rach_cfg.contentionResolutionTimer); const srslte::phy_cfg_t& current_pcell = phy_ctrl->current_cell_config()[0]; - rrc_log->info("Set PUSCH ConfigCommon: P0_pusch=%f, DMRS cs=%d, delta_ss=%d, N_sb=%d\n", - current_pcell.ul_cfg.power_ctrl.p0_ue_pusch, - current_pcell.ul_cfg.dmrs.cyclic_shift, - current_pcell.ul_cfg.dmrs.delta_ss, - current_pcell.ul_cfg.hopping.n_sb); + logger.info("Set PUSCH ConfigCommon: P0_pusch=%f, DMRS cs=%d, delta_ss=%d, N_sb=%d", + current_pcell.ul_cfg.power_ctrl.p0_ue_pusch, + current_pcell.ul_cfg.dmrs.cyclic_shift, + current_pcell.ul_cfg.dmrs.delta_ss, + current_pcell.ul_cfg.hopping.n_sb); - rrc_log->info("Set PUCCH ConfigCommon: DeltaShift=%d, CyclicShift=%d, N1=%d, NRB=%d\n", - current_pcell.ul_cfg.pucch.delta_pucch_shift, - current_pcell.ul_cfg.pucch.N_cs, - current_pcell.ul_cfg.pucch.n1_pucch_an_cs[0][0], - current_pcell.ul_cfg.pucch.n_rb_2); + logger.info("Set PUCCH ConfigCommon: DeltaShift=%d, CyclicShift=%d, N1=%d, NRB=%d", + current_pcell.ul_cfg.pucch.delta_pucch_shift, + current_pcell.ul_cfg.pucch.N_cs, + current_pcell.ul_cfg.pucch.n1_pucch_an_cs[0][0], + current_pcell.ul_cfg.pucch.n_rb_2); - rrc_log->info("Set PRACH ConfigCommon: SeqIdx=%d, HS=%s, FreqOffset=%d, ZC=%d, ConfigIndex=%d\n", - current_pcell.prach_cfg.root_seq_idx, - current_pcell.prach_cfg.hs_flag ? "yes" : "no", - current_pcell.prach_cfg.freq_offset, - current_pcell.prach_cfg.zero_corr_zone, - current_pcell.prach_cfg.config_idx); + logger.info("Set PRACH ConfigCommon: SeqIdx=%d, HS=%s, FreqOffset=%d, ZC=%d, ConfigIndex=%d", + current_pcell.prach_cfg.root_seq_idx, + current_pcell.prach_cfg.hs_flag ? "yes" : "no", + current_pcell.prach_cfg.freq_offset, + current_pcell.prach_cfg.zero_corr_zone, + current_pcell.prach_cfg.config_idx); if (current_pcell.ul_cfg.srs.configured) { - rrc_log->info("Set SRS ConfigCommon: BW-Configuration=%d, SF-Configuration=%d, Simult-ACKNACK=%s\n", - current_pcell.ul_cfg.srs.bw_cfg, - current_pcell.ul_cfg.srs.subframe_config, - current_pcell.ul_cfg.srs.simul_ack ? "yes" : "no"); + logger.info("Set SRS ConfigCommon: BW-Configuration=%d, SF-Configuration=%d, Simult-ACKNACK=%s", + current_pcell.ul_cfg.srs.bw_cfg, + current_pcell.ul_cfg.srs.subframe_config, + current_pcell.ul_cfg.srs.simul_ack ? "yes" : "no"); } } void rrc::apply_rr_config_common(rr_cfg_common_s* config, bool send_lower_layers) { - rrc_log->info("Applying MAC/PHY config common\n"); + logger.info("Applying MAC/PHY config common"); if (config->rach_cfg_common_present) { set_mac_cfg_t_rach_cfg_common(¤t_mac_cfg, config->rach_cfg_common); @@ -2223,34 +2199,30 @@ void rrc::apply_rr_config_common(rr_cfg_common_s* config, bool send_lower_layers void rrc::log_phy_config_dedicated() { - if (!rrc_log) { - return; - } - srslte::phy_cfg_t& current_pcell = phy_ctrl->current_cell_config()[0]; if (current_pcell.dl_cfg.cqi_report.periodic_configured) { - rrc_log->info("Set cqi-PUCCH-ResourceIndex=%d, cqi-pmi-ConfigIndex=%d, cqi-FormatIndicatorPeriodic=%d\n", - current_pcell.ul_cfg.pucch.n_pucch_2, - current_pcell.dl_cfg.cqi_report.pmi_idx, - current_pcell.dl_cfg.cqi_report.periodic_mode); + logger.info("Set cqi-PUCCH-ResourceIndex=%d, cqi-pmi-ConfigIndex=%d, cqi-FormatIndicatorPeriodic=%d", + current_pcell.ul_cfg.pucch.n_pucch_2, + current_pcell.dl_cfg.cqi_report.pmi_idx, + current_pcell.dl_cfg.cqi_report.periodic_mode); } if (current_pcell.dl_cfg.cqi_report.aperiodic_configured) { - rrc_log->info("Set cqi-ReportModeAperiodic=%d\n", current_pcell.dl_cfg.cqi_report.aperiodic_mode); + logger.info("Set cqi-ReportModeAperiodic=%d", current_pcell.dl_cfg.cqi_report.aperiodic_mode); } if (current_pcell.ul_cfg.pucch.sr_configured) { - rrc_log->info("Set PHY config ded: SR-n_pucch=%d, SR-ConfigIndex=%d", - current_pcell.ul_cfg.pucch.n_pucch_sr, - current_pcell.ul_cfg.pucch.I_sr); + logger.info("Set PHY config ded: SR-n_pucch=%d, SR-ConfigIndex=%d", + current_pcell.ul_cfg.pucch.n_pucch_sr, + current_pcell.ul_cfg.pucch.I_sr); } if (current_pcell.ul_cfg.srs.configured) { - rrc_log->info("Set PHY config ded: SRS-ConfigIndex=%d, SRS-bw=%d, SRS-Nrcc=%d, SRS-hop=%d, SRS-Ncs=%d\n", - current_pcell.ul_cfg.srs.I_srs, - current_pcell.ul_cfg.srs.B, - current_pcell.ul_cfg.srs.n_rrc, - current_pcell.ul_cfg.srs.b_hop, - current_pcell.ul_cfg.srs.n_srs); + logger.info("Set PHY config ded: SRS-ConfigIndex=%d, SRS-bw=%d, SRS-Nrcc=%d, SRS-hop=%d, SRS-Ncs=%d", + current_pcell.ul_cfg.srs.I_srs, + current_pcell.ul_cfg.srs.B, + current_pcell.ul_cfg.srs.n_rrc, + current_pcell.ul_cfg.srs.b_hop, + current_pcell.ul_cfg.srs.n_srs); } } @@ -2260,14 +2232,14 @@ void rrc::set_phy_default() if (phy_ctrl != nullptr) { phy_ctrl->set_phy_to_default(); } else { - rrc_log->info("RRC not initialized. Skipping default PHY config.\n"); + logger.info("RRC not initialized. Skipping default PHY config."); } } // Apply provided PHY config void rrc::apply_phy_config_dedicated(const phys_cfg_ded_s& phy_cnfg, bool is_handover) { - rrc_log->info("Applying PHY config dedicated\n"); + logger.info("Applying PHY config dedicated"); srslte::phy_cfg_t& current_pcell = phy_ctrl->current_cell_config()[0]; set_phy_cfg_t_dedicated_cfg(¤t_pcell, phy_cnfg); @@ -2288,11 +2260,11 @@ void rrc::apply_phy_scell_config(const scell_to_add_mod_r10_s& scell_config, boo uint32_t earfcn = 0; if (phy == nullptr) { - rrc_log->info("RRC not initialized. Skipping PHY config.\n"); + logger.info("RRC not initialized. Skipping PHY config."); return; } - rrc_log->info("Applying PHY config to scell\n"); + logger.info("Applying PHY config to scell"); // Initialise default parameters from primary cell earfcn = meas_cells.serving_cell().get_earfcn(); @@ -2342,33 +2314,32 @@ void rrc::apply_phy_scell_config(const scell_to_add_mod_r10_s& scell_config, boo } if (!phy->set_scell(scell, scell_config.scell_idx_r10, earfcn)) { - rrc_log->error("Adding SCell cc_idx=%d\n", scell_config.scell_idx_r10); + logger.error("Adding SCell cc_idx=%d", scell_config.scell_idx_r10); } else if (!phy_ctrl->set_cell_config(scell_cfg, scell_config.scell_idx_r10)) { - rrc_log->error("Setting SCell configuration for cc_idx=%d\n", scell_config.scell_idx_r10); + logger.error("Setting SCell configuration for cc_idx=%d", scell_config.scell_idx_r10); } } void rrc::log_mac_config_dedicated() { - rrc_log->info( - "Set MAC main config: harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d, SR %s (dsr-TransMax=%d)\n", - current_mac_cfg.harq_cfg.max_harq_msg3_tx, - current_mac_cfg.bsr_cfg.retx_timer, - current_mac_cfg.bsr_cfg.periodic_timer, - current_mac_cfg.sr_cfg.enabled ? "enabled" : "disabled", - current_mac_cfg.sr_cfg.dsr_transmax); + logger.info("Set MAC main config: harq-MaxReTX=%d, bsr-TimerReTX=%d, bsr-TimerPeriodic=%d, SR %s (dsr-TransMax=%d)", + current_mac_cfg.harq_cfg.max_harq_msg3_tx, + current_mac_cfg.bsr_cfg.retx_timer, + current_mac_cfg.bsr_cfg.periodic_timer, + current_mac_cfg.sr_cfg.enabled ? "enabled" : "disabled", + current_mac_cfg.sr_cfg.dsr_transmax); if (current_mac_cfg.phr_cfg.enabled) { - rrc_log->info("Set MAC PHR config: periodicPHR-Timer=%d, prohibitPHR-Timer=%d, dl-PathlossChange=%d\n", - current_mac_cfg.phr_cfg.periodic_timer, - current_mac_cfg.phr_cfg.prohibit_timer, - current_mac_cfg.phr_cfg.db_pathloss_change); + logger.info("Set MAC PHR config: periodicPHR-Timer=%d, prohibitPHR-Timer=%d, dl-PathlossChange=%d", + current_mac_cfg.phr_cfg.periodic_timer, + current_mac_cfg.phr_cfg.prohibit_timer, + current_mac_cfg.phr_cfg.db_pathloss_change); } } // 3GPP 36.331 v10 9.2.2 Default MAC main configuration void rrc::apply_mac_config_dedicated_default() { - rrc_log->info("Setting MAC default configuration\n"); + logger.info("Setting MAC default configuration"); current_mac_cfg.set_mac_main_cfg_default(); mac->set_config(current_mac_cfg); log_mac_config_dedicated(); @@ -2391,7 +2362,7 @@ bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg, bool is_handover) } } - rrc_log->info("Applying MAC config dedicated\n"); + logger.info("Applying MAC config dedicated"); if (cnfg->mac_main_cfg_present) { if (cnfg->mac_main_cfg.type() == rr_cfg_ded_s::mac_main_cfg_c_::types::default_value) { @@ -2418,13 +2389,13 @@ bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg, bool is_handover) N310 = cnfg->rlf_timers_and_consts_r9->setup().n310_r9.to_number(); N311 = cnfg->rlf_timers_and_consts_r9->setup().n311_r9.to_number(); - rrc_log->info("Updated Constants and Timers: N310=%d, N311=%d, t300=%u, t301=%u, t310=%u, t311=%u\n", - N310, - N311, - t300.duration(), - t301.duration(), - t310.duration(), - t311.duration()); + logger.info("Updated Constants and Timers: N310=%d, N311=%d, t300=%u, t301=%u, t310=%u, t311=%u", + N310, + N311, + t300.duration(), + t301.duration(), + t310.duration(), + t311.duration()); } for (uint32_t i = 0; i < cnfg->srb_to_add_mod_list.size(); i++) { // TODO: handle SRB modification @@ -2442,7 +2413,7 @@ bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg, bool is_handover) bool rrc::apply_rr_config_dedicated_on_ho_complete(const rr_cfg_ded_s& cnfg) { - rrc_log->info("Applying MAC/PHY config dedicated on HO complete\n"); + logger.info("Applying MAC/PHY config dedicated on HO complete"); // Apply SR+CQI configuration to PHY if (cnfg.phys_cfg_ded_present) { @@ -2556,7 +2527,7 @@ void rrc::handle_con_setup(const rrc_conn_setup_s& setup) if (dedicated_info_nas.get()) { send_con_setup_complete(std::move(dedicated_info_nas)); } else { - rrc_log->error("Pending to transmit a ConnectionSetupComplete but no dedicatedInfoNAS was in queue\n"); + logger.error("Pending to transmit a ConnectionSetupComplete but no dedicatedInfoNAS was in queue"); } } @@ -2593,7 +2564,7 @@ void rrc::add_srb(const srb_to_add_mod_s& srb_cnfg) // Set default SRB values as defined in Table 9.2.1 switch (srb_cnfg.srb_id) { case RB_ID_SRB0: - rrc_log->error("Setting SRB0: Should not be set by RRC\n"); + logger.error("Setting SRB0: Should not be set by RRC"); break; case RB_ID_SRB1: priority = 1; @@ -2623,13 +2594,13 @@ void rrc::add_srb(const srb_to_add_mod_s& srb_cnfg) } srbs[srb_cnfg.srb_id] = srb_cnfg; - rrc_log->info("Added radio bearer %s\n", get_rb_name(srb_cnfg.srb_id).c_str()); + logger.info("Added radio bearer %s", get_rb_name(srb_cnfg.srb_id).c_str()); } void rrc::add_drb(const drb_to_add_mod_s& drb_cnfg) { if (!drb_cnfg.pdcp_cfg_present || !drb_cnfg.rlc_cfg_present || !drb_cnfg.lc_ch_cfg_present) { - rrc_log->error("Cannot add DRB - incomplete configuration\n"); + logger.error("Cannot add DRB - incomplete configuration"); return; } uint32_t lcid = 0; @@ -2637,7 +2608,7 @@ void rrc::add_drb(const drb_to_add_mod_s& drb_cnfg) lcid = drb_cnfg.lc_ch_id; } else { lcid = RB_ID_SRB2 + drb_cnfg.drb_id; - rrc_log->warning("LCID not present, using %d\n", lcid); + logger.warning("LCID not present, using %d", lcid); } // Setup RLC @@ -2658,7 +2629,7 @@ void rrc::add_drb(const drb_to_add_mod_s& drb_cnfg) if (drb_cnfg.lc_ch_cfg.ul_specific_params.lc_ch_group_present) { log_chan_group = drb_cnfg.lc_ch_cfg.ul_specific_params.lc_ch_group; } else { - rrc_log->warning("LCG not present, setting to 0\n"); + logger.warning("LCG not present, setting to 0"); } priority = drb_cnfg.lc_ch_cfg.ul_specific_params.prio; prioritized_bit_rate = drb_cnfg.lc_ch_cfg.ul_specific_params.prioritised_bit_rate.to_number(); @@ -2668,16 +2639,16 @@ void rrc::add_drb(const drb_to_add_mod_s& drb_cnfg) drbs[drb_cnfg.drb_id] = drb_cnfg; drb_up = true; - rrc_log->info("Added DRB Id %d (LCID=%d)\n", drb_cnfg.drb_id, lcid); + logger.info("Added DRB Id %d (LCID=%d)", drb_cnfg.drb_id, lcid); } void rrc::release_drb(uint32_t drb_id) { if (drbs.find(drb_id) != drbs.end()) { - rrc_log->info("Releasing DRB Id %d\n", drb_id); + logger.info("Releasing DRB Id %d", drb_id); drbs.erase(drb_id); } else { - rrc_log->error("Couldn't release DRB Id %d. Doesn't exist.\n", drb_id); + logger.error("Couldn't release DRB Id %d. Doesn't exist.", drb_id); } } @@ -2692,7 +2663,7 @@ uint32_t rrc::get_lcid_for_eps_bearer(const uint32_t& eps_bearer_id) lcid = drb_cnfg.lc_ch_id; } else { lcid = RB_ID_SRB2 + drb_cnfg.drb_id; - rrc_log->warning("LCID not present, using %d\n", lcid); + logger.warning("LCID not present, using %d", lcid); } return lcid; } @@ -2711,10 +2682,8 @@ uint32_t rrc::get_drb_id_for_eps_bearer(const uint32_t& eps_bearer_id) bool rrc::has_nr_dc() { bool has_nr_dc = false; -#ifdef HAVE_5GNR if (args.release >= 15) has_nr_dc = true; -#endif return has_nr_dc; } @@ -2723,7 +2692,7 @@ void rrc::add_mrb(uint32_t lcid, uint32_t port) gw->add_mch_port(lcid, port); rlc->add_bearer_mrb(lcid); mac->mch_start_rx(lcid); - rrc_log->info("Added MRB bearer for lcid:%d\n", lcid); + logger.info("Added MRB bearer for lcid:%d", lcid); } // PHY CONFIG DEDICATED Defaults (3GPP 36.331 v10 9.2.4) @@ -2732,7 +2701,7 @@ void rrc::set_phy_default_pucch_srs() if (phy_ctrl != nullptr) { phy_ctrl->set_phy_to_default_pucch_srs(); } else { - rrc_log->info("RRC not initialized. Skipping default PUCCH/SRS config.\n"); + logger.info("RRC not initialized. Skipping default PUCCH/SRS config."); } // SR configuration affects to MAC SR too @@ -2763,11 +2732,7 @@ asn1::rrc::ue_cap_rat_container_s rrc::get_eutra_nr_capabilities() { srslte::byte_buffer_t caps_buf; asn1::rrc::ue_cap_rat_container_s cap; -#ifdef HAVE_5GNR rrc_nr->get_eutra_nr_capabilities(&caps_buf); -#else - rrc_log->error("Not able to access get_eutra_nr_capabilities function\n"); -#endif cap.rat_type = asn1::rrc::rat_type_e::eutra_nr; cap.ue_cap_rat_container.resize(caps_buf.N_bytes); memcpy(cap.ue_cap_rat_container.data(), caps_buf.msg, caps_buf.N_bytes); @@ -2778,11 +2743,7 @@ asn1::rrc::ue_cap_rat_container_s rrc::get_nr_capabilities() { srslte::byte_buffer_t caps_buf; asn1::rrc::ue_cap_rat_container_s cap; -#ifdef HAVE_5GNR rrc_nr->get_nr_capabilities(&caps_buf); -#else - rrc_log->error("Not able to access get_nr_capabilities function\n"); -#endif cap.rat_type = asn1::rrc::rat_type_e::nr; cap.ue_cap_rat_container.resize(caps_buf.N_bytes); memcpy(cap.ue_cap_rat_container.data(), caps_buf.msg, caps_buf.N_bytes); diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index 9f9550134..f7f370cdc 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -103,7 +103,6 @@ bool meas_cell::has_sib(uint32_t index) const return false; } -#ifdef HAVE_5GNR std::string meas_cell_nr::to_string() const { char buf[256]; @@ -117,7 +116,6 @@ std::string meas_cell_nr::to_string() const get_cfo_hz()); return std::string{buf}; } -#endif std::string meas_cell_eutra::to_string() const { @@ -178,8 +176,7 @@ uint16_t meas_cell_eutra::get_mnc() const ********************************************/ template meas_cell_list::meas_cell_list(srslte::task_sched_handle task_sched_) : - serv_cell(new T(task_sched_.get_unique_timer())), - task_sched(task_sched_) + serv_cell(new T(task_sched_.get_unique_timer())), task_sched(task_sched_) {} template @@ -226,12 +223,12 @@ bool meas_cell_list::add_neighbour_cell_unsorted(unique_meas_cell new_cell) { // Make sure cell is valid if (!new_cell->is_valid()) { - log_h->error("Trying to add cell %s but is not valid", new_cell->to_string().c_str()); + logger.error("Trying to add cell %s but is not valid", new_cell->to_string().c_str()); return false; } if (is_same_cell(serving_cell(), *new_cell)) { - log_h->info("Added neighbour cell %s is serving cell\n", new_cell->to_string().c_str()); + logger.info("Added neighbour cell %s is serving cell", new_cell->to_string().c_str()); serv_cell = std::move(new_cell); return true; } @@ -242,22 +239,22 @@ bool meas_cell_list::add_neighbour_cell_unsorted(unique_meas_cell new_cell) if (std::isnormal(new_cell.get()->get_rsrp())) { existing_cell->set_rsrp(new_cell.get()->get_rsrp()); } - log_h->info("Updated neighbour cell %s rsrp=%f\n", new_cell->to_string().c_str(), new_cell.get()->get_rsrp()); + logger.info("Updated neighbour cell %s rsrp=%f", new_cell->to_string().c_str(), new_cell.get()->get_rsrp()); return true; } if (neighbour_cells.size() >= MAX_NEIGHBOUR_CELLS) { // If there isn't space, keep the strongest only if (not new_cell->greater(neighbour_cells.back().get())) { - log_h->warning("Could not add cell %s: no space in neighbours\n", new_cell->to_string().c_str()); + logger.warning("Could not add cell %s: no space in neighbours", new_cell->to_string().c_str()); return false; } rem_last_neighbour(); } - log_h->info( - "Adding neighbour cell %s, nof_neighbours=%zd\n", new_cell->to_string().c_str(), neighbour_cells.size() + 1); + logger.info( + "Adding neighbour cell %s, nof_neighbours=%zd", new_cell->to_string().c_str(), neighbour_cells.size() + 1); neighbour_cells.push_back(std::move(new_cell)); return true; } @@ -266,7 +263,7 @@ void meas_cell_list::rem_last_neighbour() { if (not neighbour_cells.empty()) { unique_meas_cell& c = neighbour_cells.back(); - log_h->debug("Delete cell %s from neighbor list.\n", c->to_string().c_str()); + logger.debug("Delete cell %s from neighbor list.", c->to_string().c_str()); neighbour_cells.pop_back(); } } @@ -310,9 +307,9 @@ void meas_cell_list::log_neighbour_cells() const } } } - log_h->debug("Neighbours: %s]\n", ordered); + logger.debug("Neighbours: %s]", ordered); } else { - log_h->debug("Neighbours: Empty\n"); + logger.debug("Neighbours: Empty"); } } @@ -322,7 +319,7 @@ void meas_cell_list::clean_neighbours() { for (auto it = neighbour_cells.begin(); it != neighbour_cells.end();) { if (it->get()->timer.is_expired()) { - log_h->info("Neighbour PCI=%d timed out. Deleting.\n", (*it)->get_pci()); + logger.info("Neighbour PCI=%d timed out. Deleting.", (*it)->get_pci()); it = neighbour_cells.erase(it); } else { ++it; @@ -378,19 +375,19 @@ int meas_cell_list::set_serving_cell(phy_cell_t phy_cell, bool discard_servin // Remove future serving cell from neighbours to make space for current serving cell unique_meas_cell new_serving_cell = remove_neighbour_cell(phy_cell.earfcn, phy_cell.pci); if (new_serving_cell == nullptr) { - log_h->error("Setting serving cell: Unknown cell with earfcn=%d, PCI=%d\n", phy_cell.earfcn, phy_cell.pci); + logger.error("Setting serving cell: Unknown cell with earfcn=%d, PCI=%d", phy_cell.earfcn, phy_cell.pci); return SRSLTE_ERROR; } // Set new serving cell std::swap(serv_cell, new_serving_cell); auto& old_serv_cell = new_serving_cell; - log_h->info("Setting serving cell %s, nof_neighbours=%zd\n", serv_cell->to_string().c_str(), nof_neighbours()); + logger.info("Setting serving cell %s, nof_neighbours=%zd", serv_cell->to_string().c_str(), nof_neighbours()); // Re-add old serving cell to list of neighbours if (old_serv_cell->is_valid() and not is_same_cell(phy_cell, *old_serv_cell) and not discard_serving) { if (not add_meas_cell(std::move(old_serv_cell))) { - log_h->info("Serving cell not added to list of neighbours. Worse than current neighbours\n"); + logger.info("Serving cell not added to list of neighbours. Worse than current neighbours"); } } return SRSLTE_SUCCESS; @@ -409,7 +406,7 @@ bool meas_cell_list::process_new_cell_meas(const std::vector& if (is_serving_cell) { c = serv_cell.get(); if (not serving_cell().is_valid()) { - log_h->error("MEAS: Received serving cell measurement but undefined or invalid\n"); + logger.error("MEAS: Received serving cell measurement but undefined or invalid"); continue; } } else { @@ -425,7 +422,7 @@ bool meas_cell_list::process_new_cell_meas(const std::vector& neighbour_added |= add_meas_cell(m); } - log_h->info("MEAS: New measurement %s cell: earfcn=%d, pci=%d, rsrp=%.2f dBm, cfo=%+.1f Hz\n", + logger.info("MEAS: New measurement %s cell: earfcn=%d, pci=%d, rsrp=%.2f dBm, cfo=%+.1f Hz", is_serving_cell ? "serving" : "neighbour", m.earfcn, m.pci, @@ -436,8 +433,6 @@ bool meas_cell_list::process_new_cell_meas(const std::vector& } template class meas_cell_list; -#ifdef HAVE_5GNR template class meas_cell_list; -#endif } // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_meas.cc b/srsue/src/stack/rrc/rrc_meas.cc index c13f7f9b2..df26193df 100644 --- a/srsue/src/stack/rrc/rrc_meas.cc +++ b/srsue/src/stack/rrc/rrc_meas.cc @@ -21,8 +21,8 @@ #include "srsue/hdr/stack/rrc/rrc_meas.h" #include "srslte/asn1/rrc/dl_dcch_msg.h" -#include "srsue/hdr/stack/rrc/rrc.h" #include "srslte/rrc/rrc_cfg_utils.h" +#include "srsue/hdr/stack/rrc/rrc.h" /************************************************************************ * @@ -82,9 +82,7 @@ void rrc::rrc_meas::update_phy() { std::list objects = meas_cfg.get_active_objects(); rrc_ptr->phy->meas_stop(); -#ifdef HAVE_5GNR rrc_ptr->rrc_nr->phy_meas_stop(); -#endif for (const auto& obj : objects) { switch (obj.meas_obj.type().value) { case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_eutra: { @@ -96,14 +94,12 @@ void rrc::rrc_meas::update_phy() rrc_ptr->phy->set_cells_to_meas(obj.meas_obj.meas_obj_eutra().carrier_freq, neighbour_pcis); break; } -#ifdef HAVE_5GNR case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_nr_r15: { rrc_ptr->rrc_nr->phy_set_cells_to_meas(obj.meas_obj.meas_obj_nr_r15().carrier_freq_r15); break; } -#endif default: - log_h->error("Not supported\n"); + logger.error("Not supported"); break; } // Concatenate cells indicated by enodeb with discovered neighbours @@ -262,7 +258,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s* { meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { - log_h->warning("MEAS: Serving cell not set when evaluating triggers\n"); + logger.warning("MEAS: Serving cell not set when evaluating triggers"); return; } @@ -280,7 +276,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s* for (auto& cell : var_meas.cell_triggered_list) { // report neighbour cells only if (cell.pci == serv_cell->get_pci() && cell.earfcn == serv_cell->get_earfcn()) { - log_h->info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f\n", + logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f", neigh_list.size(), cell.pci, var_meas.carrier_freq, @@ -318,7 +314,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s* rc.meas_result.rsrp_result = value_to_range(report_cfg_eutra_s::trigger_quant_opts::rsrp, rsrp_value); rc.meas_result.rsrq_result = value_to_range(report_cfg_eutra_s::trigger_quant_opts::rsrq, rsrq_value); - log_h->info("MEAS: Adding to report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f\n", + logger.info("MEAS: Adding to report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f", neigh_list.size(), rc.pci, var_meas.carrier_freq, @@ -357,7 +353,6 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s* } } } -#ifdef HAVE_5GNR void rrc::rrc_meas::var_meas_report_list::generate_report_interrat(meas_results_s* report, const uint32_t measId) { @@ -401,7 +396,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_interrat(meas_results_ value_to_range_nr(asn1::rrc::thres_nr_r15_c::types_opts::options::nr_sinr_r15, 1.0); } - log_h->info("MEAS: Adding to report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f\n", + logger.info("MEAS: Adding to report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f", neigh_list.size(), rc.pci_r15, var_meas.carrier_freq, @@ -441,13 +436,12 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_interrat(meas_results_ } } } -#endif /* Generate report procedure 5.5.5 */ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId) { meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { - log_h->warning("MEAS: Serving cell not set when evaluating triggers\n"); + logger.warning("MEAS: Serving cell not set when evaluating triggers"); return; } @@ -462,7 +456,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId) report->meas_result_pcell.rsrq_result = value_to_range(report_cfg_eutra_s::trigger_quant_opts::rsrq, serv_cell->get_rsrq()); - log_h->info("MEAS: Generate report MeasId=%d, Pcell rsrp=%f rsrq=%f\n", + logger.info("MEAS: Generate report MeasId=%d, Pcell rsrp=%f rsrq=%f", report->meas_id, serv_cell->get_rsrp(), serv_cell->get_rsrq()); @@ -472,19 +466,17 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId) switch (var_meas.report_type) { case eutra: { - log_h->debug("MEAS: Generate EUTRA report\n"); + logger.debug("MEAS: Generate EUTRA report"); generate_report_eutra(report, measId); break; } -#ifdef HAVE_5GNR case inter_rat: { - log_h->debug("MEAS: Generate INTER RAT NR report\n"); + logger.debug("MEAS: Generate INTER RAT NR report"); generate_report_interrat(report, measId); break; } -#endif default: - log_h->debug("MEAS: Not supported\n"); + logger.debug("MEAS: Not supported"); break; } @@ -639,7 +631,7 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra_removing_trigger(int32_t { meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { - log_h->warning("MEAS: Serving cell not set when reporting triggers\n"); + logger.warning("MEAS: Serving cell not set when reporting triggers"); return; } uint32_t serving_pci = serv_cell->get_pci(); @@ -649,7 +641,7 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra_removing_trigger(int32_t auto it = cells_triggered_list.begin(); while (it != cells_triggered_list.end()) { if (not rrc_ptr->has_neighbour_cell(it->earfcn, it->pci) and it->pci != serving_pci) { - log_h->debug("MEAS: Removing unknown PCI=%d from event trigger list\n", it->pci); + logger.debug("MEAS: Removing unknown PCI=%d from event trigger list", it->pci); it = cells_triggered_list.erase(it); meas_report->upd_measId(meas_id, cells_triggered_list); @@ -675,7 +667,6 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_eutra(uint32_t meas } } -#ifdef HAVE_5GNR void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_check_new(int32_t meas_id, report_cfg_inter_rat_s& report_cfg, meas_obj_nr_r15_s& meas_obj) @@ -702,7 +693,6 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_check_new(int32_t // initiate the measurement reporting procedure, as specified in 5.5.5; meas_report->generate_report(meas_id); } - } void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_check_leaving(int32_t meas_id, report_cfg_inter_rat_s& report_cfg) @@ -742,7 +732,7 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_removing_trigger(int3 auto it = cells_triggered_list.begin(); while (it != cells_triggered_list.end()) { if (not rrc_ptr->has_neighbour_cell_nr(it->earfcn, it->pci)) { - log_h->debug("MEAS: Removing unknown PCI=%d from event trigger list\n", it->pci); + logger.debug("MEAS: Removing unknown PCI=%d from event trigger list", it->pci); it = cells_triggered_list.erase(it); meas_report->upd_measId(meas_id, cells_triggered_list); @@ -767,21 +757,20 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers_interrat_nr(uint32_t report_triggers_interrat_removing_trigger(meas_id); } } -#endif void rrc::rrc_meas::var_meas_cfg::report_triggers() { // for each measId included in the measIdList within VarMeasConfig for (auto& m : measIdList) { if (!reportConfigList.count(m.second.report_cfg_id) || !measObjectsList.count(m.second.meas_obj_id)) { - log_h->error("MEAS: Computing report triggers. MeasId=%d has invalid report or object settings\n", m.first); + logger.error("MEAS: Computing report triggers. MeasId=%d has invalid report or object settings", m.first); continue; } report_cfg_to_add_mod_s& report_cfg = reportConfigList.at(m.second.report_cfg_id); meas_obj_to_add_mod_s& meas_obj = measObjectsList.at(m.second.meas_obj_id); - log_h->debug("MEAS: Calculating reports for MeasId=%d, ObjectId=%d (Type %s), ReportId=%d (Type %s)\n", + logger.debug("MEAS: Calculating reports for MeasId=%d, ObjectId=%d (Type %s), ReportId=%d (Type %s)", m.first, m.second.meas_obj_id, report_cfg.report_cfg.type().to_string().c_str(), @@ -792,16 +781,14 @@ void rrc::rrc_meas::var_meas_cfg::report_triggers() report_cfg.report_cfg.type().value == report_cfg_to_add_mod_s::report_cfg_c_::types::report_cfg_eutra) { report_triggers_eutra(m.first, report_cfg.report_cfg.report_cfg_eutra(), meas_obj.meas_obj.meas_obj_eutra()); } -#ifdef HAVE_5GNR else if (meas_obj.meas_obj.type().value == meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_nr_r15 && report_cfg.report_cfg.type().value == report_cfg_to_add_mod_s::report_cfg_c_::types::report_cfg_inter_rat) { report_triggers_interrat_nr( m.first, report_cfg.report_cfg.report_cfg_inter_rat(), meas_obj.meas_obj.meas_obj_nr_r15()); } -#endif else { - log_h->error("Unsupported combination of measurement object type %s and report config type %s \n", + logger.error("Unsupported combination of measurement object type %s and report config type %s ", meas_obj.meas_obj.type().to_string().c_str(), report_cfg.report_cfg.type().to_string().c_str()); } @@ -829,7 +816,7 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i float Ms = is_rsrp(report_cfg.trigger_quant.value) ? serv_cell->get_rsrp() : serv_cell->get_rsrq(); if (!std::isnormal(Ms)) { - log_h->debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers\n", Ms); + logger.debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers", Ms); return; } @@ -862,7 +849,7 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i trigger_state[meas_id][serv_cell->get_pci()].event_condition(enter_condition, exit_condition); - log_h->debug("MEAS: eventId=%s, Ms=%.2f, hyst=%.2f, Thresh=%.2f, enter_condition=%d, exit_condition=%d\n", + logger.debug("MEAS: eventId=%s, Ms=%.2f, hyst=%.2f, Thresh=%.2f, enter_condition=%d, exit_condition=%d", event_id.type().to_string().c_str(), Ms, hyst, @@ -874,8 +861,8 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i } else { auto cells = rrc_ptr->get_cells(meas_obj.carrier_freq); for (auto& pci : cells) { - log_h->debug( - "MEAS: eventId=%s, pci=%d, earfcn=%d\n", event_id.type().to_string().c_str(), pci, meas_obj.carrier_freq); + logger.debug( + "MEAS: eventId=%s, pci=%d, earfcn=%d", event_id.type().to_string().c_str(), pci, meas_obj.carrier_freq); float Ofn = offset_val(meas_obj); float Ocn = 0; // If the cell was provided by the configuration, check if it has an individual q_offset @@ -927,13 +914,13 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i exit_condition = (Ms - hyst > th1) && (Mn + Ofn + Ocn + hyst < th2); break; default: - log_h->error("Error event %s not implemented\n", event_id.type().to_string().c_str()); + logger.error("Error event %s not implemented", event_id.type().to_string().c_str()); } trigger_state[meas_id][pci].event_condition(enter_condition, exit_condition); - log_h->debug( - "MEAS: eventId=%s, pci=%d, Ms=%.2f, hyst=%.2f, Thresh=%.2f, enter_condition=%d, exit_condition=%d\n", + logger.debug( + "MEAS: eventId=%s, pci=%d, Ms=%.2f, hyst=%.2f, Thresh=%.2f, enter_condition=%d, exit_condition=%d", event_id.type().to_string().c_str(), pci, Ms, @@ -946,13 +933,12 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i } } -#ifdef HAVE_5GNR void rrc::rrc_meas::var_meas_cfg::eval_triggers_interrat_nr(uint32_t meas_id, report_cfg_inter_rat_s& report_cfg, meas_obj_nr_r15_s& meas_obj) { if (!(report_cfg.trigger_type.type() == report_cfg_inter_rat_s::trigger_type_c_::types::event)) { - log_h->error("Unsupported trigger type for interrat nr eval\n"); + logger.error("Unsupported trigger type for interrat nr eval"); return; } @@ -968,15 +954,15 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_interrat_nr(uint32_t bool exit_condition = false; float Mn = 0.0; - log_h->debug( - "MEAS: eventId=%s, pci=%d, earfcn=%d\n", event_id.type().to_string().c_str(), pci, meas_obj.carrier_freq_r15); + logger.debug( + "MEAS: eventId=%s, pci=%d, earfcn=%d", event_id.type().to_string().c_str(), pci, meas_obj.carrier_freq_r15); if (event_id.event_b1_nr_r15().b1_thres_nr_r15.type().value == thres_nr_r15_c::types::nr_rsrp_r15) { Mn = rrc_ptr->get_cell_rsrp_nr(meas_obj.carrier_freq_r15, pci); thresh = range_to_value_nr(asn1::rrc::thres_nr_r15_c::types_opts::options::nr_rsrp_r15, event_id.event_b1_nr_r15().b1_thres_nr_r15.nr_rsrp_r15()); } else { - log_h->warning("Other threshold values are not supported yet!\n"); + logger.warning("Other threshold values are not supported yet!"); } enter_condition = Mn - hyst > thresh; @@ -984,7 +970,7 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_interrat_nr(uint32_t trigger_state_nr[meas_id][pci].event_condition(enter_condition, exit_condition); - log_h->debug("MEAS (NR): eventId=%s, Mn=%.2f, hyst=%.2f, Thresh=%.2f, enter_condition=%d, exit_condition=%d\n", + logger.debug("MEAS (NR): eventId=%s, Mn=%.2f, hyst=%.2f, Thresh=%.2f, enter_condition=%d, exit_condition=%d", event_id.type().to_string().c_str(), Mn, hyst, @@ -993,14 +979,13 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_interrat_nr(uint32_t exit_condition); } } -#endif /* Evaluate event trigger conditions for each cell 5.5.4 */ void rrc::rrc_meas::var_meas_cfg::eval_triggers() { meas_cell_eutra* serv_cell = rrc_ptr->get_serving_cell(); if (serv_cell == nullptr) { - log_h->warning("MEAS: Serving cell not set when evaluating triggers\n"); + logger.warning("MEAS: Serving cell not set when evaluating triggers"); return; } @@ -1023,14 +1008,14 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers() for (auto& m : measIdList) { if (!reportConfigList.count(m.second.report_cfg_id) || !measObjectsList.count(m.second.meas_obj_id)) { - log_h->error("MEAS: Computing report triggers. MeasId=%d has invalid report or object settings\n", m.first); + logger.error("MEAS: Computing report triggers. MeasId=%d has invalid report or object settings", m.first); continue; } report_cfg_to_add_mod_s& report_cfg = reportConfigList.at(m.second.report_cfg_id); meas_obj_to_add_mod_s& meas_obj = measObjectsList.at(m.second.meas_obj_id); - log_h->debug("MEAS: Calculating trigger for MeasId=%d, ObjectId=%d (Type %s), ReportId=%d (Type %s)\n", + logger.debug("MEAS: Calculating trigger for MeasId=%d, ObjectId=%d (Type %s), ReportId=%d (Type %s)", m.first, m.second.meas_obj_id, report_cfg.report_cfg.type().to_string().c_str(), @@ -1042,14 +1027,12 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers() eval_triggers_eutra( m.first, report_cfg.report_cfg.report_cfg_eutra(), meas_obj.meas_obj.meas_obj_eutra(), serv_cell, Ofs, Ocs); } -#ifdef HAVE_5GNR else if (meas_obj.meas_obj.type().value == meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_nr_r15 && report_cfg.report_cfg.type().value == report_cfg_to_add_mod_s::report_cfg_c_::types::report_cfg_inter_rat) eval_triggers_interrat_nr( m.first, report_cfg.report_cfg.report_cfg_inter_rat(), meas_obj.meas_obj.meas_obj_nr_r15()); -#endif else { - log_h->error("Unsupported combination of measurement object type %s and report config type %s \n", + logger.error("Unsupported combination of measurement object type %s and report config type %s ", meas_obj.meas_obj.type().to_string().c_str(), report_cfg.report_cfg.type().to_string().c_str()); } @@ -1103,17 +1086,17 @@ std::list rrc::rrc_meas::var_meas_cfg::get_active_objects r.push_back(measObjectsList.at(m.second.meas_obj_id)); } } - if (log_h->get_level() == LOG_LEVEL_DEBUG) { - log_h->debug("MEAS: Returning %zd active objects\n", r.size()); + if (logger.debug.enabled()) { + logger.debug("MEAS: Returning %zd active objects", r.size()); for (auto& o : r) { switch (o.meas_obj.type().value) { case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_eutra: - log_h->debug("MEAS: carrier_freq=%d, %u cells\n", + logger.debug("MEAS: carrier_freq=%d, %u cells", o.meas_obj.meas_obj_eutra().carrier_freq, o.meas_obj.meas_obj_eutra().cells_to_add_mod_list.size()); break; case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_nr_r15: - log_h->debug("MEAS: NR: carrier_freq=%d\n", o.meas_obj.meas_obj_nr_r15().carrier_freq_r15); + logger.debug("MEAS: NR: carrier_freq=%d", o.meas_obj.meas_obj_nr_r15().carrier_freq_r15); default: break; } @@ -1126,8 +1109,7 @@ std::list rrc::rrc_meas::var_meas_cfg::get_active_objects // Procedure upon handover or reestablishment 5.5.6.1 void rrc::rrc_meas::var_meas_cfg::ho_reest_finish(const uint32_t src_earfcn, const uint32_t dst_earfcn) { - log_h->info( - "MEAS: Actions upon handover and reestablishment, src_earfcn=%d, dst_earfcn=%d\n", src_earfcn, dst_earfcn); + logger.info("MEAS: Actions upon handover and reestablishment, src_earfcn=%d, dst_earfcn=%d", src_earfcn, dst_earfcn); // for each measId included in the measIdList within VarMeasConfig, if the triggerType is set to ‘periodical’, remove // this measId from the measIdList within VarMeasConfig @@ -1146,10 +1128,10 @@ void rrc::rrc_meas::var_meas_cfg::ho_reest_finish(const uint32_t src_earfcn, con } } - if (log_h->get_level() == LOG_LEVEL_DEBUG) { - log_h->debug("MEAS: measId before HO\n"); + if (logger.debug.enabled()) { + logger.debug("MEAS: measId before HO"); for (auto& m : measIdList) { - log_h->debug("MEAS: measId=%d, measObjectId=%d\n", m.first, m.second.meas_obj_id); + logger.debug("MEAS: measId=%d, measObjectId=%d", m.first, m.second.meas_obj_id); } } @@ -1161,10 +1143,11 @@ void rrc::rrc_meas::var_meas_cfg::ho_reest_finish(const uint32_t src_earfcn, con [&src_earfcn](const std::pair& c) { return c.second.meas_obj.meas_obj_eutra().carrier_freq == src_earfcn; }); - auto dst_obj = std::find_if( - measObjectsList.begin(), measObjectsList.end(), [&dst_earfcn](const std::pair& c) { - return c.second.meas_obj.meas_obj_eutra().carrier_freq == dst_earfcn; - }); + auto dst_obj = std::find_if(measObjectsList.begin(), + measObjectsList.end(), + [&dst_earfcn](const std::pair& c) { + return c.second.meas_obj.meas_obj_eutra().carrier_freq == dst_earfcn; + }); if (dst_obj != measObjectsList.end()) { for (auto& m : measIdList) { // if the measId value is linked to the measObjectId value corresponding to the source carrier frequency @@ -1192,10 +1175,10 @@ void rrc::rrc_meas::var_meas_cfg::ho_reest_finish(const uint32_t src_earfcn, con } } - if (log_h->get_level() == LOG_LEVEL_DEBUG) { - log_h->debug("MEAS: measId after HO\n"); + if (logger.debug.enabled()) { + logger.debug("MEAS: measId after HO"); for (auto& m : measIdList) { - log_h->debug("MEAS: measId=%d, measObjectId=%d\n", m.first, m.second.meas_obj_id); + logger.debug("MEAS: measId=%d, measObjectId=%d", m.first, m.second.meas_obj_id); } } @@ -1214,14 +1197,14 @@ void rrc::rrc_meas::var_meas_cfg::measObject_removal(const meas_obj_to_rem_list_ auto it = measIdList.begin(); while (it != measIdList.end()) { if (it->second.meas_obj_id == l) { - log_h->info("MEAS: Removed measId=%d\n", it->first); + logger.info("MEAS: Removed measId=%d", it->first); remove_varmeas_report(it->first); // Remove report before `it` is updated with the next pointer it = measIdList.erase(it); } else { it++; } } - log_h->info("MEAS: Removed measObjectId=%d\n", l); + logger.info("MEAS: Removed measObjectId=%d", l); } } } @@ -1234,7 +1217,7 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_eutra(const meas_obj_to_add_ measObjectsList.emplace(l.meas_obj_id, l); } - meas_obj_eutra_s cfg_obj = l.meas_obj.meas_obj_eutra(); + meas_obj_eutra_s cfg_obj = l.meas_obj.meas_obj_eutra(); measObjectsList.at(l.meas_obj_id).meas_obj_id = l.meas_obj_id; // Assert choice will check if existing meas object is of type eutra meas_obj_eutra_s& local_obj = measObjectsList.at(l.meas_obj_id).meas_obj.meas_obj_eutra(); @@ -1249,12 +1232,12 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_eutra(const meas_obj_to_add_ { // Remove cells if (cfg_obj.cells_to_rem_list_present) { - log_h->debug("MEAS: Removing %d cells\n", cfg_obj.cells_to_rem_list.size()); + logger.debug("MEAS: Removing %d cells", cfg_obj.cells_to_rem_list.size()); apply_remlist_diff(local_obj.cells_to_add_mod_list, cfg_obj.cells_to_rem_list, local_obj.cells_to_add_mod_list); - if (log_h->get_level() == LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { for (auto& c : local_obj.cells_to_add_mod_list) { - log_h->debug("MEAS: cell idx=%d, pci=%d, q_offset=%d\n", + logger.debug("MEAS: cell idx=%d, pci=%d, q_offset=%d", c.cell_idx, c.pci, c.cell_individual_offset.to_number()); @@ -1289,19 +1272,19 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_eutra(const meas_obj_to_add_ } } - log_h->info("MEAS: %s objectId=%d, carrier_freq=%d, %u cells, %u black-listed cells\n", + logger.info("MEAS: %s objectId=%d, carrier_freq=%d, %u cells, %u black-listed cells", !entry_exists ? "Added" : "Modified", l.meas_obj_id, local_obj.carrier_freq, local_obj.cells_to_add_mod_list.size(), local_obj.black_cells_to_add_mod_list.size()); - if (log_h->get_level() == LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { for (auto& c : local_obj.cells_to_add_mod_list) { - log_h->debug( - "MEAS: cell idx=%d, pci=%d, q_offset=%d\n", c.cell_idx, c.pci, c.cell_individual_offset.to_number()); + logger.debug( + "MEAS: cell idx=%d, pci=%d, q_offset=%d", c.cell_idx, c.pci, c.cell_individual_offset.to_number()); } for (auto& b : local_obj.black_cells_to_add_mod_list) { - log_h->debug("MEAS: black-listed cell idx=%d\n", b.cell_idx); + logger.debug("MEAS: black-listed cell idx=%d", b.cell_idx); } } } @@ -1314,9 +1297,9 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_nr_r15(const meas_obj_to_add measObjectsList.emplace(l.meas_obj_id, l); } - meas_obj_nr_r15_s cfg_obj = l.meas_obj.meas_obj_nr_r15(); + meas_obj_nr_r15_s cfg_obj = l.meas_obj.meas_obj_nr_r15(); measObjectsList.at(l.meas_obj_id).meas_obj_id = l.meas_obj_id; - meas_obj_nr_r15_s& local_obj = measObjectsList.at(l.meas_obj_id).meas_obj.meas_obj_nr_r15(); + meas_obj_nr_r15_s& local_obj = measObjectsList.at(l.meas_obj_id).meas_obj.meas_obj_nr_r15(); // if an entry with the matching measObjectId exists in the measObjectList within the VarMeasConfig if (entry_exists) { // Update carrier frequency0 @@ -1344,14 +1327,14 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_nr_r15(const meas_obj_to_add } } - log_h->info("MEAS (NR R15): %s objectId=%d, carrier_freq=%d, %u black-listed cells\n", + logger.info("MEAS (NR R15): %s objectId=%d, carrier_freq=%d, %u black-listed cells", !entry_exists ? "Added" : "Modified", l.meas_obj_id, local_obj.carrier_freq_r15, local_obj.black_cells_to_add_mod_list_r15.size()); - if (log_h->get_level() == LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { for (auto& b : local_obj.black_cells_to_add_mod_list_r15) { - log_h->debug("MEAS: black-listed cell idx=%d\n", b.cell_idx_r15); + logger.debug("MEAS: black-listed cell idx=%d", b.cell_idx_r15); } } } @@ -1368,7 +1351,7 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod(const meas_obj_to_add_mod_li measObject_addmod_nr_r15(l); break; default: - log_h->error("Unsupported measObject type: %s\n", l.meas_obj.type().to_string().c_str()); + logger.error("Unsupported measObject type: %s", l.meas_obj.type().to_string().c_str()); break; } } @@ -1385,14 +1368,14 @@ void rrc::rrc_meas::var_meas_cfg::reportConfig_removal(const report_cfg_to_rem_l auto it = measIdList.begin(); while (it != measIdList.end()) { if (it->second.report_cfg_id == l) { - log_h->info("MEAS: Removed measId=%d\n", it->first); + logger.info("MEAS: Removed measId=%d", it->first); remove_varmeas_report(it->first); // Remove report before `it` is updated with the next pointer it = measIdList.erase(it); } else { it++; } } - log_h->info("MEAS: Removed reportObjectId=%d\n", l); + logger.info("MEAS: Removed reportObjectId=%d", l); } } } @@ -1419,11 +1402,11 @@ void rrc::rrc_meas::var_meas_cfg::reportConfig_addmod_eutra(const report_cfg_to_ const report_cfg_eutra_s& report_cfg = l.report_cfg.report_cfg_eutra(); if (!(report_cfg.trigger_type.type().value == report_cfg_eutra_s::trigger_type_c_::types_opts::event)) { - log_h->error("MEAS: Periodical reports not supported. Received in reportConfigId=%d\n", l.report_cfg_id); + logger.error("MEAS: Periodical reports not supported. Received in reportConfigId=%d", l.report_cfg_id); return; } bool entry_exists = reportConfig_addmod_to_reportConfigList(l); - log_h->info("MEAS: %s reportConfig id=%d, event-type=%s, time-to-trigger=%d ms, reportInterval=%d\n", + logger.info("MEAS: %s reportConfig id=%d, event-type=%s, time-to-trigger=%d ms, reportInterval=%d", !entry_exists ? "Added" : "Modified", l.report_cfg_id, report_cfg.trigger_type.event().event_id.type().to_string().c_str(), @@ -1438,11 +1421,11 @@ void rrc::rrc_meas::var_meas_cfg::reportConfig_addmod_interrat(const report_cfg_ { const report_cfg_inter_rat_s& report_cfg = l.report_cfg.report_cfg_inter_rat(); if (!(report_cfg.trigger_type.type().value == report_cfg_inter_rat_s::trigger_type_c_::types_opts::event)) { - log_h->error("MEAS: Periodical reports not supported. Received in reportConfigId=%d\n", l.report_cfg_id); + logger.error("MEAS: Periodical reports not supported. Received in reportConfigId=%d", l.report_cfg_id); return; } bool entry_exists = reportConfig_addmod_to_reportConfigList(l); - log_h->info("MEAS: Inter RAT %s reportConfig id=%d, event-type=%s, time-to-trigger=%d ms, reportInterval=%d\n", + logger.info("MEAS: Inter RAT %s reportConfig id=%d, event-type=%s, time-to-trigger=%d ms, reportInterval=%d", !entry_exists ? "Added" : "Modified", l.report_cfg_id, report_cfg.trigger_type.event().event_id.type().to_string().c_str(), @@ -1463,7 +1446,7 @@ void rrc::rrc_meas::var_meas_cfg::reportConfig_addmod(const report_cfg_to_add_mo reportConfig_addmod_interrat(l); break; default: - log_h->error("MEAS: Unsupported reportConfig type: %s\n", l.report_cfg.type().to_string().c_str()); + logger.error("MEAS: Unsupported reportConfig type: %s", l.report_cfg.type().to_string().c_str()); break; } } @@ -1473,16 +1456,17 @@ void rrc::rrc_meas::var_meas_cfg::reportConfig_addmod(const report_cfg_to_add_mo void rrc::rrc_meas::var_meas_cfg::log_debug_trigger_value_interrat( const report_cfg_inter_rat_s::trigger_type_c_::event_s_::event_id_c_& e) { - if (log_h->get_level() == LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { switch (e.type()) { case report_cfg_inter_rat_s::trigger_type_c_::event_s_::event_id_c_::types_opts::event_b1_nr_r15: { - log_h->debug("MEAS: B1-NR-R15-threashold (%d)=%.1f dBm\n", + logger.debug("MEAS: B1-NR-R15-threashold (%d)=%.1f dBm", e.event_b1_nr_r15().b1_thres_nr_r15.nr_rsrp_r15(), - range_to_value_nr(asn1::rrc::thres_nr_r15_c::types_opts::options::nr_rsrp_r15, e.event_b1_nr_r15().b1_thres_nr_r15.nr_rsrp_r15())); + range_to_value_nr(asn1::rrc::thres_nr_r15_c::types_opts::options::nr_rsrp_r15, + e.event_b1_nr_r15().b1_thres_nr_r15.nr_rsrp_r15())); break; } default: - log_h->debug("MEAS: Unsupported inter rat trigger type %s\n", e.type().to_string().c_str()); + logger.debug("MEAS: Unsupported inter rat trigger type %s", e.type().to_string().c_str()); break; } } @@ -1491,26 +1475,26 @@ void rrc::rrc_meas::var_meas_cfg::log_debug_trigger_value_interrat( // Warning: Use for Test debug purposes only. Assumes thresholds in RSRP void rrc::rrc_meas::var_meas_cfg::log_debug_trigger_value_eutra(const eutra_event_s::event_id_c_& e) { - if (log_h->get_level() == LOG_LEVEL_DEBUG) { + if (logger.debug.enabled()) { switch (e.type()) { case eutra_event_s::event_id_c_::types_opts::event_a1: - log_h->debug("MEAS: A1-threshold=%.1f dBm\n", + logger.debug("MEAS: A1-threshold=%.1f dBm", range_to_value(report_cfg_eutra_s::trigger_quant_opts::rsrp, e.event_a1().a1_thres.thres_rsrp())); break; case eutra_event_s::event_id_c_::types_opts::event_a2: - log_h->debug("MEAS: A2-threshold=%.1f dBm\n", + logger.debug("MEAS: A2-threshold=%.1f dBm", range_to_value(report_cfg_eutra_s::trigger_quant_opts::rsrp, e.event_a2().a2_thres.thres_rsrp())); break; case eutra_event_s::event_id_c_::types_opts::event_a3: - log_h->debug("MEAS: A3-offset=%.1f dB\n", + logger.debug("MEAS: A3-offset=%.1f dB", range_to_value(report_cfg_eutra_s::trigger_quant_opts::rsrp, e.event_a3().a3_offset)); break; case eutra_event_s::event_id_c_::types_opts::event_a4: - log_h->debug("MEAS: A4-threshold=%.1f dBm\n", + logger.debug("MEAS: A4-threshold=%.1f dBm", range_to_value(report_cfg_eutra_s::trigger_quant_opts::rsrp, e.event_a4().a4_thres.thres_rsrp())); break; default: - log_h->debug("MEAS: Unsupported\n"); + logger.debug("MEAS: Unsupported"); break; } } @@ -1525,7 +1509,7 @@ void rrc::rrc_meas::var_meas_cfg::measId_removal(const meas_id_to_rem_list_l& li if (measIdList.count(l)) { measIdList.erase(l); remove_varmeas_report(l); - log_h->info("MEAS: Removed measId=%d\n", l); + logger.info("MEAS: Removed measId=%d", l); } } } @@ -1536,11 +1520,11 @@ void rrc::rrc_meas::var_meas_cfg::measId_addmod(const meas_id_to_add_mod_list_l& for (auto& l : list) { // configure only if report and object exists if (reportConfigList.count(l.report_cfg_id) == 0) { - log_h->error("MEAS: Adding measId=%d, reportConfigId=%d doesn't exist\n", l.meas_id, l.report_cfg_id); + logger.error("MEAS: Adding measId=%d, reportConfigId=%d doesn't exist", l.meas_id, l.report_cfg_id); continue; } if (measObjectsList.count(l.meas_obj_id) == 0) { - log_h->error("MEAS: Adding measId=%d, measObjectId=%d doesn't exist\n", l.meas_id, l.meas_obj_id); + logger.error("MEAS: Adding measId=%d, measObjectId=%d doesn't exist", l.meas_id, l.meas_obj_id); continue; } // add/replace entry in VarMeasConfig. Safe to use [] operator here @@ -1549,8 +1533,8 @@ void rrc::rrc_meas::var_meas_cfg::measId_addmod(const meas_id_to_add_mod_list_l& // remove the measurement reporting entry for this measId from the VarMeasReportList, if included remove_varmeas_report(l.meas_id); - log_h->info( - "MEAS: AddMod measId=%d, measObjectId=%d, reportConfigId=%d\n", l.meas_id, l.meas_obj_id, l.report_cfg_id); + logger.info( + "MEAS: AddMod measId=%d, measObjectId=%d, reportConfigId=%d", l.meas_id, l.meas_obj_id, l.report_cfg_id); } } @@ -1574,7 +1558,7 @@ void rrc::rrc_meas::var_meas_cfg::quantity_config(const quant_cfg_s& cfg) filter_a.rsrp = powf(0.5f, (float)k_rsrp / 4.0f); filter_a.rsrq = powf(0.5f, (float)k_rsrq / 4.0f); - log_h->info("MEAS: Quantity configuration k_rsrp=%d, k_rsrq=%d\n", k_rsrp, k_rsrq); + logger.info("MEAS: Quantity configuration k_rsrp=%d, k_rsrq=%d", k_rsrp, k_rsrq); // for each measId included in the measIdList within VarMeasConfig for (auto& m : measIdList) { @@ -1641,7 +1625,7 @@ bool rrc::rrc_meas::var_meas_cfg::parse_meas_config(const meas_cfg_s* cfg, bool ho_reest_finish(src_earfcn, target_earfcn); } } else { - log_h->warning("MEAS: Could not get serving cell earfcn\n"); + logger.warning("MEAS: Could not get serving cell earfcn"); } } return true; diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index 9b1ccecef..22cf1fecc 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -72,7 +72,7 @@ void rrc_nr::stop() void rrc_nr::init_core_less() { - log_h->info("Creating dummy DRB on LCID=%d\n", args.coreless.drb_lcid); + log_h->info("Creating dummy DRB on LCID=%d", args.coreless.drb_lcid); srslte::rlc_config_t rlc_cnfg = srslte::rlc_config_t::default_rlc_um_nr_config(6); rlc->add_bearer(args.coreless.drb_lcid, rlc_cnfg); @@ -82,7 +82,8 @@ void rrc_nr::init_core_less() srslte::SECURITY_DIRECTION_UPLINK, srslte::PDCP_SN_LEN_18, srslte::pdcp_t_reordering_t::ms500, - srslte::pdcp_discard_timer_t ::ms100}; + srslte::pdcp_discard_timer_t::ms100, + false}; pdcp->add_bearer(args.coreless.drb_lcid, pdcp_cnfg); return; @@ -92,9 +93,9 @@ void rrc_nr::get_metrics(rrc_nr_metrics_t& m) {} // Timeout callback interface void rrc_nr::timer_expired(uint32_t timeout_id) { - log_h->debug("[NR] Handling Timer Expired\n"); + log_h->debug("[NR] Handling Timer Expired"); if (timeout_id == fake_measurement_timer.id()) { - log_h->debug("[NR] Triggered Fake Measurement\n"); + log_h->debug("[NR] Triggered Fake Measurement"); phy_meas_nr_t fake_meas = {}; std::vector phy_meas_nr; @@ -122,18 +123,18 @@ void rrc_nr::log_rrc_message(const std::string& source, const std::string& msg_type) { if (log_h->get_level() == srslte::LOG_LEVEL_INFO) { - log_h->info("%s - %s %s (%d B)\n", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); + log_h->info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); } else if (log_h->get_level() >= srslte::LOG_LEVEL_DEBUG) { asn1::json_writer json_writer; msg.to_json(json_writer); log_h->debug_hex(pdu->msg, pdu->N_bytes, - "%s - %s %s (%d B)\n", + "%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); - log_h->debug_long("Content:\n%s\n", json_writer.to_string().c_str()); + log_h->debug_long("Content:\n%s", json_writer.to_string().c_str()); } } @@ -145,28 +146,28 @@ void rrc_nr::log_rrc_message(const std::string& source, const std::string& msg_type) { if (log_h->get_level() == srslte::LOG_LEVEL_INFO) { - log_h->info("%s - %s %s (%d B)\n", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); + log_h->info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); } else if (log_h->get_level() >= srslte::LOG_LEVEL_DEBUG) { asn1::json_writer json_writer; msg.to_json(json_writer); log_h->debug_hex(oct.data(), oct.size(), - "%s - %s %s (%d B)\n", + "%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); - log_h->debug_long("Content:\n%s\n", json_writer.to_string().c_str()); + log_h->debug_long("Content:\n%s", json_writer.to_string().c_str()); } } bool rrc_nr::add_lcid_rb(uint32_t lcid, rb_type_t rb_type, uint32_t rbid) { if (lcid_rb.find(lcid) != lcid_rb.end()) { - log_h->error("Couldn't add RB to LCID. RB %d does exist.\n", rbid); + log_h->error("Couldn't add RB to LCID. RB %d does exist.", rbid); return false; } else { - log_h->info("Adding lcid %d and radio bearer ID %d with type %s \n", lcid, rbid, (rb_type == Srb) ? "SRB" : "DRB"); + log_h->info("Adding lcid %d and radio bearer ID %d with type %s ", lcid, rbid, (rb_type == Srb) ? "SRB" : "DRB"); lcid_rb[lcid].rb_id = rbid; lcid_rb[lcid].rb_type = rb_type; } @@ -180,7 +181,7 @@ uint32_t rrc_nr::get_lcid_for_rbid(uint32_t rb_id) return rb.first; } } - log_h->error("Couldn't find LCID for rb LCID. RB %d does exist.\n", rb_id); + log_h->error("Couldn't find LCID for rb LCID. RB %d does exist.", rb_id); return 0; } @@ -208,19 +209,22 @@ void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps_pdu) band_param_eutra.set_eutra(); band_param_eutra.eutra().ca_bw_class_dl_eutra_present = true; band_param_eutra.eutra().ca_bw_class_ul_eutra_present = true; - band_param_eutra.eutra().band_eutra = 1; + band_param_eutra.eutra().band_eutra = 1; // TODO: this also needs to be set here? band_param_eutra.eutra().ca_bw_class_dl_eutra = asn1::rrc_nr::ca_bw_class_eutra_opts::options::a; band_param_eutra.eutra().ca_bw_class_ul_eutra = asn1::rrc_nr::ca_bw_class_eutra_opts::options::a; band_combination.band_list.push_back(band_param_eutra); - struct band_params_c band_param_nr; - band_param_nr.set_nr(); - band_param_nr.nr().ca_bw_class_dl_nr_present = true; - band_param_nr.nr().ca_bw_class_ul_nr_present = true; - band_param_nr.nr().band_nr = 78; - band_param_nr.nr().ca_bw_class_dl_nr = asn1::rrc_nr::ca_bw_class_nr_opts::options::a; - band_param_nr.nr().ca_bw_class_ul_nr = asn1::rrc_nr::ca_bw_class_nr_opts::options::a; - band_combination.band_list.push_back(band_param_nr); + // TODO check if band is requested + for (const auto& band : args.supported_bands) { + struct band_params_c band_param_nr; + band_param_nr.set_nr(); + band_param_nr.nr().ca_bw_class_dl_nr_present = true; + band_param_nr.nr().ca_bw_class_ul_nr_present = true; + band_param_nr.nr().band_nr = band; + band_param_nr.nr().ca_bw_class_dl_nr = asn1::rrc_nr::ca_bw_class_nr_opts::options::a; + band_param_nr.nr().ca_bw_class_ul_nr = asn1::rrc_nr::ca_bw_class_nr_opts::options::a; + band_combination.band_list.push_back(band_param_nr); + } mrdc_cap.rf_params_mrdc.supported_band_combination_list.push_back(band_combination); mrdc_cap.rf_params_mrdc.supported_band_combination_list_present = true; @@ -235,10 +239,12 @@ void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps_pdu) band_info_eutra.band_info_eutra().band_eutra = 1; mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt.push_back(band_info_eutra); - freq_band_info_c band_info_nr; - band_info_nr.set_band_info_nr(); - band_info_nr.band_info_nr().band_nr = 78; - mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt.push_back(band_info_nr); + for (const auto& band : args.supported_bands) { + freq_band_info_c band_info_nr; + band_info_nr.set_band_info_nr(); + band_info_nr.band_info_nr().band_nr = band; + mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt.push_back(band_info_nr); + } mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt_present = true; @@ -281,16 +287,17 @@ void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps_pdu) feature_set_eutra.eutra().dl_set_eutra = 1; feature_set_eutra.eutra().ul_set_eutra = 1; feature_sets_per_band.push_back(feature_set_eutra); - feature_set_combination.push_back(feature_sets_per_band); - feature_set_c feature_set_nr; - feature_set_nr.set_nr(); - feature_set_nr.nr().dl_set_nr = 1; - feature_set_nr.nr().ul_set_nr = 1; - feature_sets_per_band.push_back(feature_set_nr); - - feature_set_combination.push_back(feature_sets_per_band); + for (const auto& band : args.supported_bands) { + feature_sets_per_band.resize(0); + feature_set_c feature_set_nr; + feature_set_nr.set_nr(); + feature_set_nr.nr().dl_set_nr = 1; + feature_set_nr.nr().ul_set_nr = 1; + feature_sets_per_band.push_back(feature_set_nr); + feature_set_combination.push_back(feature_sets_per_band); + } mrdc_cap.feature_set_combinations.push_back(feature_set_combination); @@ -312,7 +319,7 @@ void rrc_nr::get_eutra_nr_capabilities(srslte::byte_buffer_t* eutra_nr_caps_pdu) #endif log_h->debug_hex( - eutra_nr_caps_pdu->msg, eutra_nr_caps_pdu->N_bytes, "EUTRA-NR capabilities (%u B)\n", eutra_nr_caps_pdu->N_bytes); + eutra_nr_caps_pdu->msg, eutra_nr_caps_pdu->N_bytes, "EUTRA-NR capabilities (%u B)", eutra_nr_caps_pdu->N_bytes); return; } @@ -325,11 +332,10 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, bool nr_radio_bearer_cfg1_r15_present, asn1::dyn_octstring nr_radio_bearer_cfg1_r15) { - // sanity check only for now if (nr_secondary_cell_group_cfg_r15_present == false || sk_counter_r15_present == false || nr_radio_bearer_cfg1_r15_present == false) { - log_h->error("RRC NR Reconfiguration failed sanity check failed\n"); + log_h->error("RRC NR Reconfiguration failed sanity check failed"); return false; } @@ -342,7 +348,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, err = rrc_recfg.unpack(bref); if (err != asn1::SRSASN_SUCCESS) { - log_h->error("Could not unpack NR reconfiguration message.\n"); + log_h->error("Could not unpack NR reconfiguration message."); return false; } @@ -356,7 +362,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, err = cell_group_cfg.unpack(bref0); if (err != asn1::SRSASN_SUCCESS) { - log_h->error("Could not unpack cell group message message.\n"); + log_h->error("Could not unpack cell group message message."); return false; } @@ -366,7 +372,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, cell_group_cfg, "Secondary Cell Group Config"); } else { - log_h->error("Reconfiguration does not contain Secondary Cell Group Config\n"); + log_h->error("Reconfiguration does not contain Secondary Cell Group Config"); return false; } } @@ -375,7 +381,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, err = radio_bearer_cfg.unpack(bref1); if (err != asn1::SRSASN_SUCCESS) { - log_h->error("Could not unpack radio bearer config.\n"); + log_h->error("Could not unpack radio bearer config."); return false; } @@ -386,7 +392,7 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, sk_counter_r15_present, sk_counter_r15, radio_bearer_cfg)) { - log_h->error("Unable to launch NR RRC configuration procedure\n"); + log_h->error("Unable to launch NR RRC configuration procedure"); return false; } else { callback_list.add_proc(conn_recfg_proc); @@ -396,18 +402,19 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, void rrc_nr::get_nr_capabilities(srslte::byte_buffer_t* nr_caps_pdu) { - struct ue_nr_cap_s nr_cap; nr_cap.access_stratum_release = access_stratum_release_opts::rel15; // PDCP nr_cap.pdcp_params.max_num_rohc_context_sessions = pdcp_params_s::max_num_rohc_context_sessions_opts::cs2; - band_nr_s band_nr; - band_nr.band_nr = 78; - band_nr.ue_pwr_class_present = true; - band_nr.ue_pwr_class = band_nr_s::ue_pwr_class_opts::pc3; - nr_cap.rf_params.supported_band_list_nr.push_back(band_nr); + for (const auto& band : args.supported_bands) { + band_nr_s band_nr; + band_nr.band_nr = band; + band_nr.ue_pwr_class_present = true; + band_nr.ue_pwr_class = band_nr_s::ue_pwr_class_opts::pc3; + nr_cap.rf_params.supported_band_list_nr.push_back(band_nr); + } nr_cap.rlc_params_present = true; nr_cap.rlc_params.um_with_short_sn_present = true; @@ -431,7 +438,7 @@ void rrc_nr::get_nr_capabilities(srslte::byte_buffer_t* nr_caps_pdu) } #endif - log_h->debug_hex(nr_caps_pdu->msg, nr_caps_pdu->N_bytes, "NR capabilities (%u B)\n", nr_caps_pdu->N_bytes); + log_h->debug_hex(nr_caps_pdu->msg, nr_caps_pdu->N_bytes, "NR capabilities (%u B)", nr_caps_pdu->N_bytes); return; }; @@ -439,15 +446,15 @@ void rrc_nr::phy_meas_stop() { // possbile race condition for fake_measurement timer, which might be set at the same moment as stopped => fix with // phy integration - log_h->debug("[NR] Stopping fake measurements\n"); + log_h->debug("[NR] Stopping fake measurements"); fake_measurement_timer.stop(); } void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15) { - log_h->debug("[NR] Measuring phy cell %d \n", carrier_freq_r15); + log_h->debug("[NR] Measuring phy cell %d ", carrier_freq_r15); // Start timer for fake measurements - auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); }; + auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); }; fake_measurement_carrier_freq_r15 = carrier_freq_r15; fake_measurement_timer.set(10, timer_expire_func); fake_measurement_timer.run(); @@ -455,7 +462,7 @@ void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15) void rrc_nr::configure_sk_counter(uint16_t sk_counter) { - log_h->info("[NR] Configure new SK counter %d. Update Key for secondary gnb\n", sk_counter); + log_h->info("[NR] Configure new SK counter %d. Update Key for secondary gnb", sk_counter); usim->generate_nr_context(sk_counter, &sec_cfg); } bool rrc_nr::is_config_pending() @@ -483,7 +490,7 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) add_lcid_rb(lc_ch_id, Srb, srb_id); } } else { - log_h->warning("In RLC bearer cfg does not contain served radio bearer\n"); + log_h->warning("In RLC bearer cfg does not contain served radio bearer"); return false; } @@ -494,13 +501,13 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present && rlc_bearer_cfg.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len != rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len) { - log_h->warning("NR RLC sequence number length is not the same in uplink and downlink\n"); + log_h->warning("NR RLC sequence number length is not the same in uplink and downlink"); } } else { - log_h->warning("NR RLC type is not unacknowledged mode bidirectional\n"); + log_h->warning("NR RLC type is not unacknowledged mode bidirectional"); } } else { - log_h->warning("In RLC bearer cfg does not contain rlc cfg\n"); + log_h->warning("In RLC bearer cfg does not contain rlc cfg"); return false; } @@ -516,25 +523,24 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) } bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg) { - if (mac_cell_group_cfg.sched_request_cfg_present) { sr_cfg_t sr_cfg; if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list_present) { if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() > 1) { - log_h->warning("Only handling 1 scheduling request index to add\n"); + log_h->warning("Only handling 1 scheduling request index to add"); sr_cfg.dsr_transmax = mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[1].sr_trans_max; mac->set_config(sr_cfg); } } if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_release_list_present) { - log_h->warning("Not handling sched request to release list\n"); + log_h->warning("Not handling sched request to release list"); } } if (mac_cell_group_cfg.sched_request_cfg_present) if (mac_cell_group_cfg.bsr_cfg_present) { - log_h->debug("Handling MAC BSR config\n"); + log_h->debug("Handling MAC BSR config"); srslte::bsr_cfg_t bsr_cfg; bsr_cfg.periodic_timer = mac_cell_group_cfg.bsr_cfg.periodic_bsr_timer.to_number(); bsr_cfg.retx_timer = mac_cell_group_cfg.bsr_cfg.retx_bsr_timer.to_number(); @@ -542,41 +548,56 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg } if (mac_cell_group_cfg.tag_cfg_present) { - log_h->warning("Not handling tag cfg in MAC cell group config\n"); + log_h->warning("Not handling tag cfg in MAC cell group config"); } if (mac_cell_group_cfg.phr_cfg_present) { - log_h->warning("Not handling phr cfg in MAC cell group config\n"); + log_h->warning("Not handling phr cfg in MAC cell group config"); } if (mac_cell_group_cfg.skip_ul_tx_dynamic) { - log_h->warning("Not handling phr cfg in skip_ul_tx_dynamic cell group config\n"); + log_h->warning("Not handling phr cfg in skip_ul_tx_dynamic cell group config"); } return true; } bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) { - // TODO Setup PHY @andre and @phy interface? - log_h->warning("Not handling SP Cell config\n"); + if (sp_cell_cfg.recfg_with_sync_present) { + const recfg_with_sync_s& recfg_with_sync = sp_cell_cfg.recfg_with_sync; + mac->set_crnti(recfg_with_sync.new_ue_id); + if (recfg_with_sync.sp_cell_cfg_common_present) { + if (recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present) { + const bwp_ul_common_s* bwp_ul_common = &recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp; + if (bwp_ul_common->rach_cfg_common_present) { + if (bwp_ul_common->rach_cfg_common.type() == setup_release_c::types_opts::setup) { + const rach_cfg_common_s& rach_cfg_common = bwp_ul_common->rach_cfg_common.setup(); + rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(rach_cfg_common); + mac->set_config(rach_nr_cfg); + } + } + } + } + mac->start_ra_procedure(); + } return true; } bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) { - if (cell_group_cfg.rlc_bearer_to_add_mod_list_present == true) { + if (cell_group_cfg.rlc_bearer_to_add_mod_list_present) { for (uint32_t i = 0; i < cell_group_cfg.rlc_bearer_to_add_mod_list.size(); i++) { apply_rlc_add_mod(cell_group_cfg.rlc_bearer_to_add_mod_list[i]); } } - if (cell_group_cfg.mac_cell_group_cfg_present == true) { + if (cell_group_cfg.mac_cell_group_cfg_present) { apply_mac_cell_group(cell_group_cfg.mac_cell_group_cfg); } - if (cell_group_cfg.phys_cell_group_cfg_present == true) { - log_h->warning("Not handling physical cell group config\n"); + if (cell_group_cfg.phys_cell_group_cfg_present) { + log_h->warning("Not handling physical cell group config"); } if (cell_group_cfg.sp_cell_cfg_present) { - // apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg); + apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg); } return true; } @@ -584,7 +605,7 @@ bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) { if (!drb_cfg.pdcp_cfg_present) { - log_h->error("Cannot add DRB - incomplete configuration\n"); + log_h->error("Cannot add DRB - incomplete configuration"); return false; } @@ -592,41 +613,40 @@ bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) // Setup PDCP if (!(drb_cfg.pdcp_cfg.drb_present == true)) { - log_h->error("PDCP config does not contain DRB config\n"); + log_h->error("PDCP config does not contain DRB config"); return false; } if (!(drb_cfg.cn_assoc_present == true)) { - log_h->error("DRB config does not contain an associated cn\n"); + log_h->error("DRB config does not contain an associated cn"); return false; } if (!(drb_cfg.cn_assoc.type() == drb_to_add_mod_s::cn_assoc_c_::types_opts::eps_bearer_id)) { - log_h->error("CN associtaion type not supported %s \n", drb_cfg.cn_assoc.type().to_string().c_str()); + log_h->error("CN associtaion type not supported %s ", drb_cfg.cn_assoc.type().to_string().c_str()); return false; } - - drb_eps_bearer_id[drb_cfg.drb_id] = drb_cfg.cn_assoc.eps_bearer_id(); + uint32_t eps_bearer_id = drb_cfg.cn_assoc.eps_bearer_id(); + drb_eps_bearer_id[drb_cfg.drb_id] = eps_bearer_id; if (drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl_present && drb_cfg.pdcp_cfg.drb.pdcp_sn_size_ul_present && (drb_cfg.pdcp_cfg.drb.pdcp_sn_size_ul.to_number() != drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl.to_number())) { - log_h->warning("PDCP SN size in UL and DL are not the same. make_drb_pdcp_config_t will use the DL SN size %d \n", + log_h->warning("PDCP SN size in UL and DL are not the same. make_drb_pdcp_config_t will use the DL SN size %d ", drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl.to_number()); } srslte::pdcp_config_t pdcp_cfg = make_drb_pdcp_config_t(drb_cfg.drb_id, true, drb_cfg.pdcp_cfg); pdcp->add_bearer(lcid, pdcp_cfg); - + gw->update_lcid(eps_bearer_id, lcid); return true; } bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) { - // TODO derive correct keys if (security_cfg.key_to_use_present) { if (security_cfg.key_to_use.value != security_cfg_s::key_to_use_opts::options::secondary) { - log_h->warning("Only secondary key supported yet\n"); + log_h->warning("Only secondary key supported yet"); } } @@ -645,7 +665,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) sec_cfg.cipher_algo = CIPHERING_ALGORITHM_ID_128_EEA3; break; default: - log_h->warning("Unsupported algorithm\n"); + log_h->warning("Unsupported algorithm"); break; } @@ -664,7 +684,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) sec_cfg.integ_algo = INTEGRITY_ALGORITHM_ID_128_EIA3; break; default: - log_h->warning("Unsupported algorithm\n"); + log_h->warning("Unsupported algorithm"); break; } } @@ -708,19 +728,19 @@ proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool const uint32_t sk_counter_r15, const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg) { - Info("Starting...\n"); + Info("Starting..."); - Info("Applying Cell Group Cfg\n"); + Info("Applying Cell Group Cfg"); if (!rrc_ptr->apply_cell_group_cfg(cell_group_cfg)) { return proc_outcome_t::error; } if (sk_counter_r15_present) { - Info("Applying Cell Group Cfg\n"); + Info("Applying Cell Group Cfg"); rrc_ptr->configure_sk_counter((uint16_t)sk_counter_r15); } - Info("Applying Radio Bearer Cfg\n"); + Info("Applying Radio Bearer Cfg"); if (!rrc_ptr->apply_radio_bearer_cfg(radio_bearer_cfg)) { return proc_outcome_t::error; } @@ -730,20 +750,20 @@ proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::react(const bool& config_complete) { if (not config_complete) { - Error("Failed to config PHY\n"); + Error("Failed to config PHY"); return proc_outcome_t::error; } rrc_ptr->rrc_eutra->nr_rrc_con_reconfig_complete(true); - Info("Reconfig NR return successful\n"); + Info("Reconfig NR return successful"); return proc_outcome_t::success; } void rrc_nr::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result) { if (result.is_success()) { - Info("Finished %s successfully\n", name()); + Info("Finished %s successfully", name()); srslte::console("RRC NR reconfiguration successful.\n"); return; } @@ -752,4 +772,4 @@ void rrc_nr::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& resu // rrc_ptr->con_reconfig_failed(); } -} // namespace srsue \ No newline at end of file +} // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 0d544cc21..c6333105e 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -26,10 +26,10 @@ #include "srsue/hdr/stack/rrc/rrc_meas.h" #include // for printing uint64_t -#define Error(fmt, ...) rrc_ptr->rrc_log->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Warning(fmt, ...) rrc_ptr->rrc_log->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Info(fmt, ...) rrc_ptr->rrc_log->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Debug(fmt, ...) rrc_ptr->rrc_log->debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Error(fmt, ...) rrc_ptr->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Warning(fmt, ...) rrc_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Info(fmt, ...) rrc_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Debug(fmt, ...) rrc_ptr->logger.debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) namespace srsue { @@ -45,10 +45,10 @@ rrc::cell_search_proc::cell_search_proc(rrc* parent_) : rrc_ptr(parent_) {} /* Searches for a cell in the current frequency and retrieves SIB1 if not retrieved yet */ proc_outcome_t rrc::cell_search_proc::init() { - Info("Starting...\n"); + Info("Starting..."); state = state_t::phy_cell_search; if (not rrc_ptr->phy_ctrl->start_cell_search(rrc_ptr->cell_searcher)) { - Warning("Failed to initiate Cell Search.\n"); + Warning("Failed to initiate Cell Search."); return proc_outcome_t::error; } return proc_outcome_t::yield; @@ -77,22 +77,22 @@ proc_outcome_t rrc::cell_search_proc::step_si_acquire() } // SI Acquire has completed if (si_acquire_fut.is_error()) { - Error("Failed SI acquire for SIB0\n"); + Error("Failed SI acquire for SIB0"); search_result.cs_ret.found = cell_search_ret_t::CELL_NOT_FOUND; return proc_outcome_t::success; } - Info("Completed successfully\n"); + Info("Completed successfully"); return proc_outcome_t::success; } proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_cell_t& new_cell) { - Info("Cell found in this frequency. Setting new serving cell EARFCN=%d PCI=%d ...\n", new_cell.earfcn, new_cell.pci); + Info("Cell found in this frequency. Setting new serving cell EARFCN=%d PCI=%d ...", new_cell.earfcn, new_cell.pci); // Create a cell with NaN RSRP. Will be updated by new_phy_meas() during SIB search. if (not rrc_ptr->meas_cells.add_meas_cell( unique_cell_t(new meas_cell_eutra(new_cell, rrc_ptr->task_sched.get_unique_timer())))) { - Error("Could not add new found cell\n"); + Error("Could not add new found cell"); return proc_outcome_t::error; } @@ -101,7 +101,7 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_cell_t& new_ce // set new serving cell in PHY state = state_t::phy_cell_select; if (not rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, rrc_ptr->cell_searcher)) { - Error("Couldn't start phy cell selection\n"); + Error("Couldn't start phy cell selection"); return proc_outcome_t::error; } return proc_outcome_t::yield; @@ -114,14 +114,14 @@ proc_outcome_t rrc::cell_search_proc::step_wait_measurement() } if (rrc_ptr->meas_cells.serving_cell().has_sib1()) { - Info("Cell has SIB1\n"); + Info("Cell has SIB1"); return proc_outcome_t::success; } - Info("Cell has no SIB1. Obtaining SIB1...\n"); + Info("Cell has no SIB1. Obtaining SIB1..."); if (not rrc_ptr->si_acquirer.launch(&si_acquire_fut, 0)) { // disallow concurrent si_acquire - Error("SI Acquire is already running...\n"); + Error("SI Acquire is already running..."); return proc_outcome_t::error; } state = state_t::si_acquire; @@ -131,24 +131,24 @@ proc_outcome_t rrc::cell_search_proc::step_wait_measurement() proc_outcome_t rrc::cell_search_proc::react(const bool& cs_ret) { if (state != state_t::phy_cell_select) { - Warning("Received unexpected cell search result\n"); + Warning("Received unexpected cell search result"); return proc_outcome_t::yield; } if (not cs_ret) { - Error("Couldn't select new serving cell\n"); + Error("Couldn't select new serving cell"); search_result.cs_ret.found = cell_search_ret_t::CELL_NOT_FOUND; return proc_outcome_t::success; } if (not rrc_ptr->phy->cell_is_camping()) { - Warning("Could not camp on found cell.\n"); + Warning("Could not camp on found cell."); search_result.cs_ret.found = cell_search_ret_t::CELL_NOT_FOUND; return proc_outcome_t::success; } if (not std::isnormal(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { - Info("No valid measurement found for the serving cell. Wait for valid measurement...\n"); + Info("No valid measurement found for the serving cell. Wait for valid measurement..."); } state = state_t::wait_measurement; return proc_outcome_t::yield; @@ -157,7 +157,7 @@ proc_outcome_t rrc::cell_search_proc::react(const bool& cs_ret) proc_outcome_t rrc::cell_search_proc::react(const phy_controller::cell_srch_res& event) { if (state != state_t::phy_cell_search) { - Error("Received unexpected cell search result\n"); + Error("Received unexpected cell search result"); return proc_outcome_t::error; } search_result = event; @@ -245,7 +245,7 @@ compute_si_window(uint32_t tti, uint32_t sib_index, uint32_t n, uint32_t T, cons rrc::si_acquire_proc::si_acquire_proc(rrc* parent_) : rrc_ptr(parent_), - log_h(srslte::logmap::get("RRC")), + logger(srslog::fetch_basic_logger("RRC")), si_acq_timeout(rrc_ptr->task_sched.get_unique_timer()), si_acq_retry_timer(rrc_ptr->task_sched.get_unique_timer()) { @@ -261,22 +261,22 @@ proc_outcome_t rrc::si_acquire_proc::init(uint32_t sib_index_) { // make sure we dont already have the SIB of interest if (rrc_ptr->meas_cells.serving_cell().has_sib(sib_index_)) { - Info("The UE has already acquired SIB%d\n", sib_index + 1); + Info("The UE has already acquired SIB%d", sib_index + 1); return proc_outcome_t::success; } - Info("Starting SI Acquisition procedure for SIB%d\n", sib_index_ + 1); + Info("Starting SI Acquisition procedure for SIB%d", sib_index_ + 1); // make sure SIB1 is captured before other SIBs sib_index = sib_index_; if (sib_index > 0 and not rrc_ptr->meas_cells.serving_cell().has_sib1()) { - Error("Trying to acquire SIB%d but SIB1 not received yet\n", sib_index + 1); + Error("Trying to acquire SIB%d but SIB1 not received yet", sib_index + 1); return proc_outcome_t::error; } // compute the si-Periodicity and schedInfoList index auto ret = compute_si_periodicity_and_idx(sib_index, rrc_ptr->meas_cells.serving_cell().sib1ptr()); if (ret.second < 0) { - Info("Could not find SIB%d scheduling in SIB1\n", sib_index + 1); + Info("Could not find SIB%d scheduling in SIB1", sib_index + 1); return proc_outcome_t::error; } period = ret.first; // si-Periodicity @@ -298,9 +298,9 @@ void rrc::si_acquire_proc::then(const srslte::proc_state_t& result) si_acq_timeout.stop(); if (result.is_success()) { - Info("SIB%d acquired successfully\n", sib_index + 1); + Info("SIB%d acquired successfully", sib_index + 1); } else { - Error("Failed to acquire SIB%d\n", sib_index + 1); + Error("Failed to acquire SIB%d", sib_index + 1); } } @@ -314,7 +314,7 @@ void rrc::si_acquire_proc::start_si_acquire() compute_si_window(tti.to_uint(), sib_index, sched_index, period, rrc_ptr->meas_cells.serving_cell().sib1ptr()); tti_point si_win_start = tti_point{ret.first}; if (si_win_start < tti) { - Error("The SI Window start was incorrectly calculated. si_win_start=%d, tti=%d\n", + Error("The SI Window start was incorrectly calculated. si_win_start=%d, tti=%d", si_win_start.to_uint(), tti.to_uint()); return; @@ -329,7 +329,7 @@ void rrc::si_acquire_proc::start_si_acquire() si_acq_retry_timer.set(tics_until_si_retry); si_acq_retry_timer.run(); - Info("Instructed MAC to search for SIB%d, win_start=%d, win_len=%d, period=%d, sched_index=%d\n", + Info("Instructed MAC to search for SIB%d, win_start=%d, win_len=%d, period=%d, sched_index=%d", sib_index + 1, si_win_start.to_uint(), si_win_len, @@ -350,16 +350,16 @@ proc_outcome_t rrc::si_acquire_proc::react(si_acq_timer_expired ev) // retry si acquire if (ev.timer_id == si_acq_retry_timer.id()) { - Info("SI Acquire Retry Timeout for SIB%d\n", sib_index + 1); + Info("SI Acquire Retry Timeout for SIB%d", sib_index + 1); start_si_acquire(); return proc_outcome_t::yield; } // timeout. SI acquire failed if (ev.timer_id == si_acq_timeout.id()) { - Error("Timeout while acquiring SIB%d\n", sib_index + 1); + Error("Timeout while acquiring SIB%d", sib_index + 1); } else { - Error("Unrecognized timer id\n"); + Error("Unrecognized timer id"); } return proc_outcome_t::error; } @@ -369,8 +369,7 @@ proc_outcome_t rrc::si_acquire_proc::react(si_acq_timer_expired ev) *************************************/ rrc::serving_cell_config_proc::serving_cell_config_proc(rrc* parent_) : - rrc_ptr(parent_), - log_h(srslte::logmap::get("RRC")) + rrc_ptr(parent_), logger(srslog::fetch_basic_logger("RRC")) {} /* @@ -383,10 +382,10 @@ proc_outcome_t rrc::serving_cell_config_proc::init(const std::vector& std::sort(required_sibs.begin(), required_sibs.end()); required_sibs.erase(std::unique(required_sibs.begin(), required_sibs.end()), required_sibs.end()); - Info("Starting a Serving Cell Configuration Procedure\n"); + Info("Starting a Serving Cell Configuration Procedure"); if (not rrc_ptr->phy->cell_is_camping()) { - Error("Trying to configure Cell while not camping on it\n"); + Error("Trying to configure Cell while not camping on it"); return proc_outcome_t::error; } @@ -403,9 +402,9 @@ srslte::proc_outcome_t rrc::serving_cell_config_proc::launch_sib_acquire() uint32_t required_sib = required_sibs[req_idx]; if (not rrc_ptr->meas_cells.serving_cell().has_sib(required_sib)) { if (required_sib < 2 or rrc_ptr->meas_cells.serving_cell().is_sib_scheduled(required_sib)) { - Info("Cell has no SIB%d. Obtaining SIB%d\n", required_sib + 1, required_sib + 1); + Info("Cell has no SIB%d. Obtaining SIB%d", required_sib + 1, required_sib + 1); if (not rrc_ptr->si_acquirer.launch(&si_acquire_fut, required_sib)) { - Error("SI Acquire is already running...\n"); + Error("SI Acquire is already running..."); return proc_outcome_t::error; } // wait for si acquire to finish @@ -414,7 +413,7 @@ srslte::proc_outcome_t rrc::serving_cell_config_proc::launch_sib_acquire() // SIB is not scheduled in SchedInfoList. Skipping it... } else { // UE had SIB already. Handle its SIB - Info("Cell has SIB%d\n", required_sib + 1); + Info("Cell has SIB%d", required_sib + 1); switch (required_sib) { case 1: rrc_ptr->handle_sib2(); @@ -428,7 +427,7 @@ srslte::proc_outcome_t rrc::serving_cell_config_proc::launch_sib_acquire() } } - Info("Serving Cell Configuration Procedure has finished successfully\n"); + Info("Serving Cell Configuration Procedure has finished successfully"); return proc_outcome_t::success; } @@ -440,7 +439,7 @@ proc_outcome_t rrc::serving_cell_config_proc::step() uint32_t required_sib = required_sibs[req_idx]; if (si_acquire_fut.is_error() or not rrc_ptr->meas_cells.serving_cell().has_sib(required_sib)) { if (required_sib < 2) { - log_h->warning("Serving Cell Configuration has failed\n"); + logger.warning("Serving Cell Configuration has failed"); return proc_outcome_t::error; } } @@ -514,21 +513,21 @@ proc_outcome_t rrc::cell_selection_proc::init(std::vector required_sib // Skip cell selection if serving cell is suitable and there are no stronger neighbours in same earfcn if (is_serv_cell_suitable() and not stronger_neigh) { - Debug("Skipping cell selection procedure as there are no stronger neighbours in same EARFCN.\n"); + Debug("Skipping cell selection procedure as there are no stronger neighbours in same EARFCN."); return set_proc_complete(); } - Info("Starting...\n"); - Info("Current neighbor cells: [%s]\n", meas_cells->print_neighbour_cells().c_str()); - Info("Current PHY state: %s\n", rrc_ptr->phy_ctrl->is_in_sync() ? "in-sync" : "out-of-sync"); + Info("Starting..."); + Info("Current neighbor cells: [%s]", meas_cells->print_neighbour_cells().c_str()); + Info("Current PHY state: %s", rrc_ptr->phy_ctrl->is_in_sync() ? "in-sync" : "out-of-sync"); if (meas_cells->serving_cell().has_sib3()) { - Info("Cell selection criteria: Qrxlevmin=%f, Qrxlevminoffset=%f\n", + Info("Cell selection criteria: Qrxlevmin=%f, Qrxlevminoffset=%f", rrc_ptr->cell_resel_cfg.Qrxlevmin, rrc_ptr->cell_resel_cfg.Qrxlevminoffset); } else { - Info("Cell selection criteria: not available\n"); + Info("Cell selection criteria: not available"); } - Info("Current serving cell: %s\n", meas_cells->serving_cell().to_string().c_str()); + Info("Current serving cell: %s", meas_cells->serving_cell().to_string().c_str()); neigh_index = 0; cs_result = cs_result_t::no_cell; @@ -573,7 +572,7 @@ proc_outcome_t rrc::cell_selection_proc::start_next_cell_selection() // If any of the known cells meets the selection criteria or could not be selected, search again. if (not cell_search_called) { - Info("Could not select any known cell. Searching new cells\n"); + Info("Could not select any known cell. Searching new cells"); state = search_state_t::cell_search; cell_search_called = true; if (not rrc_ptr->cell_searcher.launch(&cell_search_fut)) { @@ -587,7 +586,7 @@ proc_outcome_t rrc::cell_selection_proc::start_next_cell_selection() proc_outcome_t rrc::cell_selection_proc::react(const bool& cell_selection_result) { if (state != search_state_t::cell_selection) { - Warning("Unexpected cell selection event received\n"); + Warning("Unexpected cell selection event received"); return proc_outcome_t::yield; } @@ -601,7 +600,7 @@ proc_outcome_t rrc::cell_selection_proc::react(const bool& cell_selection_result } } - Info("Cell selection criteria not passed.\n"); + Info("Cell selection criteria not passed."); discard_serving = not is_same_cell(init_serv_cell, meas_cells->serving_cell()); return start_next_cell_selection(); @@ -612,7 +611,7 @@ srslte::proc_outcome_t rrc::cell_selection_proc::start_phy_cell_selection(const if (not is_same_cell(cell, meas_cells->serving_cell())) { rrc_ptr->set_serving_cell(cell.phy_cell, discard_serving); discard_serving = false; - Info("Set serving cell: %s\n", meas_cells->serving_cell().to_string().c_str()); + Info("Set serving cell: %s", meas_cells->serving_cell().to_string().c_str()); } else { // in case the cell had already been selected if (is_serv_cell_suitable()) { @@ -625,7 +624,7 @@ srslte::proc_outcome_t rrc::cell_selection_proc::start_phy_cell_selection(const state = search_state_t::cell_selection; if (not rrc_ptr->phy_ctrl->start_cell_select(meas_cells->serving_cell().phy_cell, rrc_ptr->cell_selector)) { - Error("Failed to launch PHY Cell Selection\n"); + Error("Failed to launch PHY Cell Selection"); return set_proc_complete(); } return proc_outcome_t::yield; @@ -633,10 +632,10 @@ srslte::proc_outcome_t rrc::cell_selection_proc::start_phy_cell_selection(const srslte::proc_outcome_t rrc::cell_selection_proc::start_sib_acquisition() { - Info("PHY is camping on serving cell, but SIBs need to be acquired\n"); + Info("PHY is camping on serving cell, but SIBs need to be acquired"); state = search_state_t::cell_config; if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, required_sibs)) { - Warning("Failed to launch %s procedure\n", rrc_ptr->serv_cell_cfg.get()->name()); + Warning("Failed to launch %s procedure", rrc_ptr->serv_cell_cfg.get()->name()); return set_proc_complete(); } return proc_outcome_t::yield; @@ -663,7 +662,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_config() if (is_serv_cell_suitable()) { return set_proc_complete(); } - Error("Failed to configure serving cell\n"); + Error("Failed to configure serving cell"); return start_next_cell_selection(); } @@ -686,7 +685,7 @@ proc_outcome_t rrc::cell_selection_proc::step() void rrc::cell_selection_proc::then(const srslte::proc_result_t& proc_result) const { - Info("Completed with %s.\n", proc_result.is_success() ? "success" : "failure"); + Info("Completed with %s.", proc_result.is_success() ? "success" : "failure"); // Inform Connection Request Procedure rrc_ptr->task_sched.defer_task([this, proc_result]() { if (rrc_ptr->conn_req_proc.is_busy()) { @@ -701,15 +700,15 @@ void rrc::cell_selection_proc::then(const srslte::proc_result_t& pr * PLMN search Procedure *************************************/ -rrc::plmn_search_proc::plmn_search_proc(rrc* parent_) : rrc_ptr(parent_), log_h(srslte::logmap::get("RRC")) {} +rrc::plmn_search_proc::plmn_search_proc(rrc* parent_) : rrc_ptr(parent_), logger(srslog::fetch_basic_logger("RRC")) {} proc_outcome_t rrc::plmn_search_proc::init() { - Info("Starting PLMN search\n"); + Info("Starting PLMN search"); nof_plmns = 0; cell_search_fut = rrc_ptr->cell_searcher.get_future(); if (not rrc_ptr->cell_searcher.launch(&cell_search_fut)) { - Error("Failed due to fail to init cell search...\n"); + Error("Failed due to fail to init cell search..."); return proc_outcome_t::error; } return step(); @@ -729,7 +728,7 @@ proc_outcome_t rrc::plmn_search_proc::step() if (cell_search_fut.is_error() or cell_search_fut.value()->found == cell_search_ret_t::ERROR) { // stop search nof_plmns = -1; - Error("Failed due to failed cell search sub-procedure\n"); + Error("Failed due to failed cell search sub-procedure"); return proc_outcome_t::error; } @@ -742,21 +741,21 @@ proc_outcome_t rrc::plmn_search_proc::step() found_plmns[nof_plmns].tac = rrc_ptr->meas_cells.serving_cell().get_tac(); nof_plmns++; } else { - Error("No more space for plmns (%d)\n", nof_plmns); + Error("No more space for plmns (%d)", nof_plmns); } } } else { - Error("SIB1 not acquired\n"); + Error("SIB1 not acquired"); } } if (cell_search_fut.value()->last_freq == cell_search_ret_t::NO_MORE_FREQS) { - Info("completed PLMN search\n"); + Info("completed PLMN search"); return proc_outcome_t::success; } if (not rrc_ptr->cell_searcher.launch(&cell_search_fut)) { - Error("Failed due to fail to init cell search...\n"); + Error("Failed due to fail to init cell search..."); return proc_outcome_t::error; } @@ -768,10 +767,10 @@ void rrc::plmn_search_proc::then(const srslte::proc_state_t& result) const { // on cleanup, call plmn_search_completed if (result.is_success()) { - Info("completed with success\n"); + Info("completed with success"); rrc_ptr->nas->plmn_search_completed(found_plmns, nof_plmns); } else { - Error("PLMN Search completed with an error\n"); + Error("PLMN Search completed with an error"); rrc_ptr->nas->plmn_search_completed(nullptr, -1); } } @@ -781,8 +780,7 @@ void rrc::plmn_search_proc::then(const srslte::proc_state_t& result) const *************************************/ rrc::connection_request_proc::connection_request_proc(rrc* parent_) : - rrc_ptr(parent_), - log_h(srslte::logmap::get("RRC")) + rrc_ptr(parent_), logger(srslog::fetch_basic_logger("RRC")) {} proc_outcome_t rrc::connection_request_proc::init(srslte::establishment_cause_t cause_, @@ -792,22 +790,22 @@ proc_outcome_t rrc::connection_request_proc::init(srslte::establishment_cause_t dedicated_info_nas = std::move(dedicated_info_nas_); if (!rrc_ptr->plmn_is_selected) { - Error("Trying to connect but PLMN not selected.\n"); + Error("Trying to connect but PLMN not selected."); return proc_outcome_t::error; } if (rrc_ptr->state != RRC_STATE_IDLE) { - log_h->warning("Requested RRC connection establishment while not in IDLE\n"); + logger.warning("Requested RRC connection establishment while not in IDLE"); return proc_outcome_t::error; } if (rrc_ptr->t302.is_running()) { - Info("Requested RRC connection establishment while T302 is running\n"); + Info("Requested RRC connection establishment while T302 is running"); rrc_ptr->nas->set_barring(srslte::barring_t::mo_data); return proc_outcome_t::error; } - Info("Initiation of Connection establishment procedure\n"); + Info("Initiation of Connection establishment procedure"); cs_ret = cs_result_t::no_cell; @@ -815,12 +813,12 @@ proc_outcome_t rrc::connection_request_proc::init(srslte::establishment_cause_t if (rrc_ptr->cell_selector.is_idle()) { // No one is running cell selection if (not rrc_ptr->cell_selector.launch()) { - Error("Failed to initiate cell selection procedure...\n"); + Error("Failed to initiate cell selection procedure..."); return proc_outcome_t::error; } rrc_ptr->callback_list.add_proc(rrc_ptr->cell_selector); } else { - Info("Cell selection proc already on-going. Wait for its result\n"); + Info("Cell selection proc already on-going. Wait for its result"); } return proc_outcome_t::yield; } @@ -835,7 +833,7 @@ proc_outcome_t rrc::connection_request_proc::step() return proc_outcome_t::yield; } if (serv_cfg_fut.is_error()) { - Error("Configuring serving cell\n"); + Error("Configuring serving cell"); return proc_outcome_t::error; } @@ -847,17 +845,17 @@ proc_outcome_t rrc::connection_request_proc::step() // Save dedicatedInfoNAS SDU, if needed if (dedicated_info_nas.get()) { if (rrc_ptr->dedicated_info_nas.get()) { - Warning("Received a new dedicatedInfoNAS SDU but there was one still in queue. Removing it.\n"); + Warning("Received a new dedicatedInfoNAS SDU but there was one still in queue. Removing it."); rrc_ptr->dedicated_info_nas.reset(); } - Debug("Updating dedicatedInfoNAS in RRC\n"); + Debug("Updating dedicatedInfoNAS in RRC"); rrc_ptr->dedicated_info_nas = std::move(dedicated_info_nas); } else { - Debug("dedicatedInfoNAS has already been provided to RRC.\n"); + Debug("dedicatedInfoNAS has already been provided to RRC."); } - Info("Waiting for RRCConnectionSetup/Reject or expiry\n"); + Info("Waiting for RRCConnectionSetup/Reject or expiry"); state = state_t::wait_t300; return step(); @@ -872,13 +870,13 @@ proc_outcome_t rrc::connection_request_proc::step() return proc_outcome_t::success; } else if (rrc_ptr->t300.is_expired()) { // T300 is expired: 5.3.3.6 - Warning("Timer T300 expired: ConnectionRequest timed out\n"); + Warning("Timer T300 expired: ConnectionRequest timed out"); rrc_ptr->mac->reset(); rrc_ptr->set_mac_default(); rrc_ptr->rlc->reestablish(); } else { // T300 is stopped but RRC not Connected is because received Reject: Section 5.3.3.8 - Warning("Timer T300 stopped: Received ConnectionReject\n"); + Warning("Timer T300 stopped: Received ConnectionReject"); rrc_ptr->mac->reset(); rrc_ptr->set_mac_default(); } @@ -890,11 +888,11 @@ proc_outcome_t rrc::connection_request_proc::step() void rrc::connection_request_proc::then(const srslte::proc_state_t& result) { if (result.is_error()) { - log_h->warning("Could not establish connection. Deallocating dedicatedInfoNAS PDU\n"); + logger.warning("Could not establish connection. Deallocating dedicatedInfoNAS PDU"); dedicated_info_nas.reset(); rrc_ptr->dedicated_info_nas.reset(); } else { - Info("Finished connection request procedure successfully.\n"); + Info("Finished connection request procedure successfully."); } rrc_ptr->nas->connection_request_completed(result.is_success()); } @@ -911,7 +909,6 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_ cs_ret = *e.value(); // .. and SI acquisition if (rrc_ptr->phy->cell_is_camping()) { - // Set default configurations rrc_ptr->set_phy_default(); rrc_ptr->set_mac_default(); @@ -919,23 +916,23 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_ // CCCH configuration applied already at start // timeAlignmentCommon applied in configure_serving_cell - Info("Configuring serving cell...\n"); + Info("Configuring serving cell..."); state = state_t::config_serving_cell; if (not rrc_ptr->serv_cell_cfg.launch(&serv_cfg_fut, rrc_ptr->ue_required_sibs)) { - Error("Attach request failed to configure serving cell...\n"); + Error("Attach request failed to configure serving cell..."); return proc_outcome_t::error; } return step(); } else { switch (cs_ret) { case cs_result_t::same_cell: - log_h->warning("Did not reselect cell but serving cell is out-of-sync.\n"); + logger.warning("Did not reselect cell but serving cell is out-of-sync."); break; case cs_result_t::changed_cell: - log_h->warning("Selected a new cell but could not camp on. Setting out-of-sync.\n"); + logger.warning("Selected a new cell but could not camp on. Setting out-of-sync."); break; default: - log_h->warning("Could not find any suitable cell to connect\n"); + logger.warning("Could not find any suitable cell to connect"); } return proc_outcome_t::error; } @@ -950,7 +947,7 @@ rrc::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(srsue::rrc* pare srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& recfg_) { - Info("Starting...\n"); + Info("Starting..."); rx_recfg = recfg_.crit_exts.c1().rrc_conn_recfg_r8(); // If first message after reestablishment, resume SRB2 and all DRB @@ -969,8 +966,9 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: rrc_ptr->reestablishment_successful = false; for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { if (rrc_ptr->rlc->has_bearer(i)) { - rrc_ptr->pdcp->reestablish(i); rrc_ptr->rlc->reestablish(i); + rrc_ptr->pdcp->reestablish(i); + rrc_ptr->pdcp->send_status_report(i); } } } @@ -981,6 +979,7 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: return proc_outcome_t::error; } } + // Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside // apply_scell_config() Note that apply_scell_config() calls set_scell() and set_config() which run in the // background. @@ -992,14 +991,12 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: } // Apply NR config -#ifdef HAVE_5GNR bool rtn = rrc_ptr->nr_reconfiguration_proc(rx_recfg); if (rtn == false) { - rrc_ptr->rrc_log->error("Can not launch NR RRC Reconfiguration procedure\n"); + rrc_ptr->logger.error("Can not launch NR RRC Reconfiguration procedure"); return proc_outcome_t::error; } has_5g_nr_reconfig = true; -#endif // No phy config was scheduled, run config completion immediately if (rrc_ptr->phy_ctrl->is_config_pending()) { @@ -1011,7 +1008,7 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc:: srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& config_complete) { if (not config_complete) { - rrc_ptr->rrc_log->error("Failed to config PHY\n"); + rrc_ptr->logger.error("Failed to config PHY"); return proc_outcome_t::error; } @@ -1020,12 +1017,10 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& conf return proc_outcome_t::yield; } -#ifdef HAVE_5GNR // in case there is rrc_nr to configure, wait for rrc nr configuration if (has_5g_nr_reconfig == true && rrc_ptr->rrc_nr->is_config_pending()) { return proc_outcome_t::yield; } -#endif if (has_5g_nr_reconfig == true) { rrc_ptr->send_rrc_con_reconfig_complete(true); @@ -1035,13 +1030,13 @@ srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& conf srslte::unique_byte_buffer_t nas_pdu; for (auto& pdu : rx_recfg.ded_info_nas_list) { - nas_pdu = srslte::allocate_unique_buffer(*rrc_ptr->pool); + nas_pdu = srslte::make_byte_buffer(); if (nas_pdu.get()) { memcpy(nas_pdu->msg, pdu.data(), pdu.size()); nas_pdu->N_bytes = pdu.size(); rrc_ptr->nas->write_pdu(RB_ID_SRB1, std::move(nas_pdu)); } else { - rrc_ptr->rrc_log->error("Fatal Error: Couldn't allocate PDU in %s.\n", __FUNCTION__); + rrc_ptr->logger.error("Fatal Error: Couldn't allocate PDU in %s.", __FUNCTION__); return proc_outcome_t::error; } } @@ -1055,7 +1050,7 @@ void rrc::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result) has_5g_nr_reconfig = false; if (result.is_success()) { - rrc_ptr->rrc_log->info("Finished %s successfully\n", name()); + rrc_ptr->logger.info("Finished %s successfully", name()); return; } @@ -1068,7 +1063,9 @@ void rrc::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result) * Process PCCH procedure *************************************/ -rrc::process_pcch_proc::process_pcch_proc(srsue::rrc* parent_) : rrc_ptr(parent_), log_h(srslte::logmap::get("RRC")) {} +rrc::process_pcch_proc::process_pcch_proc(srsue::rrc* parent_) : + rrc_ptr(parent_), logger(srslog::fetch_basic_logger("RRC")) +{} proc_outcome_t rrc::process_pcch_proc::init(const asn1::rrc::paging_s& paging_) { @@ -1076,7 +1073,7 @@ proc_outcome_t rrc::process_pcch_proc::init(const asn1::rrc::paging_s& paging_) paging_idx = 0; state = state_t::next_record; - Info("starting...\n"); + Info("starting..."); return step(); } @@ -1085,40 +1082,40 @@ proc_outcome_t rrc::process_pcch_proc::step() if (state == state_t::next_record) { for (; paging_idx < paging.paging_record_list.size(); ++paging_idx) { srslte::s_tmsi_t s_tmsi_paged = srslte::make_s_tmsi_t(paging.paging_record_list[paging_idx].ue_id.s_tmsi()); - Info("Received paging (%d/%d) for UE %" PRIu64 ":%" PRIu64 "\n", + Info("Received paging (%d/%d) for UE %" PRIu64 ":%" PRIu64 "", paging_idx + 1, paging.paging_record_list.size(), paging.paging_record_list[paging_idx].ue_id.s_tmsi().mmec.to_number(), paging.paging_record_list[paging_idx].ue_id.s_tmsi().m_tmsi.to_number()); if (rrc_ptr->ue_identity == s_tmsi_paged) { if (RRC_STATE_IDLE == rrc_ptr->state) { - Info("S-TMSI match in paging message\n"); + Info("S-TMSI match in paging message"); srslte::console("S-TMSI match in paging message\n"); if (not rrc_ptr->nas->paging(&s_tmsi_paged)) { - Error("Unable to start NAS paging proc\n"); + Error("Unable to start NAS paging proc"); return proc_outcome_t::error; } state = state_t::nas_paging; return step(); } else { - Warning("Received paging while in CONNECT\n"); + Warning("Received paging while in CONNECT"); } } else { - Info("Received paging for unknown identity\n"); + Info("Received paging for unknown identity"); } } if (paging.sys_info_mod_present) { - Info("Received System Information notification update request.\n"); + Info("Received System Information notification update request."); // invalidate and then update all SIBs of serving cell rrc_ptr->meas_cells.serving_cell().reset_sibs(); // create a serving cell config procedure and push it to callback list if (not rrc_ptr->serv_cell_cfg.launch(&serv_cfg_fut, rrc_ptr->ue_required_sibs)) { - Error("Failed to initiate a serving cell configuration procedure\n"); + Error("Failed to initiate a serving cell configuration procedure"); return proc_outcome_t::error; } } else { - Info("Completed successfully\n"); + Info("Completed successfully"); return proc_outcome_t::success; } state = state_t::serv_cell_cfg; @@ -1131,10 +1128,10 @@ proc_outcome_t rrc::process_pcch_proc::step() return proc_outcome_t::yield; } if (serv_cfg_fut.is_success()) { - Info("All SIBs of serving cell obtained successfully\n"); + Info("All SIBs of serving cell obtained successfully"); return proc_outcome_t::success; } else { - Error("While obtaining SIBs of serving cell\n"); + Error("While obtaining SIBs of serving cell"); return proc_outcome_t::error; } } @@ -1144,16 +1141,16 @@ proc_outcome_t rrc::process_pcch_proc::step() proc_outcome_t rrc::process_pcch_proc::react(paging_complete e) { if (state != state_t::nas_paging) { - Warning("Received an unexpected paging complete\n"); + Warning("Received an unexpected paging complete"); return proc_outcome_t::yield; } if (not e.outcome) { - Info("NAS Paging has failed\n"); + Info("NAS Paging has failed"); return proc_outcome_t::error; } paging_idx++; state = state_t::next_record; - Info("Received paging complete event\n"); + Info("Received paging complete event"); return step(); } @@ -1169,7 +1166,7 @@ rrc::go_idle_proc::go_idle_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) proc_outcome_t rrc::go_idle_proc::init() { - Info("Starting...\n"); + Info("Starting..."); rlc_flush_timer.run(); // Do not call step() directly. Instead we defer for one TTI to avoid double-locking the RLC mutex return proc_outcome_t::yield; @@ -1178,24 +1175,25 @@ proc_outcome_t rrc::go_idle_proc::init() srslte::proc_outcome_t rrc::go_idle_proc::react(bool timeout) { rrc_ptr->leave_connected(); - Info("Left connected state\n"); + Info("Left connected state"); return proc_outcome_t::success; } proc_outcome_t rrc::go_idle_proc::step() { if (rrc_ptr->state == RRC_STATE_IDLE) { - Info("Interrupting as RRC has already became IDLE\n"); + Info("Interrupting as RRC has already became IDLE"); return proc_outcome_t::success; } // wait for RLC of SRB1 and SRB2 to be flushed if (rrc_ptr->srbs_flushed()) { rrc_ptr->leave_connected(); - Info("Left connected state\n"); + Info("Left connected state"); return proc_outcome_t::success; } else { - Debug("Postponing transition to RRC IDLE (%d ms < %d ms)\n", rlc_flush_timer.time_elapsed(), rlc_flush_timeout_ms); + Debug( + "Postponing transition to RRC IDLE (%d ms < %d ms)", rlc_flush_timer.time_elapsed(), int(rlc_flush_timeout_ms)); } return proc_outcome_t::yield; } @@ -1203,7 +1201,7 @@ proc_outcome_t rrc::go_idle_proc::step() void rrc::go_idle_proc::then(const srslte::proc_state_t& result) { if (rrc_ptr->nas->is_registered() and not rrc_ptr->cell_reselector.launch()) { - rrc_ptr->rrc_log->error("Failed to initiate a Cell Reselection procedure...\n"); + rrc_ptr->logger.error("Failed to initiate a Cell Reselection procedure..."); return; } rrc_ptr->callback_list.add_proc(rrc_ptr->cell_reselector); @@ -1219,7 +1217,7 @@ rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rr reselection_timer = rrc_ptr->task_sched.get_unique_timer(); reselection_timer.set(cell_reselection_periodicity_ms, [this](uint32_t tid) { if (not rrc_ptr->cell_reselector.launch()) { - rrc_ptr->rrc_log->error("Failed to initiate a Cell Reselection procedure...\n"); + rrc_ptr->logger.error("Failed to initiate a Cell Reselection procedure..."); return; } rrc_ptr->callback_list.add_proc(rrc_ptr->cell_reselector); @@ -1228,9 +1226,9 @@ rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rr proc_outcome_t rrc::cell_reselection_proc::init() { - Info("Starting...\n"); + Info("Starting..."); if (not rrc_ptr->cell_selector.launch(&cell_selection_fut)) { - Error("Failed to initiate a Cell Selection procedure...\n"); + Error("Failed to initiate a Cell Selection procedure..."); return proc_outcome_t::error; } @@ -1243,29 +1241,29 @@ proc_outcome_t rrc::cell_reselection_proc::step() return srslte::proc_outcome_t::yield; } if (cell_selection_fut.is_error()) { - Error("Error while selecting a cell\n"); + Error("Error while selecting a cell"); return srslte::proc_outcome_t::error; } cell_sel_result = *cell_selection_fut.value(); - Info("Cell Selection completed. Handling its result...\n"); + Info("Cell Selection completed. Handling its result..."); switch (cell_sel_result) { case cs_result_t::changed_cell: if (rrc_ptr->state == rrc_state_t::RRC_STATE_IDLE) { - Info("New cell has been selected, start receiving PCCH\n"); + Info("New cell has been selected, start receiving PCCH"); rrc_ptr->mac->pcch_start_rx(); } break; case cs_result_t::no_cell: - Warning("Could not find any cell to camp on\n"); + Warning("Could not find any cell to camp on"); break; case cs_result_t::same_cell: if (!rrc_ptr->phy->cell_is_camping()) { - Warning("Did not reselect cell but serving cell is out-of-sync.\n"); + Warning("Did not reselect cell but serving cell is out-of-sync."); } break; } - Info("Finished successfully\n"); + Info("Finished successfully"); return srslte::proc_outcome_t::success; } @@ -1314,7 +1312,7 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) // 5.3.7.1 - Conditions for Reestablishment procedure if (not rrc_ptr->security_is_activated or rrc_ptr->state != RRC_STATE_CONNECTED or uernti.crnti == SRSLTE_INVALID_RNTI) { - Warning("Conditions are NOT met to start procedure.\n"); + Warning("Conditions are NOT met to start procedure."); return proc_outcome_t::error; } @@ -1331,10 +1329,10 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) } reest_cellid = rrc_ptr->meas_cells.find_cell(reest_source_freq, reest_source_pci)->get_cell_id(); - Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, CELL ID=%d}\n", - reest_cause == asn1::rrc::reest_cause_opts::recfg_fail - ? "Reconfiguration failure" - : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" : "Other failure", + Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, CELL ID=%d}", + reest_cause == asn1::rrc::reest_cause_opts::recfg_fail ? "Reconfiguration failure" + : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" + : "Other failure", reest_rnti, reest_source_pci, reest_cellid); @@ -1386,17 +1384,17 @@ bool rrc::connection_reest_proc::passes_cell_criteria() const srslte::proc_outcome_t rrc::connection_reest_proc::cell_criteria() { if (not passes_cell_criteria()) { - Info("Selected Serving cell does not pass criteria. Re-launching re-selection procedure\n"); + Info("Selected Serving cell does not pass criteria. Re-launching re-selection procedure"); return start_cell_selection(); } // Upon selecting a suitable E-UTRA cell, the UE shall: - Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n", + Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request", rrc_ptr->t311.time_elapsed()); // Note: Not explicitly defined in the specs, but UE should apply SIB1 and SIB2 configuration in order to attempt // a PRACH to a different cell - Info("Applying SIB2 configuration\n"); + Info("Applying SIB2 configuration"); rrc_ptr->handle_sib2(); // 1> stop timer T311; @@ -1420,7 +1418,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::start_cell_selection() // Launch cell reselection state = state_t::wait_cell_selection; if (not rrc_ptr->cell_selector.launch(std::vector{0, 1, 2})) { - Error("Failed to initiate a Cell re-selection procedure...\n"); + Error("Failed to initiate a Cell re-selection procedure..."); // Wait for T311 to expire return proc_outcome_t::yield; } @@ -1432,14 +1430,14 @@ srslte::proc_outcome_t rrc::connection_reest_proc::react(const cell_selection_proc::cell_selection_complete_ev& cell_selected_ev) { if (state != state_t::wait_cell_selection) { - Warning("Received unexpected \"%s\" completion signal\n", rrc_ptr->cell_selector.get()->name()); + Warning("Received unexpected \"%s\" completion signal", rrc_ptr->cell_selector.get()->name()); return proc_outcome_t::yield; } // Relaunch cell selection if there is still time if (cell_selected_ev.is_error() or not rrc_ptr->phy_ctrl->is_in_sync()) { // Out-of-sync, relaunch reselection - Info("Serving cell is out-of-sync, re-launching re-selection procedure. T311: %d/%d ms\n", + Info("Serving cell is out-of-sync, re-launching re-selection procedure. T311: %d/%d ms", rrc_ptr->t311.time_elapsed(), rrc_ptr->t311.duration()); return start_cell_selection(); @@ -1448,7 +1446,7 @@ rrc::connection_reest_proc::react(const cell_selection_proc::cell_selection_comp // SIBs should be available if (not rrc_ptr->meas_cells.serving_cell().has_sib1() or not rrc_ptr->meas_cells.serving_cell().has_sib2() or not rrc_ptr->meas_cells.serving_cell().has_sib3()) { - Warning("SIBs missing (%d, %d, %d) after cell selection procedure\n", + Warning("SIBs missing (%d, %d, %d) after cell selection procedure", rrc_ptr->meas_cells.serving_cell().has_sib1(), rrc_ptr->meas_cells.serving_cell().has_sib2(), rrc_ptr->meas_cells.serving_cell().has_sib3()); @@ -1505,14 +1503,14 @@ srslte::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_co // procedure ends; rrc_ptr->send_con_restablish_complete(); - Info("Finished successfully\n"); + Info("Finished successfully"); return proc_outcome_t::success; } // 5.3.7.7 - T301 expiry or selected cell no longer suitable srslte::proc_outcome_t rrc::connection_reest_proc::react(const t301_expiry& ev) { - Info("Timer T301 expired: Going to RRC IDLE\n"); + Info("Timer T301 expired: Going to RRC IDLE"); srslte::console("Timer T301 expired: Going to RRC IDLE\n"); rrc_ptr->start_go_idle(); @@ -1521,7 +1519,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::react(const t301_expiry& ev) srslte::proc_outcome_t rrc::connection_reest_proc::step() { if (rrc_ptr->t301.is_running() and not passes_cell_criteria()) { - Info("Selected cell no longer suitable: Going to RRC IDLE\n"); + Info("Selected cell no longer suitable: Going to RRC IDLE"); srslte::console("Selected cell no longer suitable: Going to RRC IDLE\n"); rrc_ptr->start_go_idle(); return proc_outcome_t::error; @@ -1533,7 +1531,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::step() srslte::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_conn_reest_reject_s& reject_msg) { srslte::console("Reestablishment Reject. Going to RRC IDLE\n"); - Info("Reestablishment Reject. Going to RRC IDLE\n"); + Info("Reestablishment Reject. Going to RRC IDLE"); rrc_ptr->t301.stop(); rrc_ptr->start_go_idle(); return proc_outcome_t::error; @@ -1543,7 +1541,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_co srslte::proc_outcome_t rrc::connection_reest_proc::react(const t311_expiry& ev) { // Abort procedure if T311 expires - Info("T311 expired during cell configuration. Going to RRC IDLE\n"); + Info("T311 expired during cell configuration. Going to RRC IDLE"); rrc_ptr->start_go_idle(); return proc_outcome_t::error; } @@ -1569,12 +1567,12 @@ rrc::ho_proc::ho_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) {} */ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc_reconf) { - Info("Starting...\n"); + Info("Starting..."); recfg_r8 = rrc_reconf.crit_exts.c1().rrc_conn_recfg_r8(); asn1::rrc::mob_ctrl_info_s* mob_ctrl_info = &recfg_r8.mob_ctrl_info; size_t nof_scells_active = rrc_ptr->phy_ctrl->current_config_scells().count(); - Info("Received HO command to target PCell=%d\n", mob_ctrl_info->target_pci); + Info("Received HO command to target PCell=%d", mob_ctrl_info->target_pci); srslte::console("Received HO command to target PCell=%d, NCC=%d\n", mob_ctrl_info->target_pci, recfg_r8.security_cfg_ho.handov_type.intra_lte().next_hop_chaining_count); @@ -1588,7 +1586,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc target_cell = cell_to_ho->phy_cell; } else { srslte::console("Received HO command to unknown PCI=%d\n", mob_ctrl_info->target_pci); - Error("Could not find target cell earfcn=%d, pci=%d\n", + Error("Could not find target cell earfcn=%d, pci=%d", rrc_ptr->meas_cells.serving_cell().get_earfcn(), mob_ctrl_info->target_pci); rrc_ptr->con_reconfig_failed(); @@ -1608,9 +1606,9 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // starting at start synchronising to the DL of the target PCell rrc_ptr->set_serving_cell(target_cell, false); - Info("Starting cell selection of target cell PCI=%d EARFCN=%d\n", target_cell.pci, target_cell.earfcn); + Info("Starting cell selection of target cell PCI=%d EARFCN=%d", target_cell.pci, target_cell.earfcn); if (not rrc_ptr->phy_ctrl->start_cell_select(target_cell)) { - Error("Failed to launch the selection of target cell PCI=%d EARFCN=%d\n", target_cell.pci, target_cell.earfcn); + Error("Failed to launch the selection of target cell PCI=%d EARFCN=%d", target_cell.pci, target_cell.earfcn); return proc_outcome_t::yield; // wait t304 expiry } @@ -1618,8 +1616,8 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc rrc_ptr->mac->reset(); // Reestablish PDCP/RLC - rrc_ptr->pdcp->reestablish(); rrc_ptr->rlc->reestablish(); + rrc_ptr->pdcp->reestablish(); // configure lower layers to consider the SCell(s), if configured, to be in deactivated state; if (nof_scells_active > 0) { @@ -1631,7 +1629,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // perform radio configuration when fullConfig is enabled if (recfg_r8.non_crit_ext.non_crit_ext.full_cfg_r9_present) { - Error("fullConfig section was present but is not supported. Ignoring it.\n"); + Error("fullConfig section was present but is not supported. Ignoring it."); } // configure lower layers in accordance with the received radioResourceConfigCommon @@ -1641,7 +1639,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // configure lower layers in accordance with any additional fields, not covered in the previous, if included in the // received mobilityControlInfo if (recfg_r8.mob_ctrl_info.rach_cfg_ded_present) { - Info("Configuring RACH dedicated configuration with preamble_idx=%d, mask_idx=%d\n", + Info("Configuring RACH dedicated configuration with preamble_idx=%d, mask_idx=%d", recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_preamb_idx, recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_prach_mask_idx); rrc_ptr->mac->set_rach_ded_cfg(recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_preamb_idx, @@ -1669,7 +1667,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc (srslte::CIPHERING_ALGORITHM_ID_ENUM)sec_intralte.security_algorithm_cfg.ciphering_algorithm.to_number(); rrc_ptr->sec_cfg.integ_algo = (srslte::INTEGRITY_ALGORITHM_ID_ENUM)sec_intralte.security_algorithm_cfg.integrity_prot_algorithm.to_number(); - Info("Changed Ciphering to %s and Integrity to %s\n", + Info("Changed Ciphering to %s and Integrity to %s", srslte::ciphering_algorithm_id_text[rrc_ptr->sec_cfg.cipher_algo], srslte::integrity_algorithm_id_text[rrc_ptr->sec_cfg.integ_algo]); } @@ -1684,7 +1682,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // if the RRCConnectionReconfiguration message includes the measConfig: if (not rrc_ptr->measurements->parse_meas_config(&recfg_r8, true, ho_src_cell.earfcn)) { - Error("Parsing measurementConfig. TODO: Send ReconfigurationReject\n"); + Error("Parsing measurementConfig. TODO: Send ReconfigurationReject"); return proc_outcome_t::yield; // wait for t304 expiry } @@ -1694,14 +1692,17 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // SCell addition/removal can take some time to compute. Enqueue in a background task and do it in the end. rrc_ptr->apply_scell_config(&recfg_r8, false); - Info("Finished HO configuration. Waiting PHY to synchronize with target cell\n"); + // Send PDCP status report if configured + rrc_ptr->pdcp->send_status_report(); + + Info("Finished HO configuration. Waiting PHY to synchronize with target cell"); return proc_outcome_t::yield; } srslte::proc_outcome_t rrc::ho_proc::react(t304_expiry ev) { - Info("HO preparation timed out. Reverting RRC security config from source cell.\n"); + Info("HO preparation timed out. Reverting RRC security config from source cell."); // revert security settings from source cell for reestablishment according to Sec 5.3.7.4 rrc_ptr->usim->restore_keys_from_failed_ho(&rrc_ptr->sec_cfg); @@ -1714,7 +1715,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(t304_expiry ev) srslte::proc_outcome_t rrc::ho_proc::react(ra_completed_ev ev) { if (ev.success) { - Info("Random Access completed. Applying final configuration and finishing procedure\n"); + Info("Random Access completed. Applying final configuration and finishing procedure"); // TS 36.331, sec. 5.3.5.4, last "1>" rrc_ptr->t304.stop(); @@ -1729,7 +1730,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(ra_completed_ev ev) void rrc::ho_proc::then(const srslte::proc_state_t& result) { - Info("HO to PCI=%d, EARFCN=%d %ssuccessful\n", target_cell.pci, target_cell.earfcn, result.is_success() ? "" : "un"); + Info("HO to PCI=%d, EARFCN=%d %ssuccessful", target_cell.pci, target_cell.earfcn, result.is_success() ? "" : "un"); srslte::console("HO %ssuccessful\n", result.is_success() ? "" : "un"); rrc_ptr->t304.stop(); diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 8803dd38a..c18ce250b 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -31,24 +31,30 @@ using namespace srslte; namespace srsue { -ue_stack_lte::ue_stack_lte() : +ue_stack_lte::ue_stack_lte(srslog::sink& log_sink) : running(false), args(), logger(nullptr), + stack_logger(srslog::fetch_basic_logger("STCK", log_sink, false)), + mac_logger(srslog::fetch_basic_logger("MAC", log_sink)), + rlc_logger(srslog::fetch_basic_logger("RLC", log_sink, false)), + pdcp_logger(srslog::fetch_basic_logger("PDCP", log_sink, false)), + rrc_logger(srslog::fetch_basic_logger("RRC", log_sink, false)), + usim_logger(srslog::fetch_basic_logger("USIM", log_sink, false)), + nas_logger(srslog::fetch_basic_logger("NAS", log_sink, false)), usim(nullptr), phy(nullptr), rlc("RLC"), mac("MAC", &task_sched), rrc(this, &task_sched), -#ifdef HAVE_5GNR mac_nr(&task_sched), rrc_nr(&task_sched), -#endif pdcp(&task_sched, "PDCP"), nas(&task_sched), thread("STACK"), task_sched(512, 2, 64), - tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD) + tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD), + mac_pcap(srslte_rat_t::lte) { ue_task_queue = task_sched.make_task_queue(); gw_queue_id = task_sched.make_task_queue(); @@ -66,6 +72,19 @@ std::string ue_stack_lte::get_type() return "lte"; } +int ue_stack_lte::init(const stack_args_t& args_, + srslte::logger* logger_, + phy_interface_stack_lte* phy_, + phy_interface_stack_nr* phy_nr_, + gw_interface_stack* gw_) +{ + phy_nr = phy_nr_; + if (init(args_, logger_, phy_, gw_)) { + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; +} + int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_, phy_interface_stack_lte* phy_, @@ -87,30 +106,42 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) logger = logger_; // init own log - stack_log->set_level(args.log.stack_level); - stack_log->set_hex_limit(args.log.stack_hex_limit); - pool_log->set_level(srslte::LOG_LEVEL_WARNING); - byte_buffer_pool::get_instance()->set_log(pool_log.get()); + stack_logger.set_level(srslog::str_to_basic_level(args.log.stack_level)); + stack_logger.set_hex_dump_max_size(args.log.stack_hex_limit); + byte_buffer_pool::get_instance()->enable_logger(true); // init layer logs srslte::logmap::register_log(std::unique_ptr{new srslte::log_filter{"MAC", logger, true}}); mac_log->set_level(args.log.mac_level); mac_log->set_hex_limit(args.log.mac_hex_limit); + mac_logger.set_level(srslog::str_to_basic_level(args.log.mac_level)); + mac_logger.set_hex_dump_max_size(args.log.mac_hex_limit); rlc_log->set_level(args.log.rlc_level); rlc_log->set_hex_limit(args.log.rlc_hex_limit); + rlc_logger.set_level(srslog::str_to_basic_level(args.log.rlc_level)); + rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); pdcp_log->set_level(args.log.pdcp_level); pdcp_log->set_hex_limit(args.log.pdcp_hex_limit); + pdcp_logger.set_level(srslog::str_to_basic_level(args.log.pdcp_level)); + pdcp_logger.set_hex_dump_max_size(args.log.pdcp_hex_limit); rrc_log->set_level(args.log.rrc_level); rrc_log->set_hex_limit(args.log.rrc_hex_limit); + rrc_logger.set_level(srslog::str_to_basic_level(args.log.rrc_level)); + rrc_logger.set_hex_dump_max_size(args.log.rrc_hex_limit); usim_log->set_level(args.log.usim_level); usim_log->set_hex_limit(args.log.usim_hex_limit); + usim_logger.set_level(srslog::str_to_basic_level(args.log.usim_level)); + usim_logger.set_hex_dump_max_size(args.log.usim_hex_limit); nas_log->set_level(args.log.nas_level); nas_log->set_hex_limit(args.log.nas_hex_limit); + nas_logger.set_level(srslog::str_to_basic_level(args.log.nas_level)); + nas_logger.set_hex_dump_max_size(args.log.nas_hex_limit); // Set up pcap if (args.pcap.enable) { - mac_pcap.open(args.pcap.filename.c_str()); - mac.start_pcap(&mac_pcap); + if (mac_pcap.open(args.pcap.filename.c_str()) == SRSLTE_SUCCESS) { + mac.start_pcap(&mac_pcap); + } } if (args.pcap.nas_enable) { nas_pcap.open(args.pcap.nas_filename.c_str()); @@ -118,7 +149,7 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) } // Init USIM first to allow early exit in case reader couldn't be found - usim = usim_base::get_instance(&args.usim, usim_log.get()); + usim = usim_base::get_instance(&args.usim, usim_logger); if (usim->init(&args.usim)) { srslte::console("Failed to initialize USIM.\n"); return SRSLTE_ERROR; @@ -131,15 +162,20 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) rlc.init(&pdcp, &rrc, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); pdcp.init(&rlc, &rrc, gw); nas.init(usim.get(), &rrc, gw, args.nas); -#ifdef HAVE_5GNR - mac_nr_args_t mac_nr_args; - mac_nr.init(mac_nr_args, nullptr, &rlc); - rrc_nr.init( - nullptr, &mac_nr, &rlc, &pdcp, gw, &rrc, usim.get(), task_sched.get_timer_handler(), nullptr, args.rrc_nr); + + mac_nr_args_t mac_nr_args = {}; + mac_nr.init(mac_nr_args, phy_nr, &rlc); + rrc_nr.init(phy_nr, + &mac_nr, + &rlc, + &pdcp, + gw, + &rrc, + usim.get(), + task_sched.get_timer_handler(), + nullptr, + args.rrc_nr); rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc); -#else - rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, args.rrc); -#endif running = true; start(STACK_MAIN_THREAD_PRIO); @@ -195,7 +231,7 @@ bool ue_stack_lte::switch_off() } bool detach_sent = true; if (not rrc.srbs_flushed()) { - logmap::get("NAS ")->warning("Detach couldn't be sent after %dms.\n", timeout_ms); + srslog::fetch_basic_logger("NAS").warning("Detach couldn't be sent after %dms.", timeout_ms); detach_sent = false; } @@ -229,6 +265,7 @@ bool ue_stack_lte::get_metrics(stack_metrics_t* metrics) // use stack thread to query metrics ue_task_queue.try_push([this]() { stack_metrics_t metrics{}; + metrics.ul_dropped_sdus = ul_dropped_sdus; mac.get_metrics(metrics.mac); rlc.get_metrics(metrics.rlc, metrics.mac[0].nof_tti); nas.get_metrics(&metrics.nas); @@ -266,7 +303,8 @@ void ue_stack_lte::write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) auto task = [this, lcid](srslte::unique_byte_buffer_t& sdu) { pdcp.write_sdu(lcid, std::move(sdu)); }; bool ret = gw_queue_id.try_push(std::bind(task, std::move(sdu))).first; if (not ret) { - pdcp_log->warning("GW SDU with lcid=%d was discarded.\n", lcid); + pdcp_logger.info("GW SDU with lcid=%d was discarded.", lcid); + ul_dropped_sdus++; } } @@ -346,15 +384,15 @@ void ue_stack_lte::run_tti_impl(uint32_t tti, uint32_t tti_jump) if (args.have_tti_time_stats) { std::chrono::nanoseconds dur = tti_tprof.stop(); if (dur > TTI_WARN_THRESHOLD_MS) { - mac_log->warning("%s: detected long duration=%" PRId64 "ms\n", - "proc_time", - std::chrono::duration_cast(dur).count()); + mac_logger.warning("%s: detected long duration=%" PRId64 "ms", + "proc_time", + std::chrono::duration_cast(dur).count()); } } // print warning if PHY pushes new TTI messages faster than we process them if (sync_task_queue.size() > SYNC_QUEUE_WARN_THRESHOLD) { - stack_log->warning("Detected slow task processing (sync_queue_len=%zd).\n", sync_task_queue.size()); + stack_logger.warning("Detected slow task processing (sync_queue_len=%zd).", sync_task_queue.size()); } } diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index aa94ca08b..bcb1a0e24 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -27,12 +27,7 @@ using namespace srslte; namespace srsue { ue_stack_nr::ue_stack_nr(srslte::logger* logger_) : - logger(logger_), - thread("STACK"), - task_sched(64, 2, 64), - rlc_log("RLC"), - pdcp_log("PDCP"), - pool_log("POOL") + logger(logger_), thread("STACK"), task_sched(64, 2, 64), rlc_log("RLC"), pdcp_log("PDCP") { mac.reset(new mac_nr(&task_sched)); pdcp.reset(new srslte::pdcp(&task_sched, "PDCP")); @@ -40,8 +35,7 @@ ue_stack_nr::ue_stack_nr(srslte::logger* logger_) : rrc.reset(new rrc_nr(&task_sched)); // setup logging for pool, RLC and PDCP - pool_log->set_level(srslte::LOG_LEVEL_ERROR); - byte_buffer_pool::get_instance()->set_log(pool_log.get()); + byte_buffer_pool::get_instance()->enable_logger(true); ue_task_queue = task_sched.make_task_queue(); sync_task_queue = task_sched.make_task_queue(); @@ -81,7 +75,6 @@ int ue_stack_nr::init(const stack_args_t& args_) mac_nr_args_t mac_args = {}; mac_args.pcap = args.pcap; - mac_args.drb_lcid = 4; mac->init(mac_args, phy, rlc.get()); rlc->init(pdcp.get(), rrc.get(), task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); pdcp->init(rlc.get(), rrc.get(), gw); @@ -118,17 +111,13 @@ void ue_stack_nr::stop_impl() rlc->stop(); pdcp->stop(); mac->stop(); - - if (mac_pcap != nullptr) { - mac_pcap.reset(); - } } bool ue_stack_nr::switch_on() { // statically setup TUN (will be done through RRC later) char* err_str = nullptr; - if (gw->setup_if_addr(4, LIBLTE_MME_PDN_TYPE_IPV4, htonl(inet_addr("192.168.1.3")), nullptr, err_str)) { + if (gw->setup_if_addr(5, 4, LIBLTE_MME_PDN_TYPE_IPV4, htonl(inet_addr("192.168.1.3")), nullptr, err_str)) { printf("Error configuring TUN interface\n"); } return true; @@ -174,7 +163,7 @@ void ue_stack_nr::write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) std::pair ret = gw_task_queue.try_push(std::bind( [this, lcid](srslte::unique_byte_buffer_t& sdu) { pdcp->write_sdu(lcid, std::move(sdu)); }, std::move(sdu))); if (not ret.first) { - pdcp_log->warning("GW SDU with lcid=%d was discarded.\n", lcid); + pdcp_log->warning("GW SDU with lcid=%d was discarded.", lcid); } } } diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index c8595692d..af08d5801 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -34,29 +34,28 @@ namespace srsue { -gw::gw() : thread("GW"), pool(srslte::byte_buffer_pool::get_instance()), tft_matcher(&log) {} +gw::gw() : thread("GW"), logger(srslog::fetch_basic_logger("GW", false)), tft_matcher(logger) {} int gw::init(const gw_args_t& args_, srslte::logger* logger_, stack_interface_gw* stack_) { stack = stack_; - logger = logger_; + old_logger = logger_; args = args_; run_enable = true; - log.init("GW ", logger); - log.set_level(args.log.gw_level); - log.set_hex_limit(args.log.gw_hex_limit); + logger.set_level(srslog::str_to_basic_level(args.log.gw_level)); + logger.set_hex_dump_max_size(args.log.gw_hex_limit); metrics_tp = std::chrono::high_resolution_clock::now(); // MBSFN mbsfn_sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (mbsfn_sock_fd < 0) { - log.error("Failed to create MBSFN sink socket\n"); + logger.error("Failed to create MBSFN sink socket"); return SRSLTE_ERROR; } if (fcntl(mbsfn_sock_fd, F_SETFL, O_NONBLOCK)) { - log.error("Failed to set non-blocking MBSFN sink socket\n"); + logger.error("Failed to set non-blocking MBSFN sink socket"); return SRSLTE_ERROR; } @@ -104,11 +103,11 @@ void gw::get_metrics(gw_metrics_t& m, const uint32_t nof_tti) m.dl_tput_mbps = (nof_tti > 0) ? ((dl_tput_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; m.ul_tput_mbps = (nof_tti > 0) ? ((ul_tput_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; - log.info("gw_rx_rate_mbps=%4.2f (real=%4.2f), gw_tx_rate_mbps=%4.2f (real=%4.2f)\n", - m.dl_tput_mbps, - dl_tput_mbps_real_time, - m.ul_tput_mbps, - ul_tput_mbps_real_time); + logger.info("gw_rx_rate_mbps=%4.2f (real=%4.2f), gw_tx_rate_mbps=%4.2f (real=%4.2f)", + m.dl_tput_mbps, + dl_tput_mbps_real_time, + m.ul_tput_mbps, + ul_tput_mbps_real_time); // reset counters and store time metrics_tp = std::chrono::high_resolution_clock::now(); @@ -121,23 +120,23 @@ void gw::get_metrics(gw_metrics_t& m, const uint32_t nof_tti) *******************************************************************************/ void gw::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { - log.info_hex(pdu->msg, pdu->N_bytes, "RX PDU. Stack latency: %ld us\n", pdu->get_latency_us().count()); + logger.info(pdu->msg, pdu->N_bytes, "RX PDU. Stack latency: %ld us", pdu->get_latency_us().count()); dl_tput_bytes += pdu->N_bytes; if (!if_up) { - log.warning("TUN/TAP not up - dropping gw RX message\n"); + logger.warning("TUN/TAP not up - dropping gw RX message"); } else if (pdu->N_bytes < 20) { // Packet not large enough to hold IPv4 Header - log.warning("Packet to small to hold IPv4 header. Dropping packet with %d B\n", pdu->N_bytes); + logger.warning("Packet to small to hold IPv4 header. Dropping packet with %d B", pdu->N_bytes); } else { // Only handle IPv4 and IPv6 packets struct iphdr* ip_pkt = (struct iphdr*)pdu->msg; if (ip_pkt->version == 4 || ip_pkt->version == 6) { int n = write(tun_fd, pdu->msg, pdu->N_bytes); if (n > 0 && (pdu->N_bytes != (uint32_t)n)) { - log.warning("DL TUN/TAP write failure. Wanted to write %d B but only wrote %d B.\n", pdu->N_bytes, n); + logger.warning("DL TUN/TAP write failure. Wanted to write %d B but only wrote %d B.", pdu->N_bytes, n); } } else { - log.error("Unsupported IP version. Dropping packet with %d B\n", pdu->N_bytes); + logger.error("Unsupported IP version. Dropping packet with %d B", pdu->N_bytes); } } } @@ -145,11 +144,11 @@ void gw::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) void gw::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { if (pdu->N_bytes > 2) { - log.info_hex(pdu->msg, - pdu->N_bytes, - "RX MCH PDU (%d B). Stack latency: %ld us\n", - pdu->N_bytes, - pdu->get_latency_us().count()); + logger.info(pdu->msg, + pdu->N_bytes, + "RX MCH PDU (%d B). Stack latency: %ld us", + pdu->N_bytes, + pdu->get_latency_us().count()); dl_tput_bytes += pdu->N_bytes; // Hack to drop initial 2 bytes @@ -159,11 +158,11 @@ void gw::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) memcpy(&dst_addr.s_addr, &pdu->msg[16], 4); if (!if_up) { - log.warning("TUN/TAP not up - dropping gw RX message\n"); + logger.warning("TUN/TAP not up - dropping gw RX message"); } else { int n = write(tun_fd, pdu->msg, pdu->N_bytes); if (n > 0 && (pdu->N_bytes != (uint32_t)n)) { - log.warning("DL TUN/TAP write failure\n"); + logger.warning("DL TUN/TAP write failure"); } } } @@ -172,7 +171,12 @@ void gw::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) /******************************************************************************* NAS interface *******************************************************************************/ -int gw::setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str) +int gw::setup_if_addr(uint32_t eps_bearer_id, + uint32_t lcid, + uint8_t pdn_type, + uint32_t ip_addr, + uint8_t* ipv6_if_addr, + char* err_str) { int err; if (pdn_type == LIBLTE_MME_PDN_TYPE_IPV4 || pdn_type == LIBLTE_MME_PDN_TYPE_IPV4V6) { @@ -188,7 +192,8 @@ int gw::setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t } } - default_lcid = lcid; + eps_lcid[eps_bearer_id] = lcid; + default_lcid = lcid; tft_matcher.set_default_lcid(lcid); // Setup a thread to receive packets from the TUN device @@ -196,6 +201,26 @@ int gw::setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t return SRSLTE_SUCCESS; } +int gw::update_lcid(uint32_t eps_bearer_id, uint32_t new_lcid) +{ + auto it = eps_lcid.find(eps_bearer_id); + if (it != eps_lcid.end()) { + uint32_t old_lcid = eps_lcid[eps_bearer_id]; + logger.debug("Found EPS bearer %d. Update old lcid %d to new lcid %d", eps_bearer_id, old_lcid, new_lcid); + eps_lcid[eps_bearer_id] = new_lcid; + if (old_lcid == default_lcid) { + logger.debug("Defaulting new lcid %d", new_lcid); + default_lcid = new_lcid; + tft_matcher.set_default_lcid(new_lcid); + } + // TODO: update need filters if not the default lcid + } else { + logger.error("Did not found EPS bearer %d for updating LCID.", eps_bearer_id); + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; +} + int gw::apply_traffic_flow_template(const uint8_t& erab_id, const uint8_t& lcid, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) @@ -205,7 +230,7 @@ int gw::apply_traffic_flow_template(const uint8_t& void gw::set_test_loop_mode(const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms) { - log.error("UE test loop mode not supported\n"); + logger.error("UE test loop mode not supported"); } /******************************************************************************* @@ -226,16 +251,16 @@ void gw::run_thread() uint32 idx = 0; int32 N_bytes = 0; - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - log.error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in run_thread()."); return; } const static uint32_t REGISTER_WAIT_TOUT = 40, SERVICE_WAIT_TOUT = 40; // 4 sec uint32_t register_wait = 0, service_wait = 0; - log.info("GW IP packet receiver thread run_enable\n"); + logger.info("GW IP packet receiver thread run_enable"); running = true; while (run_enable) { @@ -243,14 +268,14 @@ void gw::run_thread() if (SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET > idx) { N_bytes = read(tun_fd, &pdu->msg[idx], SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET - idx); } else { - log.error("GW pdu buffer full - gw receive thread exiting.\n"); + logger.error("GW pdu buffer full - gw receive thread exiting."); srslte::console("GW pdu buffer full - gw receive thread exiting.\n"); break; } - log.debug("Read %d bytes from TUN fd=%d, idx=%d\n", N_bytes, tun_fd, idx); + logger.debug("Read %d bytes from TUN fd=%d, idx=%d", N_bytes, tun_fd, idx); if (N_bytes <= 0) { - log.error("Failed to read from TUN interface - gw receive thread exiting.\n"); + logger.error("Failed to read from TUN interface - gw receive thread exiting."); srslte::console("Failed to read from TUN interface - gw receive thread exiting.\n"); break; } @@ -265,19 +290,19 @@ void gw::run_thread() } else if (ip_pkt->version == 6) { pkt_len = ntohs(ip6_pkt->payload_len) + 40; } else { - log.error_hex(pdu->msg, pdu->N_bytes, "Unsupported IP version. Dropping packet.\n"); + logger.error(pdu->msg, pdu->N_bytes, "Unsupported IP version. Dropping packet."); continue; } - log.debug("IPv%d packet total length: %d Bytes\n", ip_pkt->version, pkt_len); + logger.debug("IPv%d packet total length: %d Bytes", int(ip_pkt->version), pkt_len); // Check if entire packet was received if (pkt_len == pdu->N_bytes) { - log.info_hex(pdu->msg, pdu->N_bytes, "TX PDU"); + logger.info(pdu->msg, pdu->N_bytes, "TX PDU"); // Make sure UE is attached while (run_enable && !stack->is_registered() && register_wait < REGISTER_WAIT_TOUT) { if (!register_wait) { - log.info("UE is not attached, waiting for NAS attach (%d/%d)\n", register_wait, REGISTER_WAIT_TOUT); + logger.info("UE is not attached, waiting for NAS attach (%d/%d)", register_wait, REGISTER_WAIT_TOUT); } usleep(100000); register_wait++; @@ -292,8 +317,8 @@ void gw::run_thread() // Wait for service request if necessary while (run_enable && !stack->is_lcid_enabled(default_lcid) && service_wait < SERVICE_WAIT_TOUT) { if (!service_wait) { - log.info( - "UE does not have service, waiting for NAS service request (%d/%d)\n", service_wait, SERVICE_WAIT_TOUT); + logger.info( + "UE does not have service, waiting for NAS service request (%d/%d)", service_wait, SERVICE_WAIT_TOUT); stack->start_service_request(); } usleep(100000); @@ -313,9 +338,9 @@ void gw::run_thread() ul_tput_bytes += pdu->N_bytes; stack->write_sdu(lcid, std::move(pdu)); do { - pdu = srslte::allocate_unique_buffer(*pool); + pdu = srslte::make_byte_buffer(); if (!pdu) { - log.error("Fatal Error: Couldn't allocate PDU in run_thread().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in run_thread()."); usleep(100000); } } while (!pdu); @@ -323,11 +348,11 @@ void gw::run_thread() } } else { idx += N_bytes; - log.debug("Entire packet not read from socket. Total Length %d, N_Bytes %d.\n", ip_pkt->tot_len, pdu->N_bytes); + logger.debug("Entire packet not read from socket. Total Length %d, N_Bytes %d.", ip_pkt->tot_len, pdu->N_bytes); } } running = false; - log.info("GW IP receiver thread exiting.\n"); + logger.info("GW IP receiver thread exiting."); } /**************************/ @@ -346,22 +371,22 @@ int gw::init_if(char* err_str) netns_fd = open(netns.c_str(), O_RDONLY); if (netns_fd == -1) { err_str = strerror(errno); - log.error("Failed to find netns %s (%s): %s\n", args.netns.c_str(), netns.c_str(), err_str); + logger.error("Failed to find netns %s (%s): %s", args.netns.c_str(), netns.c_str(), err_str); return SRSLTE_ERROR_CANT_START; } if (setns(netns_fd, CLONE_NEWNET) == -1) { err_str = strerror(errno); - log.error("Failed to change netns: %s\n", err_str); + logger.error("Failed to change netns: %s", err_str); return SRSLTE_ERROR_CANT_START; } } // Construct the TUN device tun_fd = open("/dev/net/tun", O_RDWR); - log.info("TUN file descriptor = %d\n", tun_fd); + logger.info("TUN file descriptor = %d", tun_fd); if (0 > tun_fd) { err_str = strerror(errno); - log.error("Failed to open TUN device: %s\n", err_str); + logger.error("Failed to open TUN device: %s", err_str); return SRSLTE_ERROR_CANT_START; } @@ -372,7 +397,7 @@ int gw::init_if(char* err_str) ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0; if (0 > ioctl(tun_fd, TUNSETIFF, &ifr)) { err_str = strerror(errno); - log.error("Failed to set TUN device name: %s\n", err_str); + logger.error("Failed to set TUN device name: %s", err_str); close(tun_fd); return SRSLTE_ERROR_CANT_START; } @@ -381,14 +406,14 @@ int gw::init_if(char* err_str) sock = socket(AF_INET, SOCK_DGRAM, 0); if (0 > ioctl(sock, SIOCGIFFLAGS, &ifr)) { err_str = strerror(errno); - log.error("Failed to bring up socket: %s\n", err_str); + logger.error("Failed to bring up socket: %s", err_str); close(tun_fd); return SRSLTE_ERROR_CANT_START; } ifr.ifr_flags |= IFF_UP | IFF_RUNNING; if (0 > ioctl(sock, SIOCSIFFLAGS, &ifr)) { err_str = strerror(errno); - log.error("Failed to set socket flags: %s\n", err_str); + logger.error("Failed to set socket flags: %s", err_str); close(tun_fd); return SRSLTE_ERROR_CANT_START; } @@ -397,10 +422,10 @@ int gw::init_if(char* err_str) struct in6_addr in6p; char addr_str[INET6_ADDRSTRLEN]; if (find_ipv6_addr(&in6p)) { - log.debug("Found link-local IPv6 address: %s\n", inet_ntop(AF_INET6, &in6p, addr_str, INET6_ADDRSTRLEN)); + logger.debug("Found link-local IPv6 address: %s", inet_ntop(AF_INET6, &in6p, addr_str, INET6_ADDRSTRLEN)); del_ipv6_addr(&in6p); } else { - log.warning("Could not find link-local IPv6 address.\n"); + logger.warning("Could not find link-local IPv6 address."); } if_up = true; @@ -412,7 +437,7 @@ int gw::setup_if_addr4(uint32_t ip_addr, char* err_str) if (ip_addr != current_ip_addr) { if (!if_up) { if (init_if(err_str)) { - log.error("init_if failed\n"); + logger.error("init_if failed"); return SRSLTE_ERROR_CANT_START; } } @@ -423,7 +448,7 @@ int gw::setup_if_addr4(uint32_t ip_addr, char* err_str) ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr = htonl(ip_addr); if (0 > ioctl(sock, SIOCSIFADDR, &ifr)) { err_str = strerror(errno); - log.debug("Failed to set socket address: %s\n", err_str); + logger.debug("Failed to set socket address: %s", err_str); close(tun_fd); return SRSLTE_ERROR_CANT_START; } @@ -431,7 +456,7 @@ int gw::setup_if_addr4(uint32_t ip_addr, char* err_str) ((struct sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr(args.tun_dev_netmask.c_str()); if (0 > ioctl(sock, SIOCSIFNETMASK, &ifr)) { err_str = strerror(errno); - log.debug("Failed to set socket netmask: %s\n", err_str); + logger.debug("Failed to set socket netmask: %s", err_str); close(tun_fd); return SRSLTE_ERROR_CANT_START; } @@ -456,7 +481,7 @@ int gw::setup_if_addr6(uint8_t* ipv6_if_id, char* err_str) if (!match) { if (!if_up) { if (init_if(err_str)) { - log.error("init_if failed\n"); + logger.error("init_if failed"); return SRSLTE_ERROR_CANT_START; } } @@ -466,7 +491,7 @@ int gw::setup_if_addr6(uint8_t* ipv6_if_id, char* err_str) ifr.ifr_addr.sa_family = AF_INET6; if (inet_pton(AF_INET6, "fe80::", (void*)&sai.sin6_addr) <= 0) { - log.error("Bad address\n"); + logger.error("Bad address"); return SRSLTE_ERROR_CANT_START; } @@ -481,7 +506,7 @@ int gw::setup_if_addr6(uint8_t* ipv6_if_id, char* err_str) if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) { err_str = strerror(errno); - log.error("Could not set IPv6 Link local address. Error %s\n", err_str); + logger.error("Could not set IPv6 Link local address. Error %s", err_str); return SRSLTE_ERROR_CANT_START; } @@ -508,19 +533,19 @@ bool gw::find_ipv6_addr(struct in6_addr* in6_out) char buf[1024]; } req; - log.debug("Trying to obtain IPv6 addr of %s interface\n", args.tun_dev_name.c_str()); + logger.debug("Trying to obtain IPv6 addr of %s interface", args.tun_dev_name.c_str()); // Get Interface Index if_index = if_nametoindex(args.tun_dev_name.c_str()); if (if_index == 0) { - log.error("Could not find interface index\n"); + logger.error("Could not find interface index"); goto err_out; } // Open NETLINK socket fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); if (fd < 0) { - log.error("Error openning NETLINK socket -- %s\n", strerror(errno)); + logger.error("Error openning NETLINK socket -- %s", strerror(errno)); goto err_out; } @@ -541,34 +566,33 @@ bool gw::find_ipv6_addr(struct in6_addr* in6_out) // Time to send and recv the message from kernel n = send(fd, &req, req.n.nlmsg_len, 0); if (n < 0) { - log.error("Error sending NETLINK message to kernel -- %s", strerror(errno)); + logger.error("Error sending NETLINK message to kernel -- %s", strerror(errno)); goto err_out; } n = recv(fd, buf, sizeof(buf), 0); if (n < 0) { - log.error("Error receiving from NETLINK socket\n"); + logger.error("Error receiving from NETLINK socket"); goto err_out; } if (n == 0) { - log.error("Nothing received from NETLINK Socket\n"); + logger.error("Nothing received from NETLINK Socket"); goto err_out; } // Parse the reply for (nlmp = (struct nlmsghdr*)buf; NLMSG_OK(nlmp, n); nlmp = NLMSG_NEXT(nlmp, n)) { - // Chack NL message type if (nlmp->nlmsg_type == NLMSG_DONE) { - log.error("Reach end of NETLINK message without finding IPv6 address.\n"); + logger.error("Reach end of NETLINK message without finding IPv6 address."); goto err_out; } if (nlmp->nlmsg_type == NLMSG_ERROR) { - log.error("NLMSG_ERROR in NETLINK reply\n"); + logger.error("NLMSG_ERROR in NETLINK reply"); goto err_out; } - log.debug("NETLINK message type %d\n", nlmp->nlmsg_type); + logger.debug("NETLINK message type %d", nlmp->nlmsg_type); // Get IFA message rtmp = (struct ifaddrmsg*)NLMSG_DATA(nlmp); @@ -612,14 +636,14 @@ void gw::del_ipv6_addr(struct in6_addr* in6p) // Get Interface Index if_index = if_nametoindex(args.tun_dev_name.c_str()); if (if_index == 0) { - log.error("Could not find interface index\n"); + logger.error("Could not find interface index"); goto out; } // Open netlink socket fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); if (fd < 0) { - log.error("Error openning NETLINK socket -- %s\n", strerror(errno)); + logger.error("Error openning NETLINK socket -- %s", strerror(errno)); goto out; } @@ -644,7 +668,7 @@ void gw::del_ipv6_addr(struct in6_addr* in6p) status = send(fd, &req, req.n.nlmsg_len, 0); if (status < 0) { - log.error("Error sending NETLINK message\n"); + logger.error("Error sending NETLINK message"); goto out; } diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index ed6f80385..c42d4c570 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -45,7 +45,6 @@ namespace srsue { ********************************************************************/ nas::nas(srslte::task_sched_handle task_sched_) : - pool(byte_buffer_pool::get_instance()), plmn_searcher(this), task_sched(task_sched_), t3402(task_sched_.get_unique_timer()), @@ -54,7 +53,7 @@ nas::nas(srslte::task_sched_handle task_sched_) : t3421(task_sched_.get_unique_timer()), reattach_timer(task_sched_.get_unique_timer()), airplane_mode_sim_timer(task_sched_.get_unique_timer()), - nas_log{"NAS"} + logger(srslog::fetch_basic_logger("NAS")) {} void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& cfg_) @@ -64,7 +63,7 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ gw = gw_; if (!usim->get_home_plmn_id(&home_plmn)) { - nas_log->error("Getting Home PLMN Id from USIM. Defaulting to 001-01\n"); + logger.error("Getting Home PLMN Id from USIM. Defaulting to 001-01"); home_plmn.from_number(61441, 65281); // This is 001 01 } @@ -72,26 +71,26 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ std::vector cap_list; srslte::string_parse_list(cfg_.eia, ',', cap_list); if (cap_list.empty()) { - nas_log->error("Empty EIA list. Select at least one EIA algorithm.\n"); + logger.error("Empty EIA list. Select at least one EIA algorithm."); } for (std::vector::const_iterator it = cap_list.begin(); it != cap_list.end(); ++it) { if (*it != 0 && *it < 4) { eia_caps[*it] = true; } else { - nas_log->error("EIA%d is not a valid EIA algorithm.\n", *it); + logger.error("EIA%d is not a valid EIA algorithm.", *it); } } // parse and sanity check EEA list srslte::string_parse_list(cfg_.eea, ',', cap_list); if (cap_list.empty()) { - nas_log->error("Empty EEA list. Select at least one EEA algorithm.\n"); + logger.error("Empty EEA list. Select at least one EEA algorithm."); } for (std::vector::const_iterator it = cap_list.begin(); it != cap_list.end(); ++it) { if (*it < 4) { eea_caps[*it] = true; } else { - nas_log->error("EEA%d is not a valid EEA algorithm.\n", *it); + logger.error("EEA%d is not a valid EEA algorithm.", *it); } } @@ -99,8 +98,8 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ if ((read_ctxt_file(&ctxt))) { usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); - nas_log->debug_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - nas_log->debug_hex(k_nas_int, 32, "NAS integrity key - k_nas_int"); + logger.debug(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.debug(k_nas_int, 32, "NAS integrity key - k_nas_int"); } // Configure timers @@ -145,7 +144,7 @@ void nas::run_tti() // TODO Make sure cell selection is finished after transitioning from another state (if required) // Make sure the RRC is finished transitioning to RRC Idle if (reattach_timer.is_running()) { - nas_log->debug("Waiting for reatach timer to expire to attach again.\n"); + logger.debug("Waiting for re-attach timer to expire to attach again."); return; } switch (state.get_deregistered_substate()) { @@ -157,14 +156,14 @@ void nas::run_tti() start_attach_request(srslte::establishment_cause_t::mo_data); break; case emm_state_t::deregistered_substate_t::attempting_to_attach: - nas_log->debug("Attempting to attach\n"); + logger.debug("Attempting to attach"); default: break; } case emm_state_t::state_t::registered: break; case emm_state_t::state_t::deregistered_initiated: - nas_log->debug("UE detaching...\n"); + logger.debug("UE detaching..."); break; default: break; @@ -177,7 +176,7 @@ void nas::run_tti() void nas::enter_emm_null() { // Deactivate EPS bearer according to Sec. 5.5.2.2.2 - nas_log->debug("Clearing EPS bearer context\n"); + logger.debug("Clearing EPS bearer context"); eps_bearer.clear(); state.set_null(); } @@ -185,7 +184,7 @@ void nas::enter_emm_null() void nas::enter_emm_deregistered_initiated() { // Deactivate EPS bearer according to Sec. 5.5.2.2.2 - nas_log->debug("Clearing EPS bearer context\n"); + logger.debug("Clearing EPS bearer context"); eps_bearer.clear(); state.set_deregistered_initiated(); } @@ -195,7 +194,7 @@ void nas::enter_emm_deregistered(emm_state_t::deregistered_substate_t substate) // TODO Start cell selection. // Deactivate EPS bearer according to Sec. 5.5.2.2.2 - nas_log->debug("Clearing EPS bearer context\n"); + logger.debug("Clearing EPS bearer context"); eps_bearer.clear(); state.set_deregistered(substate); } @@ -206,7 +205,7 @@ void nas::enter_emm_deregistered(emm_state_t::deregistered_substate_t substate) void nas::timer_expired(uint32_t timeout_id) { if (timeout_id == t3402.id()) { - nas_log->info("Timer T3402 expired: trying to attach again\n"); + logger.warning("Timer T3402 expired: trying to attach again"); attach_attempt_counter = 0; // Sec. 5.5.1.1 enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); } else if (timeout_id == t3410.id()) { @@ -215,16 +214,16 @@ void nas::timer_expired(uint32_t timeout_id) srslte::console("Attach failed (attempt %d/%d)\n", attach_attempt_counter, max_attach_attempts); if (attach_attempt_counter < max_attach_attempts) { - nas_log->info("Timer T3410 expired after attach attempt %d/%d: starting T3411\n", - attach_attempt_counter, - max_attach_attempts); + logger.warning("Timer T3410 expired after attach attempt %d/%d: starting T3411", + attach_attempt_counter, + max_attach_attempts); // start T3411 t3411.run(); enter_emm_deregistered(emm_state_t::deregistered_substate_t::attempting_to_attach); } else { // maximum attach attempts reached - nas_log->info("Timer T3410 expired. Maximum attempts reached. Starting T3402\n"); + logger.warning("Timer T3410 expired. Maximum attempts reached. Starting T3402"); t3402.run(); reset_security_context(); } @@ -232,7 +231,7 @@ void nas::timer_expired(uint32_t timeout_id) // In order to allow reattaching the UE, we switch into EMM_STATE_DEREGISTERED straight enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); } else if (timeout_id == reattach_timer.id()) { - nas_log->info("Reattach timer expired: trying to attach again\n"); + logger.warning("Reattach timer expired: trying to attach again"); start_attach_request(srslte::establishment_cause_t::mo_sig); } else if (timeout_id == airplane_mode_sim_timer.id()) { if (airplane_mode_state == DISABLED) { @@ -255,7 +254,7 @@ void nas::timer_expired(uint32_t timeout_id) } } } else { - nas_log->error("Timeout from unknown timer id %d\n", timeout_id); + logger.error("Timeout from unknown timer id %d", timeout_id); } } /******************************************************************************* @@ -271,23 +270,27 @@ bool nas::is_registered() ******************************************************************************/ bool nas::switch_on() { + logger.info("Switching on"); state.set_deregistered(emm_state_t::deregistered_substate_t::plmn_search); return true; } bool nas::switch_off() { + logger.info("Switching off"); detach_request(true); return true; } bool nas::enable_data() { + logger.info("Enabling data services"); return switch_on(); } bool nas::disable_data() { + logger.info("Disabling data services"); detach_request(false); return true; } @@ -299,21 +302,16 @@ bool nas::disable_data() */ void nas::start_attach_request(srslte::establishment_cause_t cause_) { - if (rrc->is_connected()) { - nas_log->info("RRC is connected. Aborting attach reuqest %s.\n", to_string(cause_).c_str()); - return; - } - - nas_log->info("Attach Request with cause %s.\n", to_string(cause_).c_str()); + logger.info("Attach Request with cause %s.", to_string(cause_).c_str()); if (state.get_state() != emm_state_t::state_t::deregistered) { - nas_log->info("NAS in invalid state for Attach Request\n"); - nas_log->info("Attach request ignored. State = %s\n", state.get_full_state_text().c_str()); + logger.info("NAS in invalid state for Attach Request"); + logger.info("Attach request ignored. State = %s", state.get_full_state_text().c_str()); return; } // start T3410 - nas_log->debug("Starting T3410\n"); + logger.debug("Starting T3410"); t3410.run(); // stop T3411 @@ -327,12 +325,19 @@ void nas::start_attach_request(srslte::establishment_cause_t cause_) } // Start attach request - unique_byte_buffer_t msg = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t msg = srslte::make_byte_buffer(); + if (msg == nullptr) { + logger.warning("Couldn't allocate buffer for Attach request.\n"); + return; + } + gen_attach_request(msg); - if (!rrc->is_connected()) { - nas_log->debug("Initiating RRC Connection\n"); + if (rrc->is_connected()) { + rrc->write_sdu(std::move(msg)); + } else { + logger.debug("Initiating RRC Connection"); if (not rrc->connection_request(cause_, std::move(msg))) { - nas_log->error("Error starting RRC connection"); + logger.error("Error starting RRC connection"); return; } } @@ -347,26 +352,26 @@ void nas::start_attach_request(srslte::establishment_cause_t cause_) */ void nas::start_service_request(srslte::establishment_cause_t cause_) { - nas_log->info("Service Request with cause %s.\n", to_string(cause_).c_str()); + logger.info("Service Request with cause %s.", to_string(cause_).c_str()); srslte::console("Service Request with cause %s.\n", to_string(cause_).c_str()); if (state.get_state() != emm_state_t::state_t::registered) { - nas_log->info("NAS in invalid state for Service Request\n"); - nas_log->info("Service request ignored. State = %s\n", state.get_full_state_text().c_str()); + logger.info("NAS in invalid state for Service Request"); + logger.info("Service request ignored. State = %s", state.get_full_state_text().c_str()); return; } if (rrc->is_connected()) { - nas_log->info("NAS is already registered and RRC connected\n"); - nas_log->info("Service request ignored. State = %s\n", state.get_full_state_text().c_str()); + logger.info("NAS is already registered and RRC connected"); + logger.info("Service request ignored. State = %s", state.get_full_state_text().c_str()); return; } - nas_log->info("NAS is already registered but RRC disconnected. Connecting now...\n"); + logger.info("NAS is already registered but RRC disconnected. Connecting now..."); // Start service request - unique_byte_buffer_t msg = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t msg = srslte::make_byte_buffer(); gen_service_request(msg); if (not rrc->connection_request(cause_, std::move(msg))) { - nas_log->error("Error starting RRC connection"); + logger.error("Error starting RRC connection"); return; } state.set_service_request_initiated(); @@ -391,7 +396,7 @@ bool nas::detach_request(const bool switch_off) send_detach_request(switch_off); break; default: - nas_log->debug("Received request to detach in state %s\n", state.get_full_state_text().c_str()); + logger.debug("Received request to detach in state %s", state.get_full_state_text().c_str()); break; } if (switch_off) { @@ -407,18 +412,18 @@ bool nas::detach_request(const bool switch_off) bool nas::connection_request_completed(bool outcome) { if (outcome == true) { - nas_log->debug("RRC connection request completed. NAS State %s.\n", state.get_full_state_text().c_str()); + logger.debug("RRC connection request completed. NAS State %s.", state.get_full_state_text().c_str()); if (state.get_state() == emm_state_t::state_t::service_request_initiated) { srslte::console("Service Request successful.\n"); - nas_log->info("Service Request successful.\n"); + logger.info("Service Request successful."); rrc->paging_completed(true); state.set_registered(emm_state_t::registered_substate_t::normal_service); } } else { - nas_log->debug("RRC connection request failed. NAS State %s.\n", state.get_full_state_text().c_str()); + logger.debug("RRC connection request failed. NAS State %s.", state.get_full_state_text().c_str()); if (state.get_state() == emm_state_t::state_t::service_request_initiated) { srslte::console("RRC connection for Service Request failed.\n"); - nas_log->info("RRC connection for Service Request failed.\n"); + logger.info("RRC connection for Service Request failed."); rrc->paging_completed(false); state.set_registered(emm_state_t::registered_substate_t::normal_service); } @@ -434,16 +439,16 @@ void nas::plmn_search_completed(const rrc_interface_nas::found_plmn_t found_plmn void nas::left_rrc_connected() { - nas_log->debug("RRC no longer connected. NAS State %s.\n", state.get_full_state_text().c_str()); + logger.debug("RRC no longer connected. NAS State %s.", state.get_full_state_text().c_str()); } bool nas::paging(s_tmsi_t* ue_identity) { if (state.get_state() == emm_state_t::state_t::registered) { - nas_log->info("Received paging: requesting RRC connection establishment\n"); + logger.info("Received paging: requesting RRC connection establishment"); start_service_request(srslte::establishment_cause_t::mt_access); } else { - nas_log->warning("Received paging while in state %s\n", state.get_full_state_text().c_str()); + logger.warning("Received paging while in state %s", state.get_full_state_text().c_str()); return false; } return true; @@ -460,7 +465,7 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) uint8 msg_type = 0; uint8 sec_hdr_type = 0; - nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); + logger.info(pdu->msg, pdu->N_bytes, "DL %s PDU", rrc->get_rb_name(lcid).c_str()); // Parse the message security header liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &pd, &sec_hdr_type); @@ -477,13 +482,13 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) } break; } else { - nas_log->error("Not handling NAS message with integrity check error\n"); + logger.error("Not handling NAS message with integrity check error"); return; } case LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT: break; default: - nas_log->error("Not handling NAS message with SEC_HDR_TYPE=%02X\n", sec_hdr_type); + logger.error("Not handling NAS message with SEC_HDR_TYPE=%02X", sec_hdr_type); return; } @@ -494,7 +499,7 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) // Parse the message header liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &pd, &msg_type); - nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s Decrypted PDU", rrc->get_rb_name(lcid).c_str()); + logger.info(pdu->msg, pdu->N_bytes, "DL %s Decrypted PDU", rrc->get_rb_name(lcid).c_str()); // drop messages if integrity protection isn't applied (see TS 24.301 Sec. 4.4.4.2) if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { @@ -511,9 +516,9 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: break; default: - nas_log->error("Not handling NAS message MSG_TYPE=%02X with SEC_HDR_TYPE=%02X without integrity protection!\n", - msg_type, - sec_hdr_type); + logger.error("Not handling NAS message MSG_TYPE=%02X with SEC_HDR_TYPE=%02X without integrity protection!", + msg_type, + sec_hdr_type); return; } } @@ -521,9 +526,9 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) // Reserved for Security Mode Command (Sec 9.3.1) if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT && msg_type != LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND) { - nas_log->error("Not handling NAS message MSG_TYPE=%02X with SEC_HDR_TYPE=%02X. Security header type reserved!\n", - msg_type, - sec_hdr_type); + logger.error("Not handling NAS message MSG_TYPE=%02X with SEC_HDR_TYPE=%02X. Security header type reserved!", + msg_type, + sec_hdr_type); return; } @@ -582,7 +587,7 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) gw->set_test_loop_mode(gw_interface_nas::TEST_LOOP_INACTIVE); break; default: - nas_log->error("Not handling NAS message with MSG_TYPE=%02X\n", msg_type); + logger.error("Not handling NAS message with MSG_TYPE=%02X", msg_type); return; } } @@ -602,11 +607,11 @@ uint32_t nas::get_k_enb_count() bool nas::get_k_asme(uint8_t* k_asme_, uint32_t n) { if (!have_ctxt) { - nas_log->error("K_asme requested before security context established\n"); + logger.error("K_asme requested before security context established"); return false; } if (nullptr == k_asme_ || n < 32) { - nas_log->error("Invalid parameters to get_k_asme"); + logger.error("Invalid parameters to get_k_asme"); return false; } @@ -634,11 +639,11 @@ bool nas::get_ipv6_addr(uint8_t* ipv6_addr) ******************************************************************************/ void nas::start_plmn_selection_proc() { - nas_log->debug("Attempting to select PLMN\n"); + logger.debug("Attempting to select PLMN"); if (plmn_searcher.is_idle()) { - nas_log->info("No PLMN selected. Starting PLMN Selection...\n"); + logger.info("No PLMN selected. Starting PLMN Selection..."); if (not plmn_searcher.launch()) { - nas_log->error("Error starting PLMN selection"); + logger.error("Error starting PLMN selection"); return; } } @@ -648,19 +653,19 @@ void nas::start_plmn_selection_proc() // TODO check whether PLMN or Tracking Area of the selected cell is in forbiden list. void nas::select_plmn() { - nas_log->debug("Selecting PLMN from list of known PLMNs.\n"); + logger.debug("Selecting PLMN from list of known PLMNs."); // check whether the state hasn't changed if (state.get_state() != emm_state_t::state_t::deregistered and state.get_deregistered_substate() != emm_state_t::deregistered_substate_t::plmn_search) { - nas_log->error("Selecting PLMN when in incorrect EMM State\n"); + logger.error("Selecting PLMN when in incorrect EMM State"); return; } // First find if Home PLMN is available for (const srslte::plmn_id_t& known_plmn : known_plmns) { if (known_plmn == home_plmn) { - nas_log->info("Selecting Home PLMN Id=%s\n", known_plmn.to_string().c_str()); + logger.info("Selecting Home PLMN Id=%s", known_plmn.to_string().c_str()); current_plmn = known_plmn; state.set_deregistered(emm_state_t::deregistered_substate_t::normal_service); return; @@ -670,9 +675,9 @@ void nas::select_plmn() // If not, select the first available PLMN if (not known_plmns.empty()) { std::string debug_str = "Could not find Home PLMN Id=" + home_plmn.to_string() + - ", trying to connect to PLMN Id=" + known_plmns[0].to_string() + "\n"; - nas_log->info("%s", debug_str.c_str()); - srslte::console(debug_str.c_str()); + ", trying to connect to PLMN Id=" + known_plmns[0].to_string(); + logger.info("%s", debug_str.c_str()); + srslte::console("%s\n", debug_str.c_str()); current_plmn = known_plmns[0]; state.set_deregistered(emm_state_t::deregistered_substate_t::normal_service); } @@ -734,7 +739,7 @@ void nas::integrity_generate(uint8_t* key_128, bool nas::integrity_check(byte_buffer_t* pdu) { if (pdu == nullptr) { - nas_log->error("Invalid PDU\n"); + logger.error("Invalid PDU"); return false; } @@ -750,37 +755,37 @@ bool nas::integrity_check(byte_buffer_t* pdu) // Check if expected mac equals the sent mac for (int i = 0; i < 4; i++) { if (exp_mac[i] != mac[i]) { - nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " - "Received: count=%d, [%02x %02x %02x %02x]\n", - count_est, - exp_mac[0], - exp_mac[1], - exp_mac[2], - exp_mac[3], - pdu->msg[5], - mac[0], - mac[1], - mac[2], - mac[3]); + logger.warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], " + "Received: count=%d, [%02x %02x %02x %02x]", + count_est, + exp_mac[0], + exp_mac[1], + exp_mac[2], + exp_mac[3], + pdu->msg[5], + mac[0], + mac[1], + mac[2], + mac[3]); return false; } } - nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d [%02x %02x %02x %02x]\n", - count_est, - pdu->msg[5], - mac[0], - mac[1], - mac[2], - mac[3]); + logger.info("Integrity check ok. Local: count=%d, Received: count=%d [%02x %02x %02x %02x]", + count_est, + pdu->msg[5], + mac[0], + mac[1], + mac[2], + mac[3]); // Updated local count (according to TS 24.301 Sec. 4.4.3.3) if (pdu->msg[5] != ctxt.rx_count) { - nas_log->info("Update local count to received value %d\n", pdu->msg[5]); + logger.info("Update local count to received value %d", pdu->msg[5]); ctxt.rx_count = count_est; } return true; } else { - nas_log->error("Invalid integrity check PDU size (%d)\n", pdu->N_bytes); + logger.error("Invalid integrity check PDU size (%d)", pdu->N_bytes); return false; } } @@ -822,7 +827,7 @@ void nas::cipher_encrypt(byte_buffer_t* pdu) memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); break; default: - nas_log->error("Ciphering algorithm not known\n"); + logger.error("Ciphering algorithm not known"); break; } } @@ -851,7 +856,7 @@ void nas::cipher_decrypt(byte_buffer_t* pdu) &pdu->msg[6], pdu->N_bytes - 6, &tmp_pdu.msg[6]); - nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); + logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); break; case CIPHERING_ALGORITHM_ID_128_EEA3: @@ -862,11 +867,11 @@ void nas::cipher_decrypt(byte_buffer_t* pdu) &pdu->msg[6], pdu->N_bytes - 6, &tmp_pdu.msg[6]); - nas_log->debug_hex(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); + logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); break; default: - nas_log->error("Ciphering algorithms not known\n"); + logger.error("Ciphering algorithms not known"); break; } } @@ -905,11 +910,11 @@ int nas::apply_security_config(srslte::unique_byte_buffer_t& pdu, uint8_t sec_hd &k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[5], pdu->N_bytes - 5, &pdu->msg[1]); } } else { - nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); + logger.error("Invalid PDU size %d", pdu->N_bytes); return SRSLTE_ERROR; } } else { - nas_log->debug("Not applying security for PDU. No context configured.\n"); + logger.debug("Not applying security for PDU. No context configured."); } return SRSLTE_SUCCESS; } @@ -933,20 +938,20 @@ void nas::reset_security_context() void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) { if (!pdu) { - nas_log->error("Invalid PDU\n"); + logger.error("Invalid PDU"); return; } if (pdu->N_bytes <= 5) { - nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes); + logger.error("Invalid attach accept PDU size (%d)", pdu->N_bytes); return; } - nas_log->info("Received Attach Accept\n"); + logger.info("Received Attach Accept"); // stop T3410 if (t3410.is_running()) { - nas_log->debug("Stopping T3410\n"); + logger.debug("Stopping T3410"); t3410.stop(); } @@ -1002,15 +1007,15 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) if ((cfg.apn_protocol == "ipv4" && LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) || (cfg.apn_protocol == "ipv6" && LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type)) { - nas_log->error("Failed to attach -- Mismatch between PDN protocol and PDN type in attach accept.\n"); + logger.error("Failed to attach -- Mismatch between PDN protocol and PDN type in attach accept."); return; } if (("ipv4v6" == cfg.apn_protocol && LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) || ("ipv4v6" == cfg.apn_protocol && LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type)) { - nas_log->warning("Requested IPv4v6, but only received a single PDN address.\n"); - nas_log->warning("EMM Cause: %d\n", attach_accept.emm_cause); + logger.warning("Requested IPv4v6, but only received a single PDN address."); + logger.warning("EMM Cause: %d", attach_accept.emm_cause); } if (LIBLTE_MME_PDN_TYPE_IPV4 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) { ip_addr = 0; @@ -1019,113 +1024,116 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[2] << 8u; ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[3]; - nas_log->info("Network attach successful. APN: %s, IP: %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.apn.apn, - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3]); + logger.info("Network attach successful. APN: %s, IP: %u.%u.%u.%u", + act_def_eps_bearer_context_req.apn.apn, + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3]); srslte::console("Network attach successful. IP: %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3]); + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3]); // Setup GW char* err_str = nullptr; - if (gw->setup_if_addr(rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id), + if (gw->setup_if_addr(act_def_eps_bearer_context_req.eps_bearer_id, + rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id), LIBLTE_MME_PDN_TYPE_IPV4, ip_addr, nullptr, err_str)) { - nas_log->error("%s - %s\n", gw_setup_failure_str.c_str(), err_str); + logger.error("%s - %s", gw_setup_failure_str.c_str(), err_str ? err_str : ""); srslte::console("%s\n", gw_setup_failure_str.c_str()); } } else if (LIBLTE_MME_PDN_TYPE_IPV6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) { memcpy(ipv6_if_id, act_def_eps_bearer_context_req.pdn_addr.addr, 8); - nas_log->info("Network attach successful. APN: %s, IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - act_def_eps_bearer_context_req.apn.apn, - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3], - act_def_eps_bearer_context_req.pdn_addr.addr[4], - act_def_eps_bearer_context_req.pdn_addr.addr[5], - act_def_eps_bearer_context_req.pdn_addr.addr[6], - act_def_eps_bearer_context_req.pdn_addr.addr[7]); + logger.info("Network attach successful. APN: %s, IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x", + act_def_eps_bearer_context_req.apn.apn, + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3], + act_def_eps_bearer_context_req.pdn_addr.addr[4], + act_def_eps_bearer_context_req.pdn_addr.addr[5], + act_def_eps_bearer_context_req.pdn_addr.addr[6], + act_def_eps_bearer_context_req.pdn_addr.addr[7]); srslte::console("Network attach successful. IPv6 interface Id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3], - act_def_eps_bearer_context_req.pdn_addr.addr[4], - act_def_eps_bearer_context_req.pdn_addr.addr[5], - act_def_eps_bearer_context_req.pdn_addr.addr[6], - act_def_eps_bearer_context_req.pdn_addr.addr[7]); + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3], + act_def_eps_bearer_context_req.pdn_addr.addr[4], + act_def_eps_bearer_context_req.pdn_addr.addr[5], + act_def_eps_bearer_context_req.pdn_addr.addr[6], + act_def_eps_bearer_context_req.pdn_addr.addr[7]); // Setup GW char* err_str = nullptr; - if (gw->setup_if_addr(rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id), + if (gw->setup_if_addr(act_def_eps_bearer_context_req.eps_bearer_id, + rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id), LIBLTE_MME_PDN_TYPE_IPV6, 0, ipv6_if_id, err_str)) { - nas_log->error("%s - %s\n", gw_setup_failure_str.c_str(), err_str); + logger.error("%s - %s", gw_setup_failure_str.c_str(), err_str); srslte::console("%s\n", gw_setup_failure_str.c_str()); } } else if (LIBLTE_MME_PDN_TYPE_IPV4V6 == act_def_eps_bearer_context_req.pdn_addr.pdn_type) { memcpy(ipv6_if_id, act_def_eps_bearer_context_req.pdn_addr.addr, 8); // IPv6 - nas_log->info("Network attach successful. APN: %s, IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - act_def_eps_bearer_context_req.apn.apn, - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3], - act_def_eps_bearer_context_req.pdn_addr.addr[4], - act_def_eps_bearer_context_req.pdn_addr.addr[5], - act_def_eps_bearer_context_req.pdn_addr.addr[6], - act_def_eps_bearer_context_req.pdn_addr.addr[7]); + logger.info("Network attach successful. APN: %s, IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x", + act_def_eps_bearer_context_req.apn.apn, + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3], + act_def_eps_bearer_context_req.pdn_addr.addr[4], + act_def_eps_bearer_context_req.pdn_addr.addr[5], + act_def_eps_bearer_context_req.pdn_addr.addr[6], + act_def_eps_bearer_context_req.pdn_addr.addr[7]); srslte::console("Network attach successful. IPv6 interface Id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", - act_def_eps_bearer_context_req.pdn_addr.addr[0], - act_def_eps_bearer_context_req.pdn_addr.addr[1], - act_def_eps_bearer_context_req.pdn_addr.addr[2], - act_def_eps_bearer_context_req.pdn_addr.addr[3], - act_def_eps_bearer_context_req.pdn_addr.addr[4], - act_def_eps_bearer_context_req.pdn_addr.addr[5], - act_def_eps_bearer_context_req.pdn_addr.addr[6], - act_def_eps_bearer_context_req.pdn_addr.addr[7]); + act_def_eps_bearer_context_req.pdn_addr.addr[0], + act_def_eps_bearer_context_req.pdn_addr.addr[1], + act_def_eps_bearer_context_req.pdn_addr.addr[2], + act_def_eps_bearer_context_req.pdn_addr.addr[3], + act_def_eps_bearer_context_req.pdn_addr.addr[4], + act_def_eps_bearer_context_req.pdn_addr.addr[5], + act_def_eps_bearer_context_req.pdn_addr.addr[6], + act_def_eps_bearer_context_req.pdn_addr.addr[7]); // IPv4 ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[8] << 24u; ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[9] << 16u; ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[10] << 8u; ip_addr |= act_def_eps_bearer_context_req.pdn_addr.addr[11]; - nas_log->info("Network attach successful. APN: %s, IP: %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.apn.apn, - act_def_eps_bearer_context_req.pdn_addr.addr[8], - act_def_eps_bearer_context_req.pdn_addr.addr[9], - act_def_eps_bearer_context_req.pdn_addr.addr[10], - act_def_eps_bearer_context_req.pdn_addr.addr[11]); + logger.info("Network attach successful. APN: %s, IP: %u.%u.%u.%u", + act_def_eps_bearer_context_req.apn.apn, + act_def_eps_bearer_context_req.pdn_addr.addr[8], + act_def_eps_bearer_context_req.pdn_addr.addr[9], + act_def_eps_bearer_context_req.pdn_addr.addr[10], + act_def_eps_bearer_context_req.pdn_addr.addr[11]); srslte::console("Network attach successful. IP: %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.pdn_addr.addr[8], - act_def_eps_bearer_context_req.pdn_addr.addr[9], - act_def_eps_bearer_context_req.pdn_addr.addr[10], - act_def_eps_bearer_context_req.pdn_addr.addr[11]); + act_def_eps_bearer_context_req.pdn_addr.addr[8], + act_def_eps_bearer_context_req.pdn_addr.addr[9], + act_def_eps_bearer_context_req.pdn_addr.addr[10], + act_def_eps_bearer_context_req.pdn_addr.addr[11]); char* err_str = nullptr; - if (gw->setup_if_addr(rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id), + if (gw->setup_if_addr(act_def_eps_bearer_context_req.eps_bearer_id, + rrc->get_lcid_for_eps_bearer(act_def_eps_bearer_context_req.eps_bearer_id), LIBLTE_MME_PDN_TYPE_IPV4V6, ip_addr, ipv6_if_id, err_str)) { - nas_log->error("%s - %s\n", gw_setup_failure_str.c_str(), err_str); + logger.error("%s - %s", gw_setup_failure_str.c_str(), err_str); srslte::console("%s\n", gw_setup_failure_str.c_str()); } } else { - nas_log->error("PDN type not IPv4, IPv6 nor IPv4v6\n"); + logger.error("PDN type not IPv4, IPv6 nor IPv4v6"); return; } @@ -1143,11 +1151,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) dns_addr |= act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[1] << 16u; dns_addr |= act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[2] << 8u; dns_addr |= act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[3]; - nas_log->info("DNS: %u.%u.%u.%u\n", - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[0], - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[1], - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[2], - act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[3]); + logger.info("DNS: %u.%u.%u.%u", + act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[0], + act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[1], + act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[2], + act_def_eps_bearer_context_req.protocol_cnfg_opts.opt[i].contents[3]); } } } @@ -1180,11 +1188,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) } else { // bearer already exists (perhaps the attach complete got lost and this is a retx?) // TODO: what are we supposed to do in this case? - nas_log->error("Error adding EPS bearer.\n"); + logger.error("Error adding EPS bearer."); } } else { - nas_log->info("Not handling attach type %u\n", attach_accept.eps_attach_result); + logger.info("Not handling attach type %u", attach_accept.eps_attach_result); enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); } @@ -1197,12 +1205,12 @@ void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu) ZERO_OBJECT(attach_rej); liblte_mme_unpack_attach_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &attach_rej); - nas_log->warning("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); + logger.warning("Received Attach Reject. Cause= %02X", attach_rej.emm_cause); srslte::console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); // stop T3410 if (t3410.is_running()) { - nas_log->debug("Stopping T3410\n"); + logger.debug("Stopping T3410"); t3410.stop(); } @@ -1240,7 +1248,7 @@ void nas::parse_authentication_request(uint32_t lcid, unique_byte_buffer_t pdu, { LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req = {}; - nas_log->info("Received Authentication Request\n"); + logger.info("Received Authentication Request"); liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &auth_req); ctxt.rx_count++; @@ -1250,35 +1258,35 @@ void nas::parse_authentication_request(uint32_t lcid, unique_byte_buffer_t pdu, mcc = rrc->get_mcc(); mnc = rrc->get_mnc(); - nas_log->info("MCC=%d, MNC=%d\n", mcc, mnc); + logger.info("MCC=%d, MNC=%d", mcc, mnc); uint8_t res[16]; int res_len = 0; - nas_log->debug_hex(auth_req.rand, 16, "Authentication request RAND\n"); - nas_log->debug_hex(auth_req.autn, 16, "Authentication request AUTN\n"); + logger.debug(auth_req.rand, 16, "Authentication request RAND"); + logger.debug(auth_req.autn, 16, "Authentication request AUTN"); auth_result_t auth_result = usim->generate_authentication_response(auth_req.rand, auth_req.autn, mcc, mnc, res, &res_len, ctxt.k_asme); if (LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE == auth_req.nas_ksi.tsc_flag) { ctxt.ksi = auth_req.nas_ksi.nas_ksi; } else { - nas_log->error("NAS mapped security context not currently supported\n"); + logger.error("NAS mapped security context not currently supported"); srslte::console("Warning: NAS mapped security context not currently supported\n"); } if (auth_result == AUTH_OK) { - nas_log->info("Network authentication successful\n"); + logger.info("Network authentication successful"); // MME wants to re-establish security context, use provided protection level until security (re-)activation current_sec_hdr = sec_hdr_type; send_authentication_response(res, res_len); - nas_log->info_hex(ctxt.k_asme, 32, "Generated k_asme:\n"); + logger.info(ctxt.k_asme, 32, "Generated k_asme:"); set_k_enb_count(0); auth_request = true; } else if (auth_result == AUTH_SYNCH_FAILURE) { - nas_log->error("Network authentication synchronization failure.\n"); + logger.error("Network authentication synchronization failure."); send_authentication_failure(LIBLTE_MME_EMM_CAUSE_SYNCH_FAILURE, res); } else { - nas_log->warning("Network authentication failure\n"); + logger.warning("Network authentication failure"); srslte::console("Warning: Network authentication failure\n"); send_authentication_failure(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE, nullptr); } @@ -1286,7 +1294,7 @@ void nas::parse_authentication_request(uint32_t lcid, unique_byte_buffer_t pdu, void nas::parse_authentication_reject(uint32_t lcid, unique_byte_buffer_t pdu) { - nas_log->warning("Received Authentication Reject\n"); + logger.warning("Received Authentication Reject"); reset_security_context(); enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); // TODO: Command RRC to release? @@ -1297,7 +1305,7 @@ void nas::parse_identity_request(unique_byte_buffer_t pdu, const uint8_t sec_hdr LIBLTE_MME_ID_REQUEST_MSG_STRUCT id_req = {}; liblte_mme_unpack_identity_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &id_req); - nas_log->info("Received Identity Request. ID type: %d\n", id_req.id_type); + logger.info("Received Identity Request. ID type: %d", id_req.id_type); ctxt.rx_count++; // do not respond if request is not protected (TS 24.301 Sec. 4.4.4.2) @@ -1306,37 +1314,37 @@ void nas::parse_identity_request(unique_byte_buffer_t pdu, const uint8_t sec_hdr current_sec_hdr = sec_hdr_type; // use MME protection level until security (re-)activation send_identity_response(id_req.id_type); } else { - nas_log->info("Not sending identity response due to missing integrity protection.\n"); + logger.info("Not sending identity response due to missing integrity protection."); } } void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) { if (!pdu) { - nas_log->error("Invalid PDU\n"); + logger.error("Invalid PDU"); return; } if (pdu->N_bytes <= 5) { - nas_log->error("Invalid security mode command PDU size (%d)\n", pdu->N_bytes); + logger.error("Invalid security mode command PDU size (%d)", pdu->N_bytes); return; } LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd = {}; liblte_mme_unpack_security_mode_command_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &sec_mode_cmd); - nas_log->info("Received Security Mode Command ksi: %d, eea: %s, eia: %s\n", - sec_mode_cmd.nas_ksi.nas_ksi, - ciphering_algorithm_id_text[sec_mode_cmd.selected_nas_sec_algs.type_of_eea], - integrity_algorithm_id_text[sec_mode_cmd.selected_nas_sec_algs.type_of_eia]); + logger.info("Received Security Mode Command ksi: %d, eea: %s, eia: %s", + sec_mode_cmd.nas_ksi.nas_ksi, + ciphering_algorithm_id_text[sec_mode_cmd.selected_nas_sec_algs.type_of_eea], + integrity_algorithm_id_text[sec_mode_cmd.selected_nas_sec_algs.type_of_eia]); if (sec_mode_cmd.nas_ksi.tsc_flag != LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE) { - nas_log->error("Mapped security context not supported\n"); + logger.error("Mapped security context not supported"); return; } if (have_ctxt) { if (sec_mode_cmd.nas_ksi.nas_ksi != ctxt.ksi) { - nas_log->warning("Sending Security Mode Reject due to key set ID mismatch\n"); + logger.warning("Sending Security Mode Reject due to key set ID mismatch"); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED); return; } @@ -1348,7 +1356,7 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) // Check capabilities replay if (!check_cap_replay(&sec_mode_cmd.ue_security_cap)) { - nas_log->warning("Sending Security Mode Reject due to security capabilities replay mismatch\n"); + logger.warning("Sending Security Mode Reject due to security capabilities replay mismatch"); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH); return; } @@ -1365,21 +1373,20 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) // Check capabilities if (!eea_caps[ctxt.cipher_algo] || !eia_caps[ctxt.integ_algo]) { - nas_log->warning("Sending Security Mode Reject due to security capabilities mismatch\n"); + logger.warning("Sending Security Mode Reject due to security capabilities mismatch"); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_UE_SECURITY_CAPABILITIES_MISMATCH); return; } // Generate NAS keys usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); - nas_log->info_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - nas_log->info_hex(k_nas_int, 32, "NAS integrity key - k_nas_int"); + logger.info(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.info(k_nas_int, 32, "NAS integrity key - k_nas_int"); - nas_log->debug( - "Generating integrity check. integ_algo:%d, count_dl:%d, lcid:%d\n", ctxt.integ_algo, ctxt.rx_count, lcid); + logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d, lcid:%d", ctxt.integ_algo, ctxt.rx_count, lcid); if (not integrity_check(pdu.get())) { - nas_log->warning("Sending Security Mode Reject due to integrity check failure\n"); + logger.warning("Sending Security Mode Reject due to integrity check failure"); send_security_mode_reject(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE); return; } @@ -1410,13 +1417,13 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s\n", - ctxt.tx_count, - rrc->get_rb_name(lcid).c_str()); + logger.info("Sending Security Mode Complete nas_current_ctxt.tx_count=%d, RB=%s", + ctxt.tx_count, + rrc->get_rb_name(lcid).c_str()); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -1428,14 +1435,14 @@ void nas::parse_service_reject(uint32_t lcid, unique_byte_buffer_t pdu) { LIBLTE_MME_SERVICE_REJECT_MSG_STRUCT service_reject; if (liblte_mme_unpack_service_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &service_reject)) { - nas_log->error("Error unpacking service reject.\n"); + logger.error("Error unpacking service reject."); return; } srslte::console("Received service reject with EMM cause=0x%x.\n", service_reject.emm_cause); if (service_reject.t3446_present) { - nas_log->info( - "Received service reject with EMM cause=0x%x and t3446=%d\n", service_reject.emm_cause, service_reject.t3446); + logger.info( + "Received service reject with EMM cause=0x%x and t3446=%d", service_reject.emm_cause, service_reject.t3446); } // TODO: handle NAS backoff-timers correctly @@ -1454,9 +1461,9 @@ void nas::parse_esm_information_request(uint32_t lcid, unique_byte_buffer_t pdu) LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req; liblte_mme_unpack_esm_information_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &esm_info_req); - nas_log->info("ESM information request received for beaser=%d, transaction_id=%d\n", - esm_info_req.eps_bearer_id, - esm_info_req.proc_transaction_id); + logger.info("ESM information request received for beaser=%d, transaction_id=%d", + esm_info_req.eps_bearer_id, + esm_info_req.proc_transaction_id); ctxt.rx_count++; // send response @@ -1468,7 +1475,7 @@ void nas::parse_emm_information(uint32_t lcid, unique_byte_buffer_t pdu) LIBLTE_MME_EMM_INFORMATION_MSG_STRUCT emm_info = {}; liblte_mme_unpack_emm_information_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &emm_info); std::string str = emm_info_str(&emm_info); - nas_log->info("Received EMM Information: %s\n", str.c_str()); + logger.info("Received EMM Information: %s", str.c_str()); srslte::console("%s\n", str.c_str()); ctxt.rx_count++; } @@ -1479,9 +1486,9 @@ void nas::parse_detach_request(uint32_t lcid, unique_byte_buffer_t pdu) liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &detach_request); ctxt.rx_count++; - nas_log->info("Received detach request (type=%d). NAS State: %s\n", - detach_request.detach_type.type_of_detach, - state.get_full_state_text().c_str()); + logger.info("Received detach request (type=%d). NAS State: %s", + detach_request.detach_type.type_of_detach, + state.get_full_state_text().c_str()); switch (state.get_state()) { case emm_state_t::state_t::service_request_initiated: // intentional fall-through to complete detach procedure @@ -1489,18 +1496,20 @@ void nas::parse_detach_request(uint32_t lcid, unique_byte_buffer_t pdu) case emm_state_t::state_t::registered: // send accept and leave state send_detach_accept(); - enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); + + // TODO: add parsing and correct handling of EMM cause for detach (Sec. 5.5.2.3.2) + enter_emm_deregistered(emm_state_t::deregistered_substate_t::null); // schedule reattach if required if (detach_request.detach_type.type_of_detach == LIBLTE_MME_TOD_DL_REATTACH_REQUIRED) { // Section 5.5.2.3.2 // delay re-attach to allow RRC to release - nas_log->debug("Starting reattach timer\n"); + logger.debug("Starting reattach timer"); reattach_timer.run(); } break; default: - nas_log->warning("Received detach request in invalid state (%s)\n", state.get_full_state_text().c_str()); + logger.warning("Received detach request in invalid state (%s)", state.get_full_state_text().c_str()); break; } } @@ -1510,22 +1519,22 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni LIBLTE_MME_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT request; liblte_mme_unpack_activate_dedicated_eps_bearer_context_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &request); - nas_log->info( - "Received Activate Dedicated EPS bearer context request (eps_bearer_id=%d, linked_bearer_id=%d, proc_id=%d)\n", + logger.info( + "Received Activate Dedicated EPS bearer context request (eps_bearer_id=%d, linked_bearer_id=%d, proc_id=%d)", request.eps_bearer_id, request.linked_eps_bearer_id, request.proc_transaction_id); ctxt.rx_count++; LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft = &request.tft; - nas_log->info("Traffic Flow Template: TFT OP code 0x%x, Filter list size %d, Parameter list size %d\n", - tft->tft_op_code, - tft->packet_filter_list_size, - tft->parameter_list_size); + logger.info("Traffic Flow Template: TFT OP code 0x%x, Filter list size %d, Parameter list size %d", + tft->tft_op_code, + tft->packet_filter_list_size, + tft->parameter_list_size); // check the a linked default bearer exists if (eps_bearer.find(request.linked_eps_bearer_id) == eps_bearer.end()) { - nas_log->error("No linked default EPS bearer found (%d).\n", request.linked_eps_bearer_id); + logger.error("No linked default EPS bearer found (%d).", request.linked_eps_bearer_id); // TODO: send reject according to 24.301 Sec 6.4.2.5 paragraph c return; } @@ -1533,7 +1542,7 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni // check if the dedicated EPS bearer already exists if (eps_bearer.find(request.eps_bearer_id) != eps_bearer.end()) { // according to 24.301 Sec 6.4.2.5 paragraph b) the existing bearer shall be deactived before proceeding - nas_log->error("EPS bearer already exists (%d). Removing it.\n", request.eps_bearer_id); + logger.error("EPS bearer already exists (%d). Removing it.", request.eps_bearer_id); // remove bearer eps_bearer_map_t::iterator it = eps_bearer.find(request.eps_bearer_id); @@ -1546,7 +1555,7 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni bearer.eps_bearer_id = request.eps_bearer_id; bearer.linked_eps_bearer_id = request.linked_eps_bearer_id; if (not eps_bearer.insert(eps_bearer_map_pair_t(bearer.eps_bearer_id, bearer)).second) { - nas_log->error("Error adding EPS bearer.\n"); + logger.error("Error adding EPS bearer."); return; } @@ -1562,16 +1571,16 @@ void nas::parse_deactivate_eps_bearer_context_request(unique_byte_buffer_t pdu) liblte_mme_unpack_deactivate_eps_bearer_context_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &request); - nas_log->info("Received Deactivate EPS bearer context request (eps_bearer_id=%d, proc_id=%d, cause=0x%X)\n", - request.eps_bearer_id, - request.proc_transaction_id, - request.esm_cause); + logger.info("Received Deactivate EPS bearer context request (eps_bearer_id=%d, proc_id=%d, cause=0x%X)", + request.eps_bearer_id, + request.proc_transaction_id, + request.esm_cause); ctxt.rx_count++; // check if bearer exists if (eps_bearer.find(request.eps_bearer_id) == eps_bearer.end()) { - nas_log->error("EPS bearer doesn't exist (eps_bearer_id=%d)\n", request.eps_bearer_id); + logger.error("EPS bearer doesn't exist (eps_bearer_id=%d)", request.eps_bearer_id); // fixme: send proper response return; } @@ -1580,7 +1589,7 @@ void nas::parse_deactivate_eps_bearer_context_request(unique_byte_buffer_t pdu) eps_bearer_map_t::iterator it = eps_bearer.find(request.eps_bearer_id); eps_bearer.erase(it); - nas_log->info("Removed EPS bearer context (eps_bearer_id=%d)\n", request.eps_bearer_id); + logger.info("Removed EPS bearer context (eps_bearer_id=%d)", request.eps_bearer_id); send_deactivate_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id); } @@ -1591,28 +1600,28 @@ void nas::parse_modify_eps_bearer_context_request(srslte::unique_byte_buffer_t p liblte_mme_unpack_modify_eps_bearer_context_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &request); - nas_log->info("Received Modify EPS bearer context request (eps_bearer_id=%d, proc_id=%d)\n", - request.eps_bearer_id, - request.proc_transaction_id); + logger.info("Received Modify EPS bearer context request (eps_bearer_id=%d, proc_id=%d)", + request.eps_bearer_id, + request.proc_transaction_id); ctxt.rx_count++; // check if bearer exists if (eps_bearer.find(request.eps_bearer_id) == eps_bearer.end()) { - nas_log->error("EPS bearer doesn't exist (eps_bearer_id=%d)\n", request.eps_bearer_id); + logger.error("EPS bearer doesn't exist (eps_bearer_id=%d)", request.eps_bearer_id); // fixme: send proper response return; } // fixme: carry out modification - nas_log->info("Modified EPS bearer context (eps_bearer_id=%d)\n", request.eps_bearer_id); + logger.info("Modified EPS bearer context (eps_bearer_id=%d)", request.eps_bearer_id); send_modify_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id); } void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu) { - nas_log->info("Received Activate test mode\n"); + logger.info("Received Activate test mode"); ctxt.rx_count++; @@ -1622,7 +1631,7 @@ void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu) void nas::parse_close_ue_test_loop(uint32_t lcid, unique_byte_buffer_t pdu) { LIBLTE_MME_UE_TEST_LOOP_MODE_ENUM mode = static_cast(pdu->msg[8]); - nas_log->info("Received Close UE test loop for %s\n", liblte_ue_test_loop_mode_text[mode]); + logger.info("Received Close UE test loop for %s", liblte_ue_test_loop_mode_text[mode]); switch (mode) { case LIBLTE_MME_UE_TEST_LOOP_MODE_A: gw->set_test_loop_mode(gw_interface_nas::TEST_LOOP_MODE_A_ACTIVE); @@ -1650,19 +1659,19 @@ void nas::parse_emm_status(uint32_t lcid, unique_byte_buffer_t pdu) switch (emm_status.emm_cause) { case LIBLTE_MME_ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY: - nas_log->info("Received EMM status: Invalid EPS bearer identity\n"); + logger.info("Received EMM status: Invalid EPS bearer identity"); // TODO: abort any ongoing procedure (see Sec. 6.7 in TS 24.301) break; case LIBLTE_MME_ESM_CAUSE_INVALID_PTI_VALUE: - nas_log->info("Received EMM status: Invalid PTI value\n"); + logger.info("Received EMM status: Invalid PTI value"); // TODO: abort any ongoing procedure (see Sec. 6.7 in TS 24.301) break; case LIBLTE_MME_ESM_CAUSE_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED: - nas_log->info("Received EMM status: Invalid PTI value\n"); + logger.info("Received EMM status: Invalid PTI value"); // TODO: see Sec. 6.7 in TS 24.301 break; default: - nas_log->info("Received unknown EMM status (cause=%d)\n", emm_status.emm_cause); + logger.info("Received unknown EMM status (cause=%d)", emm_status.emm_cause); break; } } @@ -1674,13 +1683,13 @@ void nas::parse_emm_status(uint32_t lcid, unique_byte_buffer_t pdu) void nas::gen_attach_request(srslte::unique_byte_buffer_t& msg) { if (msg == nullptr) { - nas_log->error("Fatal Error: Couldn't allocate PDU in gen_attach_request().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in gen_attach_request()."); return; } LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; bzero(&attach_req, sizeof(LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT)); - nas_log->info("Generating attach request\n"); + logger.info("Generating attach request"); attach_req.eps_attach_type = LIBLTE_MME_EPS_ATTACH_TYPE_EPS_ATTACH; @@ -1730,20 +1739,20 @@ void nas::gen_attach_request(srslte::unique_byte_buffer_t& msg) attach_req.old_guti_type_present = true; attach_req.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; attach_req.nas_ksi.nas_ksi = ctxt.ksi; - nas_log->info("Requesting GUTI attach. " - "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x\n", - ctxt.guti.m_tmsi, - ctxt.guti.mcc, - ctxt.guti.mnc, - ctxt.guti.mme_group_id, - ctxt.guti.mme_code); + logger.info("Requesting GUTI attach. " + "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x", + ctxt.guti.m_tmsi, + ctxt.guti.mcc, + ctxt.guti.mnc, + ctxt.guti.mme_group_id, + ctxt.guti.mme_code); // According to Sec 4.4.5, the attach request is always unciphered, even if a context exists liblte_mme_pack_attach_request_msg( &attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)msg.get()); if (apply_security_config(msg, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } } else { @@ -1751,7 +1760,7 @@ void nas::gen_attach_request(srslte::unique_byte_buffer_t& msg) attach_req.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; attach_req.nas_ksi.nas_ksi = LIBLTE_MME_NAS_KEY_SET_IDENTIFIER_NO_KEY_AVAILABLE; usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15); - nas_log->info("Requesting IMSI attach (IMSI=%s)\n", usim->get_imsi_str().c_str()); + logger.info("Requesting IMSI attach (IMSI=%s)", usim->get_imsi_str().c_str()); liblte_mme_pack_attach_request_msg(&attach_req, (LIBLTE_BYTE_MSG_STRUCT*)msg.get()); } @@ -1766,28 +1775,28 @@ void nas::gen_attach_request(srslte::unique_byte_buffer_t& msg) // stop T3411 and T3402 if (t3411.is_running()) { - nas_log->debug("Stopping T3411\n"); + logger.debug("Stopping T3411"); t3411.stop(); } if (t3402.is_running()) { - nas_log->debug("Stopping T3402\n"); + logger.debug("Stopping T3402"); t3402.stop(); } // start T3410 - nas_log->debug("Starting T3410. Timeout in %d ms.\n", t3410.duration()); + logger.debug("Starting T3410. Timeout in %d ms.", t3410.duration()); t3410.run(); } void nas::gen_service_request(srslte::unique_byte_buffer_t& msg) { if (msg == nullptr) { - nas_log->error("Fatal Error: Couldn't allocate PDU in gen_service_request().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in gen_service_request()."); return; } - nas_log->info("Generating service request\n"); + logger.info("Generating service request"); // Pack the service request message directly msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4u) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); @@ -1815,7 +1824,7 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT* msg) { LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req = {}; - nas_log->info("Generating PDN Connectivity Request\n"); + logger.info("Generating PDN Connectivity Request"); // Set the PDN con req parameters pdn_con_req.eps_bearer_id = 0x00; // Unassigned bearer ID @@ -1825,16 +1834,16 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT* msg) // Set PDN protocol type if (cfg.apn_protocol == "ipv4" || cfg.apn_protocol.empty()) { - nas_log->debug("Requesting IPv4 PDN protocol\n"); + logger.debug("Requesting IPv4 PDN protocol"); pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4; } else if (cfg.apn_protocol == "ipv6") { - nas_log->debug("Requesting IPv6 PDN protocol\n"); + logger.debug("Requesting IPv6 PDN protocol"); pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV6; } else if (cfg.apn_protocol == "ipv4v6") { - nas_log->debug("Requesting IPv4v6 PDN protocol\n"); + logger.debug("Requesting IPv4v6 PDN protocol"); pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4V6; } else { - nas_log->warning("Unsupported PDN prtocol. Defaulting to IPv4\n"); + logger.warning("Unsupported PDN prtocol. Defaulting to IPv4"); srslte::console("Unsupported PDN prtocol: %s. Defaulting to IPv4\n", cfg.apn_protocol.c_str()); pdn_con_req.pdn_type = LIBLTE_MME_PDN_TYPE_IPV4; } @@ -1857,9 +1866,9 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT* msg) void nas::send_security_mode_reject(uint8_t cause) { - unique_byte_buffer_t msg = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t msg = srslte::make_byte_buffer(); if (!msg) { - nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject()."); return; } @@ -1869,7 +1878,7 @@ void nas::send_security_mode_reject(uint8_t cause) if (pcap != nullptr) { pcap->write_nas(msg->msg, msg->N_bytes); } - nas_log->info("Sending security mode reject\n"); + logger.info("Sending security mode reject"); rrc->write_sdu(std::move(msg)); } @@ -1878,9 +1887,9 @@ void nas::send_security_mode_reject(uint8_t cause) */ void nas::send_attach_request() { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); + logger.error("Fatal Error: Couldn't allocate PDU in %s().", __FUNCTION__); return; } gen_attach_request(pdu); @@ -1889,9 +1898,9 @@ void nas::send_attach_request() void nas::send_detach_request(bool switch_off) { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); + logger.error("Fatal Error: Couldn't allocate PDU in %s().", __FUNCTION__); return; } @@ -1910,7 +1919,7 @@ void nas::send_detach_request(bool switch_off) memcpy(&detach_request.eps_mobile_id.guti, &ctxt.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT)); detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; detach_request.nas_ksi.nas_ksi = ctxt.ksi; - nas_log->info("Sending detach request with GUTI\n"); // If sent as an Initial UE message, it cannot be ciphered + logger.info("Sending detach request with GUTI"); // If sent as an Initial UE message, it cannot be ciphered liblte_mme_pack_detach_request_msg( &detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); @@ -1919,7 +1928,7 @@ void nas::send_detach_request(bool switch_off) } if (apply_security_config(pdu, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } } else { @@ -1927,7 +1936,7 @@ void nas::send_detach_request(bool switch_off) detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; detach_request.nas_ksi.nas_ksi = 0; usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15); - nas_log->info("Sending detach request with IMSI\n"); + logger.info("Sending detach request with IMSI"); liblte_mme_pack_detach_request_msg( &detach_request, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); @@ -1943,7 +1952,7 @@ void nas::send_detach_request(bool switch_off) state.set_deregistered_initiated(); // start T3421 - nas_log->info("Starting T3421\n"); + logger.info("Starting T3421"); t3421.run(); } @@ -1951,7 +1960,7 @@ void nas::send_detach_request(bool switch_off) rrc->write_sdu(std::move(pdu)); } else { if (not rrc->connection_request(srslte::establishment_cause_t::mo_sig, std::move(pdu))) { - nas_log->error("Error starting RRC connection"); + logger.error("Error starting RRC connection"); } } @@ -1970,7 +1979,7 @@ void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& ep &attach_complete.esm_msg); // Pack entire message - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); liblte_mme_pack_attach_complete_msg( &attach_complete, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); // Write NAS pcap @@ -1979,23 +1988,23 @@ void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& ep } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } // Instruct RRC to enable capabilities rrc->enable_capabilities(); - nas_log->info("Sending Attach Complete\n"); + logger.info("Sending Attach Complete"); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; } void nas::send_detach_accept() { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - nas_log->error("Fatal Error: Couldn't allocate PDU in %s().\n", __FUNCTION__); + logger.error("Fatal Error: Couldn't allocate PDU in %s().", __FUNCTION__); return; } @@ -2008,19 +2017,19 @@ void nas::send_detach_accept() } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info("Sending detach accept\n"); + logger.info("Sending detach accept"); rrc->write_sdu(std::move(pdu)); } void nas::send_authentication_response(const uint8_t* res, const size_t res_len) { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in send_authentication_response()."); return; } @@ -2038,20 +2047,20 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len) } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info("Sending Authentication Response\n"); + logger.info("Sending Authentication Response"); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; } void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param) { - unique_byte_buffer_t msg = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t msg = srslte::make_byte_buffer(); if (!msg) { - nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_failure().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in send_authentication_failure()."); return; } @@ -2059,7 +2068,7 @@ void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_f auth_failure.emm_cause = cause; if (auth_fail_param != nullptr) { memcpy(auth_failure.auth_fail_param, auth_fail_param, 14); - nas_log->debug_hex(auth_failure.auth_fail_param, 14, "auth_failure.auth_fail_param\n"); + logger.debug(auth_failure.auth_fail_param, 14, "auth_failure.auth_fail_param"); auth_failure.auth_fail_param_present = true; } else { auth_failure.auth_fail_param_present = false; @@ -2069,7 +2078,7 @@ void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_f if (pcap != nullptr) { pcap->write_nas(msg->msg, msg->N_bytes); } - nas_log->info("Sending authentication failure.\n"); + logger.info("Sending authentication failure."); rrc->write_sdu(std::move(msg)); } @@ -2093,13 +2102,13 @@ void nas::send_identity_response(const uint8 id_type) id_resp.mobile_id.imeisv[15] = ue_svn_oct2; break; default: - nas_log->error("Unhandled ID type: %d\n", id_type); + logger.error("Unhandled ID type: %d", id_type); return; } - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - nas_log->error("Fatal Error: Couldn't allocate PDU in send_identity_response().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in send_identity_response()."); return; } @@ -2107,7 +2116,7 @@ void nas::send_identity_response(const uint8 id_type) // add security if needed if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } @@ -2121,9 +2130,9 @@ void nas::send_identity_response(const uint8 id_type) void nas::send_service_request() { - unique_byte_buffer_t msg = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t msg = srslte::make_byte_buffer(); if (!msg) { - nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n"); + logger.error("Fatal Error: Couldn't allocate PDU in send_service_request()."); return; } @@ -2146,7 +2155,7 @@ void nas::send_service_request() pcap->write_nas(msg->msg, msg->N_bytes); } - nas_log->info("Sending service request\n"); + logger.info("Sending service request"); rrc->write_sdu(std::move(msg)); ctxt.tx_count++; } @@ -2160,7 +2169,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) if (cfg.apn_name == "") { esm_info_resp.apn_present = false; } else { - nas_log->debug("Including APN %s in ESM info response\n", cfg.apn_name.c_str()); + logger.debug("Including APN %s in ESM info response", cfg.apn_name.c_str()); esm_info_resp.apn_present = true; int len = std::min((int)cfg.apn_name.length(), LIBLTE_STRING_LEN - 1); strncpy(esm_info_resp.apn.apn, cfg.apn_name.c_str(), len); @@ -2169,8 +2178,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) if (cfg.apn_user != "" && cfg.apn_user.length() < LIBLTE_STRING_LEN && cfg.apn_pass != "" && cfg.apn_pass.length() < LIBLTE_STRING_LEN) { - - nas_log->debug("Including CHAP authentication for user %s in ESM info response\n", cfg.apn_user.c_str()); + logger.debug("Including CHAP authentication for user %s in ESM info response", cfg.apn_user.c_str()); // Generate CHAP challenge uint16_t len = 1 /* CHAP code */ + 1 /* ID */ + 2 /* complete length */ + 1 /* data value size */ + @@ -2242,15 +2250,15 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) esm_info_resp.protocol_cnfg_opts_present = false; } - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (!pdu) { - nas_log->error("Fatal Error: Couldn't allocate PDU in %s.\n", __FUNCTION__); + logger.error("Fatal Error: Couldn't allocate PDU in %s.", __FUNCTION__); return; } if (liblte_mme_pack_esm_information_response_msg( &esm_info_resp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { - nas_log->error("Error packing ESM information response.\n"); + logger.error("Error packing ESM information response."); return; } @@ -2259,11 +2267,11 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending ESM information response\n"); + logger.info(pdu->msg, pdu->N_bytes, "Sending ESM information response"); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -2273,7 +2281,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id) { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); LIBLTE_MME_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT accept = {}; @@ -2282,7 +2290,7 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ if (liblte_mme_pack_activate_dedicated_eps_bearer_context_accept_msg( &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { - nas_log->error("Error packing Activate Dedicated EPS Bearer context accept.\n"); + logger.error("Error packing Activate Dedicated EPS Bearer context accept."); return; } @@ -2291,15 +2299,15 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info_hex(pdu->msg, - pdu->N_bytes, - "Sending Activate Dedicated EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)\n", - accept.eps_bearer_id, - accept.proc_transaction_id); + logger.info(pdu->msg, + pdu->N_bytes, + "Sending Activate Dedicated EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)", + accept.eps_bearer_id, + accept.proc_transaction_id); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -2307,7 +2315,7 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id) { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT accept = {}; @@ -2316,7 +2324,7 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact if (liblte_mme_pack_deactivate_eps_bearer_context_accept_msg( &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { - nas_log->error("Error packing Activate EPS Bearer context accept.\n"); + logger.error("Error packing Activate EPS Bearer context accept."); return; } @@ -2325,15 +2333,15 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info_hex(pdu->msg, - pdu->N_bytes, - "Sending Deactivate EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)\n", - accept.eps_bearer_id, - accept.proc_transaction_id); + logger.info(pdu->msg, + pdu->N_bytes, + "Sending Deactivate EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)", + accept.eps_bearer_id, + accept.proc_transaction_id); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -2341,7 +2349,7 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id) { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); LIBLTE_MME_MODIFY_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT accept = {}; @@ -2350,7 +2358,7 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ if (liblte_mme_pack_modify_eps_bearer_context_accept_msg( &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { - nas_log->error("Error packing Modify EPS Bearer context accept.\n"); + logger.error("Error packing Modify EPS Bearer context accept."); return; } @@ -2359,15 +2367,15 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info_hex(pdu->msg, - pdu->N_bytes, - "Sending Modify EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)\n", - accept.eps_bearer_id, - accept.proc_transaction_id); + logger.info(pdu->msg, + pdu->N_bytes, + "Sending Modify EPS Bearer context accept (eps_bearer_id=%d, proc_id=%d)", + accept.eps_bearer_id, + accept.proc_transaction_id); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -2375,11 +2383,11 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ void nas::send_activate_test_mode_complete() { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (liblte_mme_pack_activate_test_mode_complete_msg( (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt.tx_count)) { - nas_log->error("Error packing activate test mode complete.\n"); + logger.error("Error packing activate test mode complete."); return; } @@ -2388,11 +2396,11 @@ void nas::send_activate_test_mode_complete() } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending Activate test mode complete\n"); + logger.info(pdu->msg, pdu->N_bytes, "Sending Activate test mode complete"); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -2400,11 +2408,11 @@ void nas::send_activate_test_mode_complete() void nas::send_close_ue_test_loop_complete() { - unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); if (liblte_mme_pack_close_ue_test_loop_complete_msg( (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt.tx_count)) { - nas_log->error("Error packing close UE test loop complete.\n"); + logger.error("Error packing close UE test loop complete."); return; } @@ -2413,11 +2421,11 @@ void nas::send_close_ue_test_loop_complete() } if (apply_security_config(pdu, current_sec_hdr)) { - nas_log->error("Error applying NAS security.\n"); + logger.error("Error applying NAS security."); return; } - nas_log->info_hex(pdu->msg, pdu->N_bytes, "Sending Close UE test loop complete\n"); + logger.info(pdu->msg, pdu->N_bytes, "Sending Close UE test loop complete"); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; @@ -2435,7 +2443,7 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) } if (cfg.force_imsi_attach) { - nas_log->info("Skip reading context from file.\n"); + logger.info("Skip reading context from file."); return false; } @@ -2477,21 +2485,21 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) } file.close(); - nas_log->info("Read GUTI from file " - "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x\n", - ctxt_->guti.m_tmsi, - ctxt_->guti.mcc, - ctxt_->guti.mnc, - ctxt_->guti.mme_group_id, - ctxt_->guti.mme_code); - nas_log->info("Read security ctxt from file .ctxt. " - "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d\n", - ctxt_->ksi, - hex_to_string(ctxt_->k_asme, 32).c_str(), - ctxt_->tx_count, - ctxt_->rx_count, - ctxt_->integ_algo, - ctxt_->cipher_algo); + logger.info("Read GUTI from file " + "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x", + ctxt_->guti.m_tmsi, + ctxt_->guti.mcc, + ctxt_->guti.mnc, + ctxt_->guti.mme_group_id, + ctxt_->guti.mme_code); + logger.info("Read security ctxt from file .ctxt. " + "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d", + ctxt_->ksi, + hex_to_string(ctxt_->k_asme, 32).c_str(), + ctxt_->tx_count, + ctxt_->rx_count, + ctxt_->integ_algo, + ctxt_->cipher_algo); have_guti = true; have_ctxt = true; @@ -2523,21 +2531,21 @@ bool nas::write_ctxt_file(nas_sec_ctxt ctxt_) file << "k_asme=" << hex_to_string(ctxt_.k_asme, 32) << std::endl; - nas_log->info("Saved GUTI to file " - "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x\n", - ctxt_.guti.m_tmsi, - ctxt_.guti.mcc, - ctxt_.guti.mnc, - ctxt_.guti.mme_group_id, - ctxt_.guti.mme_code); - nas_log->info("Saved security ctxt to file .ctxt. " - "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d\n", - ctxt_.ksi, - hex_to_string(ctxt_.k_asme, 32).c_str(), - ctxt_.tx_count, - ctxt_.rx_count, - ctxt_.integ_algo, - ctxt_.cipher_algo); + logger.info("Saved GUTI to file " + "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x", + ctxt_.guti.m_tmsi, + ctxt_.guti.mcc, + ctxt_.guti.mnc, + ctxt_.guti.mme_group_id, + ctxt_.guti.mme_code); + logger.info("Saved security ctxt to file .ctxt. " + "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d", + ctxt_.ksi, + hex_to_string(ctxt_.k_asme, 32).c_str(), + ctxt_.tx_count, + ctxt_.rx_count, + ctxt_.integ_algo, + ctxt_.cipher_algo); file.close(); return true; } diff --git a/srsue/src/stack/upper/nas_emm_state.cc b/srsue/src/stack/upper/nas_emm_state.cc index 34eb69765..b81092e8a 100644 --- a/srsue/src/stack/upper/nas_emm_state.cc +++ b/srsue/src/stack/upper/nas_emm_state.cc @@ -28,7 +28,7 @@ void emm_state_t::set_null() state = state_t::null; deregistered_substate = deregistered_substate_t::null; registered_substate = registered_substate_t::null; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } void emm_state_t::set_deregistered(deregistered_substate_t substate) @@ -36,7 +36,7 @@ void emm_state_t::set_deregistered(deregistered_substate_t substate) state = state_t::deregistered; deregistered_substate = substate; registered_substate = registered_substate_t::null; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } void emm_state_t::set_deregistered_initiated() @@ -44,7 +44,7 @@ void emm_state_t::set_deregistered_initiated() state = state_t::deregistered_initiated; deregistered_substate = deregistered_substate_t::null; registered_substate = registered_substate_t::null; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } void emm_state_t::set_registered(registered_substate_t substate) @@ -52,7 +52,7 @@ void emm_state_t::set_registered(registered_substate_t substate) state = state_t::registered; deregistered_substate = deregistered_substate_t::null; registered_substate = substate; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } void emm_state_t::set_registered_initiated() @@ -60,7 +60,7 @@ void emm_state_t::set_registered_initiated() state = state_t::registered_initiated; deregistered_substate = deregistered_substate_t::null; registered_substate = registered_substate_t::null; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } void emm_state_t::set_tau_initiated() @@ -68,7 +68,7 @@ void emm_state_t::set_tau_initiated() state = state_t::tau_initiated; deregistered_substate = deregistered_substate_t::null; registered_substate = registered_substate_t::null; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } void emm_state_t::set_service_request_initiated() @@ -76,7 +76,7 @@ void emm_state_t::set_service_request_initiated() state = state_t::service_request_initiated; deregistered_substate = deregistered_substate_t::null; registered_substate = registered_substate_t::null; - nas_log->debug("Changed to EMM state: %s\n", get_full_state_text().c_str()); + logger.debug("Changed to EMM state: %s", get_full_state_text().c_str()); } const std::string emm_state_t::get_full_state_text() diff --git a/srsue/src/stack/upper/nas_idle_procedures.cc b/srsue/src/stack/upper/nas_idle_procedures.cc index bdd16378d..75fbd5b6e 100644 --- a/srsue/src/stack/upper/nas_idle_procedures.cc +++ b/srsue/src/stack/upper/nas_idle_procedures.cc @@ -23,9 +23,9 @@ using namespace srslte; -#define ProcError(fmt, ...) nas_ptr->nas_log->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define ProcWarning(fmt, ...) nas_ptr->nas_log->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define ProcInfo(fmt, ...) nas_ptr->nas_log->info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define ProcError(fmt, ...) nas_ptr->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define ProcWarning(fmt, ...) nas_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define ProcInfo(fmt, ...) nas_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) namespace srsue { @@ -39,11 +39,11 @@ proc_outcome_t nas::plmn_search_proc::init() { // start RRC PLMN selection if (not nas_ptr->rrc->plmn_search()) { - ProcError("ProcError while searching for PLMNs\n"); + ProcError("ProcError while searching for PLMNs"); return proc_outcome_t::error; } - ProcInfo("Starting...\n"); + ProcInfo("Starting..."); return proc_outcome_t::yield; } @@ -54,7 +54,7 @@ proc_outcome_t nas::plmn_search_proc::step() void nas::plmn_search_proc::then(const srslte::proc_state_t& result) { - ProcInfo("Completed with %s\n", result.is_success() ? "success" : "failure"); + ProcInfo("Completed with %s", result.is_success() ? "success" : "failure"); if (result.is_error()) { nas_ptr->enter_emm_deregistered(emm_state_t::deregistered_substate_t::plmn_search); @@ -66,16 +66,16 @@ proc_outcome_t nas::plmn_search_proc::react(const plmn_search_complete_t& t) // check whether the NAS state hasn't changed if (nas_ptr->state.get_state() != emm_state_t::state_t::deregistered and nas_ptr->state.get_deregistered_substate() != emm_state_t::deregistered_substate_t::plmn_search) { - ProcError("ProcError while searching for PLMNs\n"); + ProcError("ProcError while searching for PLMNs"); return proc_outcome_t::error; } if (t.nof_plmns < 0) { - ProcError("Error while searching for PLMNs\n"); + ProcError("Error while searching for PLMNs"); return proc_outcome_t::error; } if (t.nof_plmns == 0) { - ProcWarning("Did not find any PLMN in the set of frequencies.\n"); + ProcWarning("Did not find any PLMN in the set of frequencies."); return proc_outcome_t::error; } @@ -83,8 +83,7 @@ proc_outcome_t nas::plmn_search_proc::react(const plmn_search_complete_t& t) nas_ptr->known_plmns.clear(); for (int i = 0; i < t.nof_plmns; i++) { nas_ptr->known_plmns.push_back(t.found_plmns[i].plmn_id); - nas_ptr->nas_log->info( - "Found PLMN: Id=%s, TAC=%d\n", t.found_plmns[i].plmn_id.to_string().c_str(), t.found_plmns[i].tac); + ProcInfo("Found PLMN: Id=%s, TAC=%d", t.found_plmns[i].plmn_id.to_string().c_str(), t.found_plmns[i].tac); srslte::console("Found PLMN: Id=%s, TAC=%d\n", t.found_plmns[i].plmn_id.to_string().c_str(), t.found_plmns[i].tac); } nas_ptr->select_plmn(); @@ -92,7 +91,7 @@ proc_outcome_t nas::plmn_search_proc::react(const plmn_search_complete_t& t) // Select PLMN in request establishment of RRC connection if (nas_ptr->state.get_state() != emm_state_t::state_t::deregistered and nas_ptr->state.get_deregistered_substate() != emm_state_t::deregistered_substate_t::normal_service) { - ProcError("PLMN is not selected because no suitable PLMN was found\n"); + ProcError("PLMN is not selected because no suitable PLMN was found"); return proc_outcome_t::error; } diff --git a/srsue/src/stack/upper/pcsc_usim.cc b/srsue/src/stack/upper/pcsc_usim.cc index 130114aa7..b1accd356 100644 --- a/srsue/src/stack/upper/pcsc_usim.cc +++ b/srsue/src/stack/upper/pcsc_usim.cc @@ -31,7 +31,7 @@ using namespace srslte; namespace srsue { -pcsc_usim::pcsc_usim(srslte::log* log_) : usim_base(log_) +pcsc_usim::pcsc_usim(srslog::basic_logger& logger) : usim_base(logger), sc(logger) { bzero(ck, CK_LEN); bzero(ik, IK_LEN); @@ -50,7 +50,7 @@ int pcsc_usim::init(usim_args_t* args) { int ret = SRSLTE_ERROR; - if (sc.init(args, log) != SRSLTE_SUCCESS) { + if (sc.init(args) != SRSLTE_SUCCESS) { return ret; } @@ -58,7 +58,7 @@ int pcsc_usim::init(usim_args_t* args) char tmp[15]; size_t tmp_len = 15; // set to max IMSI length if (sc.get_imsi(tmp, &tmp_len)) { - log->error("Error reading IMSI from SIM.\n"); + logger.error("Error reading IMSI from SIM."); return ret; } imsi_str.assign(tmp, tmp_len); @@ -72,7 +72,7 @@ int pcsc_usim::init(usim_args_t* args) imsi += imsi_c[i] - '0'; } } else { - log->error("Invalid length for IMSI: %zu should be %d\n", imsi_str.length(), 15); + logger.error("Invalid length for IMSI: %zu should be %d", imsi_str.length(), 15); srslte::console("Invalid length for IMSI: %zu should be %d\n", imsi_str.length(), 15); return ret; } @@ -86,7 +86,7 @@ int pcsc_usim::init(usim_args_t* args) imei += imei_c[i] - '0'; } } else { - log->error("Invalid length for IMEI: %zu should be %d\n", args->imei.length(), 15); + logger.error("Invalid length for IMEI: %zu should be %d", args->imei.length(), 15); srslte::console("Invalid length for IMEI: %zu should be %d\n", args->imei.length(), 15); return ret; } @@ -113,26 +113,26 @@ auth_result_t pcsc_usim::generate_authentication_response(uint8_t* rand, { auth_result_t ret = AUTH_FAILED; if (!initiated) { - ERROR("USIM not initiated!\n"); + ERROR("USIM not initiated!"); return ret; } // Use RAND and AUTN to compute RES, CK, IK using SIM card switch (sc.umts_auth(rand, autn_enb, res, res_len, ik, ck, auts)) { case 0: - log->info("SCARD: USIM authentication successful.\n"); + logger.info("SCARD: USIM authentication successful."); break; case -1: - log->error("SCARD: Failure during USIM UMTS authentication\n"); + logger.error("SCARD: Failure during USIM UMTS authentication"); return ret; case -2: - log->info("SCARD: USIM synchronization failure, AUTS generated\n"); - log->debug_hex(auts, AKA_AUTS_LEN, "AUTS\n"); + logger.info("SCARD: USIM synchronization failure, AUTS generated"); + logger.debug(auts, AKA_AUTS_LEN, "AUTS"); memcpy(res, auts, AKA_AUTS_LEN); *res_len = AKA_AUTS_LEN; return AUTH_SYNCH_FAILURE; default: - log->warning("SCARD: Unknown USIM failure.\n"); + logger.warning("SCARD: Unknown USIM failure."); return ret; } @@ -146,13 +146,13 @@ auth_result_t pcsc_usim::generate_authentication_response(uint8_t* rand, } // Generate K_asme - log->debug_hex(ck, CK_LEN, "CK:\n"); - log->debug_hex(ik, IK_LEN, "IK:\n"); - log->debug_hex(ak, AK_LEN, "AK:\n"); - log->debug_hex(sqn, SQN_LEN, "SQN:\n"); - log->debug("mcc=%d, mnc=%d\n", mcc, mnc); + logger.debug(ck, CK_LEN, "CK:"); + logger.debug(ik, IK_LEN, "IK:"); + logger.debug(ak, AK_LEN, "AK:"); + logger.debug(sqn, SQN_LEN, "SQN:"); + logger.debug("mcc=%d, mnc=%d", mcc, mnc); security_generate_k_asme(ck, ik, ak, sqn, mcc, mnc, k_asme); - log->info_hex(k_asme, KEY_LEN, "K_ASME:\n"); + logger.info(k_asme, KEY_LEN, "K_ASME:"); ret = AUTH_OK; @@ -177,49 +177,48 @@ std::string pcsc_usim::get_mnc_str(const uint8_t* imsi_vec, std::string mcc_str) ********************************/ // return 0 if initialization was successfull, -1 otherwies -int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) +int pcsc_usim::scard::init(usim_args_t* args) { int ret_value = SRSLTE_ERROR; uint pos = 0; // SC reader bool reader_found = false; // int transaction = 1; size_t blen; - log = log_; long ret; ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &scard_context); if (ret != SCARD_S_SUCCESS) { - log->error("SCardEstablishContext(): %s\n", pcsc_stringify_error(ret)); + logger.error("SCardEstablishContext(): %s", pcsc_stringify_error(ret)); return ret_value; } unsigned long len = 0; ret = SCardListReaders(scard_context, NULL, NULL, &len); if (ret != SCARD_S_SUCCESS) { - log->error("SCardListReaders(): %s\n", pcsc_stringify_error(ret)); + logger.error("SCardListReaders(): %s", pcsc_stringify_error(ret)); return ret_value; } char* readers = (char*)malloc(len); if (readers == NULL) { - log->error("Malloc failed\n"); + logger.error("Malloc failed"); return ret_value; } ret = SCardListReaders(scard_context, NULL, readers, &len); if (ret != SCARD_S_SUCCESS) { - log->error("SCardListReaders() 2: %s\n", pcsc_stringify_error(ret)); + logger.error("SCardListReaders() 2: %s", pcsc_stringify_error(ret)); goto clean_exit; } if (len < 3) { - log->info("No smart card readers available.\n"); + logger.info("No smart card readers available."); return ret_value; } /* readers: NULL-separated list of reader names, and terminating NULL */ pos = 0; while (pos < len - 1) { - log->info("Available Card Reader: %s\n", &readers[pos]); + logger.info("Available Card Reader: %s", &readers[pos]); while (readers[pos] != '\0' && pos < len) { pos++; } @@ -232,7 +231,7 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) // If no reader specified, test all available readers for SIM cards. Otherwise consider specified reader only. if (args->reader.length() == 0) { while (pos < len && !reader_found) { - log->info("Trying Card Reader: %s\n", &readers[pos]); + logger.info("Trying Card Reader: %s", &readers[pos]); // Connect to card ret = SCardConnect(scard_context, &readers[pos], @@ -244,11 +243,11 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) reader_found = true; } else { if (ret == (long)SCARD_E_NO_SMARTCARD) { - log->error("No smart card inserted.\n"); + logger.error("No smart card inserted."); } else { - log->error("%s\n", pcsc_stringify_error(ret)); + logger.error("%s", pcsc_stringify_error(ret)); } - log->info("Failed to use Card Reader: %s\n", &readers[pos]); + logger.info("Failed to use Card Reader: %s", &readers[pos]); // proceed to next reader while (pos < len && readers[pos] != '\0') { @@ -262,7 +261,7 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) while (pos < len && !reader_found) { if (strcmp(&readers[pos], args->reader.c_str()) == 0) { reader_found = true; - log->info("Card Reader found: %s\n", args->reader.c_str()); + logger.info("Card Reader found: %s", args->reader.c_str()); } else { // next reader while (pos < len && readers[pos] != '\0') { @@ -272,7 +271,7 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) } } if (!reader_found) { - log->error("Cannot find reader: %s\n", args->reader.c_str()); + logger.error("Cannot find reader: %s", args->reader.c_str()); } else { ret = SCardConnect(scard_context, &readers[pos], @@ -284,12 +283,12 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) // successfully connected to card } else { if (ret == (long)SCARD_E_NO_SMARTCARD) { - log->error("No smart card inserted.\n"); + logger.error("No smart card inserted."); } else { - log->error("%s\n", pcsc_stringify_error(ret)); + logger.error("%s", pcsc_stringify_error(ret)); } - log->info("Failed to use Card Reader: %s\n", args->reader.c_str()); + logger.info("Failed to use Card Reader: %s", args->reader.c_str()); } } } @@ -297,14 +296,14 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) free(readers); readers = NULL; - log->info("Card=0x%x active_protocol=%lu (%s)\n", - (unsigned int)scard_handle, - (unsigned long)scard_protocol, - scard_protocol == SCARD_PROTOCOL_T0 ? "T0" : "T1"); + logger.info("Card=0x%x active_protocol=%lu (%s)", + (unsigned int)scard_handle, + (unsigned long)scard_protocol, + scard_protocol == SCARD_PROTOCOL_T0 ? "T0" : "T1"); ret = SCardBeginTransaction(scard_handle); if (ret != SCARD_S_SUCCESS) { - log->error("%s\n", pcsc_stringify_error(ret)); + logger.error("%s", pcsc_stringify_error(ret)); goto clean_exit; } @@ -312,23 +311,23 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) unsigned char buf[100]; blen = sizeof(buf); if (_select_file(SCARD_FILE_MF, buf, &blen, SCARD_USIM, NULL, 0)) { - log->info("USIM is not supported. Trying to use GSM SIM"); + logger.info("USIM is not supported. Trying to use GSM SIM"); sim_type = SCARD_GSM_SIM; } else { - log->info("USIM is supported\n"); + logger.info("USIM is supported"); sim_type = SCARD_USIM; } if (sim_type == SCARD_GSM_SIM) { blen = sizeof(buf); if (select_file(SCARD_FILE_MF, buf, &blen)) { - log->debug("SCARD: Failed to read MF\n"); + logger.debug("SCARD: Failed to read MF"); goto clean_exit; } blen = sizeof(buf); if (select_file(SCARD_FILE_GSM_DF, buf, &blen)) { - log->debug("SCARD: Failed to read GSM DF\n"); + logger.debug("SCARD: Failed to read GSM DF"); goto clean_exit; } } else { @@ -337,19 +336,19 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) aid_len = get_aid(aid, sizeof(aid)); if (aid_len < 0) { - log->debug("SCARD: Failed to find AID for 3G USIM app - try to use standard 3G RID\n"); + logger.debug("SCARD: Failed to find AID for 3G USIM app - try to use standard 3G RID"); memcpy(aid, "\xa0\x00\x00\x00\x87", 5); aid_len = 5; } - log->debug_hex(aid, aid_len, "SCARD: 3G USIM AID\n"); + logger.debug(aid, aid_len, "SCARD: 3G USIM AID"); /* Select based on AID = 3G RID from EF_DIR. This is usually * starting with A0 00 00 00 87. */ blen = sizeof(buf); if (_select_file(0, buf, &blen, sim_type, aid, aid_len)) { - log->error("SCARD: Failed to read 3G USIM app\n"); - log->error_hex(aid, aid_len, "SCARD: 3G USIM AID\n"); + logger.error("SCARD: Failed to read 3G USIM app"); + logger.error(aid, aid_len, "SCARD: 3G USIM AID"); goto clean_exit; } } @@ -358,11 +357,11 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) // Verify whether CHV1 (PIN1) is needed to access the card. ret = pin_needed(buf, blen); if (ret < 0) { - log->debug("SCARD: Failed to determine whether PIN is needed\n"); + logger.debug("SCARD: Failed to determine whether PIN is needed"); goto clean_exit; } if (ret) { - log->debug("PIN1 needed for SIM access (retry counter=%d)\n", get_pin_retry_counter()); + logger.debug("PIN1 needed for SIM access (retry counter=%d)", get_pin_retry_counter()); pin1_needed = true; } else { pin1_needed = false; @@ -370,7 +369,7 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) // stop before pin retry counter reaches zero if (pin1_needed && get_pin_retry_counter() <= 1) { - log->error("PIN1 needed for SIM access (retry counter=%d), emergency stop.\n", get_pin_retry_counter()); + logger.error("PIN1 needed for SIM access (retry counter=%d), emergency stop.", get_pin_retry_counter()); goto clean_exit; } @@ -379,7 +378,7 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) // verify PIN ret = verify_pin(args->pin.c_str()); if (ret != SCARD_S_SUCCESS) { - log->debug("SCARD: Could not verify PIN\n"); + logger.debug("SCARD: Could not verify PIN"); goto clean_exit; } } @@ -389,7 +388,7 @@ int pcsc_usim::scard::init(usim_args_t* args, srslte::log* log_) ret = SCardEndTransaction(scard_handle, SCARD_LEAVE_CARD); if (ret != SCARD_S_SUCCESS) { - log->debug("SCARD: Could not end transaction: 0x%x\n", (unsigned int)ret); + logger.debug("SCARD: Could not end transaction: 0x%x", (unsigned int)ret); goto clean_exit; } @@ -423,9 +422,9 @@ int pcsc_usim::scard::_select_file(unsigned short file_id, get_resp[0] = USIM_CLA; } - log->debug("SCARD: select file %04x\n", file_id); + logger.debug("SCARD: select file %04x", file_id); if (aid) { - log->debug_hex(aid, aidlen, "SCARD: select file by AID"); + logger.debug(aid, aidlen, "SCARD: select file by AID"); if (5 + aidlen > sizeof(cmd)) return -1; cmd[2] = 0x04; /* Select by AID */ @@ -440,34 +439,34 @@ int pcsc_usim::scard::_select_file(unsigned short file_id, len = sizeof(resp); ret = transmit(cmd, cmdlen, resp, &len); if (ret != SCARD_S_SUCCESS) { - log->error("SCARD: SCardTransmit failed %s\n", pcsc_stringify_error(ret)); + logger.error("SCARD: SCardTransmit failed %s", pcsc_stringify_error(ret)); return -1; } if (len != 2) { - log->error("SCARD: unexpected resp len %d (expected 2)\n", (int)len); + logger.error("SCARD: unexpected resp len %d (expected 2)", (int)len); return -1; } if (resp[0] == 0x98 && resp[1] == 0x04) { /* Security status not satisfied (PIN_WLAN) */ - log->warning("SCARD: Security status not satisfied.\n"); + logger.warning("SCARD: Security status not satisfied."); return -1; } if (resp[0] == 0x6e) { - log->debug("SCARD: used CLA not supported.\n"); + logger.debug("SCARD: used CLA not supported."); return -1; } if (resp[0] != 0x6c && resp[0] != 0x9f && resp[0] != 0x61) { - log->warning("SCARD: unexpected response 0x%02x (expected 0x61, 0x6c, or 0x9f)\n", resp[0]); + logger.warning("SCARD: unexpected response 0x%02x (expected 0x61, 0x6c, or 0x9f)", resp[0]); return -1; } /* Normal ending of command; resp[1] bytes available */ get_resp[4] = resp[1]; - log->debug("SCARD: trying to get response (%d bytes)\n", resp[1]); + logger.debug("SCARD: trying to get response (%d bytes)", resp[1]); rlen = *buf_len; ret = transmit(get_resp, sizeof(get_resp), buf, &rlen); @@ -476,7 +475,7 @@ int pcsc_usim::scard::_select_file(unsigned short file_id, return 0; } - log->warning("SCARD: SCardTransmit err=0x%lx\n", ret); + logger.warning("SCARD: SCardTransmit err=0x%lx", ret); return -1; } @@ -490,7 +489,7 @@ long pcsc_usim::scard::transmit(unsigned char* _send, size_t send_len, unsigned long ret; unsigned long rlen; - log->debug_hex(_send, send_len, "SCARD: scard_transmit: send\n"); + logger.debug(_send, send_len, "SCARD: scard_transmit: send"); rlen = *recv_len; ret = SCardTransmit(scard_handle, scard_protocol == SCARD_PROTOCOL_T1 ? SCARD_PCI_T1 : SCARD_PCI_T0, @@ -501,9 +500,9 @@ long pcsc_usim::scard::transmit(unsigned char* _send, size_t send_len, unsigned &rlen); *recv_len = rlen; if (ret == SCARD_S_SUCCESS) { - log->debug_hex(_recv, rlen, "SCARD: SCardTransmit: recv\n"); + logger.debug(_recv, rlen, "SCARD: SCardTransmit: recv"); } else { - log->error("SCARD: SCardTransmit failed %s\n", pcsc_stringify_error(ret)); + logger.error("SCARD: SCardTransmit failed %s", pcsc_stringify_error(ret)); } return ret; } @@ -538,7 +537,7 @@ int pcsc_usim::scard::get_pin_retry_counter() size_t len; uint16_t val; - log->info("SCARD: fetching PIN retry counter\n"); + logger.info("SCARD: fetching PIN retry counter"); if (sim_type == SCARD_USIM) cmd[0] = USIM_CLA; @@ -550,20 +549,20 @@ int pcsc_usim::scard::get_pin_retry_counter() return -2; if (len != 2) { - log->error("SCARD: failed to fetch PIN retry counter\n"); + logger.error("SCARD: failed to fetch PIN retry counter"); return -1; } val = to_uint16(resp); if (val == 0x63c0 || val == 0x6983) { - log->debug("SCARD: PIN has been blocked\n"); + logger.debug("SCARD: PIN has been blocked"); return 0; } if (val >= 0x63c0 && val <= 0x63cf) return val & 0x000f; - log->info("SCARD: Unexpected PIN retry counter response value 0x%x\n", val); + logger.info("SCARD: Unexpected PIN retry counter response value 0x%x", val); return 0; } @@ -586,64 +585,64 @@ int pcsc_usim::scard::get_aid(unsigned char* aid, size_t maxlen) aid_pos = &buf[4]; blen = sizeof(buf); if (select_file(SCARD_FILE_EF_DIR, buf, &blen)) { - log->debug("SCARD: Failed to read EF_DIR\n"); + logger.debug("SCARD: Failed to read EF_DIR"); return -1; } - log->debug_hex(buf, blen, "SCARD: EF_DIR select\n"); + logger.debug(buf, blen, "SCARD: EF_DIR select"); for (rec = 1; rec < 10; rec++) { rlen = get_record_len(rec, SIM_RECORD_MODE_ABSOLUTE); if (rlen < 0) { - log->debug("SCARD: Failed to get EF_DIR record length\n"); + logger.debug("SCARD: Failed to get EF_DIR record length"); return -1; } blen = sizeof(buf); if (rlen > (int)blen) { - log->debug("SCARD: Too long EF_DIR record\n"); + logger.debug("SCARD: Too long EF_DIR record"); return -1; } if (read_record(buf, rlen, rec, SIM_RECORD_MODE_ABSOLUTE) < 0) { - log->debug("SCARD: Failed to read EF_DIR record %d", rec); + logger.debug("SCARD: Failed to read EF_DIR record %d", rec); return -1; } - log->debug_hex(buf, rlen, "SCARD: EF_DIR record\n"); + logger.debug(buf, rlen, "SCARD: EF_DIR record"); if (efdir->appl_template_tag != 0x61) { - log->debug("SCARD: Unexpected application template tag 0x%x", efdir->appl_template_tag); + logger.debug("SCARD: Unexpected application template tag 0x%x", efdir->appl_template_tag); continue; } if (efdir->appl_template_len > rlen - 2) { - log->debug("SCARD: Too long application template (len=%d rlen=%d)", efdir->appl_template_len, rlen); + logger.debug("SCARD: Too long application template (len=%d rlen=%d)", efdir->appl_template_len, rlen); continue; } if (efdir->appl_id_tag != 0x4f) { - log->debug("SCARD: Unexpected application identifier tag 0x%x", efdir->appl_id_tag); + logger.debug("SCARD: Unexpected application identifier tag 0x%x", efdir->appl_id_tag); continue; } aid_len = efdir->aid_len; if (aid_len < 1 || aid_len > 16) { - log->debug("SCARD: Invalid AID length %u\n", aid_len); + logger.debug("SCARD: Invalid AID length %u", aid_len); continue; } - log->debug_hex(aid_pos, aid_len, "SCARD: AID from EF_DIR record\n"); + logger.debug(aid_pos, aid_len, "SCARD: AID from EF_DIR record"); if (efdir->appl_code[0] == 0x10 && efdir->appl_code[1] == 0x02) { - log->debug("SCARD: 3G USIM app found from EF_DIR record %d\n", rec); + logger.debug("SCARD: 3G USIM app found from EF_DIR record %d", rec); break; } } if (rec >= 10) { - log->debug("SCARD: 3G USIM app not found from EF_DIR records\n"); + logger.debug("SCARD: 3G USIM app not found from EF_DIR records"); return -1; } if (aid_len > maxlen) { - log->debug("SCARD: Too long AID\n"); + logger.debug("SCARD: Too long AID"); return -1; } @@ -668,14 +667,14 @@ int pcsc_usim::scard::get_record_len(unsigned char recnum, unsigned char mode) blen = sizeof(buf); ret = transmit(cmd, sizeof(cmd), buf, &blen); if (ret != SCARD_S_SUCCESS) { - log->debug("SCARD: failed to determine file length for record %d\n", recnum); + logger.debug("SCARD: failed to determine file length for record %d", recnum); return -1; } - log->debug_hex(buf, blen, "SCARD: file length determination response\n"); + logger.debug(buf, blen, "SCARD: file length determination response"); if (blen < 2 || (buf[0] != 0x6c && buf[0] != 0x67)) { - log->error("SCARD: unexpected response to file length determination\n"); + logger.error("SCARD: unexpected response to file length determination"); return -1; } @@ -705,13 +704,13 @@ int pcsc_usim::scard::read_record(unsigned char* data, size_t len, unsigned char return -2; } if (blen != len + 2) { - log->debug("SCARD: record read returned unexpected length %ld (expected %ld)\n", (long)blen, (long)len + 2); + logger.debug("SCARD: record read returned unexpected length %ld (expected %ld)", (long)blen, (long)len + 2); free(buf); return -3; } if (buf[len] != 0x90 || buf[len + 1] != 0x00) { - log->debug("SCARD: record read returned unexpected status %02x %02x (expected 90 00)\n", buf[len], buf[len + 1]); + logger.debug("SCARD: record read returned unexpected status %02x %02x (expected 90 00)", buf[len], buf[len + 1]); free(buf); return -4; } @@ -742,12 +741,12 @@ int pcsc_usim::scard::get_imsi(char* imsi, size_t* len) size_t blen, imsilen, i; char* pos; - log->debug("SCARD: reading IMSI from (GSM) EF-IMSI\n"); + logger.debug("SCARD: reading IMSI from (GSM) EF-IMSI"); blen = sizeof(buf); if (select_file(SCARD_FILE_GSM_EF_IMSI, buf, &blen)) return -1; if (blen < 4) { - log->warning("SCARD: too short (GSM) EF-IMSI header (len=%ld)\n", (long)blen); + logger.warning("SCARD: too short (GSM) EF-IMSI header (len=%ld)", (long)blen); return -2; } @@ -760,12 +759,12 @@ int pcsc_usim::scard::get_imsi(char* imsi, size_t* len) blen = file_size; } if (blen < 2 || blen > sizeof(buf)) { - log->debug("SCARD: invalid IMSI file length=%ld\n", (long)blen); + logger.debug("SCARD: invalid IMSI file length=%ld", (long)blen); return -3; } imsilen = (blen - 2) * 2 + 1; - log->debug("SCARD: IMSI file length=%ld imsilen=%ld\n", (long)blen, (long)imsilen); + logger.debug("SCARD: IMSI file length=%ld imsilen=%ld", (long)blen, (long)imsilen); if (imsilen > *len) { *len = imsilen; return -4; @@ -817,13 +816,13 @@ int pcsc_usim::scard::read_file(unsigned char* data, size_t len) return -2; } if (blen != len + 2) { - log->error("SCARD: file read returned unexpected length %ld (expected %ld)\n", (long)blen, (long)len + 2); + logger.error("SCARD: file read returned unexpected length %ld (expected %ld)", (long)blen, (long)len + 2); free(buf); return -3; } if (buf[len] != 0x90 || buf[len + 1] != 0x00) { - log->error("SCARD: file read returned unexpected status %02x %02x (expected 90 00)\n", buf[len], buf[len + 1]); + logger.error("SCARD: file read returned unexpected status %02x %02x (expected 90 00)", buf[len], buf[len + 1]); free(buf); return -4; } @@ -846,7 +845,7 @@ int pcsc_usim::scard::parse_fsp_templ(unsigned char* buf, size_t buf_len, int* p pos = buf; end = pos + buf_len; if (*pos != USIM_FSP_TEMPL_TAG) { - log->error("SCARD: file header did not start with FSP template tag\n"); + logger.error("SCARD: file header did not start with FSP template tag"); return -1; } pos++; @@ -855,14 +854,14 @@ int pcsc_usim::scard::parse_fsp_templ(unsigned char* buf, size_t buf_len, int* p if (pos[0] < end - pos) end = pos + 1 + pos[0]; pos++; - log->debug_hex(pos, end - pos, "SCARD: file header FSP template\n"); + logger.debug(pos, end - pos, "SCARD: file header FSP template"); while (end - pos >= 2) { unsigned char type, len; type = pos[0]; len = pos[1]; - log->debug("SCARD: file header TLV 0x%02x len=%d\n", type, len); + logger.debug("SCARD: file header TLV 0x%02x len=%d", type, len); pos += 2; if (len > (unsigned int)(end - pos)) @@ -870,51 +869,51 @@ int pcsc_usim::scard::parse_fsp_templ(unsigned char* buf, size_t buf_len, int* p switch (type) { case USIM_TLV_FILE_DESC: - log->debug_hex(pos, len, "SCARD: File Descriptor TLV\n"); + logger.debug(pos, len, "SCARD: File Descriptor TLV"); break; case USIM_TLV_FILE_ID: - log->debug_hex(pos, len, "SCARD: File Identifier TLV\n"); + logger.debug(pos, len, "SCARD: File Identifier TLV"); break; case USIM_TLV_DF_NAME: - log->debug_hex(pos, len, "SCARD: DF name (AID) TLV\n"); + logger.debug(pos, len, "SCARD: DF name (AID) TLV"); break; case USIM_TLV_PROPR_INFO: - log->debug_hex(pos, len, "SCARD: Proprietary information TLV\n"); + logger.debug(pos, len, "SCARD: Proprietary information TLV"); break; case USIM_TLV_LIFE_CYCLE_STATUS: - log->debug_hex(pos, len, "SCARD: Life Cycle Status Integer TLV\n"); + logger.debug(pos, len, "SCARD: Life Cycle Status Integer TLV"); break; case USIM_TLV_FILE_SIZE: - log->debug_hex(pos, len, "SCARD: File size TLV\n"); + logger.debug(pos, len, "SCARD: File size TLV"); if ((len == 1 || len == 2) && file_len) { if (len == 1) { *file_len = (int)pos[0]; } else { *file_len = to_uint16(pos); } - log->debug("SCARD: file_size=%d\n", *file_len); + logger.debug("SCARD: file_size=%d", *file_len); } break; case USIM_TLV_TOTAL_FILE_SIZE: - log->debug_hex(pos, len, "SCARD: Total file size TLV\n"); + logger.debug(pos, len, "SCARD: Total file size TLV"); break; case USIM_TLV_PIN_STATUS_TEMPLATE: - log->debug_hex(pos, len, "SCARD: PIN Status Template DO TLV\n"); + logger.debug(pos, len, "SCARD: PIN Status Template DO TLV"); if (len >= 2 && pos[0] == USIM_PS_DO_TAG && pos[1] >= 1 && ps_do) { - log->debug("SCARD: PS_DO=0x%02x\n", pos[2]); + logger.debug("SCARD: PS_DO=0x%02x", pos[2]); *ps_do = (int)pos[2]; } break; case USIM_TLV_SHORT_FILE_ID: - log->debug_hex(pos, len, "SCARD: Short File Identifier (SFI) TLV\n"); + logger.debug(pos, len, "SCARD: Short File Identifier (SFI) TLV"); break; case USIM_TLV_SECURITY_ATTR_8B: case USIM_TLV_SECURITY_ATTR_8C: case USIM_TLV_SECURITY_ATTR_AB: - log->debug_hex(pos, len, "SCARD: Security attribute TLV\n"); + logger.debug(pos, len, "SCARD: Security attribute TLV"); break; default: - log->debug_hex(pos, len, "SCARD: Unrecognized TLV\n"); + logger.debug(pos, len, "SCARD: Unrecognized TLV"); break; } @@ -936,16 +935,16 @@ void pcsc_usim::scard::deinit() { long ret; - log->debug("SCARD: deinitializing smart card interface\n"); + logger.debug("SCARD: deinitializing smart card interface"); ret = SCardDisconnect(scard_handle, SCARD_UNPOWER_CARD); if (ret != SCARD_S_SUCCESS) { - log->debug("SCARD: Failed to disconnect smart card (err=%ld)\n", ret); + logger.debug("SCARD: Failed to disconnect smart card (err=%ld)", ret); } ret = SCardReleaseContext(scard_context); if (ret != SCARD_S_SUCCESS) { - log->debug("Failed to release smart card context (err=%ld)\n", ret); + logger.debug("Failed to release smart card context (err=%ld)", ret); } } @@ -965,12 +964,12 @@ int pcsc_usim::scard::get_mnc_len() size_t blen; int file_size; - log->debug("SCARD: reading MNC len from (GSM) EF-AD\n"); + logger.debug("SCARD: reading MNC len from (GSM) EF-AD"); blen = sizeof(buf); if (select_file(SCARD_FILE_GSM_EF_AD, buf, &blen)) return -1; if (blen < 4) { - log->debug("SCARD: too short (GSM) EF-AD header (len=%ld)\n", (long)blen); + logger.debug("SCARD: too short (GSM) EF-AD header (len=%ld)", (long)blen); return -2; } @@ -981,11 +980,11 @@ int pcsc_usim::scard::get_mnc_len() return -3; } if (file_size == 3) { - log->debug("SCARD: MNC length not available\n"); + logger.debug("SCARD: MNC length not available"); return -7; } if (file_size < 4 || file_size > (int)sizeof(buf)) { - log->debug("SCARD: invalid file length=%ld\n", (long)file_size); + logger.debug("SCARD: invalid file length=%ld", (long)file_size); return -4; } @@ -993,10 +992,10 @@ int pcsc_usim::scard::get_mnc_len() return -5; buf[3] = buf[3] & 0x0f; /* upper nibble reserved for future use */ if (buf[3] < 2 || buf[3] > 3) { - log->debug("SCARD: invalid MNC length=%ld\n", (long)buf[3]); + logger.debug("SCARD: invalid MNC length=%ld", (long)buf[3]); return -6; } - log->debug("SCARD: MNC length=%ld\n", (long)buf[3]); + logger.debug("SCARD: MNC length=%ld", (long)buf[3]); return buf[3]; } @@ -1035,12 +1034,12 @@ int pcsc_usim::scard::umts_auth(const unsigned char* _rand, long ret; if (sim_type == SCARD_GSM_SIM) { - log->debug("SCARD: Non-USIM card - cannot do UMTS auth\n"); + logger.debug("SCARD: Non-USIM card - cannot do UMTS auth"); return -1; } - log->debug_hex(_rand, AKA_RAND_LEN, "SCARD: UMTS auth - RAND\n"); - log->debug_hex(autn, AKA_AUTN_LEN, "SCARD: UMTS auth - AUTN\n"); + logger.debug(_rand, AKA_RAND_LEN, "SCARD: UMTS auth - RAND"); + logger.debug(autn, AKA_AUTN_LEN, "SCARD: UMTS auth - AUTN"); cmd[5] = AKA_RAND_LEN; memcpy(cmd + 6, _rand, AKA_RAND_LEN); cmd[6 + AKA_RAND_LEN] = AKA_AUTN_LEN; @@ -1052,17 +1051,17 @@ int pcsc_usim::scard::umts_auth(const unsigned char* _rand, return -1; if (len <= sizeof(resp)) - log->debug_hex(resp, len, "SCARD: UMTS alg response\n"); + logger.debug(resp, len, "SCARD: UMTS alg response"); if (len == 2 && resp[0] == 0x98 && resp[1] == 0x62) { // Authentication error, application specific - log->warning("SCARD: UMTS auth failed - MAC != XMAC\n"); + logger.warning("SCARD: UMTS auth failed - MAC != XMAC"); return -1; } if (len != 2 || resp[0] != 0x61) { - log->warning( - "SCARD: unexpected response for UMTS auth request (len=%ld resp=%02x %02x)\n", (long)len, resp[0], resp[1]); + logger.warning( + "SCARD: unexpected response for UMTS auth request (len=%ld resp=%02x %02x)", (long)len, resp[0], resp[1]); return -1; } get_resp[4] = resp[1]; @@ -1072,11 +1071,11 @@ int pcsc_usim::scard::umts_auth(const unsigned char* _rand, if (ret != SCARD_S_SUCCESS || len > sizeof(buf)) return -1; - log->debug_hex(buf, len, "SCARD: UMTS get response result\n"); + logger.debug(buf, len, "SCARD: UMTS get response result"); if (len >= 2 + AKA_AUTS_LEN && buf[0] == 0xdc && buf[1] == AKA_AUTS_LEN) { - log->debug("SCARD: UMTS Synchronization-Failure\n"); + logger.debug("SCARD: UMTS Synchronization-Failure"); memcpy(auts, buf + 2, AKA_AUTS_LEN); - log->debug_hex(auts, AKA_AUTS_LEN, "SCARD: AUTS\n"); + logger.debug(auts, AKA_AUTS_LEN, "SCARD: AUTS"); *res_len = AKA_AUTS_LEN; return -2; } @@ -1087,42 +1086,42 @@ int pcsc_usim::scard::umts_auth(const unsigned char* _rand, /* RES */ if (pos[0] > RES_MAX_LEN || pos[0] > end - pos) { - log->debug("SCARD: Invalid RES\n"); + logger.debug("SCARD: Invalid RES"); return -1; } *res_len = *pos++; memcpy(res, pos, *res_len); pos += *res_len; - log->debug_hex(res, *res_len, "SCARD: RES\n"); + logger.debug(res, *res_len, "SCARD: RES"); /* CK */ if (pos[0] != CK_LEN || CK_LEN > end - pos) { - log->debug("SCARD: Invalid CK\n"); + logger.debug("SCARD: Invalid CK"); return -1; } pos++; memcpy(ck, pos, CK_LEN); pos += CK_LEN; - log->debug_hex(ck, CK_LEN, "SCARD: CK\n"); + logger.debug(ck, CK_LEN, "SCARD: CK"); /* IK */ if (pos[0] != IK_LEN || IK_LEN > end - pos) { - log->debug("SCARD: Invalid IK\n"); + logger.debug("SCARD: Invalid IK"); return -1; } pos++; memcpy(ik, pos, IK_LEN); pos += IK_LEN; - log->debug_hex(ik, IK_LEN, "SCARD: IK\n"); + logger.debug(ik, IK_LEN, "SCARD: IK"); if (end > pos) { - log->debug_hex(pos, end - pos, "SCARD: Ignore extra data in end\n"); + logger.debug(pos, end - pos, "SCARD: Ignore extra data in end"); } return 0; } - log->debug("SCARD: Unrecognized response\n"); + logger.debug("SCARD: Unrecognized response"); return -1; } @@ -1133,7 +1132,7 @@ int pcsc_usim::scard::verify_pin(const char* pin) unsigned char cmd[5 + 8] = {SIM_CMD_VERIFY_CHV1}; size_t len; - log->debug("SCARD: verifying PIN\n"); + logger.debug("SCARD: verifying PIN"); if (pin == NULL || strlen(pin) > 8) return -1; @@ -1149,11 +1148,11 @@ int pcsc_usim::scard::verify_pin(const char* pin) return -2; if (len != 2 || resp[0] != 0x90 || resp[1] != 0x00) { - log->debug("SCARD: PIN verification failed\n"); + logger.debug("SCARD: PIN verification failed"); return -1; } - log->debug("SCARD: PIN verified successfully\n"); + logger.debug("SCARD: PIN verified successfully"); return SCARD_S_SUCCESS; } diff --git a/srsue/src/stack/upper/tft_packet_filter.cc b/srsue/src/stack/upper/tft_packet_filter.cc index 0fd7ed225..605688176 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -30,13 +30,13 @@ namespace srsue { tft_packet_filter_t::tft_packet_filter_t(uint8_t eps_bearer_id_, uint8_t lcid_, const LIBLTE_MME_PACKET_FILTER_STRUCT& tft, - srslte::log* log_) : + srslog::basic_logger& logger) : eps_bearer_id(eps_bearer_id_), lcid(lcid_), id(tft.id), eval_precedence(tft.eval_precedence), active_filters(0), - log(log_) + logger(logger) { int idx = 0; uint32_t length_in_bytes = 0; @@ -169,7 +169,7 @@ tft_packet_filter_t::tft_packet_filter_t(uint8_t break; default: - log->error("ERROR: wrong type: 0x%02x\n", filter_type); + logger.error("ERROR: wrong type: 0x%02x", filter_type); return; } } @@ -392,7 +392,7 @@ uint8_t tft_pdu_matcher::check_tft_filter_match(const srslte::unique_byte_buffer bool match = filter_pair.second.match(pdu); if (match) { lcid = filter_pair.second.lcid; - log->debug("Found filter match -- EPS bearer Id %d, LCID %d\n", filter_pair.second.eps_bearer_id, lcid); + logger.debug("Found filter match -- EPS bearer Id %d, LCID %d", filter_pair.second.eps_bearer_id, lcid); break; } } @@ -407,17 +407,17 @@ int tft_pdu_matcher::apply_traffic_flow_template(const uint8_t& switch (tft->tft_op_code) { case LIBLTE_MME_TFT_OPERATION_CODE_CREATE_NEW_TFT: for (int i = 0; i < tft->packet_filter_list_size; i++) { - log->info("New packet filter for TFT\n"); - tft_packet_filter_t filter(erab_id, lcid, tft->packet_filter_list[i], log); + logger.info("New packet filter for TFT"); + tft_packet_filter_t filter(erab_id, lcid, tft->packet_filter_list[i], logger); auto it = tft_filter_map.insert(std::make_pair(filter.eval_precedence, filter)); if (it.second == false) { - log->error("Error inserting TFT Packet Filter\n"); + logger.error("Error inserting TFT Packet Filter"); return SRSLTE_ERROR_CANT_START; } } break; default: - log->error("Unhandled TFT OP code\n"); + logger.error("Unhandled TFT OP code"); return SRSLTE_ERROR_CANT_START; } return SRSLTE_SUCCESS; diff --git a/srsue/src/stack/upper/usim.cc b/srsue/src/stack/upper/usim.cc index c3bdb39eb..867397ba2 100644 --- a/srsue/src/stack/upper/usim.cc +++ b/srsue/src/stack/upper/usim.cc @@ -27,7 +27,7 @@ using namespace srslte; namespace srsue { -usim::usim(srslte::log* log_) : usim_base(log_) {} +usim::usim(srslog::basic_logger& logger) : usim_base(logger) {} int usim::init(usim_args_t* args) { @@ -45,7 +45,7 @@ int usim::init(usim_args_t* args) if (32 == args->k.length()) { str_to_hex(args->k, k); } else { - log->error("Invalid length for K: %zu should be %d\n", args->k.length(), 32); + logger.error("Invalid length for K: %zu should be %d", args->k.length(), 32); srslte::console("Invalid length for K: %zu should be %d\n", args->k.length(), 32); } @@ -55,14 +55,14 @@ int usim::init(usim_args_t* args) str_to_hex(args->op, op); compute_opc(k, op, opc); } else { - log->error("Invalid length for OP: %zu should be %d\n", args->op.length(), 32); + logger.error("Invalid length for OP: %zu should be %d", args->op.length(), 32); srslte::console("Invalid length for OP: %zu should be %d\n", args->op.length(), 32); } } else { if (32 == args->opc.length()) { str_to_hex(args->opc, opc); } else { - log->error("Invalid length for OPc: %zu should be %d\n", args->opc.length(), 32); + logger.error("Invalid length for OPc: %zu should be %d", args->opc.length(), 32); srslte::console("Invalid length for OPc: %zu should be %d\n", args->opc.length(), 32); } } @@ -75,7 +75,7 @@ int usim::init(usim_args_t* args) imsi += imsi_c[i] - '0'; } } else { - log->error("Invalid length for IMSI: %zu should be %d\n", args->imsi.length(), 15); + logger.error("Invalid length for IMSI: %zu should be %d", args->imsi.length(), 15); srslte::console("Invalid length for IMSI: %zu should be %d\n", args->imsi.length(), 15); } @@ -86,7 +86,7 @@ int usim::init(usim_args_t* args) imei += imei_c[i] - '0'; } } else { - log->error("Invalid length for IMEI: %zu should be %d\n", args->imei.length(), 15); + logger.error("Invalid length for IMEI: %zu should be %d", args->imei.length(), 15); srslte::console("Invalid length for IMEI: %zu should be %d\n", args->imei.length(), 15); } diff --git a/srsue/src/stack/upper/usim_base.cc b/srsue/src/stack/upper/usim_base.cc index 3eb2cae9d..3ca0d9829 100644 --- a/srsue/src/stack/upper/usim_base.cc +++ b/srsue/src/stack/upper/usim_base.cc @@ -28,19 +28,19 @@ namespace srsue { -std::unique_ptr usim_base::get_instance(usim_args_t* args, srslte::log* log_) +std::unique_ptr usim_base::get_instance(usim_args_t* args, srslog::basic_logger& logger) { #if HAVE_PCSC if (args->mode == "pcsc") { - return std::unique_ptr(new pcsc_usim(log_)); + return std::unique_ptr(new pcsc_usim(logger)); } #endif // default to soft USIM - return std::unique_ptr(new usim(log_)); + return std::unique_ptr(new usim(logger)); } -usim_base::usim_base(srslte::log* _log) : log(_log) {} +usim_base::usim_base(srslog::basic_logger& logger) : logger(logger) {} usim_base::~usim_base() {} @@ -59,12 +59,12 @@ std::string usim_base::get_imei_str() bool usim_base::get_imsi_vec(uint8_t* imsi_, uint32_t n) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return false; } if (NULL == imsi_ || n < 15) { - log->error("Invalid parameters to get_imsi_vec\n"); + logger.error("Invalid parameters to get_imsi_vec"); return false; } @@ -79,12 +79,12 @@ bool usim_base::get_imsi_vec(uint8_t* imsi_, uint32_t n) bool usim_base::get_imei_vec(uint8_t* imei_, uint32_t n) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return false; } if (NULL == imei_ || n < 15) { - log->error("Invalid parameters to get_imei_vec\n"); + logger.error("Invalid parameters to get_imei_vec"); return false; } @@ -109,7 +109,7 @@ std::string usim_base::get_mcc_str(const uint8_t* imsi_vec) bool usim_base::get_home_plmn_id(srslte::plmn_id_t* home_plmn_id) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return false; } @@ -121,11 +121,11 @@ bool usim_base::get_home_plmn_id(srslte::plmn_id_t* home_plmn_id) std::string plmn_str = mcc_str + mnc_str; if (home_plmn_id->from_string(plmn_str)) { - log->error("Error reading home PLMN from SIM.\n"); + logger.error("Error reading home PLMN from SIM."); return false; } - log->info("Read Home PLMN Id=%s\n", home_plmn_id->to_string().c_str()); + logger.info("Read Home PLMN Id=%s", home_plmn_id->to_string().c_str()); return true; } @@ -137,7 +137,7 @@ void usim_base::generate_nas_keys(uint8_t* k_asme, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return; } @@ -151,12 +151,12 @@ void usim_base::generate_nas_keys(uint8_t* k_asme, void usim_base::generate_as_keys(uint8_t* k_asme_, uint32_t count_ul, srslte::as_security_config_t* sec_cfg) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return; } - log->info("Generating AS Keys. NAS UL COUNT %d\n", count_ul); - log->debug_hex(k_asme_, 32, "K_asme"); + logger.info("Generating AS Keys. NAS UL COUNT %d", count_ul); + logger.debug(k_asme_, 32, "K_asme"); // Generate K_enb srslte::security_generate_k_enb(k_asme_, count_ul, k_enb_ctx.k_enb.data()); @@ -183,22 +183,22 @@ void usim_base::generate_as_keys(uint8_t* k_asme_, uint32_t count_ul, srslte::as k_enb_ctx.ncc = 0; k_enb_ctx.is_first_ncc = true; - log->debug_hex(k_enb_ctx.k_enb.data(), 32, "Initial K_eNB"); - log->debug_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "K_RRC_int"); - log->debug_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "K_RRC_enc"); - log->debug_hex(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "K_UP_int"); - log->debug_hex(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "K_UP_enc"); + logger.debug(k_enb_ctx.k_enb.data(), 32, "Initial K_eNB"); + logger.debug(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "K_RRC_int"); + logger.debug(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "K_RRC_enc"); + logger.debug(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "K_UP_int"); + logger.debug(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "K_UP_enc"); } void usim_base::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return; } - log->info("Re-generating AS Keys. PCI 0x%02x, DL-EARFCN %d, NCC %d\n", pci, earfcn, ncc); - log->info_hex(k_enb_ctx.k_enb.data(), 32, "Old K_eNB"); + logger.info("Re-generating AS Keys. PCI 0x%02x, DL-EARFCN %d, NCC %d", pci, earfcn, ncc); + logger.info(k_enb_ctx.k_enb.data(), 32, "Old K_eNB"); uint8_t* enb_star_key = k_enb_ctx.k_enb.data(); @@ -209,14 +209,14 @@ void usim_base::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srsl while (k_enb_ctx.ncc != (uint32_t)ncc) { uint8_t* sync = nullptr; if (k_enb_ctx.is_first_ncc) { - log->debug("Using K_enb_initial for sync. 0x%02x, DL-EARFCN %d, NCC used: %d\n", pci, earfcn, k_enb_ctx.ncc); + logger.debug("Using K_enb_initial for sync. 0x%02x, DL-EARFCN %d, NCC used: %d", pci, earfcn, k_enb_ctx.ncc); sync = k_enb_initial; k_enb_ctx.is_first_ncc = false; } else { - log->debug("Using NH for sync. 0x%02x, DL-EARFCN %d, NCC %d\n", pci, earfcn, k_enb_ctx.ncc); + logger.debug("Using NH for sync. 0x%02x, DL-EARFCN %d, NCC %d", pci, earfcn, k_enb_ctx.ncc); sync = k_enb_ctx.nh.data(); } - log->debug_hex(k_enb_ctx.nh.data(), 32, "NH:"); + logger.debug(k_enb_ctx.nh.data(), 32, "NH:"); // Generate NH srslte::security_generate_nh(k_asme, sync, k_enb_ctx.nh.data()); @@ -248,19 +248,19 @@ void usim_base::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srsl sec_cfg->k_up_enc.data(), sec_cfg->k_up_int.data()); - log->info_hex(k_enb_ctx.k_enb.data(), 32, "HO K_eNB"); - log->info_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "HO K_RRC_enc"); - log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "HO K_RRC_int"); + logger.info(k_enb_ctx.k_enb.data(), 32, "HO K_eNB"); + logger.info(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "HO K_RRC_enc"); + logger.info(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "HO K_RRC_int"); } void usim_base::store_keys_before_ho(const srslte::as_security_config_t& as_ctx) { - log->info("Storing AS Keys pre-handover. NCC=%d\n", k_enb_ctx.ncc); - log->info_hex(k_enb_ctx.k_enb.data(), 32, "Old K_eNB"); - log->info_hex(as_ctx.k_rrc_enc.data(), as_ctx.k_rrc_enc.size(), "Old K_RRC_enc"); - log->info_hex(as_ctx.k_rrc_enc.data(), as_ctx.k_rrc_enc.size(), "Old K_RRC_enc"); - log->info_hex(as_ctx.k_rrc_int.data(), as_ctx.k_rrc_int.size(), "Old K_RRC_int"); - log->info_hex(as_ctx.k_rrc_int.data(), as_ctx.k_rrc_int.size(), "Old K_RRC_int"); + logger.info("Storing AS Keys pre-handover. NCC=%d", k_enb_ctx.ncc); + logger.info(k_enb_ctx.k_enb.data(), 32, "Old K_eNB"); + logger.info(as_ctx.k_rrc_enc.data(), as_ctx.k_rrc_enc.size(), "Old K_RRC_enc"); + logger.info(as_ctx.k_rrc_enc.data(), as_ctx.k_rrc_enc.size(), "Old K_RRC_enc"); + logger.info(as_ctx.k_rrc_int.data(), as_ctx.k_rrc_int.size(), "Old K_RRC_int"); + logger.info(as_ctx.k_rrc_int.data(), as_ctx.k_rrc_int.size(), "Old K_RRC_int"); old_k_enb_ctx = k_enb_ctx; old_as_ctx = as_ctx; return; @@ -268,7 +268,7 @@ void usim_base::store_keys_before_ho(const srslte::as_security_config_t& as_ctx) void usim_base::restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx) { - log->info("Restoring Keys from failed handover. NCC=%d\n", old_k_enb_ctx.ncc); + logger.info("Restoring Keys from failed handover. NCC=%d", old_k_enb_ctx.ncc); *as_ctx = old_as_ctx; k_enb_ctx = old_k_enb_ctx; return; @@ -281,23 +281,23 @@ void usim_base::restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx void usim_base::generate_nr_context(uint16_t sk_counter, srslte::as_security_config_t* sec_cfg) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return; } - log->info("Generating Keys. SCG Counter %d\n", sk_counter); + logger.info("Generating Keys. SCG Counter %d", sk_counter); srslte::security_generate_sk_gnb(k_enb_ctx.k_enb.data(), k_gnb_ctx.sk_gnb.data(), sk_counter); - log->info_hex(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb"); + logger.info(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb"); update_nr_context(sec_cfg); } void usim_base::update_nr_context(srslte::as_security_config_t* sec_cfg) { if (!initiated) { - log->error("USIM not initiated!\n"); + logger.error("USIM not initiated!"); return; } - log->info_hex(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb"); + logger.info(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb"); // Generate K_rrc_enc and K_rrc_int security_generate_k_nr_rrc(k_gnb_ctx.sk_gnb.data(), sec_cfg->cipher_algo, @@ -312,10 +312,10 @@ void usim_base::update_nr_context(srslte::as_security_config_t* sec_cfg) sec_cfg->k_up_enc.data(), sec_cfg->k_up_int.data()); - log->debug_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "NR K_RRC_int"); - log->debug_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "NR K_RRC_enc"); - log->debug_hex(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "NR K_UP_int"); - log->debug_hex(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "NR K_UP_enc"); + logger.debug(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "NR K_RRC_int"); + logger.debug(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "NR K_RRC_enc"); + logger.debug(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "NR K_UP_int"); + logger.debug(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "NR K_UP_enc"); } } // namespace srsue diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 8cc76116d..5f6646c7e 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -21,16 +21,15 @@ #include "srsue/hdr/ue.h" #include "srslte/build_info.h" +#include "srslte/common/band_helper.h" #include "srslte/common/string_helpers.h" #include "srslte/radio/radio.h" #include "srslte/radio/radio_null.h" #include "srslte/srslte.h" #include "srsue/hdr/phy/phy.h" #include "srsue/hdr/stack/ue_stack_lte.h" -#ifdef HAVE_5GNR #include "srsue/hdr/phy/vnf_phy_nr.h" #include "srsue/hdr/stack/ue_stack_nr.h" -#endif #include #include #include @@ -39,11 +38,11 @@ using namespace srslte; namespace srsue { -ue::ue() : logger(nullptr) +ue::ue(srslog::sink& log_sink) : + old_logger(nullptr), log_sink(log_sink), logger(srslog::fetch_basic_logger("UE", log_sink, false)) { // print build info - std::cout << std::endl << get_build_string() << std::endl; - pool = byte_buffer_pool::get_instance(); + std::cout << std::endl << get_build_string() << std::endl << std::endl; } ue::~ue() @@ -53,13 +52,12 @@ ue::~ue() int ue::init(const all_args_t& args_, srslte::logger* logger_) { - int ret = SRSLTE_SUCCESS; - logger = logger_; + int ret = SRSLTE_SUCCESS; + old_logger = logger_; // Init UE log - log.init("UE ", logger); - log.set_level(srslte::LOG_LEVEL_INFO); - log.info("%s", get_build_string().c_str()); + logger.set_level(srslog::basic_levels::info); + logger.info("%s", get_build_string().c_str()); // Validate arguments if (parse_args(args_)) { @@ -69,7 +67,7 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) // Instantiate layers and stack together our UE if (args.stack.type == "lte") { - std::unique_ptr lte_stack(new ue_stack_lte()); + std::unique_ptr lte_stack(new ue_stack_lte(log_sink)); if (!lte_stack) { srslte::console("Error creating LTE stack instance.\n"); return SRSLTE_ERROR; @@ -81,13 +79,13 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) return SRSLTE_ERROR; } - std::unique_ptr lte_phy = std::unique_ptr(new srsue::phy(logger)); + std::unique_ptr lte_phy = std::unique_ptr(new srsue::phy(log_sink)); if (!lte_phy) { srslte::console("Error creating LTE PHY instance.\n"); return SRSLTE_ERROR; } - std::unique_ptr lte_radio = std::unique_ptr(new srslte::radio(logger)); + std::unique_ptr lte_radio = std::unique_ptr(new srslte::radio); if (!lte_radio) { srslte::console("Error creating radio multi instance.\n"); return SRSLTE_ERROR; @@ -105,12 +103,23 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) ret = SRSLTE_ERROR; } - if (lte_stack->init(args.stack, logger, lte_phy.get(), gw_ptr.get())) { + srsue::phy_args_nr_t phy_args_nr = {}; + phy_args_nr.nof_prb = args.phy.nr_nof_prb; + phy_args_nr.nof_carriers = args.phy.nof_nr_carriers; + phy_args_nr.nof_phy_threads = args.phy.nof_phy_threads; + phy_args_nr.worker_cpu_mask = args.phy.worker_cpu_mask; + phy_args_nr.log = args.phy.log; + if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) { + srslte::console("Error initializing NR PHY.\n"); + ret = SRSLTE_ERROR; + } + + if (lte_stack->init(args.stack, old_logger, lte_phy.get(), lte_phy.get(), gw_ptr.get())) { srslte::console("Error initializing stack.\n"); ret = SRSLTE_ERROR; } - if (gw_ptr->init(args.gw, logger, lte_stack.get())) { + if (gw_ptr->init(args.gw, old_logger, lte_stack.get())) { srslte::console("Error initializing GW.\n"); ret = SRSLTE_ERROR; } @@ -121,11 +130,10 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) phy = std::move(lte_phy); radio = std::move(lte_radio); } else if (args.stack.type == "nr") { - log.info("Initializing NR stack.\n"); -#ifdef HAVE_5GNR - std::unique_ptr nr_stack(new srsue::ue_stack_nr(logger)); - std::unique_ptr nr_radio(new srslte::radio_null(logger)); - std::unique_ptr nr_phy(new srsue::vnf_phy_nr(logger)); + logger.info("Initializing NR stack"); + std::unique_ptr nr_stack(new srsue::ue_stack_nr(old_logger)); + std::unique_ptr nr_radio(new srslte::radio_null); + std::unique_ptr nr_phy(new srsue::vnf_phy_nr); std::unique_ptr gw_ptr(new gw()); // Init layers @@ -144,7 +152,7 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) return SRSLTE_ERROR; } - if (gw_ptr->init(args.gw, logger, nr_stack.get())) { + if (gw_ptr->init(args.gw, old_logger, nr_stack.get())) { srslte::console("Error initializing GW.\n"); return SRSLTE_ERROR; } @@ -154,10 +162,6 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) gw_inst = std::move(gw_ptr); phy = std::move(nr_phy); radio = std::move(nr_radio); -#else - srslte::console("ERROR: 5G NR stack not compiled. Please, activate CMAKE HAVE_5GNR flag.\n"); - log.error("5G NR stack not compiled. Please, activate CMAKE HAVE_5GNR flag.\n"); -#endif } else { srslte::console("Invalid stack type %s. Supported values are [lte].\n", args.stack.type.c_str()); ret = SRSLTE_ERROR; @@ -180,20 +184,20 @@ int ue::parse_args(const all_args_t& args_) // carry out basic sanity checks if (args.stack.rrc.mbms_service_id > -1) { if (!args.phy.interpolate_subframe_enabled) { - log.error("interpolate_subframe_enabled = %d, While using MBMS, " - "please set interpolate_subframe_enabled to true\n", - args.phy.interpolate_subframe_enabled); + logger.error("interpolate_subframe_enabled = %d, While using MBMS, " + "please set interpolate_subframe_enabled to true", + args.phy.interpolate_subframe_enabled); return SRSLTE_ERROR; } if (args.phy.nof_phy_threads > 2) { - log.error("nof_phy_threads = %d, While using MBMS, please set " - "number of phy threads to 1 or 2\n", - args.phy.nof_phy_threads); + logger.error("nof_phy_threads = %d, While using MBMS, please set " + "number of phy threads to 1 or 2", + args.phy.nof_phy_threads); return SRSLTE_ERROR; } if ((0 == args.phy.snr_estim_alg.find("refs"))) { - log.error("snr_estim_alg = refs, While using MBMS, please set " - "algorithm to pss or empty \n"); + logger.error("snr_estim_alg = refs, While using MBMS, please set " + "algorithm to pss or empty"); return SRSLTE_ERROR; } } @@ -218,8 +222,8 @@ int ue::parse_args(const all_args_t& args_) // replicate some RF parameter to make them available to PHY args.phy.nof_lte_carriers = args.rf.nof_carriers - args.phy.nof_nr_carriers; - args.phy.nof_rx_ant = args.rf.nof_antennas; - args.phy.agc_enable = args.rf.rx_gain < 0.0f; + args.phy.nof_rx_ant = args.rf.nof_antennas; + args.phy.agc_enable = args.rf.rx_gain < 0.0f; // populate DL EARFCN list if (not args.phy.dl_earfcn.empty()) { @@ -237,7 +241,7 @@ int ue::parse_args(const all_args_t& args_) } } } else { - log.error("Error: dl_earfcn list is empty\n"); + logger.error("Error: dl_earfcn list is empty"); srslte::console("Error: dl_earfcn list is empty\n"); return SRSLTE_ERROR; } @@ -254,6 +258,32 @@ int ue::parse_args(const all_args_t& args_) } } + srslte_band_helper bands_helper; + + // populate NR DL ARFCNs + if (args.phy.nof_nr_carriers > 0) { + if (not args.phy.dl_nr_arfcn.empty()) { + // Parse list + srslte::string_parse_list(args.phy.dl_nr_arfcn, ',', args.phy.dl_nr_arfcn_list); + + // Populates supported bands + for (uint32_t& arfcn : args.phy.dl_nr_arfcn_list) { + std::vector bands = bands_helper.get_bands_nr(arfcn); + for (const auto& band : bands) { + // make sure we don't add duplicates + if (std::find(args.stack.rrc_nr.supported_bands.begin(), args.stack.rrc_nr.supported_bands.end(), band) == + args.stack.rrc_nr.supported_bands.end()) { + args.stack.rrc_nr.supported_bands.push_back(band); + } + } + } + } else { + logger.error("Error: dl_nr_arfcn list is empty"); + srslte::console("Error: dl_nr_arfcn list is empty\n"); + return SRSLTE_ERROR; + } + } + // Set UE category args.stack.rrc.ue_category = (uint32_t)strtoul(args.stack.rrc.ue_category_str.c_str(), nullptr, 10); @@ -327,7 +357,7 @@ std::string ue::get_build_info() std::string ue::get_build_string() { std::stringstream ss; - ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "." << std::endl; + ss << "Built in " << get_build_mode() << " mode using " << get_build_info() << "."; return ss.str(); } diff --git a/srsue/test/CMakeLists.txt b/srsue/test/CMakeLists.txt index 54a7534a2..6613409ac 100644 --- a/srsue/test/CMakeLists.txt +++ b/srsue/test/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(phy) add_subdirectory(upper) +add_subdirectory(mac_nr) if (ENABLE_TTCN3) add_subdirectory(ttcn3) diff --git a/srsue/test/mac_nr/CMakeLists.txt b/srsue/test/mac_nr/CMakeLists.txt new file mode 100644 index 000000000..cd87e0084 --- /dev/null +++ b/srsue/test/mac_nr/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright 2013-2021 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_executable(proc_ra_nr_test proc_ra_nr_test.cc) +target_link_libraries(proc_ra_nr_test srsue_mac_nr srslte_common) +add_test(proc_ra_nr_test proc_ra_nr_test) \ No newline at end of file diff --git a/srsue/test/mac_nr/proc_ra_nr_test.cc b/srsue/test/mac_nr/proc_ra_nr_test.cc new file mode 100644 index 000000000..21f25a094 --- /dev/null +++ b/srsue/test/mac_nr/proc_ra_nr_test.cc @@ -0,0 +1,136 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 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 "srslte/common/common.h" +#include "srslte/common/log_filter.h" +#include "srslte/common/test_common.h" +#include "srsue/hdr/stack/mac_nr/proc_ra_nr.h" + +using namespace srsue; + +class dummy_phy : public phy_interface_mac_nr +{ +public: + dummy_phy() {} + void send_prach(const uint32_t prach_occasion_, + const int preamble_index_, + const float preamble_received_target_power_, + const float ta_base_sec_ = 0.0f) + { + prach_occasion = prach_occasion_; + preamble_index = preamble_index_; + preamble_received_target_power = preamble_received_target_power_; + } + int tx_request(const tx_request_t& request) { return 0; } + int set_ul_grant(std::array, uint16_t rnti, srslte_rnti_type_t rnti_type) + { + return 0; + } + + void get_last_send_prach(uint32_t* prach_occasion_, uint32_t* preamble_index_, int* preamble_received_target_power_) + { + *prach_occasion_ = prach_occasion; + *preamble_index_ = preamble_index; + *preamble_received_target_power_ = preamble_received_target_power; + } + +private: + uint32_t prach_occasion; + uint32_t preamble_index; + int preamble_received_target_power; +}; + +class dummy_mac : public mac_interface_proc_ra_nr +{ +public: + uint64_t get_contention_id() { return 0xdeadbeaf; } + uint16_t get_c_rnti() { return crnti; } + void set_c_rnti(uint64_t c_rnti) { crnti = c_rnti; } + + bool msg3_is_transmitted() { return true; } + void msg3_flush() {} + void msg3_prepare() {} + bool msg3_is_empty() { return true; } + + void msga_flush(){}; + +private: + uint16_t crnti; +}; + +int main() +{ + srslog::init(); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.set_level(srslog::basic_levels::debug); + mac_logger.set_hex_dump_max_size(-1); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + srslte::task_scheduler task_sched{5, 2}; + srslte::ext_task_sched_handle ext_task_sched_h(&task_sched); + + proc_ra_nr proc_ra_nr(mac_logger); + + proc_ra_nr.init(&dummy_phy, &dummy_mac, &ext_task_sched_h); + TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false); + srslte::rach_nr_cfg_t rach_cfg; + rach_cfg.powerRampingStep = 4; + rach_cfg.prach_ConfigurationIndex = 16; + rach_cfg.PreambleReceivedTargetPower = -110; + rach_cfg.preambleTransMax = 7; + rach_cfg.ra_ContentionResolutionTimer = 64; + rach_cfg.ra_responseWindow = 10; + proc_ra_nr.set_config(rach_cfg); + proc_ra_nr.start_by_rrc(); + + // Test send prach parameters + uint32_t prach_occasion = 0; + uint32_t preamble_index = 0; + int preamble_received_target_power = 0; + dummy_phy.get_last_send_prach(&prach_occasion, &preamble_index, &preamble_received_target_power); + TESTASSERT(prach_occasion == 0); + TESTASSERT(preamble_index == 0); + TESTASSERT(preamble_received_target_power == -114); + // Simulate PHY and call prach_sent (random values) + uint32_t tti_start = 0; + proc_ra_nr.prach_sent(tti_start, 7, 1, 0, 0); + + for (uint32_t i = tti_start; i < rach_cfg.ra_responseWindow; i++) { + // update clock and run internal tasks + task_sched.tic(); + task_sched.run_pending_tasks(); + bool rar_opportunity = proc_ra_nr.is_rar_opportunity(i); + if (i < 3 + tti_start) { + TESTASSERT(rar_opportunity == false); + } else if (3 + tti_start > i && i < 3 + rach_cfg.ra_responseWindow) { + TESTASSERT(rar_opportunity == true); + TESTASSERT(proc_ra_nr.get_rar_rnti() == 0x16); + } + } + mac_interface_phy_nr::mac_nr_grant_dl_t grant; + grant.rnti = 0x16; + grant.tti = rach_cfg.ra_responseWindow + tti_start + 3; + grant.pid = 0x0123; + uint8_t mac_dl_rar_pdu[] = {0x40, 0x06, 0x68, 0x03, 0x21, 0x46, 0x46, 0x02, 0x00, 0x00, 0x00}; + grant.tb[0] = srslte::make_byte_buffer(); + grant.tb[0].get()->append_bytes(mac_dl_rar_pdu, sizeof(mac_dl_rar_pdu)); + proc_ra_nr.handle_rar_pdu(grant); + + task_sched.tic(); + task_sched.run_pending_tasks(); + + proc_ra_nr.pdcch_to_crnti(); + + task_sched.tic(); + task_sched.run_pending_tasks(); + return SRSLTE_SUCCESS; +} diff --git a/srsue/test/mac_test.cc b/srsue/test/mac_test.cc index aff0be150..dc9cf06e6 100644 --- a/srsue/test/mac_test.cc +++ b/srsue/test/mac_test.cc @@ -38,15 +38,13 @@ using namespace srslte; static std::unique_ptr pcap_handle = nullptr; -srslte::log_ref mac_log{"MAC"}; - namespace srslte { // fake classes class rlc_dummy : public srsue::rlc_dummy_interface { public: - rlc_dummy(srslte::log_filter* log_) : received_bytes(0), log(log_) {} + rlc_dummy() : received_bytes(0) {} bool has_data_locked(const uint32_t lcid) final { return ul_queues[lcid] > 0; } uint32_t get_buffer_state(const uint32_t lcid) final { return ul_queues[lcid]; } int read_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) final @@ -71,7 +69,7 @@ public: }; void write_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) final { - log->debug_hex(payload, nof_bytes, "Received %d B on LCID %d\n", nof_bytes, lcid); + logger.debug(payload, nof_bytes, "Received %d B on LCID %d", nof_bytes, lcid); received_bytes += nof_bytes; } @@ -89,11 +87,11 @@ public: } private: - bool read_enable = true; - int32_t read_len = -1; // read all - uint32_t read_min = 0; // minimum "grant size" for read_pdu() to return data - uint32_t received_bytes; - srslte::log_filter* log; + bool read_enable = true; + int32_t read_len = -1; // read all + uint32_t read_min = 0; // minimum "grant size" for read_pdu() to return data + uint32_t received_bytes; + srslog::basic_logger& logger = srslog::fetch_basic_logger("RLC"); // UL queues where key is LCID and value the queue length std::map ul_queues; }; @@ -103,7 +101,6 @@ class phy_dummy : public phy_interface_mac_lte public: phy_dummy() : scell_cmd(0){}; - void set_log(srslte::log* log_h_) { log_h = log_h_; } void reset() { last_preamble_idx = 0; @@ -136,7 +133,7 @@ public: last_target_power = target_power_dbm; prach_transmitted = true; prach_info_tx = true; - log_h->info("PRACH will be transmitted at tti=%d, preamble_idx=%d\n", prach_tti, preamble_idx); + logger.info("PRACH will be transmitted at tti=%d, preamble_idx=%d", prach_tti, preamble_idx); } prach_info_t prach_get_info() override @@ -148,7 +145,7 @@ public: info.tti_ra = prach_tti; prach_info_tx = false; info.is_transmitted = true; - log_h->info("PRACH has been transmitted\n"); + logger.info("PRACH has been transmitted"); } } return info; @@ -204,8 +201,7 @@ public: memcpy(dl_action.tb[0].payload, payload, len); // print generated PDU - log_h->info_hex( - dl_action.tb[0].payload, dl_mac_grant.tb[0].tbs, "Generated DL PDU (%d B)\n", dl_mac_grant.tb[0].tbs); + logger.info(dl_action.tb[0].payload, dl_mac_grant.tb[0].tbs, "Generated DL PDU (%d B)", dl_mac_grant.tb[0].tbs); #if HAVE_PCAP pcap_handle->write_dl_crnti(dl_action.tb[0].payload, dl_mac_grant.tb[0].tbs, rnti, true, 1, 0); @@ -284,7 +280,9 @@ public: mac_h->new_grant_ul(0, ul_mac_grant, &ul_action); // print generated PDU - log_h->info_hex(ul_action.tb.payload, ul_mac_grant.tb.tbs, "Generated UL PDU (%d B)\n", ul_mac_grant.tb.tbs); + if (ul_action.tb.payload) { + logger.info(ul_action.tb.payload, ul_mac_grant.tb.tbs, "Generated UL PDU (%d B)", ul_mac_grant.tb.tbs); + } #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, ul_mac_grant.tb.tbs, rnti, true, 1, 0); @@ -319,7 +317,7 @@ private: uint16_t last_crnti = 0; - srslte::log* log_h; + srslog::basic_logger& logger = srslog::fetch_basic_logger("PHY"); bool ul_ndi = false; bool dl_ndi = false; @@ -385,14 +383,9 @@ int mac_unpack_test() 0xc3, 0xb3, 0x5c, 0xa3, 0x23, 0xad, 0x00, 0x03, 0x20, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x89, 0x00, 0x00}; - srslte::log_filter rlc_log("RLC"); - - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -437,13 +430,9 @@ int mac_ul_sch_pdu_test1() { const uint8_t tv[] = {0x3f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -472,7 +461,8 @@ int mac_ul_sch_pdu_test1() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -501,13 +491,9 @@ int mac_ul_logical_channel_prioritization_test1() const uint8_t tv[] = {0x21, 0x0a, 0x22, 0x04, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -569,7 +555,8 @@ int mac_ul_logical_channel_prioritization_test1() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -607,13 +594,9 @@ int mac_ul_logical_channel_prioritization_test2() 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -675,7 +658,8 @@ int mac_ul_logical_channel_prioritization_test2() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -702,13 +686,9 @@ int mac_ul_logical_channel_prioritization_test3() const uint8_t tv[] = {0x24, 0x0a, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -764,7 +744,8 @@ int mac_ul_logical_channel_prioritization_test3() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -786,13 +767,9 @@ int mac_ul_logical_channel_prioritization_test4() const uint8_t tv2[] = {0x3d, 0x04, 0x88, 0x04}; // Short BSR plus SDU for LCID4 const uint8_t tv3[] = {0x1e, 0x00, 0x12, 0x00}; // Long BSR - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -853,7 +830,8 @@ int mac_ul_logical_channel_prioritization_test4() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -883,7 +861,8 @@ int mac_ul_logical_channel_prioritization_test4() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -915,7 +894,8 @@ int mac_ul_logical_channel_prioritization_test4() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -935,13 +915,9 @@ int mac_ul_sch_pdu_with_short_bsr_test() { const uint8_t tv[] = {0x3f, 0x3d, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -975,7 +951,8 @@ int mac_ul_sch_pdu_with_short_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -995,13 +972,9 @@ int mac_ul_sch_pdu_with_short_bsr_zero_test() { const uint8_t tv[] = {0x3f, 0x3d, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1035,7 +1008,8 @@ int mac_ul_sch_pdu_with_short_bsr_zero_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1054,13 +1028,9 @@ int mac_ul_sch_pdu_with_short_bsr_zero_test() // Because there is no outstanding data, all LCGs are reported as zero int mac_ul_sch_pdu_with_padding_long_bsr_test() { - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1088,7 +1058,8 @@ int mac_ul_sch_pdu_with_padding_long_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1106,13 +1077,9 @@ int mac_ul_sch_pdu_with_padding_long_bsr_test() // PDU SDU and Long BSR as padding (indicating that more data is ready to be sent) int mac_ul_sch_pdu_with_padding_long_bsr_test2() { - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1163,7 +1130,8 @@ int mac_ul_sch_pdu_with_padding_long_bsr_test2() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1182,13 +1150,9 @@ int mac_ul_sch_pdu_with_padding_long_bsr_test2() // LCG 1 has highest priority and 100 B to transmit int mac_ul_sch_pdu_with_padding_trunc_bsr_test() { - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1248,7 +1212,8 @@ int mac_ul_sch_pdu_with_padding_trunc_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1270,13 +1235,9 @@ int mac_ul_sch_regular_bsr_retx_test() const uint8_t tv2[] = {0x01, 0x01, 0x01, 0x01, 0x01}; // Second PDU is just SDU for LCID1 const uint8_t tv3[] = {0x3f, 0x1e, 0x04, 0x00, 0x1f}; // 3rd PDU is after retx Timer is expired and contains BSR again - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1334,7 +1295,8 @@ int mac_ul_sch_regular_bsr_retx_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1361,7 +1323,8 @@ int mac_ul_sch_regular_bsr_retx_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1391,7 +1354,8 @@ int mac_ul_sch_regular_bsr_retx_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1432,14 +1396,9 @@ int mac_ul_sch_periodic_bsr_test() // 4th PDU contains LCID 1 and LCID 3 SDUs const uint8_t tv4[] = {0x21, 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x03}; - - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1503,7 +1462,8 @@ int mac_ul_sch_periodic_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1539,7 +1499,8 @@ int mac_ul_sch_periodic_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1570,7 +1531,8 @@ int mac_ul_sch_periodic_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1605,7 +1567,8 @@ int mac_ul_sch_periodic_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1638,7 +1601,8 @@ int mac_ul_sch_periodic_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1667,7 +1631,8 @@ int mac_ul_sch_periodic_bsr_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1703,13 +1668,9 @@ int mac_ul_sch_trunc_bsr_test2() // Following PDU includes only SDUs for highest priority LCID const uint8_t tv2[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1774,7 +1735,8 @@ int mac_ul_sch_trunc_bsr_test2() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1803,7 +1765,8 @@ int mac_ul_sch_trunc_bsr_test2() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1834,7 +1797,8 @@ int mac_ul_sch_trunc_bsr_test2() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1854,13 +1818,9 @@ int mac_ul_sch_pdu_one_byte_test() { const uint8_t tv[] = {0x1f}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1889,7 +1849,8 @@ int mac_ul_sch_pdu_one_byte_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1909,13 +1870,9 @@ int mac_ul_sch_pdu_two_byte_test() { const uint8_t tv[] = {0x01, 0x01}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1944,7 +1901,8 @@ int mac_ul_sch_pdu_two_byte_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -1964,13 +1922,9 @@ int mac_ul_sch_pdu_three_byte_test() { const uint8_t tv[] = {0x3f, 0x01, 0x01}; - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers phy_dummy phy; - rlc_dummy rlc(&rlc_log); + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -1999,7 +1953,8 @@ int mac_ul_sch_pdu_three_byte_test() mac.new_grant_ul(cc_idx, mac_grant, &ul_action); // print generated PDU - mac_log->info_hex(ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)\n", mac_grant.tb.tbs); + srslog::fetch_basic_logger("MAC").info( + ul_action.tb.payload, mac_grant.tb.tbs, "Generated PDU (%d B)", mac_grant.tb.tbs); #if HAVE_PCAP pcap_handle->write_ul_crnti(ul_action.tb.payload, mac_grant.tb.tbs, 0x1001, true, 1, 0); #endif @@ -2195,18 +2150,9 @@ int mac_random_access_test() { uint64_t contention_id = 0xf0f0f0f0f0f; - srslte::log_filter phy_log("PHY"); - phy_log.set_level(srslte::LOG_LEVEL_DEBUG); - phy_log.set_hex_limit(100000); - - srslte::log_filter rlc_log("RLC"); - rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); - rlc_log.set_hex_limit(100000); - // dummy layers - phy_dummy phy; - phy.set_log(&phy_log); - rlc_dummy rlc(&rlc_log); + phy_dummy phy; + rlc_dummy rlc; rrc_dummy rrc; stack_dummy stack; @@ -2260,7 +2206,7 @@ int mac_random_access_test() // Test 1: No RAR is received. // According to end of 5.1.5, UE sends up to preamb_trans_max upon which indicates RA problem to higher layers - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.rach_cfg = rach_cfg; my_test.nof_prachs = rach_cfg.ra_supervision_info.preamb_trans_max.to_number(); TESTASSERT(!run_mac_ra_test(my_test, &mac, &phy, &tti, &stack)); @@ -2277,7 +2223,7 @@ int mac_random_access_test() // Test 2: RAR received but no matching RAPID // The UE receives a RAR without a matching RAPID on every RAR response window TTI. // According to 5.1.5, the RA procedure is considered non successful and tries again - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.rar_nof_rapid = 1; my_test.nof_prachs = 1; my_test.rar_nof_invalid_rapid = rach_cfg.ra_supervision_info.ra_resp_win_size.to_number(); @@ -2286,7 +2232,7 @@ int mac_random_access_test() // Test 3: RAR with valid RAPID. Test Msg3 retransmissions // On each HARQ retx, contention resolution timer must be restarted (5.1.5) // When max-HARQ-msg3-retx, contention not successful - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.rar_nof_invalid_rapid = 0; my_test.nof_msg3_retx = rach_cfg.max_harq_msg3_tx; TESTASSERT(!run_mac_ra_test(my_test, &mac, &phy, &tti, &stack)); @@ -2305,12 +2251,12 @@ int mac_random_access_test() // Test 4: RAR with valid RAPID. Msg3 transmitted, Msg4 received but invalid ConRes // Contention resolution is defined in 5.1.5. If ConResID does not match, the ConRes is considered // not successful and tries again - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.msg4_enable = true; TESTASSERT(!run_mac_ra_test(my_test, &mac, &phy, &tti, &stack)); // Test 5: Msg4 received and valid ConRes. In this case a valid ConResID is received and RA procedure is successful - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.temp_rnti++; // Temporal C-RNTI has to change to avoid duplicate my_test.msg4_valid_conres = true; my_test.check_ra_successful = true; @@ -2326,7 +2272,7 @@ int mac_random_access_test() // or wait until BSR-reTX is triggered rlc.write_sdu(1, 100); phy.set_crnti(0); - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.crnti = my_test.temp_rnti; my_test.temp_rnti++; // Temporal C-RNTI has to change to avoid duplicate my_test.assume_prach_transmitted = -1; @@ -2337,7 +2283,7 @@ int mac_random_access_test() // It is similar to Test 5 because C-RNTI is available to the UE when start the RA but // In this case we will let the procedure expire the Contention Resolution window and make sure // and RRC HO fail signal is sent to RRC. - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); rrc.ho_finish_successful = false; phy.set_prach_tti(tti + phy.prach_delay); phy.set_crnti(0); @@ -2355,7 +2301,7 @@ int mac_random_access_test() TESTASSERT(rrc.rach_problem == 2); // Test 8: Test Contention based Random Access. Same as above but we let the procedure finish successfully. - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); rrc.ho_finish_successful = false; // Reset queue to make sure BSR retriggers a SR rlc.reset_queues(); @@ -2376,7 +2322,7 @@ int mac_random_access_test() // Test 9: Test non-Contention based HO. Used in HO but preamble is given by the network. In addition to checking // that the given preamble is correctly passed to the PHY, in this case there is no contention. // In this first test, no RAR is received and RA procedure fails - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); rrc.ho_finish_successful = false; // Reset queue to make sure BSR retriggers a SR my_test.preamble_idx = 3; @@ -2397,7 +2343,7 @@ int mac_random_access_test() // Test 10: Test non-Contention based HO. Used in HO but preamble is given by the network. We check that // the procedure is considered successful without waiting for contention - mac_log->info("\n=========== Test %d =============\n", test_id++); + srslog::fetch_basic_logger("MAC").info("\n=========== Test %d =============", test_id++); my_test.preamble_idx = 3; mac.set_rach_ded_cfg(my_test.preamble_idx, 0); stack.run_pending_tasks(); @@ -2427,8 +2373,23 @@ int main(int argc, char** argv) pcap_handle->open("mac_test.pcap"); #endif - mac_log->set_level(srslte::LOG_LEVEL_DEBUG); - mac_log->set_hex_limit(100000); + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.set_level(srslog::basic_levels::debug); + mac_logger.set_hex_dump_max_size(100000); + auto& rlc_logger = srslog::fetch_basic_logger("RLC", false); + rlc_logger.set_level(srslog::basic_levels::debug); + rlc_logger.set_hex_dump_max_size(100000); + auto& phy_logger = srslog::fetch_basic_logger("PHY", false); + phy_logger.set_level(srslog::basic_levels::none); + phy_logger.set_hex_dump_max_size(100000); + srslog::init(); + + srslte::log_filter rlc_log("RLC"); + rlc_log.set_level(srslte::LOG_LEVEL_DEBUG); + rlc_log.set_hex_limit(100000); + srslte::log_filter mac_log("MAC"); + mac_log.set_level(srslte::LOG_LEVEL_DEBUG); + mac_log.set_hex_limit(100000); TESTASSERT(mac_unpack_test() == SRSLTE_SUCCESS); TESTASSERT(mac_ul_sch_pdu_test1() == SRSLTE_SUCCESS); @@ -2446,7 +2407,9 @@ int main(int argc, char** argv) TESTASSERT(mac_ul_sch_pdu_one_byte_test() == SRSLTE_SUCCESS); TESTASSERT(mac_ul_sch_pdu_two_byte_test() == SRSLTE_SUCCESS); TESTASSERT(mac_ul_sch_pdu_three_byte_test() == SRSLTE_SUCCESS); + phy_logger.set_level(srslog::basic_levels::debug); TESTASSERT(mac_random_access_test() == SRSLTE_SUCCESS); + phy_logger.set_level(srslog::basic_levels::none); return SRSLTE_SUCCESS; } diff --git a/srsue/test/phy/CMakeLists.txt b/srsue/test/phy/CMakeLists.txt index 9bafc6010..fa48c6571 100644 --- a/srsue/test/phy/CMakeLists.txt +++ b/srsue/test/phy/CMakeLists.txt @@ -18,6 +18,8 @@ # and at http://www.gnu.org/licenses/. # +set(CTEST_LABELS "srsue;phy") + include_directories( ${Boost_INCLUDE_DIRS} ${SEC_INCLUDE_DIRS} @@ -48,5 +50,4 @@ target_link_libraries(scell_search_test srslte_radio ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) -add_test(scell_search_test scell_search_test --duration=5 --cell.nof_prb=6 --active_cell_list=2,3,4,5,6 --simulation_cell_list=1,2,3,4,5,6 --channel_period_s=30 --channel.hst.fd=750 --channel.delay_max=10000) -set_tests_properties(scell_search_test PROPERTIES LABELS "long;phy;srsue") +add_lte_test(scell_search_test scell_search_test --duration=5 --cell.nof_prb=6 --active_cell_list=2,3,4,5,6 --simulation_cell_list=1,2,3,4,5,6 --channel_period_s=30 --channel.hst.fd=750 --channel.delay_max=10000) diff --git a/srsue/test/phy/scell_search_test.cc b/srsue/test/phy/scell_search_test.cc index c0d7001d7..854e4ba42 100644 --- a/srsue/test/phy/scell_search_test.cc +++ b/srsue/test/phy/scell_search_test.cc @@ -19,6 +19,7 @@ * */ +#include "srslte/srslog/srslog.h" #include #include #include @@ -101,39 +102,38 @@ uint32_t prbset_to_bitmask() class test_enb { private: - srslte_enb_dl_t enb_dl; - srslte::channel_ptr channel; - cf_t* signal_buffer[SRSLTE_MAX_PORTS] = {}; - srslte::log_filter channel_log; + srslte_enb_dl_t enb_dl; + srslte::channel_ptr channel; + cf_t* signal_buffer[SRSLTE_MAX_PORTS] = {}; + srslog::basic_logger& logger; public: test_enb(const srslte_cell_t& cell, const srslte::channel::args_t& channel_args) : - enb_dl(), channel_log("Channel pci=" + std::to_string(cell.id)) + enb_dl(), logger(srslog::fetch_basic_logger("Channel pci=" + std::to_string(cell.id))) { - channel_log.set_level(channel_log_level); + logger.set_level(srslog::str_to_basic_level(channel_log_level)); - channel = srslte::channel_ptr(new srslte::channel(channel_args, cell_base.nof_ports)); + channel = srslte::channel_ptr(new srslte::channel(channel_args, cell_base.nof_ports, logger)); channel->set_srate(srslte_sampling_freq_hz(cell.nof_prb)); - channel->set_logger(&channel_log); // Allocate buffer for eNb for (uint32_t i = 0; i < cell_base.nof_ports; i++) { signal_buffer[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_PRB(cell_base.nof_prb)); if (!signal_buffer[i]) { - ERROR("Error allocating buffer\n"); + ERROR("Error allocating buffer"); } } if (srslte_enb_dl_init(&enb_dl, signal_buffer, cell.nof_prb)) { - ERROR("Error initiating eNb downlink\n"); + ERROR("Error initiating eNb downlink"); } if (srslte_enb_dl_set_cell(&enb_dl, cell)) { - ERROR("Error setting eNb DL cell\n"); + ERROR("Error setting eNb DL cell"); } if (srslte_enb_dl_add_rnti(&enb_dl, serving_cell_pdsch_rnti)) { - ERROR("Error adding RNTI\n"); + ERROR("Error adding RNTI"); } } @@ -145,7 +145,6 @@ public: cf_t* baseband_buffer, const srslte::rf_timestamp_t& ts) { - int ret = SRSLTE_SUCCESS; uint32_t sf_len = SRSLTE_SF_LEN_PRB(enb_dl.cell.nof_prb); @@ -154,19 +153,19 @@ public: // Put PDSCH only if it is required if (dci && dci_cfg && softbuffer_tx && data_tx) { if (srslte_enb_dl_put_pdcch_dl(&enb_dl, dci_cfg, dci)) { - ERROR("Error putting PDCCH sf_idx=%d\n", dl_sf->tti); + ERROR("Error putting PDCCH sf_idx=%d", dl_sf->tti); ret = SRSLTE_ERROR; } // Create pdsch config srslte_pdsch_cfg_t pdsch_cfg; if (srslte_ra_dl_dci_to_grant(&enb_dl.cell, dl_sf, serving_cell_pdsch_tm, false, dci, &pdsch_cfg.grant)) { - ERROR("Computing DL grant sf_idx=%d\n", dl_sf->tti); + ERROR("Computing DL grant sf_idx=%d", dl_sf->tti); ret = SRSLTE_ERROR; } char str[512]; srslte_dci_dl_info(dci, str, 512); - INFO("eNb PDCCH: rnti=0x%x, %s\n", serving_cell_pdsch_rnti, str); + INFO("eNb PDCCH: rnti=0x%x, %s", serving_cell_pdsch_rnti, str); for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { pdsch_cfg.softbuffers.tx[i] = softbuffer_tx[i]; @@ -180,11 +179,11 @@ public: pdsch_cfg.meas_time_en = false; if (srslte_enb_dl_put_pdsch(&enb_dl, &pdsch_cfg, data_tx) < 0) { - ERROR("Error putting PDSCH sf_idx=%d\n", dl_sf->tti); + ERROR("Error putting PDSCH sf_idx=%d", dl_sf->tti); ret = SRSLTE_ERROR; } srslte_pdsch_tx_info(&pdsch_cfg, str, 512); - INFO("eNb PDSCH: rnti=0x%x, %s\n", serving_cell_pdsch_rnti, str); + INFO("eNb PDSCH: rnti=0x%x, %s", serving_cell_pdsch_rnti, str); } srslte_enb_dl_gen_signal(&enb_dl); @@ -390,7 +389,6 @@ static void pci_list_parse_helper(std::string& list_str, std::set& lis } else if (list_str == "none") { // Do nothing } else if (not list_str.empty()) { - // Remove spaces from neightbour cell list list_str = srslte::string_remove_char(list_str, ' '); @@ -409,12 +407,14 @@ int main(int argc, char** argv) } // Common for simulation and over-the-air + srslog::basic_logger& logger = srslog::fetch_basic_logger("intra_measure"); + srslog::init(); + cf_t* baseband_buffer = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX); srslte::rf_timestamp_t ts = {}; - srsue::scell::intra_measure intra_measure; - srslte::log_filter logger("intra_measure"); + srsue::scell::intra_measure intra_measure(logger); meas_itf_listener rrc; - srsue::phy_common common; + srsue::phy_common common(logger); // Simulation only std::vector > test_enb_v; @@ -456,16 +456,16 @@ int main(int argc, char** argv) const size_t nof_bytes = (6144 * 16 * 3 / 8); softbuffer_tx[i] = (srslte_softbuffer_tx_t*)calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffer_tx[i]) { - ERROR("Error allocating softbuffer_tx\n"); + ERROR("Error allocating softbuffer_tx"); } if (srslte_softbuffer_tx_init(softbuffer_tx[i], cell_base.nof_prb)) { - ERROR("Error initiating softbuffer_tx\n"); + ERROR("Error initiating softbuffer_tx"); } data_tx[i] = srslte_vec_u8_malloc(nof_bytes); if (!data_tx[i]) { - ERROR("Error allocating data tx\n"); + ERROR("Error allocating data tx"); } else { for (uint32_t j = 0; j < nof_bytes; j++) { data_tx[i][j] = (uint8_t)srslte_random_uniform_int_dist(random_gen, 0, 255); @@ -482,18 +482,18 @@ int main(int argc, char** argv) uint32_t serving_cell_id = *pcis_to_simulate.begin(); cell_base.id = serving_cell_id; - logger.set_level(intra_meas_log_level); + logger.set_level(srslog::str_to_basic_level(intra_meas_log_level)); - intra_measure.init(0, &common, &rrc, &logger); + intra_measure.init(0, &common, &rrc); intra_measure.set_primary_cell(SRSLTE_MAX(earfcn_dl, 0), cell_base); if (earfcn_dl >= 0) { // Create radio log - radio_log = std::unique_ptr(new srslte::log_filter("Radio")); - radio_log->set_level(radio_log_level); + auto& radio_logger = srslog::fetch_basic_logger("RF", false); + radio_logger.set_level(srslog::str_to_basic_level(radio_log_level)); // Create radio - radio = std::unique_ptr(new srslte::radio(radio_log.get())); + radio = std::unique_ptr(new srslte::radio); // Init radio srslte::rf_args_t radio_args = {}; @@ -522,7 +522,7 @@ int main(int argc, char** argv) srslte::channel::args_t channel_args; channel_args.enable = (channel_period_s != 0); channel_args.hst_enable = std::isnormal(channel_hst_fd_hz); - channel_args.hst_init_time_s = channel_init_time_s; + channel_args.hst_init_time_s = channel_init_time_s; channel_args.hst_period_s = (float)channel_period_s; channel_args.hst_fd_hz = channel_hst_fd_hz; channel_args.delay_enable = std::isnormal(channel_delay_max_us); @@ -634,7 +634,7 @@ int main(int argc, char** argv) dci.tb[i].cw_idx = i; } } else { - ERROR("Wrong transmission mode (%d)\n", serving_cell_pdsch_tm); + ERROR("Wrong transmission mode (%d)", serving_cell_pdsch_tm); } enb->work(&sf_cfg_dl, &dci_cfg, &dci, softbuffer_tx, data_tx, baseband_buffer, ts); } else { @@ -685,6 +685,8 @@ int main(int argc, char** argv) } } + srslog::flush(); + if (ret && radio == nullptr) { printf("Error\n"); } else { diff --git a/srsue/test/phy/ue_phy_test.cc b/srsue/test/phy/ue_phy_test.cc index 2c092808e..a44d2e238 100644 --- a/srsue/test/phy/ue_phy_test.cc +++ b/srsue/test/phy/ue_phy_test.cc @@ -46,7 +46,7 @@ public: expired = (cvar.wait_until(lock, expire_time) == std::cv_status::timeout); \ } \ if (expired) { \ - log_h.debug("Expired " #NAME " waiting\n"); \ + logger.debug("Expired " #NAME " waiting"); \ } \ return received_##NAME; \ } \ @@ -58,7 +58,7 @@ private: { \ std::unique_lock lock(mutex); \ cvar.notify_all(); \ - log_h.debug(#NAME " received\n"); \ + logger.debug(#NAME " received"); \ received_##NAME = true; \ } @@ -69,7 +69,7 @@ private: class dummy_stack final : public srsue::stack_interface_phy_lte { private: - srslte::log_filter log_h; + srslog::basic_logger& logger; uint16_t rnti = 0x3c; std::mutex mutex; std::condition_variable cvar; @@ -87,9 +87,9 @@ private: public: // Local test access methods - explicit dummy_stack(srslte::logger& logger) : log_h("stack", &logger) {} + dummy_stack() : logger(srslog::fetch_basic_logger("stack", false)) {} void set_rnti(uint16_t rnti_) { rnti = rnti_; } - void set_loglevel(std::string& str) { log_h.set_level(str); } + void set_loglevel(std::string& str) { logger.set_level(srslog::str_to_basic_level(str)); } void in_sync() override { notify_in_sync(); } void out_of_sync() override { notify_out_of_sync(); } @@ -97,8 +97,7 @@ private: { for (auto& m : meas) { notify_new_phy_meas(); - log_h.info( - "New measurement earfcn=%d; pci=%d; rsrp=%+.1fdBm; rsrq=%+.1fdB;\n", m.earfcn, m.pci, m.rsrp, m.rsrq); + logger.info("New measurement earfcn=%d; pci=%d; rsrp=%+.1fdBm; rsrq=%+.1fdB;", m.earfcn, m.pci, m.rsrp, m.rsrq); } } uint16_t get_dl_sched_rnti(uint32_t tti) override { return rnti; } @@ -119,7 +118,7 @@ private: void run_tti(const uint32_t tti, const uint32_t tti_jump) override { notify_run_tti(); - log_h.debug("Run TTI %d\n", tti); + logger.debug("Run TTI %d", tti); } void cell_search_complete(cell_search_ret_t ret, srsue::phy_cell_t found_cell) override @@ -152,7 +151,7 @@ private: class dummy_radio : public srslte::radio_interface_phy { private: - srslte::log_filter log_h; + srslog::basic_logger& logger; std::vector ring_buffers; float base_srate = 0.0f; float tx_srate = 0.0f; @@ -173,10 +172,8 @@ private: CALLBACK(late) public: - dummy_radio(srslte::logger& logger, uint32_t nof_channels, float base_srate_) : - log_h("radio", &logger), - ring_buffers(nof_channels), - base_srate(base_srate_) + dummy_radio(uint32_t nof_channels, float base_srate_) : + logger(srslog::fetch_basic_logger("radio", false)), ring_buffers(nof_channels), base_srate(base_srate_) { // Create Ring buffers for (auto& rb : ring_buffers) { @@ -208,7 +205,7 @@ private: } } - void set_loglevel(std::string& str) { log_h.set_level(str); } + void set_loglevel(std::string& str) { logger.set_level(srslog::str_to_basic_level(str)); } void write_ring_buffers(cf_t** buffer, uint32_t nsamples) { @@ -216,7 +213,7 @@ private: int ret = SRSLTE_SUCCESS; do { if (ret != SRSLTE_SUCCESS) { - log_h.error("Ring buffer write failed (full). Trying again.\n"); + logger.error("Ring buffer write failed (full). Trying again."); } ret = srslte_ringbuffer_write_timed(&ring_buffers[i], buffer[i], (uint32_t)sizeof(cf_t) * nsamples, 1000); } while (ret == SRSLTE_ERROR_TIMEOUT); @@ -260,9 +257,9 @@ private: // Read base srate samples int ret = srslte_ringbuffer_read(&ring_buffers[i], buf_ptr, (uint32_t)sizeof(cf_t) * base_nsamples); if (ret < 0) { - log_h.error("Reading ring buffer\n"); + logger.error("Reading ring buffer"); } else { - log_h.debug("-- %d samples read from ring buffer\n", base_nsamples); + logger.debug("-- %d samples read from ring buffer", base_nsamples); } // Only if baseband buffer is provided @@ -301,43 +298,43 @@ private: { std::unique_lock lock(mutex); tx_freq = (float)freq; - log_h.info("Set Tx freq to %+.0f MHz.\n", freq * 1.0e-6); + logger.info("Set Tx freq to %+.0f MHz.", freq * 1.0e-6); } void set_rx_freq(const uint32_t& channel_idx, const double& freq) override { std::unique_lock lock(mutex); rx_freq = (float)freq; - log_h.info("Set Rx freq to %+.0f MHz.\n", freq * 1.0e-6); + logger.info("Set Rx freq to %+.0f MHz.", freq * 1.0e-6); } void set_rx_gain_th(const float& gain) override { std::unique_lock lock(mutex); rx_gain = srslte_convert_dB_to_amplitude(gain); - log_h.info("Set Rx gain-th to %+.1f dB (%.6f).\n", gain, rx_gain); + logger.info("Set Rx gain-th to %+.1f dB (%.6f).", gain, rx_gain); } void set_tx_gain(const float& gain) override { std::unique_lock lock(mutex); rx_gain = srslte_convert_dB_to_amplitude(gain); - log_h.info("Set Tx gain to %+.1f dB (%.6f).\n", gain, rx_gain); + logger.info("Set Tx gain to %+.1f dB (%.6f).", gain, rx_gain); } void set_rx_gain(const float& gain) override { std::unique_lock lock(mutex); rx_gain = srslte_convert_dB_to_amplitude(gain); - log_h.info("Set Rx gain to %+.1f dB (%.6f).\n", gain, rx_gain); + logger.info("Set Rx gain to %+.1f dB (%.6f).", gain, rx_gain); } void set_tx_srate(const double& srate) override { std::unique_lock lock(mutex); tx_srate = (float)srate; - log_h.info("Set Tx sampling rate to %+.3f MHz.\n", srate * 1.0e-6); + logger.info("Set Tx sampling rate to %+.3f MHz.", srate * 1.0e-6); } void set_rx_srate(const double& srate) override { std::unique_lock lock(mutex); rx_srate = (float)srate; - log_h.info("Set Rx sampling rate to %+.3f MHz.\n", srate * 1.0e-6); + logger.info("Set Rx sampling rate to %+.3f MHz.", srate * 1.0e-6); } void set_channel_rx_offset(uint32_t ch, int32_t offset_samples) override{}; float get_rx_gain() override @@ -354,7 +351,7 @@ private: }; // Common instances - srslte::log_filter log_h; + srslog::basic_logger& logger; // Dummy instances dummy_stack stack; @@ -377,16 +374,15 @@ private: public: phy_test_bench(const srsue::phy_args_t& phy_args, const srslte_cell_t& cell, srslte::logger& logger_) : - stack(logger_), - radio(logger_, cell.nof_ports, srslte_sampling_freq_hz(cell.nof_prb)), + radio(cell.nof_ports, srslte_sampling_freq_hz(cell.nof_prb)), thread("phy_test_bench"), - log_h("test bench") + logger(srslog::fetch_basic_logger("test bench", false)) { // Deduce physical attributes sf_len = SRSLTE_SF_LEN_PRB(cell.nof_prb); // Initialise UE - phy = std::unique_ptr(new srsue::phy(&logger_)); + phy = std::unique_ptr(new srsue::phy(srslog::get_default_sink())); phy->init(phy_args, &stack, &radio); // Initialise DL baseband buffers @@ -439,7 +435,7 @@ public: // Free run DL do { - log_h.debug("-- generating DL baseband SFN=%" PRId64 " TTI=%d;\n", sfn, dl_sf_cfg.tti); + logger.debug("-- generating DL baseband SFN=%" PRId64 " TTI=%d;", sfn, dl_sf_cfg.tti); // Create empty resource grid with basic signals srslte_enb_dl_put_base(&enb_dl, &dl_sf_cfg); @@ -489,7 +485,7 @@ public: void set_loglevel(std::string str) { - log_h.set_level(str); + logger.set_level(srslog::str_to_basic_level(str)); radio.set_loglevel(str); stack.set_loglevel(str); } @@ -515,15 +511,7 @@ int main(int argc, char** argv) phy_args.log.phy_level = "info"; // Setup logging. - srslog::sink* log_sink = srslog::create_stdout_sink(); - if (!log_sink) { - return SRSLTE_ERROR; - } - srslog::log_channel* chan = srslog::create_log_channel("main_channel", *log_sink); - if (!chan) { - return SRSLTE_ERROR; - } - srslte::srslog_wrapper log_wrapper(*chan); + srslte::srslog_wrapper log_wrapper(srslog::fetch_log_channel("main_channel")); // Start the log backend. srslog::init(); diff --git a/srsue/test/ttcn3/hdr/lte_ttcn3_phy.h b/srsue/test/ttcn3/hdr/lte_ttcn3_phy.h index bbaa0bf99..2e031c33c 100644 --- a/srsue/test/ttcn3/hdr/lte_ttcn3_phy.h +++ b/srsue/test/ttcn3/hdr/lte_ttcn3_phy.h @@ -44,7 +44,7 @@ public: } cell_t; typedef std::vector cell_list_t; - lte_ttcn3_phy(srslte::logger* logger_); + lte_ttcn3_phy(); ~lte_ttcn3_phy() = default; int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, syssim_interface_phy* syssim_); @@ -112,8 +112,7 @@ public: void run_tti(); private: - srslte::logger* logger = nullptr; - srslte::log_filter log; + srslog::basic_logger& logger; // All available cells cell_list_t cells; diff --git a/srsue/test/ttcn3/hdr/swappable_sink.h b/srsue/test/ttcn3/hdr/swappable_sink.h index 7a839feb4..0968def52 100644 --- a/srsue/test/ttcn3/hdr/swappable_sink.h +++ b/srsue/test/ttcn3/hdr/swappable_sink.h @@ -25,7 +25,7 @@ #include "srslte/srslog/sink.h" /// A custom sink implementation that allows hot swapping file sinks so that loggers can write to different files -/// dynamically. +/// dynamically or other stream-like sinks like stdout. class swappable_sink : public srslog::sink { public: @@ -47,6 +47,13 @@ public: s = &srslog::fetch_file_sink(filename); } + /// Swaps the current sink to use the stdout sink. + void swap_to_stdout() + { + srslog::flush(); + s = &srslog::fetch_stdout_sink(); + } + private: srslog::sink* s; }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h b/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h index 805c796fa..655668aee 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_drb_interface.h @@ -36,27 +36,26 @@ using namespace srslte; class ttcn3_drb_interface : public ttcn3_port_handler { public: - ttcn3_drb_interface() : pool(byte_buffer_pool::get_instance()) {} + explicit ttcn3_drb_interface(srslog::basic_logger& logger) : ttcn3_port_handler(logger) {} ~ttcn3_drb_interface() = default; - int init(ss_srb_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + int init(ss_srb_interface* syssim_, std::string net_ip_, uint32_t net_port_) { syssim = syssim_; - log = log_; net_ip = net_ip_; net_port = net_port_; initialized = true; - log->debug("Initialized.\n"); + logger.debug("Initialized."); return port_listen(); } void tx(const uint8_t* buffer, uint32_t len) { if (initialized) { - log->info_hex(buffer, len, "Sending %d B to Titan\n", len); + logger.info(buffer, len, "Sending %d B to Titan", len); send(buffer, len); } else { - log->error("Trying to transmit but port not connected.\n"); + logger.error("Trying to transmit but port not connected."); } } @@ -64,7 +63,7 @@ private: ///< Main message handler int handle_message(const unique_byte_array_t& rx_buf, const uint32_t n) { - log->debug_hex(rx_buf->begin(), n, "Received %d B from remote.\n", n); + logger.debug(rx_buf->begin(), n, "Received %d B from remote.", n); // Chop incoming msg, first two bytes are length of the JSON // (see IPL4_EUTRA_SYSTEM_Definitions.ttcn @@ -76,7 +75,7 @@ private: Document document; if (document.Parse((char*)&rx_buf->at(2)).HasParseError() || document.IsObject() == false) { - log->error_hex((uint8*)&rx_buf->at(2), json_len, "Error parsing incoming data.\n"); + logger.error((uint8*)&rx_buf->at(2), json_len, "Error parsing incoming data."); return SRSLTE_ERROR; } @@ -84,7 +83,7 @@ private: StringBuffer buffer; PrettyWriter writer(buffer); document.Accept(writer); - log->info("Received JSON with %d B\n%s\n", json_len, (char*)buffer.GetString()); + logger.info("Received JSON with %d B\n%s", json_len, (char*)buffer.GetString()); // check for common assert(document.HasMember("Common")); @@ -115,9 +114,9 @@ private: handle_sdu(document, lcid, octstr.data(), octstr.size(), ttcn3_helpers::get_follow_on_flag(document)); } } else if ((*itr)["PduSduList"].HasMember("MacPdu")) { - log->warning("Not handling MacPdu type."); + logger.warning("Not handling MacPdu type."); } else { - log->warning("Not handling this PduSdu type.\n"); + logger.warning("Not handling this PduSdu type."); } } @@ -126,10 +125,10 @@ private: void handle_sdu(Document& document, const uint16_t lcid, const uint8_t* payload, const uint16_t len, bool follow_on) { - log->info_hex(payload, len, "Received DRB PDU (lcid=%d)\n", lcid); + logger.info(payload, len, "Received DRB PDU (lcid=%d)", lcid); // pack into byte buffer - unique_byte_buffer_t pdu = pool_allocate_blocking; + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); pdu->N_bytes = len; memcpy(pdu->msg, payload, pdu->N_bytes); @@ -141,7 +140,6 @@ private: } ss_srb_interface* syssim = nullptr; - byte_buffer_pool* pool = nullptr; }; #endif // SRSUE_TTCN3_DRB_INTERFACE_H diff --git a/srsue/test/ttcn3/hdr/ttcn3_helpers.h b/srsue/test/ttcn3/hdr/ttcn3_helpers.h index fb558b8c5..c7727c96c 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_helpers.h +++ b/srsue/test/ttcn3/hdr/ttcn3_helpers.h @@ -30,7 +30,7 @@ #include "rapidjson/document.h" // rapidjson's DOM-style API #include "rapidjson/prettywriter.h" // for stringify JSON #include "srslte/asn1/asn1_utils.h" -#include "srslte/common/common.h" +#include "srslte/common/byte_buffer.h" #include #include #include @@ -390,7 +390,6 @@ public: document["Common"]["TimingInfo"].HasMember("SubFrame") && document["Common"]["TimingInfo"]["SubFrame"].HasMember("SFN") && document["Common"]["TimingInfo"]["SubFrame"]["SFN"].HasMember("Number")) { - timing.tti = document["Common"]["TimingInfo"]["SubFrame"]["SFN"]["Number"].GetInt() * 10; // check SF index only diff --git a/srsue/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h b/srsue/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h index 573b997af..7d876d988 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h @@ -34,16 +34,15 @@ using namespace rapidjson; class ttcn3_ip_ctrl_interface : public ttcn3_port_handler { public: - ttcn3_ip_ctrl_interface() = default; + explicit ttcn3_ip_ctrl_interface(srslog::basic_logger& logger) : ttcn3_port_handler(logger) {} ~ttcn3_ip_ctrl_interface() = default; - int init(srslte::log* log_, std::string net_ip_, uint32_t net_port_) + int init(std::string net_ip_, uint32_t net_port_) { net_ip = net_ip_; net_port = net_port_; - log = log_; initialized = true; - log->debug("Initialized.\n"); + logger.debug("Initialized."); return port_listen(); } @@ -51,11 +50,11 @@ private: ///< Main message handler int handle_message(const unique_byte_array_t& rx_buf, const uint32_t n) { - log->debug("Received %d B from remote.\n", n); + logger.debug("Received %d B from remote.", n); Document document; if (document.Parse((char*)rx_buf->begin()).HasParseError() || document.IsObject() == false) { - log->error_hex(rx_buf->begin(), n, "Error parsing incoming data.\n"); + logger.error(rx_buf->begin(), n, "Error parsing incoming data."); return SRSLTE_ERROR; } @@ -63,14 +62,14 @@ private: StringBuffer buffer; PrettyWriter writer(buffer); document.Accept(writer); - log->info("Received %d bytes\n%s\n", n, (char*)buffer.GetString()); + logger.info("Received %d bytes\n%s", n, (char*)buffer.GetString()); // Get message if (document.HasMember("RoutingInfo")) { - log->info("Received RoutingInfo\n"); + logger.info("Received RoutingInfo"); handle_routing_info(document); } else { - log->error("Received unknown request.\n"); + logger.error("Received unknown request."); } return SRSLTE_SUCCESS; @@ -95,7 +94,7 @@ private: std::string resp = ttcn3_helpers::get_drbmux_common_ind_cnf(); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_ip_sock_interface.h b/srsue/test/ttcn3/hdr/ttcn3_ip_sock_interface.h index a8ab2f392..d150f3bc4 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ip_sock_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ip_sock_interface.h @@ -28,16 +28,15 @@ class ttcn3_ip_sock_interface : public ttcn3_port_handler { public: - ttcn3_ip_sock_interface() = default; + explicit ttcn3_ip_sock_interface(srslog::basic_logger& logger) : ttcn3_port_handler(logger) {} ~ttcn3_ip_sock_interface() = default; - int init(srslte::log* log_, std::string net_ip_, uint32_t net_port_) + int init(std::string net_ip_, uint32_t net_port_) { net_ip = net_ip_; net_port = net_port_; - log = log_; initialized = true; - log->debug("Initialized.\n"); + logger.debug("Initialized."); return port_listen(); } @@ -45,11 +44,11 @@ private: ///< Main message handler int handle_message(const unique_byte_array_t& rx_buf, const uint32_t n) { - log->debug("Received %d B from remote.\n", n); + logger.debug("Received %d B from remote.", n); Document document; if (document.Parse((char*)rx_buf->begin()).HasParseError() || document.IsObject() == false) { - log->error_hex(rx_buf->begin(), n, "Error parsing incoming data.\n"); + logger.error(rx_buf->begin(), n, "Error parsing incoming data."); return SRSLTE_ERROR; } @@ -57,14 +56,14 @@ private: StringBuffer buffer; PrettyWriter writer(buffer); document.Accept(writer); - log->info("Received %d bytes\n%s\n", n, (char*)buffer.GetString()); + logger.info("Received %d bytes\n%s", n, (char*)buffer.GetString()); // Get message if (document.HasMember("CTRL")) { - log->info("Received CTRL command.\n"); + logger.info("Received CTRL command."); handle_ctrl(document); } else { - log->error("Received unknown request.\n"); + logger.error("Received unknown request."); } return SRSLTE_SUCCESS; @@ -111,7 +110,7 @@ private: // Send response if (resp.length() > 0) { - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } } diff --git a/srsue/test/ttcn3/hdr/ttcn3_port_handler.h b/srsue/test/ttcn3/hdr/ttcn3_port_handler.h index a34545eb9..fd17dc235 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_port_handler.h +++ b/srsue/test/ttcn3/hdr/ttcn3_port_handler.h @@ -29,6 +29,7 @@ #include "srslte/common/epoll_helper.h" #include "srslte/common/log.h" +#include "srslte/srslog/srslog.h" #include "ttcn3_common.h" #include #include @@ -37,7 +38,9 @@ class ttcn3_port_handler : public epoll_handler { public: - ttcn3_port_handler() : rx_buf(unique_byte_array_t(new byte_array_t)) {} + explicit ttcn3_port_handler(srslog::basic_logger& logger) : + logger(logger), rx_buf(unique_byte_array_t(new byte_array_t)) + {} virtual ~ttcn3_port_handler() {} virtual int handle_message(const unique_byte_array_t& rx_buf, const uint32_t n) = 0; @@ -51,9 +54,9 @@ public: int rd_sz = sctp_recvmsg(fd, rx_buf->begin(), RX_BUF_SIZE, (struct sockaddr*)&client_addr, &fromlen, &sri, &msg_flags); if (rd_sz == -1 && errno != EAGAIN) { - log->error("Error reading from SCTP socket: %s", strerror(errno)); + logger.error("Error reading from SCTP socket: %s", strerror(errno)); } else if (rd_sz == -1 && errno == EAGAIN) { - log->debug("Socket timeout reached"); + logger.debug("Socket timeout reached"); } else { if (msg_flags & MSG_NOTIFICATION) { // Received notification @@ -105,8 +108,8 @@ public: break; } - log->debug( - "SCTP_ASSOC_CHANGE notif: state: %s, error code: %d, out streams: %d, in streams: %d, assoc id: %d\n", + logger.debug( + "SCTP_ASSOC_CHANGE notif: state: %s, error code: %d, out streams: %d, in streams: %d, assoc id: %d", state, n->sac_error, n->sac_outbound_streams, @@ -121,12 +124,12 @@ public: return SRSLTE_ERROR; } struct sctp_shutdown_event* n = ¬if->sn_shutdown_event; - log->debug("SCTP_SHUTDOWN_EVENT notif: assoc id: %d\n", n->sse_assoc_id); + logger.debug("SCTP_SHUTDOWN_EVENT notif: assoc id: %d", n->sse_assoc_id); break; } default: - log->warning("Unhandled notification type %d\n", notif->sn_header.sn_type); + logger.warning("Unhandled notification type %d", notif->sn_header.sn_type); break; } @@ -137,7 +140,7 @@ public: void send(const uint8_t* buffer, const uint32_t len) { if (sendto(sock_fd, buffer, len, 0, (struct sockaddr*)&client_addr, sizeof(client_addr)) == -1) { - log->error("Error sending message to tester.\n"); + logger.error("Error sending message to tester."); } } @@ -194,7 +197,7 @@ public: ret = bind(sock_fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)); if (ret != 0) { close(sock_fd); - log->error("Error binding SCTP socket\n"); + logger.error("Error binding SCTP socket"); srslte::console("Error binding SCTP socket\n"); return SRSLTE_ERROR; } @@ -203,7 +206,7 @@ public: ret = listen(sock_fd, SOMAXCONN); if (ret != SRSLTE_SUCCESS) { close(sock_fd); - log->error("Error in SCTP socket listen\n"); + logger.error("Error in SCTP socket listen"); srslte::console("Error in SCTP socket listen\n"); return SRSLTE_ERROR; } @@ -212,13 +215,13 @@ public: return sock_fd; } - bool initialized = false; - std::string net_ip = "0.0.0.0"; - uint32_t net_port = 0; - int sock_fd = -1; - struct sockaddr client_addr = {}; - srslte::log* log = nullptr; - unique_byte_array_t rx_buf; ///< Receive buffer for this port + bool initialized = false; + std::string net_ip = "0.0.0.0"; + uint32_t net_port = 0; + int sock_fd = -1; + struct sockaddr client_addr = {}; + srslog::basic_logger& logger; + unique_byte_array_t rx_buf; ///< Receive buffer for this port }; #endif // SRSUE_TTCN3_PORT_HANDLER_H diff --git a/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h b/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h index 7e118a0bd..6e1bd6d53 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h @@ -35,27 +35,28 @@ using namespace srslte; class ttcn3_srb_interface : public ttcn3_port_handler { public: - ttcn3_srb_interface() : pool(byte_buffer_pool::get_instance()) {} + explicit ttcn3_srb_interface(srslog::basic_logger& logger) : + ttcn3_port_handler(logger), pool(byte_buffer_pool::get_instance()) + {} ~ttcn3_srb_interface() = default; - int init(ss_srb_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + int init(ss_srb_interface* syssim_, std::string net_ip_, uint32_t net_port_) { - syssim = syssim_; - log = log_; - net_ip = net_ip_; - net_port = net_port_; + syssim = syssim_; + net_ip = net_ip_; + net_port = net_port_; initialized = true; - log->debug("Initialized.\n"); + logger.debug("Initialized."); return port_listen(); } void tx(const uint8_t* buffer, uint32_t len) { if (initialized) { - log->info_hex(buffer, len, "Sending %d B to Titan\n", len); + logger.info(buffer, len, "Sending %d B to Titan", len); send(buffer, len); } else { - log->error("Trying to transmit but port not connected.\n"); + logger.error("Trying to transmit but port not connected."); } } @@ -63,7 +64,7 @@ private: ///< Main message handler int handle_message(const unique_byte_array_t& rx_buf, const uint32_t n) { - log->debug_hex(rx_buf->begin(), n, "Received %d B from remote.\n", n); + logger.debug(rx_buf->begin(), n, "Received %d B from remote.", n); // Chop incoming msg, first two bytes are length of the JSON // (see IPL4_EUTRA_SYSTEM_Definitions.ttcn @@ -75,7 +76,7 @@ private: Document document; if (document.Parse((char*)&rx_buf->at(2)).HasParseError() || document.IsObject() == false) { - log->error_hex((uint8*)&rx_buf->at(2), json_len, "Error parsing incoming data.\n"); + logger.error((uint8*)&rx_buf->at(2), json_len, "Error parsing incoming data."); return SRSLTE_ERROR; } @@ -83,7 +84,7 @@ private: StringBuffer buffer; PrettyWriter writer(buffer); document.Accept(writer); - log->info("Received JSON with %d B\n%s\n", json_len, (char*)buffer.GetString()); + logger.info("Received JSON with %d B\n%s", json_len, (char*)buffer.GetString()); // check for common assert(document.HasMember("Common")); @@ -101,9 +102,10 @@ private: } else if (rrcpdu.HasMember("Dcch")) { rx_buf_offset += 2; uint32_t lcid = document["Common"]["RoutingInfo"]["RadioBearerId"]["Srb"].GetInt(); - handle_dcch_pdu(document, lcid, &rx_buf->at(rx_buf_offset), n - rx_buf_offset, ttcn3_helpers::get_follow_on_flag(document)); + handle_dcch_pdu( + document, lcid, &rx_buf->at(rx_buf_offset), n - rx_buf_offset, ttcn3_helpers::get_follow_on_flag(document)); } else { - log->error("Received unknown request.\n"); + logger.error("Received unknown request."); } return SRSLTE_SUCCESS; @@ -112,10 +114,10 @@ private: // Todo: move to SYSSIM void handle_ccch_pdu(Document& document, const uint8_t* payload, const uint16_t len) { - log->info_hex(payload, len, "Received CCCH RRC PDU\n"); + logger.info(payload, len, "Received CCCH RRC PDU"); // pack into byte buffer - unique_byte_buffer_t pdu = pool_allocate_blocking; + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); pdu->N_bytes = len; memcpy(pdu->msg, payload, pdu->N_bytes); @@ -132,10 +134,10 @@ private: void handle_dcch_pdu(Document& document, const uint16_t lcid, const uint8_t* payload, const uint16_t len, bool follow_on) { - log->info_hex(payload, len, "Received DCCH RRC PDU (lcid=%d)\n", lcid); + logger.info(payload, len, "Received DCCH RRC PDU (lcid=%d)", lcid); // pack into byte buffer - unique_byte_buffer_t pdu = pool_allocate_blocking; + unique_byte_buffer_t pdu = srslte::make_byte_buffer(); pdu->N_bytes = len; memcpy(pdu->msg, payload, pdu->N_bytes); diff --git a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h index 8048fa60d..5db433d14 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h @@ -33,17 +33,16 @@ using namespace srslte; class ttcn3_sys_interface : public ttcn3_port_handler { public: - ttcn3_sys_interface(){}; + explicit ttcn3_sys_interface(srslog::basic_logger& logger) : ttcn3_port_handler(logger) {} ~ttcn3_sys_interface(){}; - int init(ss_sys_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + int init(ss_sys_interface* syssim_, std::string net_ip_, uint32_t net_port_) { syssim = syssim_; net_ip = net_ip_; net_port = net_port_; - log = log_; initialized = true; - log->debug("Initialized.\n"); + logger.debug("Initialized."); pool = byte_buffer_pool::get_instance(); return port_listen(); } @@ -52,7 +51,7 @@ private: ///< Main message handler int handle_message(const unique_byte_array_t& rx_buf, const uint32_t n) { - log->debug("Received %d B from remote.\n", n); + logger.debug("Received %d B from remote.", n); // Chop incoming msg, first two bytes are length of the JSON // (see IPL4_EUTRA_SYSTEM_Definitions.ttcn @@ -69,7 +68,7 @@ private: Document document; if (document.Parse(json).HasParseError() || document.IsObject() == false) { - log->error_hex((uint8*)json, json_len, "Error parsing incoming data.\n"); + logger.error((uint8*)json, json_len, "Error parsing incoming data."); return SRSLTE_ERROR; } @@ -77,7 +76,7 @@ private: StringBuffer buffer; PrettyWriter writer(buffer); document.Accept(writer); - log->info_long("Received %d bytes\n%s\n", json_len, (char*)buffer.GetString()); + logger.info("Received %d bytes\n%s", json_len, (char*)buffer.GetString()); // check for common assert(document.HasMember("Common")); @@ -90,34 +89,34 @@ private: // Get request type const Value& request = document["Request"]; if (request.HasMember("Cell")) { - log->info("Received Cell request.\n"); + logger.info("Received Cell request."); handle_request_cell(document, &rx_buf->at(rx_buf_offset), n - rx_buf_offset); } else if (request.HasMember("L1MacIndCtrl")) { - log->info("Received L1MacIndCtrl request.\n"); + logger.info("Received L1MacIndCtrl request."); handle_request_l1_mac_ind_ctrl(document); } else if (request.HasMember("RadioBearerList")) { - log->info("Received RadioBearerList request.\n"); + logger.info("Received RadioBearerList request."); handle_request_radio_bearer_list(document); } else if (request.HasMember("CellAttenuationList")) { - log->info("Received CellAttenuationList request.\n"); + logger.info("Received CellAttenuationList request."); handle_request_cell_attenuation_list(document); } else if (request.HasMember("PdcpCount")) { - log->info("Received PdcpCount request.\n"); + logger.info("Received PdcpCount request."); handle_request_pdcp_count(document); } else if (request.HasMember("AS_Security")) { - log->info("Received AS_Security request.\n"); + logger.info("Received AS_Security request."); handle_request_as_security(document); } else if (request.HasMember("EnquireTiming")) { - log->info("Received EnquireTiming request.\n"); + logger.info("Received EnquireTiming request."); handle_request_enquire_timing(document); } else if (request.HasMember("Paging")) { - log->info("Received Paging request.\n"); + logger.info("Received Paging request."); handle_request_paging(document, &rx_buf->at(rx_buf_offset), n - rx_buf_offset); } else if (request.HasMember("PdcpHandoverControl")) { - log->info("Received PdcpHandoverControl.\n"); + logger.info("Received PdcpHandoverControl."); handle_request_pdcp_handover_control(document); } else { - log->error("Received unknown request.\n"); + logger.error("Received unknown request."); } return SRSLTE_SUCCESS; @@ -164,7 +163,7 @@ private: (strcmp(phy_dl_config["Phich"]["PhichConfig"]["R8"]["phich_Resource"].GetString(), "one") == 0) ? SRSLTE_PHICH_R_1 : SRSLTE_PHICH_R_1_6; - log->info("DL EARFCN is %d with n_prb=%d\n", cell.earfcn, cell.phy_cell.nof_prb); + logger.info("DL EARFCN is %d with n_prb=%d", cell.earfcn, cell.phy_cell.nof_prb); const Value& ref_power = document["Request"]["Cell"]["AddOrReconfigure"]["Basic"]["InitialCellPower"]["MaxReferencePower"]; @@ -192,7 +191,7 @@ private: // Now configure cell syssim->set_cell_config(ttcn3_helpers::get_timing_info(document), cell); - log->info("Configuring attenuation of %s to %.2f dB\n", cell_name.GetString(), cell.attenuation); + logger.info("Configuring attenuation of %s to %.2f dB", cell_name.GetString(), cell.attenuation); syssim->set_cell_attenuation(ttcn3_helpers::get_timing_info(document), cell_name.GetString(), cell.attenuation); } @@ -203,13 +202,13 @@ private: uint16_t tb_len = ((uint16_t)payload_ptr[0] << 8) | payload_ptr[1]; payload_ptr += 2; - unique_byte_buffer_t sib = pool_allocate_blocking; + unique_byte_buffer_t sib = srslte::make_byte_buffer(); memcpy(sib->msg, payload_ptr, tb_len); payload_ptr += tb_len; sib->N_bytes = tb_len; // Push to main component - log->info_hex(sib->msg, sib->N_bytes, "Received BCCH DL-SCH for %s\n", cell_name.GetString()); + logger.info(sib->msg, sib->N_bytes, "Received BCCH DL-SCH for %s", cell_name.GetString()); syssim->add_bcch_dlsch_pdu(cell_name.GetString(), std::move(sib)); consumed_bytes = payload_ptr - payload; @@ -219,7 +218,7 @@ private: // Create response for template car_CellConfig_CNF(CellId_Type p_CellId) std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_name.GetString(), "Cell"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } } @@ -241,10 +240,10 @@ private: if (ttcn3_helpers::requires_confirm(document)) { std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id, "Cell"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } else { - log->info("Skipping response for request cell active message.\n"); + logger.info("Skipping response for request cell active message."); } } @@ -323,7 +322,7 @@ private: handle_request_cell_active(document, payload, len); } } else if (document["Request"]["Cell"].HasMember("Release")) { - log->info("Received cell release command\n"); + logger.info("Received cell release command"); // do nothing more } } @@ -349,13 +348,13 @@ private: if (mac_ind_ctrl.HasMember("HarqError")) { assert(mac_ind_ctrl["HarqError"].IsString()); bool harq_error = (strcmp(mac_ind_ctrl["HarqError"].GetString(), "enable") == 0) ? true : false; - log->info("Setting HarqError to %s\n", harq_error ? "True" : "False"); + logger.info("Setting HarqError to %s", harq_error ? "True" : "False"); } if (ttcn3_helpers::requires_confirm(document)) { std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id.GetString(), "L1MacIndCtrl"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } } @@ -394,11 +393,11 @@ private: const Value& dlcid = aor["Mac"]["TestMode"]["Info"]["DiffLogChId"]; assert(dlcid.HasMember("LogChId")); force_lcid = dlcid["LogChId"].GetInt(); - log->info("TestMode: lcid overridden: %d\n", force_lcid); + logger.info("TestMode: lcid overridden: %d", force_lcid); syssim->set_forced_lcid(force_lcid); } else { // Unset override function to use different lcid - log->info("TestMode: lcid reset\n"); + logger.info("TestMode: lcid reset"); syssim->set_forced_lcid(-1); } if (lcid > 0) { @@ -410,10 +409,10 @@ private: uint32_t lcid = id["Srb"].GetInt(); syssim->del_srb(ttcn3_helpers::get_timing_info(document), ttcn3_helpers::get_cell_name(document), lcid); } else { - log->error("Unknown config.\n"); + logger.error("Unknown config."); } } else if (id.HasMember("Drb")) { - log->info("Configure DRB%d\n", id["Drb"].GetInt()); + logger.info("Configure DRB%d", id["Drb"].GetInt()); const Value& config = (*itr)["Config"]; if (config.HasMember("AddOrReconfigure")) { @@ -430,7 +429,7 @@ private: uint32_t lcid = id["Drb"].GetInt() + 2; syssim->del_drb(ttcn3_helpers::get_timing_info(document), ttcn3_helpers::get_cell_name(document), lcid); } else { - log->error("Unknown config.\n"); + logger.error("Unknown config."); } } } @@ -438,10 +437,10 @@ private: if (ttcn3_helpers::requires_confirm(document)) { std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id.GetString(), "RadioBearerList"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } else { - log->info("Skipping response for radio bearer list message.\n"); + logger.info("Skipping response for radio bearer list message."); } } @@ -484,13 +483,13 @@ private: } } - log->info("Configuring attenuation of %s to %.2f dB\n", id.GetString(), att_value); + logger.info("Configuring attenuation of %s to %.2f dB", id.GetString(), att_value); syssim->set_cell_attenuation(ttcn3_helpers::get_timing_info(document), id.GetString(), att_value); } std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id.GetString(), "CellAttenuationList"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } @@ -519,7 +518,7 @@ private: std::string resp = ttcn3_helpers::get_pdcp_count_response( cell_id.GetString(), syssim->get_pdcp_count(ttcn3_helpers::get_cell_name(document))); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } @@ -555,13 +554,13 @@ private: } else if (int_algo_string == "eia2") { integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA2; } else { - log->error("Unsupported integrity algorithm %s\n", int_algo_string.c_str()); + logger.error("Unsupported integrity algorithm %s", int_algo_string.c_str()); } // get integrity key std::string integ_key_string = as_sec["StartRestart"]["Integrity"]["KRRCint"].GetString(); std::array k_rrc_int = get_key_from_string(integ_key_string); - log->debug_hex(k_rrc_int.data(), k_rrc_int.size(), "K_rrc_int"); + logger.debug(k_rrc_int.data(), k_rrc_int.size(), "K_rrc_int"); // get enc algo srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo = {}; @@ -573,18 +572,18 @@ private: } else if (cipher_algo_string == "eea2") { cipher_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA2; } else { - log->error("Unsupported ciphering algorithm %s\n", cipher_algo_string.c_str()); + logger.error("Unsupported ciphering algorithm %s", cipher_algo_string.c_str()); } // get cipher key std::string cipher_key_string = as_sec["StartRestart"]["Ciphering"]["KRRCenc"].GetString(); std::array k_rrc_enc = get_key_from_string(cipher_key_string); - log->debug_hex(k_rrc_enc.data(), k_rrc_enc.size(), "K_rrc_enc"); + logger.debug(k_rrc_enc.data(), k_rrc_enc.size(), "K_rrc_enc"); // get UP enc key std::string up_enc_key_string = as_sec["StartRestart"]["Ciphering"]["KUPenc"].GetString(); std::array k_up_enc = get_key_from_string(up_enc_key_string); - log->debug_hex(k_up_enc.data(), k_up_enc.size(), "K_UP_enc"); + logger.debug(k_up_enc.data(), k_up_enc.size(), "K_UP_enc"); // parse ActTimeList ttcn3_helpers::pdcp_count_map_t bearers; @@ -637,10 +636,10 @@ private: if (config_flag.GetBool() == true) { std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id.GetString(), "AS_Security"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } else { - log->info("Skipping response for AS_Security message.\n"); + logger.info("Skipping response for AS_Security message."); } } @@ -675,7 +674,7 @@ private: std::string resp = ttcn3_helpers::get_sys_req_cnf_with_time(cell_id.GetString(), "EnquireTiming", syssim->get_tti()); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } @@ -704,22 +703,22 @@ private: uint16_t tb_len = ((uint16_t)payload_ptr[0] << 8) | payload_ptr[1]; payload_ptr += 2; - unique_byte_buffer_t pch = pool_allocate_blocking; + unique_byte_buffer_t pch = srslte::make_byte_buffer(); memcpy(pch->msg, payload_ptr, tb_len); payload_ptr += tb_len; pch->N_bytes = tb_len; // Push to main component - log->info_hex(pch->msg, pch->N_bytes, "Received PCH DL-SCH\n"); + logger.info(pch->msg, pch->N_bytes, "Received PCH DL-SCH"); syssim->add_pch_pdu(std::move(pch)); if (ttcn3_helpers::requires_confirm(document)) { std::string resp = ttcn3_helpers::get_sys_req_cnf_with_time(cell_id.GetString(), "Paging", syssim->get_tti()); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } else { - log->info("Skipping response for Paging message.\n"); + logger.info("Skipping response for Paging message."); } } @@ -751,7 +750,7 @@ private: if (ttcn3_helpers::requires_confirm(document)) { std::string resp = ttcn3_helpers::get_basic_sys_req_cnf(cell_id.GetString(), "PdcpHandoverControl"); - log->info("Sending %s to tester (%zd B)\n", resp.c_str(), resp.length()); + logger.info("Sending %s to tester (%zd B)", resp.c_str(), resp.length()); send((const uint8_t*)resp.c_str(), resp.length()); } } diff --git a/srsue/test/ttcn3/hdr/ttcn3_syssim.h b/srsue/test/ttcn3/hdr/ttcn3_syssim.h index 0a461f9af..8b07f9329 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_syssim.h +++ b/srsue/test/ttcn3/hdr/ttcn3_syssim.h @@ -202,6 +202,18 @@ public: ttcn3_helpers::pdcp_count_map_t get_pdcp_count(const std::string cell_name); private: + // Logging stuff. + srslog::basic_logger& logger; + srslog::basic_logger& ut_logger; + srslog::basic_logger& sys_logger; + srslog::basic_logger& ip_sock_logger; + srslog::basic_logger& ip_ctrl_logger; + srslog::basic_logger& srb_logger; + srslog::basic_logger& drb_logger; + srslog::basic_logger& ss_mac_logger; + srslog::basic_logger& ss_rlc_logger; + srslog::basic_logger& ss_pdcp_logger; + // SYS interface ttcn3_ut_interface ut; ttcn3_sys_interface sys; @@ -217,25 +229,17 @@ private: epoll_timer_handler timer_handler; epoll_signal_handler signal_handler; - // Logging stuff - srslte::logger& logger_stdout; - srslte::logger& logger_file; - srslte::logger* logger = nullptr; - srslte::log_ref log; - srslte::log_filter ut_log; - srslte::log_filter sys_log; - srslte::log_filter ip_sock_log; - srslte::log_filter ip_ctrl_log; - srslte::log_filter srb_log; - srslte::log_filter drb_log; - srslte::log_ref ss_mac_log{"SS-MAC"}; - srslte::log_ref ss_rlc_log{"SS-RLC"}; - srslte::log_ref ss_pdcp_log{"SS-PDCP"}; + // Logging stuff (to be removed) + srslte::logger& logger_stdout; + srslte::logger& logger_file; + srslte::logger* old_logger = nullptr; + srslte::log_ref log; + srslte::log_ref ss_mac_log{"SS-MAC"}; + srslte::log_ref ss_rlc_log{"SS-RLC"}; + srslte::log_ref ss_pdcp_log{"SS-PDCP"}; all_args_t args = {}; - srslte::byte_buffer_pool* pool = nullptr; - // Simulator vars ttcn3_ue* ue = nullptr; bool running = false; diff --git a/srsue/test/ttcn3/hdr/ttcn3_ue.h b/srsue/test/ttcn3/hdr/ttcn3_ue.h index 1b08b019d..fc23c4b90 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ue.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ue.h @@ -60,7 +60,13 @@ public: void add_mch_port(uint32_t lcid, uint32_t port); void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu); - int setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str); + int setup_if_addr(uint32_t eps_bearer_id, + uint32_t lcid, + uint8_t pdn_type, + uint32_t ip_addr, + uint8_t* ipv6_if_id, + char* err_str); + int update_lcid(uint32_t eps_bearer_id, uint32_t new_lcid); int apply_traffic_flow_template(const uint8_t& eps_bearer_id, const uint8_t& lcid, @@ -79,8 +85,8 @@ private: std::unique_ptr stack; // Generic logger members - srslte::logger* logger = nullptr; - srslte::log_filter log; // Own logger for UE + srslte::logger* old_logger = nullptr; + srslog::basic_logger& logger; test_loop_mode_state_t test_loop_mode = TEST_LOOP_INACTIVE; srslte::timer_handler::unique_timer pdu_delay_timer; diff --git a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h index 43c362784..ec852b825 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h @@ -34,13 +34,12 @@ using namespace rapidjson; class ttcn3_ut_interface : public ttcn3_port_handler { public: - ttcn3_ut_interface() {} + explicit ttcn3_ut_interface(srslog::basic_logger& logger) : ttcn3_port_handler(logger) {} ~ttcn3_ut_interface(){}; - int init(ss_ut_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + int init(ss_ut_interface* syssim_, std::string net_ip_, uint32_t net_port_) { syssim = syssim_; - log = log_; net_ip = net_ip_; net_port = net_port_; initialized = true; @@ -54,7 +53,7 @@ private: { Document document; if (document.Parse((char*)rx_buf->begin()).HasParseError() || document.IsObject() == false) { - log->error_hex(rx_buf->begin(), n, "Error parsing incoming data.\n"); + logger.error(rx_buf->begin(), n, "Error parsing incoming data."); return SRSLTE_ERROR; } @@ -62,7 +61,7 @@ private: StringBuffer buffer; PrettyWriter writer(buffer); document.Accept(writer); - log->info("Received %d bytes\n%s\n", n, (char*)buffer.GetString()); + logger.info("Received %d bytes\n%s.", n, (char*)buffer.GetString()); // check for command assert(document.HasMember("Cmd")); @@ -86,30 +85,30 @@ private: assert(document.HasMember("CnfRequired")); if (strcmp(mmi_cmd.GetString(), "POWER_OFF") == 0) { - log->info("Received POWER_OFF command.\n"); + logger.info("Received POWER_OFF command."); handle_power_off(document); } else if (strcmp(mmi_cmd.GetString(), "SWITCH_ON") == 0) { - log->info("Received SWITCH_ON command.\n"); + logger.info("Received SWITCH_ON command."); syssim->switch_on_ue(); } else if (strcmp(mmi_cmd.GetString(), "SWITCH_OFF") == 0) { - log->info("Received SWITCH_OFF command.\n"); + logger.info("Received SWITCH_OFF command."); syssim->switch_off_ue(); } else { - log->error("Received unknown command: %s\n", mmi_cmd.GetString()); + logger.error("Received unknown command: %s", mmi_cmd.GetString()); } } else if (a.HasMember("AT")) { handle_at_command(document); } else if (a.HasMember("TC_START")) { - log->info("Received TC_START command.\n"); + logger.info("Received TC_START command."); const Value& cmd = a["TC_START"]; assert(cmd.HasMember("Name")); const Value& tc_name = cmd["Name"]; syssim->tc_start(tc_name.GetString()); } else if (a.HasMember("TC_END")) { - log->info("Received TC_END command.\n"); + logger.info("Received TC_END command."); syssim->tc_end(); } else { - log->error("Unknown command type.\n"); + logger.error("Unknown command type."); } return SRSLTE_SUCCESS; @@ -129,7 +128,7 @@ private: Writer writer(buffer); resp.Accept(writer); - log->info("Sending %s to tester (%zd B)\n", buffer.GetString(), buffer.GetSize()); + logger.info("Sending %s to tester (%zd B)", buffer.GetString(), buffer.GetSize()); send((const uint8_t*)buffer.GetString(), buffer.GetSize()); } @@ -140,13 +139,13 @@ private: // turn off data services if (std::string(at.GetString()) == "AT+CGATT=0") { - log->info("Disabling data services\n"); + logger.info("Disabling data services"); syssim->disable_data(); } else if (std::string(at.GetString()) == "AT+CGATT=1") { - log->info("Enabling data services\n"); + logger.info("Enabling data services"); syssim->enable_data(); } else { - log->error("Not handling AT command %s\n", at.GetString()); + logger.error("Not handling AT command %s", at.GetString()); } } diff --git a/srsue/test/ttcn3/src/CMakeLists.txt b/srsue/test/ttcn3/src/CMakeLists.txt index 93c067b00..d74ee6261 100644 --- a/srsue/test/ttcn3/src/CMakeLists.txt +++ b/srsue/test/ttcn3/src/CMakeLists.txt @@ -27,19 +27,18 @@ set(LINK_LIBRARIES srsue_stack srslte_upper srslte_common srslte_mac + srslte_mac srslte_phy srslte_radio srslte_upper srsue_phy srsue_mac + srsue_mac_nr rrc_asn1 + rrc_nr_asn1 sctp ${Boost_LIBRARIES}) -if (ENABLE_5GNR) - set(LINK_LIBRARIES ${LINK_LIBRARIES} rrc_nr_asn1 srsue_mac_nr srslte_mac) -endif (ENABLE_5GNR) - target_link_libraries(ttcn3_dut ${LINK_LIBRARIES}) include_directories(${PROJECT_SOURCE_DIR}/srsue/test/ttcn3/hdr) diff --git a/srsue/test/ttcn3/src/lte_ttcn3_phy.cc b/srsue/test/ttcn3/src/lte_ttcn3_phy.cc index 421a6df0b..6c4ef33b6 100644 --- a/srsue/test/ttcn3/src/lte_ttcn3_phy.cc +++ b/srsue/test/ttcn3/src/lte_ttcn3_phy.cc @@ -29,7 +29,7 @@ namespace srsue { #define SUITABLE_NEIGHBOR_INTRAFREQ_RS_EPRE (-91) #define DEFAULT_RSRQ (-3.0) -lte_ttcn3_phy::lte_ttcn3_phy(srslte::logger* logger_) : logger(logger_) {} +lte_ttcn3_phy::lte_ttcn3_phy() : logger(srslog::fetch_basic_logger("PHY")) {} int lte_ttcn3_phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_, syssim_interface_phy* syssim_) { @@ -47,8 +47,8 @@ int lte_ttcn3_phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_ // ue_phy_base interface int lte_ttcn3_phy::init(const phy_args_t& args_) { - log.init("PHY ", logger, true); - log.set_level(args_.log.phy_level); + logger.set_level(srslog::str_to_basic_level(args_.log.phy_level)); + logger.set_hex_dump_max_size(-1); return SRSLTE_SUCCESS; } @@ -72,29 +72,29 @@ void lte_ttcn3_phy::set_config_tdd(srslte_tdd_config_t& tdd_config) {} void lte_ttcn3_phy::enable_pregen_signals(bool enable) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } void lte_ttcn3_phy::deactivate_scells() { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } void lte_ttcn3_phy::set_activation_deactivation_scell(uint32_t cmd, uint32_t tti) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } bool lte_ttcn3_phy::set_config(srslte::phy_cfg_t config, uint32_t cc_idx_) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); task_sched.defer_task([this]() { stack->set_config_complete(true); }); return true; } bool lte_ttcn3_phy::set_scell(srslte_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); task_sched.defer_task([this]() { stack->set_scell_complete(true); }); return true; } @@ -111,7 +111,7 @@ bool lte_ttcn3_phy::cell_search() { std::lock_guard lock(mutex); - log.info("Running cell search in PHY\n"); + logger.info("Running cell search in PHY"); rrc_interface_phy_lte::cell_search_ret_t ret = {}; ret.found = rrc_interface_phy_lte::cell_search_ret_t::CELL_NOT_FOUND; @@ -120,10 +120,10 @@ bool lte_ttcn3_phy::cell_search() if (not cells.empty() && cell_idx < cells.size()) { // only find suitable cells if (cells[cell_idx].power >= SUITABLE_CELL_RS_EPRE) { - log.info("Found Cell: EARFCN=%d CellId=%d power=%.2f\n", - cells[cell_idx].earfcn, - cells[cell_idx].info.id, - cells[cell_idx].power); + logger.info("Found Cell: EARFCN=%d CellId=%d power=%.2f", + cells[cell_idx].earfcn, + cells[cell_idx].info.id, + cells[cell_idx].power); found_cell.earfcn = cells[cell_idx].earfcn; found_cell.pci = cells[cell_idx].info.id; ret.found = rrc_interface_phy_lte::cell_search_ret_t::CELL_FOUND; @@ -141,7 +141,7 @@ bool lte_ttcn3_phy::cell_search() cell_idx = 0; } } else { - log.warning("No cells configured yet.\n"); + logger.warning("No cells configured yet."); } stack->cell_search_complete(ret, found_cell); @@ -158,10 +158,10 @@ bool lte_ttcn3_phy::cell_select(phy_cell_t rrc_cell) pcell = cell; pcell_set = true; syssim->select_cell(pcell.info); - log.info("Select PCell with %.2f on PCI=%d on EARFCN=%d.\n", cell.power, rrc_cell.pci, rrc_cell.earfcn); + logger.info("Select PCell with %.2f on PCI=%d on EARFCN=%d.", cell.power, rrc_cell.pci, rrc_cell.earfcn); } else { pcell_set = false; - log.error("Power of selected cell too low (%.2f < %.2f)\n", cell.power, SUITABLE_CELL_RS_EPRE); + logger.error("Power of selected cell too low (%.2f < %.2f)", cell.power, SUITABLE_CELL_RS_EPRE); } stack->cell_select_complete(pcell_set); @@ -169,14 +169,14 @@ bool lte_ttcn3_phy::cell_select(phy_cell_t rrc_cell) } } - log.error("Couldn't find RRC cell with PCI=%d on EARFCN=%d in cell map.\n", rrc_cell.pci, rrc_cell.earfcn); + logger.error("Couldn't find RRC cell with PCI=%d on EARFCN=%d in cell map.", rrc_cell.pci, rrc_cell.earfcn); return false; } bool lte_ttcn3_phy::cell_is_camping() { if (pcell_set) { - log.info("pcell.power=%2.f\n", pcell.power); + logger.info("pcell.power=%2.f", pcell.power); return (pcell.power >= SUITABLE_CELL_RS_EPRE); } return false; @@ -187,7 +187,7 @@ bool lte_ttcn3_phy::cell_is_camping() void lte_ttcn3_phy::prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm, float ta_base_sec) { std::lock_guard lock(mutex); - log.info("Sending PRACH with preamble %d on PCID=%d\n", preamble_idx, pcell.info.id); + logger.info("Sending PRACH with preamble %d on PCID=%d", preamble_idx, pcell.info.id); prach_tti_tx = current_tti; ra_trans_cnt++; @@ -227,25 +227,25 @@ int lte_ttcn3_phy::sr_last_tx_tti() /* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */ void lte_ttcn3_phy::set_crnti(uint16_t rnti) { - log.debug("Set Temp-RNTI=%d, pregen not used\n", rnti); + logger.debug("Set Temp-RNTI=%d, pregen not used", rnti); } /* Time advance commands */ void lte_ttcn3_phy::set_timeadv_rar(uint32_t ta_cmd) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } void lte_ttcn3_phy::set_timeadv(uint32_t ta_cmd) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } // Sets RAR grant payload void lte_ttcn3_phy::set_rar_grant(uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN], uint16_t rnti) { // Empty, SYSSIM knows when to provide UL grant for Msg3 - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } // Called from the SYSSIM to configure the current TTI @@ -265,13 +265,13 @@ uint32_t lte_ttcn3_phy::get_current_tti() float lte_ttcn3_phy::get_phr() { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); return 0.1; } float lte_ttcn3_phy::get_pathloss_db() { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); return 85.0; } @@ -298,7 +298,7 @@ void lte_ttcn3_phy::new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t dl std::lock_guard lock(mutex); if (data == nullptr) { - log.error("Invalid data buffer passed\n"); + logger.error("Invalid data buffer passed"); return; } @@ -310,15 +310,15 @@ void lte_ttcn3_phy::new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t dl bool dl_ack[SRSLTE_MAX_CODEWORDS] = {}; if (dl_action.tb[0].enabled && dl_action.tb[0].payload != nullptr) { - log.info_hex(data, - dl_grant.tb[0].tbs, - "TB received rnti=%d, tti=%d, n_bytes=%d\n", - dl_grant.rnti, - current_tti, - dl_grant.tb[0].tbs); + logger.info(data, + dl_grant.tb[0].tbs, + "TB received rnti=%d, tti=%d, n_bytes=%d", + dl_grant.rnti, + current_tti, + dl_grant.tb[0].tbs); if (dl_action.generate_ack) { - log.debug("Calling generate ACK callback\n"); + logger.debug("Calling generate ACK callback"); // action.generate_ack_callback(action.generate_ack_callback_arg); } memcpy(dl_action.tb->payload, data, dl_grant.tb[0].tbs); @@ -326,9 +326,9 @@ void lte_ttcn3_phy::new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t dl // ACK first TB and pass up dl_ack[0] = true; - log.info("TB processed correctly\n"); + logger.info("TB processed correctly"); } else { - log.error("Couldn't get buffer for TB\n"); + logger.error("Couldn't get buffer for TB"); } stack->tb_decoded(cc_idx, dl_grant, dl_ack); @@ -336,12 +336,12 @@ void lte_ttcn3_phy::new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t dl void lte_ttcn3_phy::radio_overflow() { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } void lte_ttcn3_phy::radio_failure() { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } // Calling function set_tti() is holding mutex @@ -352,17 +352,17 @@ void lte_ttcn3_phy::run_tti() for (auto& cell : cells) { if (cell.power >= NON_SUITABLE_CELL_RS_EPRE) { phy_meas_t m = {}; - m.pci = cell.info.id; - m.earfcn = cell.earfcn; - m.rsrp = cell.power; - m.rsrq = DEFAULT_RSRQ; + m.pci = cell.info.id; + m.earfcn = cell.earfcn; + m.rsrp = cell.power; + m.rsrq = DEFAULT_RSRQ; // Measurement for PCell needs to have EARFCN set to 0 if (pcell_set && m.earfcn == pcell.earfcn && m.pci == pcell.info.id) { - log.debug("Creating Pcell measurement for PCI=%d, EARFCN=%d with RSRP=%.2f\n", m.pci, m.earfcn, m.rsrp); + logger.debug("Creating Pcell measurement for PCI=%d, EARFCN=%d with RSRP=%.2f", m.pci, m.earfcn, m.rsrp); m.earfcn = 0; } else { - log.debug("Create cell measurement for PCI=%d, EARFCN=%d with RSRP=%.2f\n", m.pci, m.earfcn, m.rsrp); + logger.debug("Create cell measurement for PCI=%d, EARFCN=%d with RSRP=%.2f", m.pci, m.earfcn, m.rsrp); } phy_meas.push_back(m); } @@ -378,10 +378,10 @@ void lte_ttcn3_phy::run_tti() if (cell.info.id == pcell.info.id) { // consider Pcell in-sync until reaching threshold if (cell.power >= NON_SUITABLE_CELL_RS_EPRE) { - log.debug("PCell id=%d power=%.2f -> sync\n", pcell.info.id, cell.power); + logger.debug("PCell id=%d power=%.2f -> sync", pcell.info.id, cell.power); stack->in_sync(); } else { - log.debug("PCell id=%d power=%.2f -> out of sync\n", pcell.info.id, cell.power); + logger.debug("PCell id=%d power=%.2f -> out of sync", pcell.info.id, cell.power); stack->out_of_sync(); } break; // make sure to call stack only once @@ -389,7 +389,7 @@ void lte_ttcn3_phy::run_tti() } } - log.step(current_tti); + logger.set_context(current_tti); // Check for SR if (sr_pending) { @@ -403,7 +403,7 @@ void lte_ttcn3_phy::run_tti() void lte_ttcn3_phy::set_cells_to_meas(uint32_t earfcn, const std::set& pci) { - log.debug("%s not implemented.\n", __FUNCTION__); + logger.debug("%s not implemented.", __FUNCTION__); } } // namespace srsue diff --git a/srsue/test/ttcn3/src/ttcn3_syssim.cc b/srsue/test/ttcn3/src/ttcn3_syssim.cc index ad005e341..07e30c45a 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -39,19 +39,34 @@ #include ttcn3_syssim::ttcn3_syssim(srslte::logger& logger_file_, srslte::logger& logger_stdout_, ttcn3_ue* ue_) : + logger(srslog::fetch_basic_logger("SS")), + ut_logger(srslog::fetch_basic_logger("UT", false)), + sys_logger(srslog::fetch_basic_logger("SYS", false)), + ip_sock_logger(srslog::fetch_basic_logger("IP_S", false)), + ip_ctrl_logger(srslog::fetch_basic_logger("IP_C", false)), + srb_logger(srslog::fetch_basic_logger("SRB", false)), + drb_logger(srslog::fetch_basic_logger("DRB", false)), + ss_mac_logger(srslog::fetch_basic_logger("SS-MAC", false)), + ss_rlc_logger(srslog::fetch_basic_logger("SS-RLC", false)), + ss_pdcp_logger(srslog::fetch_basic_logger("SS-PDCP", false)), + ut(ut_logger), + sys(sys_logger), + ip_sock(ip_sock_logger), + ip_ctrl(ip_ctrl_logger), + srb(srb_logger), + drb(drb_logger), log{"SS "}, - mac_msg_ul(20, ss_mac_log), - mac_msg_dl(20, ss_mac_log), - pdus(128), + mac_msg_ul(20, ss_mac_logger), + mac_msg_dl(20, ss_mac_logger), + pdus(logger, 128), logger_stdout(logger_stdout_), logger_file(logger_file_), - logger(&logger_file), - pool(byte_buffer_pool::get_instance()), + old_logger(&logger_file), ue(ue_), signal_handler(&running), timer_handler(create_tti_timer(), [&](uint64_t res) { new_tti_indication(res); }) { - if (ue->init(all_args_t{}, logger, this, "INIT_TEST") != SRSLTE_SUCCESS) { + if (ue->init(all_args_t{}, old_logger, this, "INIT_TEST") != SRSLTE_SUCCESS) { ue->stop(); fprintf(stderr, "Couldn't initialize UE.\n"); } @@ -65,66 +80,78 @@ int ttcn3_syssim::init(const all_args_t& args_) // Make sure to get SS logging as well if (args.log.filename == "stdout") { - logger = &logger_stdout; + old_logger = &logger_stdout; + auto* swp_sink = srslog::find_sink(swappable_sink::name()); + if (!swp_sink) { + logger.error("Unable to find the swappable sink"); + srslte::console("Unable to find the swappable sink\n"); + return SRSLTE_ERROR; + } + static_cast(swp_sink)->swap_to_stdout(); } - srslte::logmap::set_default_logger(logger); + srslte::logmap::set_default_logger(old_logger); // init and configure logging - srslte::logmap::register_log(std::unique_ptr{new log_filter{"SS ", logger, true}}); - ut_log.init("UT ", logger); - sys_log.init("SYS ", logger); - ip_sock_log.init("IP_S", logger); - ip_ctrl_log.init("IP_C", logger); - srb_log.init("SRB ", logger); - drb_log.init("DRB ", logger); - srslte::logmap::register_log(std::unique_ptr{new log_filter{"SS-RLC", logger}}); - srslte::logmap::register_log(std::unique_ptr{new log_filter{"SS-PDCP", logger}}); + srslte::logmap::register_log(std::unique_ptr{new log_filter{"SS ", old_logger, true}}); + srslte::logmap::register_log(std::unique_ptr{new log_filter{"SS-RLC", old_logger}}); + srslte::logmap::register_log(std::unique_ptr{new log_filter{"SS-PDCP", old_logger}}); log->set_level(args.log.all_level); - ut_log.set_level(args.log.all_level); - sys_log.set_level(args.log.all_level); - ip_sock_log.set_level(args.log.all_level); - ip_ctrl_log.set_level(args.log.all_level); - srb_log.set_level(args.log.all_level); - drb_log.set_level(args.log.all_level); ss_mac_log->set_level(args.log.all_level); ss_rlc_log->set_level(args.log.all_level); ss_pdcp_log->set_level(args.log.all_level); + auto logger_lvl = srslog::str_to_basic_level(args.log.all_level); + logger.set_level(logger_lvl); + ut_logger.set_level(logger_lvl); + sys_logger.set_level(logger_lvl); + ip_sock_logger.set_level(logger_lvl); + ip_ctrl_logger.set_level(logger_lvl); + srb_logger.set_level(logger_lvl); + drb_logger.set_level(logger_lvl); + ss_mac_logger.set_level(logger_lvl); + ss_rlc_logger.set_level(logger_lvl); + ss_pdcp_logger.set_level(logger_lvl); + log->set_hex_limit(args.log.all_hex_limit); - ut_log.set_hex_limit(args.log.all_hex_limit); - sys_log.set_hex_limit(args.log.all_hex_limit); - ip_sock_log.set_hex_limit(args.log.all_hex_limit); - ip_ctrl_log.set_hex_limit(args.log.all_hex_limit); - srb_log.set_hex_limit(args.log.all_hex_limit); - drb_log.set_hex_limit(args.log.all_hex_limit); ss_mac_log->set_hex_limit(args.log.all_hex_limit); ss_rlc_log->set_hex_limit(args.log.all_hex_limit); ss_pdcp_log->set_hex_limit(args.log.all_hex_limit); + logger.set_hex_dump_max_size(args.log.all_hex_limit); + ut_logger.set_hex_dump_max_size(args.log.all_hex_limit); + sys_logger.set_hex_dump_max_size(args.log.all_hex_limit); + ip_sock_logger.set_hex_dump_max_size(args.log.all_hex_limit); + ip_ctrl_logger.set_hex_dump_max_size(args.log.all_hex_limit); + srb_logger.set_hex_dump_max_size(args.log.all_hex_limit); + drb_logger.set_hex_dump_max_size(args.log.all_hex_limit); + ss_mac_logger.set_hex_dump_max_size(args.log.all_hex_limit); + ss_rlc_logger.set_hex_dump_max_size(args.log.all_hex_limit); + ss_pdcp_logger.set_hex_dump_max_size(args.log.all_hex_limit); + // Init epoll socket and add FDs epoll_fd = epoll_create1(0); if (epoll_fd == -1) { - log->error("Error creating epoll\n"); + logger.error("Error creating epoll"); return SRSLTE_ERROR; } // add signalfd signal_fd = add_signalfd(); if (add_epoll(signal_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding signalfd to epoll\n"); + logger.error("Error while adding signalfd to epoll"); return SRSLTE_ERROR; } event_handler.insert({signal_fd, &signal_handler}); // init system interfaces to tester if (add_port_handler() != SRSLTE_SUCCESS) { - log->error("Error creating port handlers\n"); + logger.error("Error creating port handlers"); return SRSLTE_ERROR; } // Init common SS layers - pdus.init(this, log); + pdus.init(this); return SRSLTE_SUCCESS; } @@ -137,54 +164,54 @@ void ttcn3_syssim::set_forced_lcid(int lcid) int ttcn3_syssim::add_port_handler() { // UT port - int ut_fd = ut.init(this, &ut_log, listen_address, UT_PORT); + int ut_fd = ut.init(this, listen_address, UT_PORT); if (add_epoll(ut_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding UT port to epoll\n"); + logger.error("Error while adding UT port to epoll"); return SRSLTE_ERROR; } event_handler.insert({ut_fd, &ut}); srslte::console("UT handler listening on SCTP port %d\n", UT_PORT); // SYS port - int sys_fd = sys.init(this, &sys_log, listen_address, SYS_PORT); + int sys_fd = sys.init(this, listen_address, SYS_PORT); if (add_epoll(sys_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding SYS port to epoll\n"); + logger.error("Error while adding SYS port to epoll"); return SRSLTE_ERROR; } event_handler.insert({sys_fd, &sys}); srslte::console("SYS handler listening on SCTP port %d\n", SYS_PORT); // IPsock port - int ip_sock_fd = ip_sock.init(&ip_sock_log, listen_address, IPSOCK_PORT); + int ip_sock_fd = ip_sock.init(listen_address, IPSOCK_PORT); if (add_epoll(ip_sock_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding IP sock port to epoll\n"); + logger.error("Error while adding IP sock port to epoll"); return SRSLTE_ERROR; } event_handler.insert({ip_sock_fd, &ip_sock}); srslte::console("IPSOCK handler listening on SCTP port %d\n", IPSOCK_PORT); // IPctrl port - int ip_ctrl_fd = ip_ctrl.init(&ip_ctrl_log, listen_address, IPCTRL_PORT); + int ip_ctrl_fd = ip_ctrl.init(listen_address, IPCTRL_PORT); if (add_epoll(ip_ctrl_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding IP ctrl port to epoll\n"); + logger.error("Error while adding IP ctrl port to epoll"); return SRSLTE_ERROR; } event_handler.insert({ip_ctrl_fd, &ip_ctrl}); srslte::console("IPCTRL handler listening on SCTP port %d\n", IPCTRL_PORT); // add SRB fd - int srb_fd = srb.init(this, &srb_log, listen_address, SRB_PORT); + int srb_fd = srb.init(this, listen_address, SRB_PORT); if (add_epoll(srb_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding SRB port to epoll\n"); + logger.error("Error while adding SRB port to epoll"); return SRSLTE_ERROR; } event_handler.insert({srb_fd, &srb}); srslte::console("SRB handler listening on SCTP port %d\n", SRB_PORT); // add DRB fd - int drb_fd = drb.init(this, &drb_log, listen_address, DRB_PORT); + int drb_fd = drb.init(this, listen_address, DRB_PORT); if (add_epoll(drb_fd, epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding DRB port to epoll\n"); + logger.error("Error while adding DRB port to epoll"); return SRSLTE_ERROR; } event_handler.insert({drb_fd, &drb}); @@ -199,7 +226,8 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) tti = (tti + 1) % 10240; log->step(tti); - log->debug("Start TTI\n"); + logger.set_context(tti); + logger.debug("Start TTI"); // Make sure to step SS step_stack(); @@ -210,7 +238,7 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) // check scheduled actions for this TTI if (tti_actions.find(tti) != tti_actions.end()) { while (!tti_actions[tti].empty()) { - log->debug("Running scheduled action\n"); + logger.debug("Running scheduled action"); move_task_t task = std::move(tti_actions[tti].front()); task(); tti_actions[tti].pop(); @@ -241,7 +269,7 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) } if (pcell_idx == -1) { - log->debug("Skipping TTI. Pcell not yet selected.\n"); + logger.debug("Skipping TTI. Pcell not yet selected."); return; } @@ -256,7 +284,7 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) dl_grant.tb[0].tbs = cells[pcell_idx]->sibs[cells[pcell_idx]->sib_idx]->N_bytes; dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti); ue->new_tb(dl_grant, cells[pcell_idx]->sibs[cells[pcell_idx]->sib_idx]->msg); - log->info("Delivered SIB%d for pcell_idx=%d\n", cells[pcell_idx]->sib_idx, pcell_idx); + logger.info("Delivered SIB%d for pcell_idx=%d", cells[pcell_idx]->sib_idx, pcell_idx); cells[pcell_idx]->sib_idx = (cells[pcell_idx]->sib_idx + 1) % cells[pcell_idx]->sibs.size(); } else if (SRSLTE_RNTI_ISRAR(dl_rnti)) { if (prach_tti != -1) { @@ -266,12 +294,12 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) } } } else if (SRSLTE_RNTI_ISPA(dl_rnti)) { - log->debug("Searching for paging RNTI\n"); + logger.debug("Searching for paging RNTI"); // PCH will be triggered from SYSSIM after receiving Paging } else if (SRSLTE_RNTI_ISUSER(dl_rnti)) { // check if this is for contention resolution after PRACH/RAR if (dl_rnti == cells[pcell_idx]->config.crnti) { - log->debug("Searching for C-RNTI=0x%x\n", dl_rnti); + logger.debug("Searching for C-RNTI=0x%x", dl_rnti); if (rar_tti != -1) { msg3_tti = (rar_tti + 3) % 10240; @@ -288,7 +316,7 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) } if (dl_rnti != SRSLTE_INVALID_RNTI) { - log->debug("Searching for RNTI=0x%x\n", dl_rnti); + logger.debug("Searching for RNTI=0x%x", dl_rnti); // look for DL data to be send in each bearer and provide grant accordingly for (int lcid = 0; lcid < SRSLTE_N_RADIO_BEARERS; lcid++) { @@ -296,7 +324,7 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) // Schedule DL transmission if there is data in RLC buffer or we need to send Msg4 if ((buf_state > 0 && cells[pcell_idx]->bearer_follow_on_map[lcid] == false) || (msg3_tti != -1 && conres_id != 0)) { - log->debug("LCID=%d, buffer_state=%d\n", lcid, buf_state); + logger.debug("LCID=%d, buffer_state=%d", lcid, buf_state); tx_payload_buffer.clear(); const uint32_t mac_header_size = 10; // Add MAC header (10 B for all subheaders, etc) @@ -306,13 +334,13 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) if (msg3_tti != -1 && lcid == 0 && conres_id != 0) { if (mac_msg_dl.new_subh()) { if (mac_msg_dl.get()->set_con_res_id(conres_id)) { - log->info("CE: Added Contention Resolution ID=0x%" PRIx64 "\n", conres_id); + logger.info("CE: Added Contention Resolution ID=0x%" PRIx64 "", conres_id); } else { - log->error("CE: Setting Contention Resolution ID CE\n"); + logger.error("CE: Setting Contention Resolution ID CE"); } conres_id = 0; // reset CR so it's not sent twice } else { - log->error("CE: Setting Contention Resolution ID CE. No space for a subheader\n"); + logger.error("CE: Setting Contention Resolution ID CE. No space for a subheader"); } msg3_tti = -1; } @@ -324,7 +352,7 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) if (mac_msg_dl.new_subh()) { int n = mac_msg_dl.get()->set_sdu(lcid, buf_state, &cells[pcell_idx]->rlc); if (n == -1) { - log->error("Error while adding SDU (%d B) to MAC PDU\n", buf_state); + logger.error("Error while adding SDU (%d B) to MAC PDU", buf_state); mac_msg_dl.del_subh(); } @@ -340,18 +368,18 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) } // Assemble entire MAC PDU - uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(log); + uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(logger); if (mac_pdu_ptr != nullptr) { if (force_lcid != -1 && lcid == 0) { if (has_single_sdu) { - log->info("Patched lcid in mac header to: %d\n", force_lcid); + logger.info("Patched lcid in mac header to: %d", force_lcid); mac_pdu_ptr[0] = (mac_pdu_ptr[0] & 0xe0) | (force_lcid & 0x1f); } else if (mac_msg_dl.nof_subh() > 1) { - log->warning( - "Not patching lcid to %d in mac header (nof_subh == %d)\n", force_lcid, mac_msg_dl.nof_subh()); + logger.warning( + "Not patching lcid to %d in mac header (nof_subh == %d)", force_lcid, mac_msg_dl.nof_subh()); } } - log->info_hex(mac_pdu_ptr, mac_msg_dl.get_pdu_len(), "DL MAC PDU (%d B):\n", mac_msg_dl.get_pdu_len()); + logger.info(mac_pdu_ptr, mac_msg_dl.get_pdu_len(), "DL MAC PDU (%d B):", mac_msg_dl.get_pdu_len()); // Prepare MAC grant for CCCH mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; @@ -364,18 +392,18 @@ void ttcn3_syssim::new_tti_indication(uint64_t res) ue->new_tb(dl_grant, (const uint8_t*)mac_pdu_ptr); } else { - log->error("Error writing DL MAC PDU\n"); + logger.error("Error writing DL MAC PDU"); } mac_msg_dl.reset(); } else if (cells[pcell_idx]->bearer_follow_on_map[lcid]) { - log->info("Waiting for more PDUs for transmission on LCID=%d\n", lcid); + logger.info("Waiting for more PDUs for transmission on LCID=%d", lcid); } } // Check if we need to provide a UL grant as well } } else { - log->debug("Not handling RNTI=%d\n", dl_rnti); + logger.debug("Not handling RNTI=%d", dl_rnti); } } @@ -387,7 +415,7 @@ void ttcn3_syssim::stop() void ttcn3_syssim::reset() { - log->info("Resetting SS\n"); + logger.info("Resetting SS"); cells.clear(); pcell_idx = -1; } @@ -401,22 +429,24 @@ void ttcn3_syssim::tc_start(const char* name) // Make a copy of the UE args for this run all_args_t local_args = args; - // set up logging - if (args.log.filename == "stdout") { - logger = &logger_stdout; - } else { - const std::string& file_tc_name = get_filename_with_tc_name(local_args.log.filename, run_id, tc_name); - auto* swp_sink = srslog::find_sink(swappable_sink::name()); - if (!swp_sink) { - log->error("Unable to find the swappable sink\n"); - srslte::console("Unable to find the swappable sink\n"); - return; - } - static_cast(swp_sink)->swap_sink(file_tc_name); - logger = &logger_file; + auto* swp_sink = srslog::find_sink(swappable_sink::name()); + if (!swp_sink) { + logger.error("Unable to find the swappable sink"); + srslte::console("Unable to find the swappable sink\n"); + return; } - log->info("Initializing UE ID=%d for TC=%s\n", run_id, tc_name.c_str()); + // set up logging + if (args.log.filename == "stdout") { + old_logger = &logger_stdout; + static_cast(swp_sink)->swap_to_stdout(); + } else { + const std::string& file_tc_name = get_filename_with_tc_name(local_args.log.filename, run_id, tc_name); + static_cast(swp_sink)->swap_sink(file_tc_name); + old_logger = &logger_file; + } + + logger.info("Initializing UE ID=%d for TC=%s", run_id, tc_name.c_str()); srslte::console("Initializing UE ID=%d for TC=%s\n", run_id, tc_name.c_str()); // Patch UE config @@ -424,17 +454,17 @@ void ttcn3_syssim::tc_start(const char* name) local_args.stack.pcap.nas_filename = get_filename_with_tc_name(args.stack.pcap.nas_filename, run_id, tc_name); // bring up UE - if (ue->init(local_args, logger, this, tc_name)) { + if (ue->init(local_args, old_logger, this, tc_name)) { ue->stop(); - std::string err("Couldn't initialize UE.\n"); - log->error("%s\n", err.c_str()); + std::string err("Couldn't initialize UE."); + logger.error("%s", err.c_str()); srslte::console("%s\n", err.c_str()); return; } // create and add TTI timer to epoll if (add_epoll(timer_handler.get_timer_fd(), epoll_fd) != SRSLTE_SUCCESS) { - log->error("Error while adding TTI timer to epoll\n"); + logger.error("Error while adding TTI timer to epoll"); } event_handler.insert({timer_handler.get_timer_fd(), &timer_handler}); } @@ -442,7 +472,7 @@ void ttcn3_syssim::tc_start(const char* name) // Called from UT to terminate the testcase void ttcn3_syssim::tc_end() { - log->info("Deinitializing UE ID=%d\n", run_id); + logger.info("Deinitializing UE ID=%d", run_id); srslte::console("Deinitializing UE ID=%d\n", run_id); ue->stop(); @@ -486,8 +516,8 @@ void ttcn3_syssim::prach_indication(uint32_t preamble_index_, const uint32_t& ce { // verify that UE intends to send PRACH on current Pcell if (cells[pcell_idx]->config.phy_cell.id != cell_id) { - log->error( - "UE is attempting to PRACH on pci=%d, current Pcell=%d\n", cell_id, cells[pcell_idx]->config.phy_cell.id); + logger.error( + "UE is attempting to PRACH on pci=%d, current Pcell=%d", cell_id, cells[pcell_idx]->config.phy_cell.id); return; } @@ -499,7 +529,7 @@ void ttcn3_syssim::prach_indication(uint32_t preamble_index_, const uint32_t& ce // Called from PHY void ttcn3_syssim::sr_req(uint32_t tti_tx) { - log->info("Received SR from PHY\n"); + logger.info("Received SR from PHY"); sr_tti = tti_tx; } @@ -507,16 +537,16 @@ void ttcn3_syssim::sr_req(uint32_t tti_tx) void ttcn3_syssim::tx_pdu(const uint8_t* payload, const int len, const uint32_t tx_tti) { if (payload == NULL) { - ss_mac_log->error("Received NULL as PDU payload. Dropping.\n"); + ss_mac_logger.error("Received NULL as PDU payload. Dropping."); return; } if (pcell_idx == -1) { - log->debug("Skipping TTI. Pcell not yet selected.\n"); + logger.debug("Skipping TTI. Pcell not yet selected."); return; } - log->info_hex(payload, len, "UL MAC PDU (%d B):\n", len); + logger.info(payload, len, "UL MAC PDU (%d B):", len); // Parse MAC mac_msg_ul.init_rx(len, true); @@ -526,11 +556,11 @@ void ttcn3_syssim::tx_pdu(const uint8_t* payload, const int len, const uint32_t assert(mac_msg_ul.get()); if (mac_msg_ul.get()->is_sdu()) { // Push PDU to our own RLC (needed to handle status reporting, etc. correctly - ss_mac_log->info_hex(mac_msg_ul.get()->get_sdu_ptr(), - mac_msg_ul.get()->get_payload_size(), - "Route UL PDU to LCID=%d (%d B)\n", - mac_msg_ul.get()->get_sdu_lcid(), - mac_msg_ul.get()->get_payload_size()); + ss_mac_logger.info(mac_msg_ul.get()->get_sdu_ptr(), + mac_msg_ul.get()->get_payload_size(), + "Route UL PDU to LCID=%d (%d B)", + mac_msg_ul.get()->get_sdu_lcid(), + mac_msg_ul.get()->get_payload_size()); cells[pcell_idx]->rlc.write_pdu( mac_msg_ul.get()->get_sdu_lcid(), mac_msg_ul.get()->get_sdu_ptr(), mac_msg_ul.get()->get_payload_size()); @@ -543,10 +573,10 @@ void ttcn3_syssim::tx_pdu(const uint8_t* payload, const int len, const uint32_t for (int i = 0; i < nbytes; i++) { ue_cri_ptr[nbytes - i - 1] = pkt_ptr[i]; } - ss_mac_log->info_hex(ue_cri_ptr, nbytes, "Contention resolution ID:\n"); + ss_mac_logger.info(ue_cri_ptr, nbytes, "Contention resolution ID:"); } else { - ss_mac_log->error("Received CCCH UL message of invalid size=%d bytes\n", - mac_msg_ul.get()->get_payload_size()); + ss_mac_logger.error("Received CCCH UL message of invalid size=%d bytes", + mac_msg_ul.get()->get_payload_size()); } } } @@ -567,7 +597,7 @@ void ttcn3_syssim::tx_pdu(const uint8_t* payload, const int len, const uint32_t // Internal function called from main thread void ttcn3_syssim::send_rar(uint32_t preamble_index) { - log->info("Sending RAR for RAPID=%d\n", preamble_index); + logger.info("Sending RAR for RAPID=%d", preamble_index); // Prepare RAR grant uint8_t grant_buffer[64] = {}; @@ -609,7 +639,7 @@ void ttcn3_syssim::send_rar(uint32_t preamble_index) // Internal function called from main thread void ttcn3_syssim::send_msg3_grant() { - log->info("Sending Msg3 grant for C-RNTI=0x%x\n", cells[pcell_idx]->config.crnti); + logger.info("Sending Msg3 grant for C-RNTI=0x%x", cells[pcell_idx]->config.crnti); mac_interface_phy_lte::mac_grant_ul_t ul_grant = {}; ul_grant.tti_tx = (tti + 3) % 10240; @@ -654,41 +684,41 @@ bool ttcn3_syssim::process_ce(srslte::sch_subh* subh) switch (subh->ul_sch_ce_type()) { case srslte::ul_sch_lcid::PHR_REPORT: phr = subh->get_phr(); - ss_mac_log->info("CE: Received PHR from rnti=0x%x, value=%.0f\n", rnti, phr); + ss_mac_logger.info("CE: Received PHR from rnti=0x%x, value=%.0f", rnti, phr); break; case srslte::ul_sch_lcid::CRNTI: old_rnti = subh->get_c_rnti(); - ss_mac_log->info("CE: Received C-RNTI from temp_rnti=0x%x, rnti=0x%x\n", rnti, old_rnti); + ss_mac_logger.info("CE: Received C-RNTI from temp_rnti=0x%x, rnti=0x%x", rnti, old_rnti); break; case srslte::ul_sch_lcid::TRUNC_BSR: case srslte::ul_sch_lcid::SHORT_BSR: idx = subh->get_bsr(buff_size_idx, buff_size_bytes); if (idx == -1) { - ss_mac_log->error("Invalid Index Passed to lc groups\n"); + ss_mac_logger.error("Invalid Index Passed to lc groups"); break; } - ss_mac_log->info("CE: Received %s BSR rnti=0x%x, lcg=%d, value=%d\n", - subh->ul_sch_ce_type() == srslte::ul_sch_lcid::SHORT_BSR ? "Short" : "Trunc", - rnti, - idx, - buff_size_idx[idx]); + ss_mac_logger.info("CE: Received %s BSR rnti=0x%x, lcg=%d, value=%d", + subh->ul_sch_ce_type() == srslte::ul_sch_lcid::SHORT_BSR ? "Short" : "Trunc", + rnti, + idx, + buff_size_idx[idx]); is_bsr = true; break; case srslte::ul_sch_lcid::LONG_BSR: subh->get_bsr(buff_size_idx, buff_size_bytes); is_bsr = true; - ss_mac_log->info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n", - rnti, - buff_size_idx[0], - buff_size_idx[1], - buff_size_idx[2], - buff_size_idx[3]); + ss_mac_logger.info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d", + rnti, + buff_size_idx[0], + buff_size_idx[1], + buff_size_idx[2], + buff_size_idx[3]); break; case srslte::ul_sch_lcid::PADDING: - ss_mac_log->debug("CE: Received padding for rnti=0x%x\n", rnti); + ss_mac_logger.debug("CE: Received padding for rnti=0x%x", rnti); break; default: - ss_mac_log->error("CE: Invalid lcid=0x%x\n", subh->lcid_value()); + ss_mac_logger.error("CE: Invalid lcid=0x%x", subh->lcid_value()); break; } return is_bsr; @@ -704,7 +734,7 @@ bool ttcn3_syssim::get_ndi_for_new_ul_tx(const uint32_t tti_) // toggle NDI to always create new Tx const uint32_t pid = get_pid(tti_); last_ul_ndi[pid] = !last_ul_ndi[pid]; - log->info("UL-PID=%d NDI=%s\n", pid, last_ul_ndi[pid] ? "1" : "0"); + logger.info("UL-PID=%d NDI=%s", pid, last_ul_ndi[pid] ? "1" : "0"); return last_ul_ndi[pid]; } @@ -713,7 +743,7 @@ bool ttcn3_syssim::get_ndi_for_new_dl_tx(const uint32_t tti_) // toggle NDI to always create new Tx const uint32_t pid = get_pid(tti_); last_dl_ndi[pid] = !last_dl_ndi[pid]; - log->info("DL-PID=%d NDI=%s\n", pid, last_dl_ndi[pid] ? "1" : "0"); + logger.info("DL-PID=%d NDI=%s", pid, last_dl_ndi[pid] ? "1" : "0"); return last_dl_ndi[pid]; } @@ -767,7 +797,7 @@ void ttcn3_syssim::set_cell_config(const ttcn3_helpers::timing_info_t timing, co if (timing.now) { set_cell_config_impl(cell); } else { - log->debug("Scheduling Cell configuration of %s for TTI=%d\n", cell.name.c_str(), timing.tti); + logger.debug("Scheduling Cell configuration of %s for TTI=%d", cell.name.c_str(), timing.tti); tti_actions[timing.tti].push([this, cell]() { set_cell_config_impl(cell); }); } } @@ -777,10 +807,10 @@ void ttcn3_syssim::set_cell_config_impl(const cell_config_t config) // check if cell already exists if (not syssim_has_cell(config.name)) { // insert new cell - log->info("Adding cell %s with cellId=%d and initial_power=%.2f dBm\n", - config.name.c_str(), - config.phy_cell.id, - config.initial_power); + logger.info("Adding cell %s with cellId=%d and initial_power=%.2f dBm", + config.name.c_str(), + config.phy_cell.id, + config.initial_power); unique_syssim_cell_t cell = unique_syssim_cell_t(new syssim_cell_t(this)); cell->config = config; @@ -791,7 +821,7 @@ void ttcn3_syssim::set_cell_config_impl(const cell_config_t config) cells.push_back(std::move(cell)); } else { // cell is already there - log->info("Cell already there, reconfigure\n"); + logger.info("Cell already there, reconfigure"); // We only support (Temp-)CRNTI reconfiguration syssim_cell_t* ss_cell = get_cell(config.name); if (config.crnti > 0) { @@ -833,7 +863,7 @@ void ttcn3_syssim::set_cell_attenuation(const ttcn3_helpers::timing_info_t timin if (timing.now) { set_cell_attenuation_impl(cell_name, value); } else { - log->debug("Scheduling Cell attenuation reconfiguration of %s for TTI=%d\n", cell_name.c_str(), timing.tti); + logger.debug("Scheduling Cell attenuation reconfiguration of %s for TTI=%d", cell_name.c_str(), timing.tti); tti_actions[timing.tti].push([this, cell_name, value]() { set_cell_attenuation_impl(cell_name, value); }); } } @@ -841,7 +871,7 @@ void ttcn3_syssim::set_cell_attenuation(const ttcn3_helpers::timing_info_t timin void ttcn3_syssim::set_cell_attenuation_impl(const std::string cell_name, const float value) { if (not syssim_has_cell(cell_name)) { - log->error("Can't set cell power. Cell not found.\n"); + logger.error("Can't set cell power. Cell not found."); return; } @@ -862,7 +892,7 @@ void ttcn3_syssim::update_cell_map() phy_cell.info = ss_cell->config.phy_cell; phy_cell.power = ss_cell->config.initial_power - ss_cell->config.attenuation; phy_cell.earfcn = ss_cell->config.earfcn; - log->info("Configuring cell with PCI=%d with TxPower=%.2f\n", phy_cell.info.id, phy_cell.power); + logger.info("Configuring cell with PCI=%d with TxPower=%.2f", phy_cell.info.id, phy_cell.power); phy_cells.push_back(phy_cell); } @@ -878,7 +908,7 @@ bool ttcn3_syssim::have_valid_pcell() void ttcn3_syssim::add_bcch_dlsch_pdu(const string cell_name, unique_byte_buffer_t pdu) { if (not syssim_has_cell(cell_name)) { - log->error("Can't add BCCH to cell. Cell not found.\n"); + logger.error("Can't add BCCH to cell. Cell not found."); return; } @@ -894,7 +924,7 @@ void ttcn3_syssim::add_ccch_pdu(const ttcn3_helpers::timing_info_t timing, // Add to SRB0 Tx queue add_ccch_pdu_impl(cell_name, std::move(pdu)); } else { - log->debug("Scheduling CCCH PDU for TTI=%d\n", timing.tti); + logger.debug("Scheduling CCCH PDU for TTI=%d", timing.tti); auto task = [this, cell_name](srslte::unique_byte_buffer_t& pdu) { add_ccch_pdu_impl(cell_name, std::move(pdu)); }; tti_actions[timing.tti].push(std::bind(task, std::move(pdu))); } @@ -903,7 +933,7 @@ void ttcn3_syssim::add_ccch_pdu(const ttcn3_helpers::timing_info_t timing, void ttcn3_syssim::add_ccch_pdu_impl(const std::string cell_name, unique_byte_buffer_t pdu) { if (not syssim_has_cell(cell_name)) { - log->error("Can't add CCCH to cell. Cell not found.\n"); + logger.error("Can't add CCCH to cell. Cell not found."); return; } @@ -921,7 +951,7 @@ void ttcn3_syssim::add_dcch_pdu(const ttcn3_helpers::timing_info_t timing, if (timing.now) { add_dcch_pdu_impl(cell_name, lcid, std::move(pdu), follow_on_flag); } else { - log->debug("Scheduling DCCH PDU for TTI=%d\n", timing.tti); + logger.debug("Scheduling DCCH PDU for TTI=%d", timing.tti); auto task = [this, cell_name](uint32_t lcid, srslte::unique_byte_buffer_t& pdu, bool follow_on_flag) { add_dcch_pdu_impl(cell_name, lcid, std::move(pdu), follow_on_flag); }; @@ -935,21 +965,21 @@ void ttcn3_syssim::add_dcch_pdu_impl(const std::string cell_name, bool follow_on_flag) { if (not syssim_has_cell(cell_name)) { - log->error("Can't add CCCH to cell. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't add CCCH to cell. Cell %s not found.", cell_name.c_str()); return; } auto cell = get_cell(cell_name); // push to PDCP and create DL grant for it - log->info("Writing PDU (%d B) to LCID=%d\n", pdu->N_bytes, lcid); + logger.info("Writing PDU (%d B) to LCID=%d", pdu->N_bytes, lcid); cell->pdcp.write_sdu(lcid, std::move(pdu)); cell->bearer_follow_on_map[lcid] = follow_on_flag; } void ttcn3_syssim::add_pch_pdu(unique_byte_buffer_t pdu) { - log->info("Received PCH PDU (%d B)\n", pdu->N_bytes); + logger.info("Received PCH PDU (%d B)", pdu->N_bytes); // Prepare MAC grant for PCH mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; @@ -975,7 +1005,7 @@ void ttcn3_syssim::add_srb(const ttcn3_helpers::timing_info_t timing, if (timing.now) { add_srb_impl(cell_name, lcid, pdcp_config); } else { - log->debug("Scheduling SRB%d addition for TTI=%d\n", lcid, timing.tti); + logger.debug("Scheduling SRB%d addition for TTI=%d", lcid, timing.tti); tti_actions[timing.tti].push( [this, cell_name, lcid, pdcp_config]() { add_srb_impl(cell_name, lcid, pdcp_config); }); } @@ -984,13 +1014,13 @@ void ttcn3_syssim::add_srb(const ttcn3_helpers::timing_info_t timing, void ttcn3_syssim::add_srb_impl(const std::string cell_name, const uint32_t lcid, const pdcp_config_t pdcp_config) { if (not syssim_has_cell(cell_name)) { - log->error("Can't add SRB to cell. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't add SRB to cell. Cell %s not found.", cell_name.c_str()); return; } auto cell = get_cell(cell_name); - log->info("Adding SRB%d\n", lcid); + logger.info("Adding SRB%d", lcid); cell->pdcp.add_bearer(lcid, pdcp_config); cell->rlc.add_bearer(lcid, srslte::rlc_config_t::srb_config(lcid)); } @@ -998,13 +1028,13 @@ void ttcn3_syssim::add_srb_impl(const std::string cell_name, const uint32_t lcid void ttcn3_syssim::reestablish_bearer(const std::string cell_name, const uint32_t lcid) { if (not syssim_has_cell(cell_name)) { - log->error("Can't reestablish bearer. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't reestablish bearer. Cell %s not found.", cell_name.c_str()); return; } auto cell = get_cell(cell_name); - log->info("Reestablishing LCID=%d\n", lcid); + logger.info("Reestablishing LCID=%d", lcid); cell->pdcp.reestablish(lcid); cell->rlc.reestablish(lcid); } @@ -1014,7 +1044,7 @@ void ttcn3_syssim::del_srb(const ttcn3_helpers::timing_info_t timing, const std: if (timing.now) { del_srb_impl(cell_name, lcid); } else { - log->debug("Scheduling SRB%d deletion for TTI=%d\n", lcid, timing.tti); + logger.debug("Scheduling SRB%d deletion for TTI=%d", lcid, timing.tti); tti_actions[timing.tti].push([this, cell_name, lcid]() { del_srb_impl(cell_name, lcid); }); } } @@ -1022,13 +1052,13 @@ void ttcn3_syssim::del_srb(const ttcn3_helpers::timing_info_t timing, const std: void ttcn3_syssim::del_srb_impl(const std::string cell_name, const uint32_t lcid) { if (not syssim_has_cell(cell_name)) { - log->error("Can't delete bearer. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't delete bearer. Cell %s not found.", cell_name.c_str()); return; } auto cell = get_cell(cell_name); - log->info("Deleting SRB%d\n", lcid); + logger.info("Deleting SRB%d", lcid); // Only delete SRB1/2 if (lcid > 0) { cell->pdcp.del_bearer(lcid); @@ -1044,7 +1074,7 @@ void ttcn3_syssim::add_drb(const ttcn3_helpers::timing_info_t timing, if (timing.now) { add_drb_impl(cell_name, lcid, pdcp_config); } else { - log->debug("Scheduling DRB%d addition for TTI=%d\n", lcid - 2, timing.tti); + logger.debug("Scheduling DRB%d addition for TTI=%d", lcid - 2, timing.tti); tti_actions[timing.tti].push( [this, cell_name, lcid, pdcp_config]() { add_drb_impl(cell_name, lcid, pdcp_config); }); } @@ -1053,14 +1083,14 @@ void ttcn3_syssim::add_drb(const ttcn3_helpers::timing_info_t timing, void ttcn3_syssim::add_drb_impl(const std::string cell_name, const uint32_t lcid, const pdcp_config_t pdcp_config) { if (not syssim_has_cell(cell_name)) { - log->error("Can't add DRB. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't add DRB. Cell %s not found.", cell_name.c_str()); return; } auto cell = get_cell(cell_name); if (lcid > 2) { - log->info("Adding DRB%d\n", lcid - 2); + logger.info("Adding DRB%d", lcid - 2); cell->pdcp.add_bearer(lcid, pdcp_config); cell->rlc.add_bearer(lcid, srslte::rlc_config_t::default_rlc_am_config()); } @@ -1071,7 +1101,7 @@ void ttcn3_syssim::del_drb(const ttcn3_helpers::timing_info_t timing, const std: if (timing.now) { del_drb_impl(cell_name, lcid); } else { - log->debug("Scheduling DRB%d deletion for TTI=%d\n", lcid - 2, timing.tti); + logger.debug("Scheduling DRB%d deletion for TTI=%d", lcid - 2, timing.tti); tti_actions[timing.tti].push([this, cell_name, lcid]() { del_drb_impl(cell_name, lcid); }); } } @@ -1079,7 +1109,7 @@ void ttcn3_syssim::del_drb(const ttcn3_helpers::timing_info_t timing, const std: void ttcn3_syssim::del_drb_impl(const std::string cell_name, const uint32_t lcid) { if (not syssim_has_cell(cell_name)) { - log->error("Can't delete DRB. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't delete DRB. Cell %s not found.", cell_name.c_str()); return; } @@ -1087,7 +1117,7 @@ void ttcn3_syssim::del_drb_impl(const std::string cell_name, const uint32_t lcid // Only delete DRB if (lcid > 2) { - log->info("Deleting DRB%d\n", lcid - 2); + logger.info("Deleting DRB%d", lcid - 2); cell->pdcp.del_bearer(lcid); cell->rlc.del_bearer(lcid); } @@ -1096,12 +1126,12 @@ void ttcn3_syssim::del_drb_impl(const std::string cell_name, const uint32_t lcid // RRC interface for PDCP, PDCP calls RRC to push RRC SDU void ttcn3_syssim::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) { - log->info_hex(pdu->msg, - pdu->N_bytes, - "RRC SDU received for LCID=%d cell_id=%d (%d B)\n", - lcid, - cells[pcell_idx]->config.phy_cell.id, - pdu->N_bytes); + logger.info(pdu->msg, + pdu->N_bytes, + "RRC SDU received for LCID=%d cell_id=%d (%d B)", + lcid, + cells[pcell_idx]->config.phy_cell.id, + pdu->N_bytes); // push content to Titan if (lcid <= 2) { @@ -1117,23 +1147,23 @@ void ttcn3_syssim::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) // Not supported right now void ttcn3_syssim::write_pdu_bcch_bch(unique_byte_buffer_t pdu) { - log->error("%s not implemented.\n", __FUNCTION__); + logger.error("%s not implemented.", __FUNCTION__); } void ttcn3_syssim::write_pdu_bcch_dlsch(unique_byte_buffer_t pdu) { - log->error("%s not implemented.\n", __FUNCTION__); + logger.error("%s not implemented.", __FUNCTION__); } void ttcn3_syssim::write_pdu_pcch(unique_byte_buffer_t pdu) { - log->error("%s not implemented.\n", __FUNCTION__); + logger.error("%s not implemented.", __FUNCTION__); } void ttcn3_syssim::write_pdu_mch(uint32_t lcid, unique_byte_buffer_t pdu) { - log->error("%s not implemented.\n", __FUNCTION__); + logger.error("%s not implemented.", __FUNCTION__); } void ttcn3_syssim::max_retx_attempted() { - log->error("%s not implemented.\n", __FUNCTION__); + logger.error("%s not implemented.", __FUNCTION__); } std::string ttcn3_syssim::get_rb_name(uint32_t lcid) @@ -1146,10 +1176,10 @@ std::string ttcn3_syssim::get_rb_name(uint32_t lcid) void ttcn3_syssim::write_sdu(uint32_t lcid, unique_byte_buffer_t sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "Received SDU on LCID=%d\n", lcid); + logger.info(sdu->msg, sdu->N_bytes, "Received SDU on LCID=%d", lcid); - uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(log); - log->info_hex(mac_pdu_ptr, mac_msg_dl.get_pdu_len(), "DL MAC PDU:\n"); + uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(logger); + logger.info(mac_pdu_ptr, mac_msg_dl.get_pdu_len(), "DL MAC PDU:"); // Prepare MAC grant for CCCH mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; @@ -1188,7 +1218,7 @@ void ttcn3_syssim::set_as_security(const ttcn3_helpers::timing_info_t tim if (timing.now) { set_as_security_impl(cell_name, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_, bearers_); } else { - log->debug("Scheduling AS security configuration for TTI=%d\n", timing.tti); + logger.debug("Scheduling AS security configuration for TTI=%d", timing.tti); tti_actions[timing.tti].push( [this, cell_name, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_, bearers_]() { set_as_security_impl(cell_name, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_, bearers_); @@ -1205,7 +1235,7 @@ void ttcn3_syssim::set_as_security_impl(const std::string const ttcn3_helpers::pdcp_count_map_t bearers) { if (not syssim_has_cell(cell_name)) { - log->error("Can't configure AS security. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't configure AS security. Cell %s not found.", cell_name.c_str()); return; } @@ -1222,10 +1252,10 @@ void ttcn3_syssim::set_as_security_impl(const std::string for (auto& lcid : bearers) { cell->pdcp.config_security(lcid.rb_id, cell->sec_cfg); - log->info("Setting AS security for LCID=%d in DL direction from SN=%d onwards\n", lcid.rb_id, lcid.dl_value); + logger.info("Setting AS security for LCID=%d in DL direction from SN=%d onwards", lcid.rb_id, lcid.dl_value); cell->pdcp.enable_security_timed(lcid.rb_id, DIRECTION_TX, lcid.dl_value); - log->info("Setting AS security for LCID=%d in UL direction from SN=%d onwards\n", lcid.rb_id, lcid.ul_value); + logger.info("Setting AS security for LCID=%d in UL direction from SN=%d onwards", lcid.rb_id, lcid.ul_value); cell->pdcp.enable_security_timed(lcid.rb_id, DIRECTION_RX, lcid.ul_value); } } @@ -1235,7 +1265,7 @@ void ttcn3_syssim::release_as_security(const ttcn3_helpers::timing_info_t timing if (timing.now) { release_as_security_impl(cell_name); } else { - log->debug("Scheduling Release of AS security for TTI=%d\n", timing.tti); + logger.debug("Scheduling Release of AS security for TTI=%d", timing.tti); tti_actions[timing.tti].push([this, cell_name]() { release_as_security_impl(cell_name); }); } } @@ -1243,13 +1273,13 @@ void ttcn3_syssim::release_as_security(const ttcn3_helpers::timing_info_t timing void ttcn3_syssim::release_as_security_impl(const std::string cell_name) { if (not syssim_has_cell(cell_name)) { - log->error("Can't release AS security. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't release AS security. Cell %s not found.", cell_name.c_str()); return; } auto cell = get_cell(cell_name); - log->info("Releasing AS security\n"); + logger.info("Releasing AS security"); cell->pending_bearer_config.clear(); } @@ -1259,7 +1289,7 @@ void ttcn3_syssim::select_cell(srslte_cell_t phy_cell) for (uint32_t i = 0; i < cells.size(); ++i) { if (cells[i]->config.phy_cell.id == phy_cell.id) { pcell_idx = i; - log->info("New PCell: PCI=%d\n", cells[pcell_idx]->config.phy_cell.id); + logger.info("New PCell: PCI=%d", cells[pcell_idx]->config.phy_cell.id); return; } } @@ -1271,7 +1301,7 @@ ttcn3_helpers::pdcp_count_map_t ttcn3_syssim::get_pdcp_count(const std::string c std::vector bearers; if (not syssim_has_cell(cell_name)) { - log->error("Can't obtain PDCP count. Cell %s not found.\n", cell_name.c_str()); + logger.error("Can't obtain PDCP count. Cell %s not found.", cell_name.c_str()); return bearers; } @@ -1287,7 +1317,7 @@ ttcn3_helpers::pdcp_count_map_t ttcn3_syssim::get_pdcp_count(const std::string c bearer.rb_id = i; bearer.dl_value = pdcp_state.next_pdcp_tx_sn; bearer.ul_value = pdcp_state.next_pdcp_rx_sn; - log->debug("PDCP count lcid=%d, dl=%d, ul=%d\n", bearer.rb_id, bearer.dl_value, bearer.ul_value); + logger.debug("PDCP count lcid=%d, dl=%d, ul=%d", bearer.rb_id, bearer.dl_value, bearer.ul_value); bearers.push_back(bearer); } } diff --git a/srsue/test/ttcn3/src/ttcn3_ue.cc b/srsue/test/ttcn3/src/ttcn3_ue.cc index a74186ddc..63a4edd11 100644 --- a/srsue/test/ttcn3/src/ttcn3_ue.cc +++ b/srsue/test/ttcn3/src/ttcn3_ue.cc @@ -29,16 +29,16 @@ SRSLTE_API char* srslte_get_build_info(); SRSLTE_API char* srslte_get_build_mode(); } -ttcn3_ue::ttcn3_ue() : tft_matcher(&log) {} +ttcn3_ue::ttcn3_ue() : logger(srslog::fetch_basic_logger("UE", false)), tft_matcher(logger) {} int ttcn3_ue::init(all_args_t args, srslte::logger* logger_, syssim_interface_phy* syssim_, const std::string tc_name_) { - logger = logger_; + old_logger = logger_; // Init UE log - log.init("UE ", logger); - log.set_level(srslte::LOG_LEVEL_INFO); - log.info("Built in %s mode using %s.\n", srslte_get_build_mode(), srslte_get_build_info()); + logger.set_level(srslog::basic_levels::info); + logger.set_hex_dump_max_size(128); + logger.info("Built in %s mode using %s.", srslte_get_build_mode(), srslte_get_build_info()); // Patch args args.stack.nas.force_imsi_attach = true; @@ -66,13 +66,13 @@ int ttcn3_ue::init(all_args_t args, srslte::logger* logger_, syssim_interface_ph // Instantiate layers and stack together our UE if (args.stack.type == "lte") { - stack = std::unique_ptr(new ue_stack_lte()); + stack = std::unique_ptr(new ue_stack_lte(srslog::get_default_sink())); if (!stack) { srslte::console("Error creating LTE stack instance.\n"); return SRSLTE_ERROR; } - phy = std::unique_ptr(new srsue::lte_ttcn3_phy(logger)); + phy = std::unique_ptr(new srsue::lte_ttcn3_phy); if (!phy) { srslte::console("Error creating LTE PHY instance.\n"); return SRSLTE_ERROR; @@ -88,7 +88,7 @@ int ttcn3_ue::init(all_args_t args, srslte::logger* logger_, syssim_interface_ph return SRSLTE_ERROR; } - if (stack->init(args.stack, logger, phy.get(), this)) { + if (stack->init(args.stack, old_logger, phy.get(), this)) { srslte::console("Error initializing stack.\n"); return SRSLTE_ERROR; } @@ -163,13 +163,13 @@ uint16_t ttcn3_ue::get_dl_sched_rnti(uint32_t tti) void ttcn3_ue::add_mch_port(uint32_t lcid, uint32_t port) {} void ttcn3_ue::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { - log.debug_hex(pdu->msg, pdu->N_bytes, "Rx PDU (%d B) on lcid=%d\n", pdu->N_bytes, lcid); + logger.debug(pdu->msg, pdu->N_bytes, "Rx PDU (%d B) on lcid=%d", pdu->N_bytes, lcid); switch (test_loop_mode) { case TEST_LOOP_INACTIVE: - log.warning("Test loop inactive. Dropping PDU.\n"); + logger.warning("Test loop inactive. Dropping PDU."); break; case TEST_LOOP_MODE_A_ACTIVE: - log.error("Test loop mode A not implemented. Dropping PDU.\n"); + logger.error("Test loop mode A not implemented. Dropping PDU."); break; case TEST_LOOP_MODE_B_ACTIVE: // Section 5.4.4 in TS 36.509 @@ -185,15 +185,24 @@ void ttcn3_ue::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) } break; case TEST_LOOP_MODE_C_ACTIVE: - log.error("Test loop mode C not implemented. Dropping PDU.\n"); + logger.error("Test loop mode C not implemented. Dropping PDU."); break; } } void ttcn3_ue::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} -int ttcn3_ue::setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str) +int ttcn3_ue::setup_if_addr(uint32_t eps_bearer_id, + uint32_t lcid, + uint8_t pdn_type, + uint32_t ip_addr, + uint8_t* ipv6_if_id, + char* err_str) { return 0; } +int ttcn3_ue::update_lcid(uint32_t eps_bearer_id, uint32_t new_lcid) +{ + return SRSLTE_SUCCESS; +} int ttcn3_ue::apply_traffic_flow_template(const uint8_t& eps_bearer_id, const uint8_t& lcid, @@ -208,21 +217,21 @@ void ttcn3_ue::set_test_loop_mode(const test_loop_mode_state_t mode, const uint3 switch (test_loop_mode) { case TEST_LOOP_INACTIVE: // deactivate timer - log.info("Deactivating Test Loop Mode\n"); + logger.info("Deactivating Test Loop Mode"); pdu_delay_timer.release(); break; case TEST_LOOP_MODE_A_ACTIVE: - log.error("Test loop mode A not implemented\n"); + logger.error("Test loop mode A not implemented"); break; case TEST_LOOP_MODE_B_ACTIVE: - log.info("Activating Test loop mode B with %d ms PDU delay\n", ip_pdu_delay_ms_); + logger.info("Activating Test loop mode B with %d ms PDU delay", ip_pdu_delay_ms_); pdu_delay_timer = stack->get_task_sched().get_unique_timer(); if (ip_pdu_delay_ms_ > 0) { pdu_delay_timer.set(ip_pdu_delay_ms_, [this](uint32_t tid) { timer_expired(tid); }); } break; case TEST_LOOP_MODE_C_ACTIVE: - log.error("Test loop mode A not implemented\n"); + logger.error("Test loop mode A not implemented"); break; } } @@ -230,23 +239,23 @@ void ttcn3_ue::set_test_loop_mode(const test_loop_mode_state_t mode, const uint3 void ttcn3_ue::timer_expired(uint32_t timeout_id) { if (timeout_id == pdu_delay_timer.id()) { - log.info("Testmode B PDU delay timer expired\n"); + logger.info("Testmode B PDU delay timer expired"); send_queued_data(); } } void ttcn3_ue::send_queued_data() { if (!stack->is_rrc_connected()) { - log.info("RRC not connected, requesting NAS attach\n"); + logger.info("RRC not connected, requesting NAS attach"); if (not stack->start_service_request()) { - log.warning("Could not reestablish the connection\n"); + logger.warning("Could not reestablish the connection"); } stack->get_task_sched().defer_callback(500, [&]() { send_queued_data(); }); return; } for (auto& bearer_pdu_queue : pdu_queue) { - log.info("Delivering %zd buffered PDUs for LCID=%d\n", bearer_pdu_queue.second.size(), bearer_pdu_queue.first); + logger.info("Delivering %zd buffered PDUs for LCID=%d", bearer_pdu_queue.second.size(), bearer_pdu_queue.first); while (not bearer_pdu_queue.second.empty()) { srslte::unique_byte_buffer_t pdu; bearer_pdu_queue.second.try_pop(&pdu); @@ -257,6 +266,6 @@ void ttcn3_ue::send_queued_data() void ttcn3_ue::loop_back_pdu_with_tft(uint32_t input_lcid, srslte::unique_byte_buffer_t pdu) { - log.info_hex(pdu->msg, pdu->N_bytes, "Rx PDU (%d B) on lcid=%d, looping back\n", pdu->N_bytes, input_lcid); + logger.info(pdu->msg, pdu->N_bytes, "Rx PDU (%d B) on lcid=%d, looping back", pdu->N_bytes, input_lcid); stack->write_sdu(input_lcid, std::move(pdu)); } diff --git a/srsue/test/ttcn3/test/ttcn3_if_handler_test.cc b/srsue/test/ttcn3/test/ttcn3_if_handler_test.cc index b98398fd0..c33bd82e6 100644 --- a/srsue/test/ttcn3/test/ttcn3_if_handler_test.cc +++ b/srsue/test/ttcn3/test/ttcn3_if_handler_test.cc @@ -27,11 +27,12 @@ int if_handler_test() { - ttcn3_ut_interface ut; - ttcn3_sys_interface sys; - ttcn3_ip_sock_interface ip_sock; - ttcn3_ip_ctrl_interface ip_ctrl; - ttcn3_srb_interface srb; + auto& logger = srslog::fetch_basic_logger("TEST", false); + ttcn3_ut_interface ut(logger); + ttcn3_sys_interface sys(logger); + ttcn3_ip_sock_interface ip_sock(logger); + ttcn3_ip_ctrl_interface ip_ctrl(logger); + ttcn3_srb_interface srb(logger); return SRSLTE_SUCCESS; } diff --git a/srsue/test/upper/CMakeLists.txt b/srsue/test/upper/CMakeLists.txt index 2570b5796..09493416d 100644 --- a/srsue/test/upper/CMakeLists.txt +++ b/srsue/test/upper/CMakeLists.txt @@ -32,17 +32,17 @@ target_link_libraries(rrc_reconfig_test srsue_upper srslte_upper srslte_phy rrc_ add_test(rrc_reconfig_test rrc_reconfig_test) add_executable(rrc_meas_test rrc_meas_test.cc) -if (ENABLE_5GNR) - target_link_libraries(rrc_meas_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) -else (ENABLE_5GNR) - target_link_libraries(rrc_meas_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1) -endif(ENABLE_5GNR) +target_link_libraries(rrc_meas_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) add_test(rrc_meas_test rrc_meas_test) add_executable(nas_test nas_test.cc) target_link_libraries(nas_test srsue_upper srslte_upper srslte_phy rrc_asn1) add_test(nas_test nas_test) +add_executable(gw_test gw_test.cc) +target_link_libraries(gw_test srsue_upper srslte_upper srslte_phy) +add_test(gw_test gw_test) + add_executable(tft_test tft_test.cc) target_link_libraries(tft_test srsue_upper srslte_upper srslte_phy) add_test(tft_test tft_test) @@ -52,17 +52,11 @@ target_link_libraries(rrc_phy_ctrl_test srslte_common srsue_rrc) add_test(rrc_phy_ctrl_test rrc_phy_ctrl_test) add_executable(rrc_cell_test rrc_cell_test.cc) -if (ENABLE_5GNR) - target_link_libraries(rrc_cell_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) -else (ENABLE_5GNR) - target_link_libraries(rrc_cell_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1) -endif(ENABLE_5GNR) +target_link_libraries(rrc_cell_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) add_test(rrc_cell_test rrc_cell_test) -if (ENABLE_5GNR) - add_executable(ue_rrc_nr_test ue_rrc_nr_test.cc) - target_link_libraries(ue_rrc_nr_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) -endif(ENABLE_5GNR) +add_executable(ue_rrc_nr_test ue_rrc_nr_test.cc) +target_link_libraries(ue_rrc_nr_test srsue_rrc srsue_upper srslte_upper srslte_phy rrc_asn1 rrc_nr_asn1) ######################################################################## # Option to run command after build (useful for remote builds) diff --git a/srsue/test/upper/gw_test.cc b/srsue/test/upper/gw_test.cc new file mode 100644 index 000000000..573b46a23 --- /dev/null +++ b/srsue/test/upper/gw_test.cc @@ -0,0 +1,88 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 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 "srslte/common/common.h" +#include "srslte/common/log.h" +#include "srslte/common/logger_srslog_wrapper.h" +#include "srslte/common/test_common.h" +#include "srslte/interfaces/ue_interfaces.h" +#include "srslte/srslog/srslog.h" +#include "srslte/srslte.h" +#include "srsue/hdr/stack/upper/gw.h" + +class test_stack_dummy : public srsue::stack_interface_gw +{ +public: + bool is_registered() { return true; } + bool start_service_request() { return true; }; + void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) { return; } + bool is_lcid_enabled(uint32_t lcid) { return true; } +}; + +int gw_change_lcid_test() +{ + + // Setup logging. + srslog::sink* log_sink = srslog::create_stdout_sink(); + if (!log_sink) { + return SRSLTE_ERROR; + } + + srslog::log_channel* chan = srslog::create_log_channel("main_channel", *log_sink); + if (!chan) { + return SRSLTE_ERROR; + } + + srslte::srslog_wrapper log_wrapper(*chan); + + srslte::log_filter log; + log.init("TEST ", &log_wrapper); + log.set_level("debug"); + log.set_hex_limit(10000); + + srslog::init(); + + srsue::gw_args_t gw_args; + gw_args.tun_dev_name = "tun1"; + gw_args.log.gw_level = "debug"; + gw_args.log.gw_hex_limit = 100000; + test_stack_dummy stack; + srsue::gw gw; + gw.init(gw_args, &log_wrapper, &stack); + + uint32_t eps_bearer_id = 5; + uint32_t non_existing_eps_bearer_id = 23; + uint32_t old_lcid = 3; + uint32_t new_lcid = 4; + char* err_str = nullptr; + int rtn = 0; + + rtn = gw.setup_if_addr( + eps_bearer_id, old_lcid, LIBLTE_MME_PDN_TYPE_IPV4, htonl(inet_addr("192.168.56.32")), nullptr, err_str); + + if (rtn != SRSLTE_SUCCESS) { + log.error("Failed to setup GW interface. Not possible to test function. Try to execute with sudo rights."); + gw.stop(); + return SRSLTE_SUCCESS; + } + + TESTASSERT(gw.update_lcid(eps_bearer_id, new_lcid) == SRSLTE_SUCCESS); + TESTASSERT(gw.update_lcid(non_existing_eps_bearer_id, new_lcid) == SRSLTE_ERROR); + gw.stop(); + return SRSLTE_SUCCESS; +} + +int main(int argc, char** argv) +{ + TESTASSERT(gw_change_lcid_test() == SRSLTE_SUCCESS); + return SRSLTE_SUCCESS; +} diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 4bb6a2fcb..146a19d64 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -41,6 +41,15 @@ using namespace srsue; using namespace asn1::rrc; +static_assert(alignof(LIBLTE_BYTE_MSG_STRUCT) == alignof(byte_buffer_t), + "liblte buffer and byte buffer members misaligned"); +static_assert(offsetof(LIBLTE_BYTE_MSG_STRUCT, N_bytes) == offsetof(byte_buffer_t, N_bytes), + "liblte buffer and byte buffer members misaligned"); +static_assert(offsetof(LIBLTE_BYTE_MSG_STRUCT, header) == offsetof(byte_buffer_t, buffer), + "liblte buffer and byte buffer members misaligned"); +static_assert(sizeof(LIBLTE_BYTE_MSG_STRUCT) <= offsetof(byte_buffer_t, msg), + "liblte buffer and byte buffer members misaligned"); + #define LCID 1 uint8_t auth_request_pdu[] = {0x07, 0x52, 0x01, 0x0c, 0x63, 0xa8, 0x54, 0x13, 0xe6, 0xa4, 0xce, 0xd9, @@ -176,7 +185,6 @@ public: running = false; wait_thread_finish(); } - srslte::log_ref stack_log{"STCK"}; pdcp_interface_gw* pdcp = nullptr; srsue::nas* nas = nullptr; bool running = false; @@ -186,7 +194,12 @@ public: class gw_dummy : public gw_interface_nas, public gw_interface_pdcp { - int setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str) + int setup_if_addr(uint32_t eps_bearer_id, + uint32_t lcid, + uint8_t pdn_type, + uint32_t ip_addr, + uint8_t* ipv6_if_id, + char* err_str) { return SRSLTE_SUCCESS; } @@ -227,7 +240,7 @@ int security_command_test() args.using_op = true; // init USIM - srsue::usim usim(&usim_log); + srsue::usim usim(srslog::fetch_basic_logger("USIM")); usim.init(&args); { @@ -240,7 +253,7 @@ int security_command_test() // push auth request PDU to NAS to generate security context byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - unique_byte_buffer_t tmp = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, auth_request_pdu, sizeof(auth_request_pdu)); tmp->N_bytes = sizeof(auth_request_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -249,7 +262,7 @@ int security_command_test() rrc_dummy.reset(); // reuse buffer for security mode command - tmp = srslte::allocate_unique_buffer(*pool, true); + tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, sec_mode_command_pdu, sizeof(sec_mode_command_pdu)); tmp->N_bytes = sizeof(sec_mode_command_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -260,8 +273,6 @@ int security_command_test() } } - byte_buffer_pool::get_instance()->cleanup(); - return ret; } @@ -283,7 +294,7 @@ int mme_attach_request_test() rrc_dummy rrc_dummy; pdcp_dummy pdcp_dummy; - srsue::usim usim(&usim_log); + srsue::usim usim(srslog::fetch_basic_logger("USIM")); usim_args_t args; args.mode = "soft"; args.algo = "xor"; @@ -323,7 +334,7 @@ int mme_attach_request_test() // finally push attach accept byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - unique_byte_buffer_t tmp = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, attach_accept_pdu, sizeof(attach_accept_pdu)); tmp->N_bytes = sizeof(attach_accept_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -339,8 +350,6 @@ int mme_attach_request_test() gw.stop(); } - byte_buffer_pool::get_instance()->cleanup(); - return ret; } @@ -367,12 +376,9 @@ int esm_info_request_test() args.op = "63BFA50EE6523365FF14C1F45F88737D"; // init USIM - srsue::usim usim(&usim_log); + srsue::usim usim(srslog::fetch_basic_logger("USIM")); usim.init(&args); - srslte::byte_buffer_pool* pool; - pool = byte_buffer_pool::get_instance(); - { srsue::nas nas(&stack.task_sched); nas_args_t cfg; @@ -383,7 +389,7 @@ int esm_info_request_test() nas.init(&usim, &rrc_dummy, &gw, cfg); // push ESM info request PDU to NAS to generate response - unique_byte_buffer_t tmp = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, esm_info_req_pdu, sizeof(esm_info_req_pdu)); tmp->N_bytes = sizeof(esm_info_req_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -419,18 +425,16 @@ int dedicated_eps_bearer_test() args.op = "63BFA50EE6523365FF14C1F45F88737D"; // init USIM - srsue::usim usim(&usim_log); + srsue::usim usim(srslog::fetch_basic_logger("USIM")); usim.init(&args); - srslte::byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - srsue::nas nas(&stack.task_sched); nas_args_t cfg = {}; cfg.force_imsi_attach = true; // make sure we get a fresh security context nas.init(&usim, &rrc_dummy, &gw, cfg); // push dedicated EPS bearer PDU to NAS - unique_byte_buffer_t tmp = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, activate_dedicated_eps_bearer_pdu, sizeof(activate_dedicated_eps_bearer_pdu)); tmp->N_bytes = sizeof(activate_dedicated_eps_bearer_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -441,7 +445,7 @@ int dedicated_eps_bearer_test() TESTASSERT(metrics.nof_active_eps_bearer == 0); // add default EPS beaerer - unique_byte_buffer_t attach_with_default_bearer = srslte::allocate_unique_buffer(*pool, true); + unique_byte_buffer_t attach_with_default_bearer = srslte::make_byte_buffer(); memcpy(attach_with_default_bearer->msg, attach_accept_pdu, sizeof(attach_accept_pdu)); attach_with_default_bearer->N_bytes = sizeof(attach_accept_pdu); nas.write_pdu(LCID, std::move(attach_with_default_bearer)); @@ -451,7 +455,7 @@ int dedicated_eps_bearer_test() TESTASSERT(metrics.nof_active_eps_bearer == 1); // push dedicated bearer activation and check that it was added - tmp = srslte::allocate_unique_buffer(*pool, true); + tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, activate_dedicated_eps_bearer_pdu, sizeof(activate_dedicated_eps_bearer_pdu)); tmp->N_bytes = sizeof(activate_dedicated_eps_bearer_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -459,7 +463,7 @@ int dedicated_eps_bearer_test() TESTASSERT(metrics.nof_active_eps_bearer == 2); // tear-down dedicated bearer - tmp = srslte::allocate_unique_buffer(*pool, true); + tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, deactivate_eps_bearer_pdu, sizeof(deactivate_eps_bearer_pdu)); tmp->N_bytes = sizeof(deactivate_eps_bearer_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -467,7 +471,7 @@ int dedicated_eps_bearer_test() TESTASSERT(metrics.nof_active_eps_bearer == 1); // try to tear-down dedicated bearer again - tmp = srslte::allocate_unique_buffer(*pool, true); + tmp = srslte::make_byte_buffer(); memcpy(tmp->msg, deactivate_eps_bearer_pdu, sizeof(deactivate_eps_bearer_pdu)); tmp->N_bytes = sizeof(deactivate_eps_bearer_pdu); nas.write_pdu(LCID, std::move(tmp)); @@ -485,6 +489,19 @@ int main(int argc, char** argv) srslte::srslog_wrapper log_wrapper(*chan); g_logger = &log_wrapper; + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(100000); + auto& nas_logger = srslog::fetch_basic_logger("NAS", false); + nas_logger.set_level(srslog::basic_levels::debug); + nas_logger.set_hex_dump_max_size(100000); + auto& usim_logger = srslog::fetch_basic_logger("USIM", false); + usim_logger.set_level(srslog::basic_levels::debug); + usim_logger.set_hex_dump_max_size(100000); + auto& gw_logger = srslog::fetch_basic_logger("GW", false); + gw_logger.set_level(srslog::basic_levels::debug); + gw_logger.set_hex_dump_max_size(100000); + // Start the log backend. srslog::init(); diff --git a/srsue/test/upper/pcsc_usim_test.cc b/srsue/test/upper/pcsc_usim_test.cc index c92d136b6..9969b3835 100644 --- a/srsue/test/upper/pcsc_usim_test.cc +++ b/srsue/test/upper/pcsc_usim_test.cc @@ -19,12 +19,10 @@ * */ +#include "srsue/hdr/stack/upper/pcsc_usim.h" #include #include -#include "srslte/common/log_filter.h" -#include "srsue/hdr/stack/upper/pcsc_usim.h" - using namespace srsue; using namespace std; @@ -33,9 +31,11 @@ uint8_t autn_enb[] = {0x5a, 0x17, 0x77, 0x3c, 0x62, 0x57, 0x90, 0x01, 0xcf, 0x47 int main(int argc, char** argv) { - srslte::log_filter usim_log("USIM"); - usim_log.set_level(srslte::LOG_LEVEL_DEBUG); - usim_log.set_hex_limit(100000); + srslog::basic_logger& logger = srslog::fetch_basic_logger("USIM", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(100000); + srslog::init(); + uint8_t res[16]; int res_len; uint8_t k_asme[32]; @@ -46,7 +46,7 @@ int main(int argc, char** argv) args.pin = "6129"; args.imei = "353490069873319"; - srsue::pcsc_usim usim(&usim_log); + srsue::pcsc_usim usim(logger); if (usim.init(&args)) { printf("Error initializing PC/SC USIM.\n"); return SRSLTE_ERROR; diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index 9af8a06f7..6689c8d5d 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -144,7 +144,7 @@ public: get_dlsch_with_sys_info(dlsch_msg); } - pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance()); + pdu = srslte::make_byte_buffer(); asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); dlsch_msg.pack(bref); pdu->N_bytes = bref.distance_bytes(); @@ -203,7 +203,7 @@ class pdcp_test : public srslte::pdcp { public: pdcp_test(const char* logname, srslte::task_sched_handle t) : srslte::pdcp(t, logname) {} - void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu) override + void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, int sn = -1) override { ul_dcch_msg_s ul_dcch_msg; asn1::cbit_ref bref(sdu->msg, sdu->N_bytes); @@ -260,19 +260,14 @@ public: rrc_test(srslte::log_ref log_, stack_test_dummy* stack_) : rrc(stack_, &stack_->task_sched), stack(stack_), mactest(this, &stack_->task_sched) { - pool = srslte::byte_buffer_pool::get_instance(); nastest = std::unique_ptr(new nas_test(&stack->task_sched)); pdcptest = std::unique_ptr(new pdcp_test(log_->get_service_name().c_str(), &stack->task_sched)); rrcnrtest = std::unique_ptr(new rrc_nr_test()); } -#ifdef HAVE_5GNR void init() { rrc::init(&phytest, &mactest, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, rrcnrtest.get(), {}); } -#else - void init() { rrc::init(&phytest, &mactest, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, {}); } -#endif void run_tti(uint32_t tti_) { @@ -313,7 +308,7 @@ public: void send_ccch_msg(dl_ccch_msg_s& dl_ccch_msg) { - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); dl_ccch_msg.pack(bref); @@ -325,7 +320,7 @@ public: void send_dcch_msg(dl_dcch_msg_s& dl_dcch_msg) { - srslte::unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); + srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); ; asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); dl_dcch_msg.pack(bref); @@ -356,7 +351,6 @@ public: run_tti(1); } -#ifdef HAVE_5GNR void add_neighbour_cell_nr(uint32_t pci, uint32_t earfcn, float rsrp = 0) { std::vector phy_meas = {}; @@ -368,7 +362,6 @@ public: new_cell_meas_nr(phy_meas); run_tti(1); } -#endif using rrc::has_neighbour_cell; using rrc::is_serving_cell; @@ -380,11 +373,10 @@ public: mac_test mactest; private: - std::unique_ptr pdcptest; - std::unique_ptr nastest; + std::unique_ptr pdcptest; + std::unique_ptr nastest; std::unique_ptr rrcnrtest; - uint32_t tti = 0; - srslte::byte_buffer_pool* pool = nullptr; + uint32_t tti = 0; }; // Test Cell select @@ -498,6 +490,7 @@ int meas_obj_test() srslte::log_ref log1("RRC_MEAS"); log1->set_level(srslte::LOG_LEVEL_DEBUG); log1->set_hex_limit(-1); + auto& rrc_meas_logger = srslog::fetch_basic_logger("RRC_MEAS"); printf("==========================================================\n"); printf("====== Object Configuration Testing ===============\n"); @@ -515,7 +508,7 @@ int meas_obj_test() rrc_conn_recfg.meas_cfg_present = true; meas_cfg_s& meas_cfg = rrc_conn_recfg.meas_cfg; - log1->info("Test1: Remove non-existing measObject, reportConfig and measId\n"); + rrc_meas_logger.info("Test1: Remove non-existing measObject, reportConfig and measId"); meas_cfg = {}; meas_cfg.meas_id_to_rem_list.push_back(3); meas_cfg.meas_obj_to_rem_list.push_back(3); @@ -527,7 +520,7 @@ int meas_obj_test() TESTASSERT(rrctest.send_meas_cfg(rrc_conn_recfg)); TESTASSERT(rrctest.phytest.meas_nof_freqs() == 0); - log1->info("Test2: Add measId pointing to non-existing measObject or reportConfig\n"); + rrc_meas_logger.info("Test2: Add measId pointing to non-existing measObject or reportConfig"); meas_cfg = {}; meas_id_to_add_mod_s m = {}; m.meas_obj_id = 1; @@ -540,7 +533,7 @@ int meas_obj_test() TESTASSERT(rrctest.send_meas_cfg(rrc_conn_recfg)); TESTASSERT(rrctest.phytest.meas_nof_freqs() == 0); - log1->info("Test3: Add meaObject and report of unsupported type. Setup a supported report for later use\n"); + rrc_meas_logger.info("Test3: Add meaObject and report of unsupported type. Setup a supported report for later use"); meas_cfg = {}; meas_obj_to_add_mod_s obj = {}; obj.meas_obj.set_meas_obj_utra(); @@ -569,7 +562,7 @@ int meas_obj_test() TESTASSERT(rrctest.send_meas_cfg(rrc_conn_recfg)); TESTASSERT(rrctest.phytest.meas_nof_freqs() == 0); - log1->info("Test4: Add 2 measObjects and 2 measId both pointing to the same measObject \n"); + rrc_meas_logger.info("Test4: Add 2 measObjects and 2 measId both pointing to the same measObject "); meas_cfg = {}; for (int i = 0; i < 2; i++) { m = {}; @@ -605,7 +598,7 @@ int meas_obj_test() TESTASSERT(rrctest.phytest.meas_freq_started(100)); TESTASSERT(rrctest.phytest.meas_nof_cells(100) == 0); - log1->info("Test5: Add existing objects and measId. Now add measId for 2nd cell\n"); + rrc_meas_logger.info("Test5: Add existing objects and measId. Now add measId for 2nd cell"); meas_cfg = {}; m = {}; m.meas_obj_id = 2; // same object @@ -636,7 +629,7 @@ int meas_obj_test() } // Reconfigure 2nd object only, we should see 8 cells now - log1->info("Test6: Add 1 cell to 1st object. Mixed add/mod and removal command.\n"); + rrc_meas_logger.info("Test6: Add 1 cell to 1st object. Mixed add/mod and removal command."); meas_cfg = {}; meas_cfg.meas_obj_to_add_mod_list_present = true; @@ -690,7 +683,7 @@ int meas_obj_test() TESTASSERT(rrctest.phytest.meas_cell_started(2, 23)); // was added TESTASSERT(rrctest.phytest.meas_cell_started(2, 24)); // was added - log1->info("Test7: PHY finds new neighbours in frequency 1 and 2, check RRC instructs to search them\n"); + rrc_meas_logger.info("Test7: PHY finds new neighbours in frequency 1 and 2, check RRC instructs to search them"); std::vector phy_meas = {}; phy_meas.push_back({0, 0, 0.0f, 1, 31}); phy_meas.push_back({-1, 0, 0.0f, 1, 32}); @@ -726,13 +719,13 @@ int meas_obj_test() TESTASSERT(rrctest.phytest.meas_cell_started(2, 24)); // was added TESTASSERT(rrctest.phytest.meas_cell_started(2, 31)); - log1->info("Test8: Simulate a Release (reset() call) make sure resets correctly\n"); + rrc_meas_logger.info("Test8: Simulate a Release (reset() call) make sure resets correctly"); rrctest.init(); rrctest.run_tti(1); rrctest.connect(); rrctest.run_tti(1); - log1->info("Test9: Config removal\n"); + rrc_meas_logger.info("Test9: Config removal"); meas_cfg = {}; meas_cfg.meas_obj_to_rem_list.push_back(1); meas_cfg.meas_obj_to_rem_list.push_back(2); @@ -919,12 +912,12 @@ int a1event_report_test(uint32_t a1_rsrp_th, report_cfg_eutra_s::report_amount_e_ report_amount, report_interv_e report_interv) { - srslte::log_ref log1("RRC_MEAS"), rrc_log("RRC"); log1->set_level(srslte::LOG_LEVEL_DEBUG); log1->set_hex_limit(-1); rrc_log->set_level(srslte::LOG_LEVEL_DEBUG); rrc_log->set_hex_limit(-1); + auto& rrc_meas_logger = srslog::fetch_basic_logger("RRC_MEAS"); printf("==========================================================\n"); printf("============ Report Testing A1 ===============\n"); @@ -956,20 +949,20 @@ int a1event_report_test(uint32_t a1_rsrp_th, // Entering condition during half timeToTrigger, should not trigger measurement for (int i = 0; i < ttt_iters / 2; i++) { - log1->info("Report %d/%d enter condition is true\n", i, ttt_iters / 2); + rrc_meas_logger.info("Report %d/%d enter condition is true", i, ttt_iters / 2); enter_condition(rrctest, event_id, hyst, 0, {1, 2}); // Check doesn't generate measurement report TESTASSERT(!rrctest.get_meas_res(meas_res)); } - log1->info("Report leaving enter condition\n"); + rrc_meas_logger.info("Report leaving enter condition"); // Not satisfy entering condition for 1 TTI middle_condition(rrctest, event_id, hyst, 0, {1}); TESTASSERT(!rrctest.get_meas_res(meas_res)); // Should go again all timeToTrigger, should not trigger measurement until end for (int i = 0; i < ttt_iters; i++) { - log1->info("Report %d/%d enter condition is true\n", i, ttt_iters); + rrc_meas_logger.info("Report %d/%d enter condition is true", i, ttt_iters); enter_condition(rrctest, event_id, hyst, 0, {1, 2}); if (i < ttt_iters - 1) { // Check doesn't generate measurement report @@ -989,14 +982,14 @@ int a1event_report_test(uint32_t a1_rsrp_th, // Trigger again entering condition for the same cell it shouldn't trigger a new report, just keep sending the // periodic reports without restarting counter for (int i = 0; i < ttt_iters; i++) { - log1->info("Report %d/%d enter condition is true\n", i, ttt_iters); + rrc_meas_logger.info("Report %d/%d enter condition is true", i, ttt_iters); enter_condition(rrctest, event_id, hyst, 0, {1}); } // Do not expect report if timer not expired TESTASSERT(!rrctest.get_meas_res(meas_res)); // Wait to generate all reports for (int i = 0; i < report_amount.to_number() - 1; i++) { - log1->info("Testing report %d/%d\n", i, report_amount.to_number()); + rrc_meas_logger.info("Testing report %d/%d", i, report_amount.to_number()); int interval = report_interv.to_number(); if (i == 0) { // already stepped these iterations @@ -1007,7 +1000,7 @@ int a1event_report_test(uint32_t a1_rsrp_th, // Exit the enter condition in the last one, should still send the last report middle_condition(rrctest, event_id, hyst, 0, {1}); } else { - log1->info("Stepping timer %d/%d\n", j, interval); + rrc_meas_logger.info("Stepping timer %d/%d", j, interval); rrctest.run_tti(1); } if (j < interval - 1) { @@ -1026,7 +1019,7 @@ int a1event_report_test(uint32_t a1_rsrp_th, } // Trigger again condition for (int i = 0; i < ttt_iters; i++) { - log1->info("Report %d/%d enter condition is true\n", i, ttt_iters); + rrc_meas_logger.info("Report %d/%d enter condition is true", i, ttt_iters); enter_condition(rrctest, event_id, hyst, 0, {1}); } // Do not expect report @@ -1034,14 +1027,14 @@ int a1event_report_test(uint32_t a1_rsrp_th, // Leaving condition for timeToTrigger for (int i = 0; i < ttt_iters; i++) { - log1->info("Report %d/%d leaving condition is true\n", i, ttt_iters); + rrc_meas_logger.info("Report %d/%d leaving condition is true", i, ttt_iters); exit_condition(rrctest, event_id, hyst, 0, {1}); // Check doesn't generate measurement report TESTASSERT(!rrctest.get_meas_res(meas_res)); } // Trigger again condition for (int i = 0; i < ttt_iters; i++) { - log1->info("Report %d/%d enter condition is true\n", i, ttt_iters); + rrc_meas_logger.info("Report %d/%d enter condition is true", i, ttt_iters); enter_condition(rrctest, event_id, hyst, 0, {1}); } // Expect report @@ -1055,12 +1048,12 @@ int a1event_report_test(uint32_t a1_rsrp_th, // Test A3-event reporting and management of report amount and interval int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) { - srslte::log_ref log1("RRC_MEAS"), rrc_log("RRC"); log1->set_level(srslte::LOG_LEVEL_DEBUG); log1->set_hex_limit(-1); rrc_log->set_level(srslte::LOG_LEVEL_DEBUG); rrc_log->set_hex_limit(-1); + auto& rrc_meas_logger = srslog::fetch_basic_logger("RRC_MEAS"); printf("==========================================================\n"); printf("============ Report Testing A3 ===============\n"); @@ -1093,14 +1086,14 @@ int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) meas_results_s meas_res = {}; - log1->info("Test no-enter condition and no trigger report \n"); + rrc_meas_logger.info("Test no-enter condition and no trigger report "); no_condition(rrctest, {0}, {1}); TESTASSERT(!rrctest.get_meas_res(meas_res)); no_condition(rrctest, {0, 1}, {1, 0}); TESTASSERT(!rrctest.get_meas_res(meas_res)); - log1->info("Test enter condition triggers report. 1 neighbour cell in enter + 1 in exit \n"); + rrc_meas_logger.info("Test enter condition triggers report. 1 neighbour cell in enter + 1 in exit "); float offset = 0.5 * event_id.event_a3().a3_offset; std::vector rsrp = {}; rsrp.push_back(-60 + offset + 0.5 * hyst + (float)1e-2); @@ -1119,11 +1112,11 @@ int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) 81 + (hyst + a3_offset) / 2); // Next iteration in entering state does not trigger another report - log1->info("Test enter condition for the same cell does not trigger report\n"); + rrc_meas_logger.info("Test enter condition for the same cell does not trigger report"); rrctest.run_tti(1); TESTASSERT(!rrctest.get_meas_res(meas_res)); - log1->info("Test enter condition for different earfcn triggers report\n"); + rrc_meas_logger.info("Test enter condition for different earfcn triggers report"); enter_condition(rrctest, event_id, hyst, 2, {1, 3}); TESTASSERT(rrctest.get_meas_res(meas_res)); TESTASSERT(meas_res.meas_id == 2); @@ -1136,7 +1129,7 @@ int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) 81 + (hyst + a3_offset) / 2); // if a new cell enters conditions then expect another report - log1->info("Test a new cell enter condition triggers report\n"); + rrc_meas_logger.info("Test a new cell enter condition triggers report"); enter_condition(rrctest, event_id, hyst, 1, {1, 3}); TESTASSERT(rrctest.get_meas_res(meas_res)); TESTASSERT(meas_res.meas_id == 1); @@ -1150,14 +1143,14 @@ int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) 81 + (hyst + a3_offset) / 2); // cell pci=0 exists condition - log1->info("Test exit condition\n"); + rrc_meas_logger.info("Test exit condition"); exit_condition(rrctest, event_id, hyst, 1, {1, 0}); if (report_on_leave) { TESTASSERT(rrctest.get_meas_res(meas_res)); } // 2 enters again, now expect report again - log1->info("Test trigger again the cell that exited\n"); + rrc_meas_logger.info("Test trigger again the cell that exited"); enter_condition(rrctest, event_id, hyst, 1, {1, 0}); TESTASSERT(rrctest.get_meas_res(meas_res)); TESTASSERT(meas_res.meas_id == 1); @@ -1196,63 +1189,68 @@ int meas_obj_inter_rat_nr_test() obj.meas_obj_id = 2; obj.meas_obj.set_meas_obj_nr_r15(); - obj.meas_obj.meas_obj_nr_r15().ext = true; + obj.meas_obj.meas_obj_nr_r15().ext = true; obj.meas_obj.meas_obj_nr_r15().carrier_freq_r15 = 631680; obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.periodicity_and_offset_r15.set_sf20_r15(); - obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.ssb_dur_r15 = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::options::sf1; - obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.subcarrier_spacing_ssb_r15 = asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::options::khz30; + obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.ssb_dur_r15 = + asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::options::sf1; + obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.subcarrier_spacing_ssb_r15 = + asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::options::khz30; obj.meas_obj.meas_obj_nr_r15().quant_cfg_set_r15 = 1; obj.meas_obj.meas_obj_nr_r15().band_nr_r15.reset(new asn1::rrc::meas_obj_nr_r15_s::band_nr_r15_c_{}); obj.meas_obj.meas_obj_nr_r15().band_nr_r15->set_setup() = 78; meas_cfg.meas_obj_to_add_mod_list.push_back(obj); - obj = {}; + obj = {}; obj.meas_obj_id = 1; obj.meas_obj.set_meas_obj_eutra(); - obj.meas_obj.meas_obj_eutra().carrier_freq = 300; - obj.meas_obj.meas_obj_eutra().allowed_meas_bw = asn1::rrc::allowed_meas_bw_opts::options::mbw100; + obj.meas_obj.meas_obj_eutra().carrier_freq = 300; + obj.meas_obj.meas_obj_eutra().allowed_meas_bw = asn1::rrc::allowed_meas_bw_opts::options::mbw100; obj.meas_obj.meas_obj_eutra().presence_ant_port1 = true; - obj.meas_obj.meas_obj_eutra().neigh_cell_cfg.from_number(01); - + obj.meas_obj.meas_obj_eutra().neigh_cell_cfg.from_number(01); + meas_cfg.meas_obj_to_add_mod_list.push_back(obj); meas_cfg.meas_obj_to_add_mod_list_present = true; - report_cfg_to_add_mod_s rep = {}; - rep.report_cfg_id = 1; + report_cfg_to_add_mod_s rep = {}; + rep.report_cfg_id = 1; rep.report_cfg.set_report_cfg_inter_rat(); rep.report_cfg.report_cfg_inter_rat().ext = true; rep.report_cfg.report_cfg_inter_rat().trigger_type.set_event(); rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.set_event_b1_nr_r15(); - rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.event_b1_nr_r15().b1_thres_nr_r15.set_nr_rsrp_r15(); + rep.report_cfg.report_cfg_inter_rat() + .trigger_type.event() + .event_id.event_b1_nr_r15() + .b1_thres_nr_r15.set_nr_rsrp_r15(); rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.event_b1_nr_r15().b1_thres_nr_r15.nr_rsrp_r15() = 56; rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.event_b1_nr_r15().report_on_leave_r15 = true; - rep.report_cfg.report_cfg_inter_rat().trigger_type.event().hysteresis = 0; - rep.report_cfg.report_cfg_inter_rat().trigger_type.event().time_to_trigger = asn1::rrc::time_to_trigger_opts::options::ms100; + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().hysteresis = 0; + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().time_to_trigger = + asn1::rrc::time_to_trigger_opts::options::ms100; rep.report_cfg.report_cfg_inter_rat().max_report_cells = 8; - rep.report_cfg.report_cfg_inter_rat().report_interv = asn1::rrc::report_interv_opts::options::ms120; - rep.report_cfg.report_cfg_inter_rat().report_amount = asn1::rrc::report_cfg_inter_rat_s::report_amount_opts::r1; + rep.report_cfg.report_cfg_inter_rat().report_interv = asn1::rrc::report_interv_opts::options::ms120; + rep.report_cfg.report_cfg_inter_rat().report_amount = asn1::rrc::report_cfg_inter_rat_s::report_amount_opts::r1; rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15.reset(new asn1::rrc::report_quant_nr_r15_s{}); rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_rsrp = true; rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_rsrq = true; - rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_sinr = true; + rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_sinr = true; meas_cfg.report_cfg_to_add_mod_list.push_back(rep); meas_cfg.report_cfg_to_add_mod_list_present = true; meas_cfg.meas_id_to_add_mod_list_present = true; - meas_id_to_add_mod_s meas = {}; - meas.meas_id = 1; - meas.meas_obj_id = 2; - meas.report_cfg_id = 1; + meas_id_to_add_mod_s meas = {}; + meas.meas_id = 1; + meas.meas_obj_id = 2; + meas.report_cfg_id = 1; meas_cfg.meas_id_to_add_mod_list.push_back(meas); // Just test it doesn't crash TESTASSERT(rrctest.send_meas_cfg(rrc_conn_recfg)); TESTASSERT(rrctest.phytest.meas_nof_freqs() == 0); -#ifdef HAVE_5GNR rrctest.add_neighbour_cell(2, 300, 2.0); rrctest.set_serving_cell(2, 300); @@ -1260,16 +1258,24 @@ int meas_obj_inter_rat_nr_test() int ttt_iters = 100 + 1; // 100 ms for (int i = 0; i < ttt_iters; i++) { - log1->info("Report %d/%d enter condition is true\n", i, ttt_iters); + srslog::fetch_basic_logger("RRC_MEAS").info("Report %d/%d enter condition is true", i, ttt_iters); rrctest.add_neighbour_cell_nr(500, 631680, -60.0); } -#endif return SRSLTE_SUCCESS; } int main(int argc, char** argv) { + auto& rrc_meas_logger = srslog::fetch_basic_logger("RRC_MEAS", false); + rrc_meas_logger.set_level(srslog::basic_levels::debug); + rrc_meas_logger.set_hex_dump_max_size(-1); + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(-1); + + srslog::init(); + TESTASSERT(cell_select_test() == SRSLTE_SUCCESS); TESTASSERT(meas_obj_test() == SRSLTE_SUCCESS); TESTASSERT(meas_obj_inter_rat_nr_test() == SRSLTE_SUCCESS); diff --git a/srsue/test/upper/rrc_phy_ctrl_test.cc b/srsue/test/upper/rrc_phy_ctrl_test.cc index bf50d5cf3..81f7f7262 100644 --- a/srsue/test/upper/rrc_phy_ctrl_test.cc +++ b/srsue/test/upper/rrc_phy_ctrl_test.cc @@ -25,8 +25,6 @@ namespace srsue { -srslte::log_ref test_log{"TEST"}; - struct cell_search_result_test { cell_search_result_test(phy_controller* phy_ctrl_) : phy_ctrl(phy_ctrl_) {} @@ -36,8 +34,8 @@ struct cell_search_result_test { result = result_; if (phy_ctrl->current_state_name() == "searching_cell" or phy_ctrl->is_trigger_locked()) { - phy_ctrl->get_log()->error( - "When caller is signalled with cell search result, cell search state cannot be active\n"); + phy_ctrl->get_logger().error( + "When caller is signalled with cell search result, cell search state cannot be active"); exit(1); } } @@ -54,16 +52,16 @@ struct cell_select_result_test { { result = result_ ? 1 : 0; if (phy_ctrl->current_state_name() == "selecting_cell" or phy_ctrl->is_trigger_locked()) { - phy_ctrl->get_log()->error( - "When caller is signalled with cell select result, cell select state cannot be active\n"); + phy_ctrl->get_logger().error( + "When caller is signalled with cell select result, cell select state cannot be active"); exit(1); } // start a new cell selection right away if (counter++ < 1) { phy_cell_t new_cell = {}; - new_cell.pci = 3; - new_cell.earfcn = 3400; + new_cell.pci = 3; + new_cell.earfcn = 3400; phy_ctrl->start_cell_select(new_cell, *this); } } @@ -202,9 +200,15 @@ int test_phy_cell_select_init_error_handling() int main() { - srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO); + auto& test_logger = srslog::fetch_basic_logger("TEST", false); + test_logger.set_level(srslog::basic_levels::info); + test_logger.set_hex_dump_max_size(-1); + auto& RRC_logger = srslog::fetch_basic_logger("RRC", false); + RRC_logger.set_level(srslog::basic_levels::info); + RRC_logger.set_hex_dump_max_size(-1); + srslog::init(); TESTASSERT(srsue::test_phy_ctrl_fsm() == SRSLTE_SUCCESS); TESTASSERT(srsue::test_phy_cell_select_init_error_handling() == SRSLTE_SUCCESS); - srsue::test_log->info("Finished RRC PHY controller test successfully\n"); + test_logger.info("Finished RRC PHY controller test successfully"); } diff --git a/srsue/test/upper/rrc_reconfig_test.cc b/srsue/test/upper/rrc_reconfig_test.cc index ce1e50e2e..7dc0e4b0d 100644 --- a/srsue/test/upper/rrc_reconfig_test.cc +++ b/srsue/test/upper/rrc_reconfig_test.cc @@ -22,6 +22,7 @@ #include "srslte/asn1/liblte_mme.h" #include "srslte/asn1/rrc/dl_dcch_msg.h" #include "srslte/common/log_filter.h" +#include "srslte/srslog/srslog.h" #include #include @@ -155,6 +156,14 @@ int meas_obj_test() int main(int argc, char** argv) { + auto& nas_logger = srslog::fetch_basic_logger("NAS", false); + nas_logger.set_level(srslog::basic_levels::debug); + nas_logger.set_hex_dump_max_size(-1); + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(-1); + srslog::init(); + TESTASSERT(meas_obj_test() == 0); TESTASSERT(nas_test() == 0); } diff --git a/srsue/test/upper/tft_test.cc b/srsue/test/upper/tft_test.cc index eca8fbf44..c607bdba4 100644 --- a/srsue/test/upper/tft_test.cc +++ b/srsue/test/upper/tft_test.cc @@ -114,41 +114,38 @@ uint8_t ipv6_unmatched_packet_lport[] = { int tft_filter_test_ipv6_combined() { - srslte::log_filter log1("TFT"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT"); srslte::unique_byte_buffer_t ip_msg1, ip_msg2, ip_msg3, ip_msg4, ip_msg5; - ip_msg1 = allocate_unique_buffer(*pool); - ip_msg2 = allocate_unique_buffer(*pool); - ip_msg3 = allocate_unique_buffer(*pool); - ip_msg4 = allocate_unique_buffer(*pool); - ip_msg5 = allocate_unique_buffer(*pool); + ip_msg1 = make_byte_buffer(); + ip_msg2 = make_byte_buffer(); + ip_msg3 = make_byte_buffer(); + ip_msg4 = make_byte_buffer(); + ip_msg5 = make_byte_buffer(); // Set IP test message ip_msg1->N_bytes = sizeof(ipv6_matched_packet); memcpy(ip_msg1->msg, ipv6_matched_packet, sizeof(ipv6_matched_packet)); - log1.info_hex(ip_msg1->msg, ip_msg1->N_bytes, "IPv6 test message - match\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IPv6 test message - match"); // Set IP test message ip_msg2->N_bytes = sizeof(ipv6_unmatched_packet_tcp); memcpy(ip_msg2->msg, ipv6_unmatched_packet_tcp, sizeof(ipv6_unmatched_packet_tcp)); - log1.info_hex(ip_msg2->msg, ip_msg2->N_bytes, "IPv6 test message - unmatched tcp\n"); + logger.info(ip_msg2->msg, ip_msg2->N_bytes, "IPv6 test message - unmatched tcp"); // Set IP test message ip_msg3->N_bytes = sizeof(ipv6_unmatched_packet_daddr); memcpy(ip_msg3->msg, ipv6_unmatched_packet_daddr, sizeof(ipv6_unmatched_packet_daddr)); - log1.info_hex(ip_msg3->msg, ip_msg3->N_bytes, "IPv6 test message - unmatched daddr\n"); + logger.info(ip_msg3->msg, ip_msg3->N_bytes, "IPv6 test message - unmatched daddr"); // Set IP test message ip_msg4->N_bytes = sizeof(ipv6_unmatched_packet_rport); memcpy(ip_msg4->msg, ipv6_unmatched_packet_rport, sizeof(ipv6_unmatched_packet_rport)); - log1.info_hex(ip_msg4->msg, ip_msg4->N_bytes, "IPv6 test message - unmatched rport\n"); + logger.info(ip_msg4->msg, ip_msg4->N_bytes, "IPv6 test message - unmatched rport"); // Set IP test message ip_msg5->N_bytes = sizeof(ipv6_unmatched_packet_lport); memcpy(ip_msg5->msg, ipv6_unmatched_packet_lport, sizeof(ipv6_unmatched_packet_lport)); - log1.info_hex(ip_msg5->msg, ip_msg5->N_bytes, "IPv6 test message - unmatched lport\n"); + logger.info(ip_msg5->msg, ip_msg5->N_bytes, "IPv6 test message - unmatched lport"); // Packet filter LIBLTE_MME_PACKET_FILTER_STRUCT packet_filter; @@ -159,7 +156,7 @@ int tft_filter_test_ipv6_combined() packet_filter.filter_size = sizeof(ipv6_filter); memcpy(packet_filter.filter, ipv6_filter, sizeof(ipv6_filter)); - srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, &log1); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, logger); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -174,14 +171,11 @@ int tft_filter_test_ipv6_combined() int tft_filter_test_single_local_port() { - srslte::log_filter log1("TFT"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT"); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::unique_byte_buffer_t ip_msg1, ip_msg2; - ip_msg1 = allocate_unique_buffer(*pool); - ip_msg2 = allocate_unique_buffer(*pool); + ip_msg1 = make_byte_buffer(); + ip_msg2 = make_byte_buffer(); // Filter length: 3 bytes // Filter type: Single local port @@ -193,12 +187,12 @@ int tft_filter_test_single_local_port() // Set IP test message ip_msg1->N_bytes = ip_message_len1; memcpy(ip_msg1->msg, ip_tst_message1, ip_message_len1); - log1.info_hex(ip_msg1->msg, ip_msg1->N_bytes, "IP test message\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IP test message"); // Set IP test message ip_msg2->N_bytes = ip_message_len2; memcpy(ip_msg2->msg, ip_tst_message2, ip_message_len1); - log1.info_hex(ip_msg2->msg, ip_msg2->N_bytes, "IP test message\n"); + logger.info(ip_msg2->msg, ip_msg2->N_bytes, "IP test message"); // Packet filter LIBLTE_MME_PACKET_FILTER_STRUCT packet_filter; @@ -209,7 +203,7 @@ int tft_filter_test_single_local_port() packet_filter.filter_size = 3; memcpy(packet_filter.filter, filter_message, 3); - srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, &log1); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, logger); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -221,14 +215,11 @@ int tft_filter_test_single_local_port() int tft_filter_test_single_remote_port() { - srslte::log_filter log1("TFT"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT"); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::unique_byte_buffer_t ip_msg1, ip_msg2; - ip_msg1 = allocate_unique_buffer(*pool); - ip_msg2 = allocate_unique_buffer(*pool); + ip_msg1 = make_byte_buffer(); + ip_msg2 = make_byte_buffer(); // Filter length: 3 bytes // Filter type: Single remote port @@ -240,12 +231,12 @@ int tft_filter_test_single_remote_port() // Set IP test message ip_msg1->N_bytes = ip_message_len1; memcpy(ip_msg1->msg, ip_tst_message1, ip_message_len1); - log1.info_hex(ip_msg1->msg, ip_msg1->N_bytes, "IP test message\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IP test message"); // Set IP test message ip_msg2->N_bytes = ip_message_len2; memcpy(ip_msg2->msg, ip_tst_message2, ip_message_len1); - log1.info_hex(ip_msg2->msg, ip_msg2->N_bytes, "IP test message\n"); + logger.info(ip_msg2->msg, ip_msg2->N_bytes, "IP test message"); // Packet filter LIBLTE_MME_PACKET_FILTER_STRUCT packet_filter; @@ -256,7 +247,7 @@ int tft_filter_test_single_remote_port() packet_filter.filter_size = 3; memcpy(packet_filter.filter, filter_message, 3); - srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, &log1); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, logger); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -268,14 +259,11 @@ int tft_filter_test_single_remote_port() int tft_filter_test_ipv4_local_addr() { - srslte::log_filter log1("TFT"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT"); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::unique_byte_buffer_t ip_msg1, ip_msg2; - ip_msg1 = allocate_unique_buffer(*pool); - ip_msg2 = allocate_unique_buffer(*pool); + ip_msg1 = make_byte_buffer(); + ip_msg2 = make_byte_buffer(); // Filter length: 9 bytes // Filter type: IPv4 local address @@ -290,12 +278,12 @@ int tft_filter_test_ipv4_local_addr() // Set IP test message ip_msg1->N_bytes = ip_message_len1; memcpy(ip_msg1->msg, ip_tst_message1, ip_message_len1); - log1.info_hex(ip_msg1->msg, ip_msg1->N_bytes, "IP test message\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IP test message"); // Set IP test message ip_msg2->N_bytes = ip_message_len2; memcpy(ip_msg2->msg, ip_tst_message2, ip_message_len2); - log1.info_hex(ip_msg2->msg, ip_msg2->N_bytes, "IP test message\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IP test message"); // Packet filter LIBLTE_MME_PACKET_FILTER_STRUCT packet_filter; @@ -306,7 +294,7 @@ int tft_filter_test_ipv4_local_addr() packet_filter.filter_size = filter_size; memcpy(packet_filter.filter, filter_message, filter_size); - srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, &log1); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, logger); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -318,14 +306,11 @@ int tft_filter_test_ipv4_local_addr() int tft_filter_test_ipv4_remote_addr() { - srslte::log_filter log1("TFT"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT"); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::unique_byte_buffer_t ip_msg1, ip_msg2; - ip_msg1 = allocate_unique_buffer(*pool); - ip_msg2 = allocate_unique_buffer(*pool); + ip_msg1 = make_byte_buffer(); + ip_msg2 = make_byte_buffer(); // Filter length: 5 bytes // Filter type: IPv4 local address @@ -339,12 +324,12 @@ int tft_filter_test_ipv4_remote_addr() // Set IP test message ip_msg1->N_bytes = ip_message_len1; memcpy(ip_msg1->msg, ip_tst_message1, ip_message_len1); - log1.info_hex(ip_msg1->msg, ip_msg1->N_bytes, "IP test message\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IP test message"); // Set IP test message ip_msg2->N_bytes = ip_message_len2; memcpy(ip_msg2->msg, ip_tst_message2, ip_message_len2); - log1.info_hex(ip_msg2->msg, ip_msg2->N_bytes, "IP test message\n"); + logger.info(ip_msg2->msg, ip_msg2->N_bytes, "IP test message"); // Packet filter LIBLTE_MME_PACKET_FILTER_STRUCT packet_filter; @@ -355,7 +340,7 @@ int tft_filter_test_ipv4_remote_addr() packet_filter.filter_size = filter_size; memcpy(packet_filter.filter, filter_message, filter_size); - srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, &log1); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, logger); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -367,14 +352,11 @@ int tft_filter_test_ipv4_remote_addr() int tft_filter_test_ipv4_tos() { - srslte::log_filter log1("TFT"); - log1.set_level(srslte::LOG_LEVEL_DEBUG); - log1.set_hex_limit(128); + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT"); - srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::unique_byte_buffer_t ip_msg1, ip_msg2; - ip_msg1 = allocate_unique_buffer(*pool); - ip_msg2 = allocate_unique_buffer(*pool); + ip_msg1 = make_byte_buffer(); + ip_msg2 = make_byte_buffer(); // Filter length: 3 bytes // Filter type: Type of service @@ -389,12 +371,12 @@ int tft_filter_test_ipv4_tos() // Set IP test message ip_msg1->N_bytes = ip_message_len1; memcpy(ip_msg1->msg, ip_tst_message1, ip_message_len1); - log1.info_hex(ip_msg1->msg, ip_msg1->N_bytes, "IP test message\n"); + logger.info(ip_msg1->msg, ip_msg1->N_bytes, "IP test message"); // Set IP test message ip_msg2->N_bytes = ip_message_len2; memcpy(ip_msg2->msg, ip_tst_message2, ip_message_len2); - log1.info_hex(ip_msg2->msg, ip_msg2->N_bytes, "IP test message\n"); + logger.info(ip_msg2->msg, ip_msg2->N_bytes, "IP test message"); // Packet filter LIBLTE_MME_PACKET_FILTER_STRUCT packet_filter; @@ -405,7 +387,7 @@ int tft_filter_test_ipv4_tos() packet_filter.filter_size = filter_size; memcpy(packet_filter.filter, filter_message, filter_size); - srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, &log1); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, LCID, packet_filter, logger); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -417,6 +399,11 @@ int tft_filter_test_ipv4_tos() int main(int argc, char** argv) { + srslog::basic_logger& logger = srslog::fetch_basic_logger("TFT", false); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(128); + srslog::init(); + srslte::byte_buffer_pool::get_instance(); if (tft_filter_test_single_local_port()) { return -1; @@ -436,5 +423,4 @@ int main(int argc, char** argv) if (tft_filter_test_ipv6_combined()) { return -1; } - srslte::byte_buffer_pool::cleanup(); } diff --git a/srsue/test/upper/usim_test.cc b/srsue/test/upper/usim_test.cc index e500ad108..15aeec006 100644 --- a/srsue/test/upper/usim_test.cc +++ b/srsue/test/upper/usim_test.cc @@ -19,10 +19,8 @@ * */ -#include "srslte/common/log_filter.h" #include "srslte/common/test_common.h" #include "srsue/hdr/stack/upper/usim.h" -#include using namespace srsue; @@ -54,18 +52,23 @@ AUTN : d7.44.51.9b.25.aa.80.00.84.ba.37.b0.f6.73.4d.d1. KASME : a8.27.57.5e.ea.1a.10.17.3a.a1.bf.ce.4b.0c.21.85.e0.51.ef.bd.91.7f.fe.f5.1f.74.29.61.f9.03.7a.35. */ -uint8_t rand_enb[] = {0x88, 0x38, 0xc3, 0x55, 0xc8, 0x78, 0xaa, 0x57, 0x21, 0x49, 0xfe, 0x69, 0xdb, 0x68, 0x6b, 0x5a}; -uint8_t autn_enb[] = {0xd7, 0x44, 0x51, 0x9b, 0x25, 0xaa, 0x80, 0x00, 0x84, 0xba, 0x37, 0xb0, 0xf6, 0x73, 0x4d, 0xd1}; +static uint8_t rand_enb[] = + {0x88, 0x38, 0xc3, 0x55, 0xc8, 0x78, 0xaa, 0x57, 0x21, 0x49, 0xfe, 0x69, 0xdb, 0x68, 0x6b, 0x5a}; +static uint8_t autn_enb[] = + {0xd7, 0x44, 0x51, 0x9b, 0x25, 0xaa, 0x80, 0x00, 0x84, 0xba, 0x37, 0xb0, 0xf6, 0x73, 0x4d, 0xd1}; -uint16 mcc = 208; -uint16 mnc = 93; +static constexpr uint16 mcc = 208; +static constexpr uint16 mnc = 93; int main(int argc, char** argv) { - srslte::log_filter usim_log("USIM"); - uint8_t res[16]; - int res_len; - uint8_t k_asme[32]; + auto& logger = srslog::fetch_basic_logger("USIM", false); + // Start the log backend. + srslog::init(); + + uint8_t res[16]; + int res_len; + uint8_t k_asme[32]; usim_args_t args; args.algo = "milenage"; @@ -75,7 +78,7 @@ int main(int argc, char** argv) args.using_op = true; args.op = "11111111111111111111111111111111"; - srsue::usim usim(&usim_log); + srsue::usim usim(logger); usim.init(&args); TESTASSERT(usim.generate_authentication_response(rand_enb, autn_enb, mcc, mnc, res, &res_len, k_asme) == AUTH_OK); diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index b9890f966..47176060d 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -5,12 +5,13 @@ ##################################################################### # RF configuration # -# dl_earfcn: Downlink EARFCN code. +# dl_earfcn: Downlink EARFCN code. # freq_offset: Uplink and Downlink optional frequency offset (in Hz) # tx_gain: Transmit gain (dB). # rx_gain: Optional receive gain (dB). If disabled, AGC if enabled # # Optional parameters: +# dl_nr_arfcn: Downlink NR ARFCN for EN-DC # dl_freq: Override DL frequency corresponding to dl_earfcn # ul_freq: Override UL frequency corresponding to dl_earfcn # nof_carriers: Number of carriers @@ -29,6 +30,7 @@ ##################################################################### [rf] dl_earfcn = 3350 +#dl_nr_arfcn = 632628 freq_offset = 0 tx_gain = 80 #rx_gain = 40