mirror of https://github.com/PentHertz/srsLTE.git
Merge branch 'next' into agpl_next
# Conflicts: # lib/include/srslte/common/mac_nr_pcap.h # lib/include/srslte/phy/ue/ue_ul_nr_data.h # lib/src/common/mac_nr_pcap.cc # lib/src/phy/ue/ue_ul_nr_data.c # srsenb/hdr/phy/lte/worker_pool.h # srsenb/hdr/phy/nr/cc_worker.h # srsenb/hdr/phy/nr/sf_worker.h # srsenb/hdr/phy/nr/worker_pool.h # srsenb/src/phy/lte/worker_pool.cc # srsenb/src/phy/nr/cc_worker.cc # srsenb/src/phy/nr/sf_worker.cc # srsenb/src/phy/nr/worker_pool.cc # srsue/hdr/phy/lte/worker_pool.h # srsue/hdr/phy/nr/cc_worker.h # srsue/hdr/phy/nr/sf_worker.h # srsue/hdr/phy/nr/worker_pool.h # srsue/hdr/stack/mac/mac_nr.h # srsue/src/phy/lte/worker_pool.cc # srsue/src/phy/nr/cc_worker.cc # srsue/src/phy/nr/sf_worker.cc # srsue/src/phy/nr/worker_pool.cc # srsue/src/stack/mac/mac_nr.cc
This commit is contained in:
commit
3daa9f3fc3
|
@ -75,7 +75,7 @@ IndentWidth: 2
|
|||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
########################################################################
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
|
|
@ -31,4 +31,4 @@ add_subdirectory(test)
|
|||
########################################################################
|
||||
INSTALL( DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h" )
|
||||
FILES_MATCHING PATTERN "*.h" )
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,9 @@ class circular_array
|
|||
std::array<T, N> 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
|
||||
|
|
|
@ -241,6 +241,9 @@ inline bool operator!=(span<T> lhs, span<T> rhs)
|
|||
return not lhs.equals(rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using const_span = span<const T>;
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
#endif // SRSLTE_SPAN_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 <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -62,10 +62,29 @@ struct static_max<arg1, arg2, others...> {
|
|||
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 <typename... Args>
|
||||
void log_error(const char* format, Args&&... args)
|
||||
{
|
||||
srslog::fetch_basic_logger("ASN1").error(format, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void log_warning(const char* format, Args&&... args)
|
||||
{
|
||||
srslog::fetch_basic_logger("ASN1").warning(format, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void log_info(const char* format, Args&&... args)
|
||||
{
|
||||
srslog::fetch_basic_logger("ASN1").info(format, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void log_debug(const char* format, Args&&... args)
|
||||
{
|
||||
srslog::fetch_basic_logger("ASN1").debug(format, std::forward<Args>(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<N, aligned>& 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<LB, UB, aligned>& 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2467,6 +2467,15 @@ private:
|
|||
elem_type_paramT_ c;
|
||||
};
|
||||
|
||||
|
||||
template <class elem_type_paramT_>
|
||||
std::string setup_release_c<elem_type_paramT_>::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;
|
||||
|
|
|
@ -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
|
||||
**************************/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 <class ies_set_paramT_>
|
||||
struct protocol_ie_single_container_s;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 <array>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
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<uint32_t> 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_raster_params, 3> 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, nof_nr_bands_fr1> 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
|
|
@ -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 <arpa/inet.h>
|
||||
#include <atomic>
|
||||
#include <errno.h>
|
||||
|
@ -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<std::thread> 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<std::uint32_t> tti;
|
||||
|
|
|
@ -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 <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -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<basic_vnf_api::tx_request_msg_t> m_tx_req_msg;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef SRSLTE_BUFFER_POOL_H
|
||||
#define SRSLTE_BUFFER_POOL_H
|
||||
|
||||
#include "byte_buffer.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <pthread.h>
|
||||
|
@ -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<sizeof(byte_buffer_t), alignof(byte_buffer_t)>::type;
|
||||
|
||||
public:
|
||||
// Singleton static methods
|
||||
static std::unique_ptr<byte_buffer_pool> 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<byte_buffer_t>(capacity);
|
||||
static std::unique_ptr<byte_buffer_pool> 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<mem_chunk*>(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<byte_buffer_t>* pool;
|
||||
/// Formats and prints the input string and arguments into the configured output stream.
|
||||
template <typename... Args>
|
||||
void print_error(const char* str, Args&&... args)
|
||||
{
|
||||
if (print_to_log) {
|
||||
srslog::fetch_basic_logger("POOL", false).error(str, std::forward<Args>(args)...);
|
||||
} else {
|
||||
fmt::printf(std::string(str) + "\n", std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool print_to_log = false;
|
||||
buffer_pool<mem_chunk> 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<byte_buffer_t>(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<byte_buffer_t>(new (std::nothrow) byte_buffer_t(size, value));
|
||||
}
|
||||
|
||||
inline unique_byte_buffer_t make_byte_buffer(const char* debug_ctxt) noexcept
|
||||
{
|
||||
std::unique_ptr<byte_buffer_t> 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
|
||||
|
|
|
@ -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 <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
//#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::microseconds>(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<byte_buffer_t>;
|
||||
|
||||
///
|
||||
/// Utilities to create a span out of a byte_buffer.
|
||||
///
|
||||
|
||||
using byte_span = span<uint8_t>;
|
||||
using const_byte_span = span<const uint8_t>;
|
||||
|
||||
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
|
|
@ -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::microseconds>(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<byte_buffer_t, byte_buffer_deleter> unique_byte_buffer_t;
|
||||
|
||||
///
|
||||
/// Utilities to create a span out of a byte_buffer.
|
||||
///
|
||||
|
||||
using byte_span = span<uint8_t>;
|
||||
using const_byte_span = span<const uint8_t>;
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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 <fstream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 <cstdio>
|
||||
#include <deque>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#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<FSM, State, Stat
|
|||
//! Helper type for FSM state-related operations
|
||||
template <typename FSM, typename State>
|
||||
struct state_traits {
|
||||
static_assert(FSM::template can_hold_state<State>(), "FSM type does not hold provided State\n");
|
||||
static_assert(FSM::template can_hold_state<State>(), "FSM type does not hold provided State");
|
||||
using state_t = State;
|
||||
using is_subfsm = std::integral_constant<bool, ::srslte::is_composite_fsm<State>::value>;
|
||||
|
||||
|
@ -234,7 +235,7 @@ struct apply_first_guard_pass<FSM, type_list<First, Rows...> > {
|
|||
// Log Transition
|
||||
if (std::is_same<src_state, dest_state>::value) {
|
||||
otherfsmInfo(static_cast<typename FSM::derived_t*>(f),
|
||||
"Event \"%s\" triggered state \"%s\" update\n",
|
||||
"Event \"%s\" triggered state \"%s\" update",
|
||||
get_type_name<event_type>().c_str(),
|
||||
get_type_name<src_state>().c_str());
|
||||
} else {
|
||||
|
@ -259,7 +260,7 @@ struct apply_first_guard_pass<FSM, type_list<> > {
|
|||
{
|
||||
if (should_log_unhandled_event(&ev)) {
|
||||
otherfsmDebug(static_cast<typename FSM::derived_t*>(f),
|
||||
"unhandled event caught in state \"%s\": \"%s\"\n",
|
||||
"unhandled event caught in state \"%s\": \"%s\"",
|
||||
get_type_name<SrcState>().c_str(),
|
||||
get_type_name<Event>().c_str());
|
||||
}
|
||||
|
@ -394,7 +395,7 @@ public:
|
|||
struct state_list : public std::tuple<States...> {
|
||||
using tuple_base_t = std::tuple<States...>;
|
||||
using init_state_t = typename std::decay<decltype(std::get<0>(std::declval<tuple_base_t>()))>::type;
|
||||
static_assert(not type_list_contains<Derived, States...>(), "An FSM cannot contain itself as state\n");
|
||||
static_assert(not type_list_contains<Derived, States...>(), "An FSM cannot contain itself as state");
|
||||
|
||||
template <typename... Args>
|
||||
state_list(base_fsm_t<Derived>* f, Args&&... args) : tuple_base_t(std::forward<Args>(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 <typename Ev>
|
||||
|
@ -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 <typename... Args>
|
||||
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>(args)...);
|
||||
switch (log_level) {
|
||||
case srslog::basic_levels::debug:
|
||||
logger.debug(format, std::forward<Args>(args)...);
|
||||
break;
|
||||
case LOG_LEVEL_INFO:
|
||||
log_h->info(format, std::forward<Args>(args)...);
|
||||
case srslog::basic_levels::info:
|
||||
logger.info(format, std::forward<Args>(args)...);
|
||||
break;
|
||||
case LOG_LEVEL_WARNING:
|
||||
log_h->warning(format, std::forward<Args>(args)...);
|
||||
case srslog::basic_levels::warning:
|
||||
logger.warning(format, std::forward<Args>(args)...);
|
||||
break;
|
||||
case LOG_LEVEL_ERROR:
|
||||
log_h->error(format, std::forward<Args>(args)...);
|
||||
case srslog::basic_levels::error:
|
||||
logger.error(format, std::forward<Args>(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<srslte::move_callback<void()> > 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 <typename Ev>
|
||||
|
@ -643,7 +644,7 @@ class proc_fsm_t : public fsm_t<Derived>
|
|||
using fsm_t<Derived>::derived;
|
||||
|
||||
protected:
|
||||
using fsm_t<Derived>::log_h;
|
||||
using fsm_t<Derived>::logger;
|
||||
|
||||
public:
|
||||
using base_t = proc_fsm_t<Derived, Result>;
|
||||
|
@ -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<Derived>().c_str(), f->launch_counter);
|
||||
f->logger.warning(
|
||||
"FSM \"%s\": No result was set for run no. %d", get_type_name<Derived>().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<Derived>().c_str(), f->launch_counter);
|
||||
f->logger.info("FSM \"%s\": Finished run no. %d", get_type_name<Derived>().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<Derived>().c_str(), f->launch_counter);
|
||||
f->logger.info("FSM \"%s\": Starting run no. %d", get_type_name<Derived>().c_str(), f->launch_counter);
|
||||
}
|
||||
};
|
||||
|
||||
explicit proc_fsm_t(srslte::log_ref log_) : fsm_t<Derived>(log_) {}
|
||||
explicit proc_fsm_t(srslog::basic_logger& logger) : fsm_t<Derived>(logger) {}
|
||||
|
||||
bool is_running() const { return not base_t::template is_in_state<idle_st>(); }
|
||||
|
||||
|
@ -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>{ev});
|
||||
|
|
|
@ -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 <string>
|
||||
|
|
|
@ -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 <string>
|
||||
|
||||
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
|
|
@ -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 <mutex>
|
||||
#include <stdint.h>
|
||||
#include <thread>
|
||||
|
||||
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<pcap_pdu_t> queue;
|
||||
std::mutex mutex;
|
||||
|
|
|
@ -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 <arpa/inet.h>
|
||||
|
@ -134,7 +133,7 @@ public:
|
|||
using sctp_recv_callback_t =
|
||||
std::function<void(srslte::unique_byte_buffer_t, const sockaddr_in&, const sctp_sndrcvinfo&, int)>;
|
||||
|
||||
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<int, rx_multisocket_handler::task_callback_t>::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;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define SRSLTE_SIGNAL_HANDLER_H
|
||||
|
||||
#include "srslte/srslog/sink.h"
|
||||
#include "srslte/srslog/srslog.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -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();
|
||||
|
|
|
@ -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 <atomic>
|
||||
#include <cstdio>
|
||||
|
||||
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<srslog::log_formatter> 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<unsigned> error_counter;
|
||||
std::atomic<unsigned> 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
|
||||
|
||||
|
|
|
@ -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 <chrono>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef ENABLE_TIMEPROF
|
||||
#define TPROF_ENABLE_DEFAULT true
|
||||
|
@ -57,8 +58,7 @@ class tprof
|
|||
public:
|
||||
template <typename... Args>
|
||||
explicit tprof(Args&&... args) : prof(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void start() { meas.start(); }
|
||||
|
||||
|
@ -80,8 +80,7 @@ class tprof<Prof, false>
|
|||
public:
|
||||
template <typename... Args>
|
||||
explicit tprof(Args&&... args)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void start() {}
|
||||
|
||||
|
@ -115,8 +114,7 @@ struct mutexed_tprof {
|
|||
|
||||
template <typename... Args>
|
||||
explicit mutexed_tprof(Args&&... args) : prof(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
{}
|
||||
measure start() { return measure{this}; }
|
||||
|
||||
Prof prof;
|
||||
|
@ -135,8 +133,7 @@ struct mutexed_tprof<Prof, false> {
|
|||
|
||||
template <typename... Args>
|
||||
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<long>::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<long>::max();
|
||||
long print_period = 0;
|
||||
};
|
||||
|
||||
template <typename TUnit>
|
||||
|
@ -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<std::chrono::nanoseconds> sliding_window;
|
||||
size_t window_idx = 0;
|
||||
|
|
|
@ -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<std::mutex> 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;
|
||||
|
|
|
@ -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 <cstdint>
|
||||
#include <limits>
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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 <vector>
|
||||
#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_t> 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_t> 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<bool, SRSLTE_MAX_CARRIERS>& 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_t> 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<sched_interface::cell_cfg_t>& 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<uint16_t>* erabs_modified,
|
||||
std::vector<uint16_t>* 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<uint16_t>* erabs_released,
|
||||
std::vector<uint16_t>* 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_info>& 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<asn1::fixed_octstring<4, true> > 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:
|
||||
|
|
|
@ -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_t> 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_t> 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<sched_interface::cell_cfg_t>& 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
|
|
@ -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<srslte::rlc_metrics_t> ues;
|
||||
};
|
||||
|
||||
struct pdcp_metrics_t {
|
||||
std::vector<srslte::pdcp_metrics_t> 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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 <map>
|
||||
|
||||
#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<uint32_t, srslte::unique_byte_buffer_t> 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<uint32_t>& pdcp_sns) = 0;
|
||||
virtual void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector<uint32_t>& pdcp_sns) = 0;
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
||||
#endif // SRSLTE_ENB_PDCP_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<bool, SRSLTE_MAX_CARRIERS>& 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_t> 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
|
|
@ -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
|
|
@ -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<uint16_t>* erabs_modified,
|
||||
std::vector<uint16_t>* 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<uint16_t>* erabs_released,
|
||||
std::vector<uint16_t>* 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
|
|
@ -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<uint32_t> 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_info>& 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<asn1::s1ap::erab_admitted_item_s> 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<uint16_t>& 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
|
|
@ -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<srslte::byte_buffer_t*>& pkt_queue) = 0;
|
||||
virtual void send_all_queued_packets(srslte::gtp_fteid_t dw_user_fteid,
|
||||
std::queue<srslte::unique_byte_buffer_t>& 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
|
||||
|
|
|
@ -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<uint32_t>& tx_count) = 0;
|
||||
virtual void notify_failure(uint16_t rnti, uint32_t lcid, const std::vector<uint32_t>& 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:
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 <string>
|
||||
|
||||
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
|
|
@ -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<uint32_t>& pdcp_sn) = 0;
|
||||
virtual void notify_failure(uint32_t lcid, const std::vector<uint32_t>& pdcp_sn) = 0;
|
||||
};
|
||||
|
||||
class pdcp_interface_gw
|
||||
|
@ -526,6 +536,10 @@ typedef struct {
|
|||
std::vector<uint32_t> dl_earfcn_list = {3400}; // vectorized version of dl_earfcn that gets populated during init
|
||||
std::map<uint32_t, uint32_t> 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<uint32_t> 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;
|
||||
|
|
|
@ -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 <array>
|
||||
#include <string>
|
||||
|
||||
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<uint8_t, SRSLTE_RAR_UL_GRANT_NBITS> 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,
|
||||
|
|
|
@ -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 <memory>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
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<uint8_t, UL_GRANT_NBITS> 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<uint8_t, UL_GRANT_NBITS> 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<mac_rar_subpdu_nr>& 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<mac_rar_subpdu_nr> 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
|
|
@ -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 <memory>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
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<lcg_bsr_t, max_num_lcg_lbsr> 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<uint8_t, mac_ce_payload_len> 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<mac_nr_sch_subpdu> subpdus;
|
||||
std::vector<mac_sch_subpdu_nr> 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
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "srslte/common/interfaces_common.h"
|
||||
#include "srslte/common/logmap.h"
|
||||
#include "srslte/srslog/srslog.h"
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
@ -127,10 +128,10 @@ template <class SubH>
|
|||
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<SubH> 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<SubH> 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<sch_subh>
|
||||
{
|
||||
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<rar_subh>
|
||||
{
|
||||
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 */
|
||||
|
|
|
@ -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_t*> pdu_q;
|
||||
buffer_pool<pdu_t> pool;
|
||||
|
||||
process_callback* callback;
|
||||
log_ref log_h;
|
||||
process_callback* callback;
|
||||
srslog::basic_logger& logger;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*!
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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; \
|
||||
} \
|
||||
\
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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__); \
|
||||
} \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<srslte_rf_info_t> rf_info = {};
|
||||
std::vector<int32_t> 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<cf_t*, SRSLTE_MAX_CHANNELS> dummy_buffers;
|
||||
|
@ -133,6 +130,8 @@ private:
|
|||
std::vector<double> cur_tx_freqs = {};
|
||||
std::vector<double> 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
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue