mirror of https://github.com/PentHertz/srsLTE.git
Merge branch 'next'
This commit is contained in:
commit
4bbcfaa1dc
|
@ -42,6 +42,8 @@ include(SRSLTEPackage) #setup cpack
|
|||
|
||||
include(CTest)
|
||||
set(CTEST_MEMORYCHECK_COMMAND valgrind)
|
||||
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full" )
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake"
|
||||
|
@ -66,7 +68,7 @@ option(ENABLE_BLADERF "Enable BladeRF" ON)
|
|||
option(BUILD_STATIC "Attempt to statically link external deps" OFF)
|
||||
option(RPATH "Enable RPATH" OFF)
|
||||
|
||||
option(USE_LTE_RATES "Use standard LTE sampling rates" OFF)
|
||||
option(USE_LTE_RATES "Use standard LTE sampling rates" OFF)
|
||||
|
||||
set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.")
|
||||
|
||||
|
@ -74,28 +76,62 @@ set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.")
|
|||
########################################################################
|
||||
# Find dependencies
|
||||
########################################################################
|
||||
|
||||
# Threads
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# FFT
|
||||
find_package(MKL)
|
||||
if(MKL_FOUND)
|
||||
include_directories(${MKL_INCLUDE_DIRS})
|
||||
link_directories(${MKL_LIBRARY_DIRS})
|
||||
set(FFT_LIBRARIES "${MKL_STATIC_LIBRARIES}") # Static by default
|
||||
else(MKL_FOUND)
|
||||
find_package(FFTW3F REQUIRED)
|
||||
if(FFTW3F_FOUND)
|
||||
include_directories(${FFTW3F_INCLUDE_DIRS})
|
||||
link_directories(${FFTW3F_LIBRARY_DIRS})
|
||||
if(BUILD_STATIC)
|
||||
set(FFT_LIBRARIES "${FFTW3F_STATIC_LIBRARIES}")
|
||||
else(BUILD_STATIC)
|
||||
set(FFT_LIBRARIES "${FFTW3F_LIBRARIES}")
|
||||
endif(BUILD_STATIC)
|
||||
endif(FFTW3F_FOUND)
|
||||
endif(MKL_FOUND)
|
||||
|
||||
# Crypto
|
||||
find_package(Polarssl)
|
||||
if (POLARSSL_FOUND)
|
||||
set(SEC_INCLUDE_DIRS "${POLARSSL_INCLUDE_DIRS}")
|
||||
set(SEC_LIBRARIES "${POLARSSL_LIBRARIES}")
|
||||
if(BUILD_STATIC)
|
||||
set(SEC_LIBRARIES "${POLARSSL_STATIC_LIBRARIES}")
|
||||
else(BUILD_STATIC)
|
||||
set(SEC_LIBRARIES "${POLARSSL_LIBRARIES}")
|
||||
endif(BUILD_STATIC)
|
||||
add_definitions(-DHAVE_POLARSSL)
|
||||
else(POLARSSL_FOUND)
|
||||
find_package(MbedTLS REQUIRED)
|
||||
if (MBEDTLS_FOUND)
|
||||
set(SEC_INCLUDE_DIRS "${MBEDTLS_INCLUDE_DIRS}")
|
||||
set(SEC_LIBRARIES "${MBEDTLS_LIBRARIES}")
|
||||
if(BUILD_STATIC)
|
||||
set(SEC_LIBRARIES "${MBEDTLS_STATIC_LIBRARIES}")
|
||||
else(BUILD_STATIC)
|
||||
set(SEC_LIBRARIES "${MBEDTLS_LIBRARIES}")
|
||||
endif(BUILD_STATIC)
|
||||
add_definitions(-DHAVE_MBEDTLS)
|
||||
else(MBEDTLS_FOUND)
|
||||
message(FATAL_ERROR "Either PolarSSL or mbedTLS are required to build srsLTE")
|
||||
endif (MBEDTLS_FOUND)
|
||||
endif(POLARSSL_FOUND)
|
||||
|
||||
# UHD
|
||||
find_package(UHD)
|
||||
if(UHD_FOUND)
|
||||
include_directories(${UHD_INCLUDE_DIRS})
|
||||
link_directories(${UHD_LIBRARY_DIRS})
|
||||
endif(UHD_FOUND)
|
||||
|
||||
# BladeRF
|
||||
if(ENABLE_BLADERF)
|
||||
find_package(bladeRF)
|
||||
if(BLADERF_FOUND)
|
||||
|
@ -104,6 +140,7 @@ if(ENABLE_BLADERF)
|
|||
endif(BLADERF_FOUND)
|
||||
endif(ENABLE_BLADERF)
|
||||
|
||||
# Soapy
|
||||
find_package(SoapySDR)
|
||||
if(SOAPYSDR_FOUND)
|
||||
include_directories(${SOAPYSDR_INCLUDE_DIRS})
|
||||
|
@ -117,8 +154,12 @@ else(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
|
|||
add_definitions(-DDISABLE_RF)
|
||||
endif(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
|
||||
|
||||
# Boost
|
||||
if(ENABLE_SRSUE OR ENABLE_SRSENB)
|
||||
# Find Boost
|
||||
if(BUILD_STATIC)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
endif(BUILD_STATIC)
|
||||
|
||||
set(BOOST_REQUIRED_COMPONENTS
|
||||
program_options
|
||||
system
|
||||
|
@ -138,7 +179,7 @@ if(ENABLE_SRSUE OR ENABLE_SRSENB)
|
|||
find_package(Boost "1.35" COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
|
||||
endif(ENABLE_SRSUE OR ENABLE_SRSENB)
|
||||
|
||||
|
||||
# srsGUI
|
||||
if(ENABLE_GUI)
|
||||
find_package(SRSGUI)
|
||||
if(SRSGUI_FOUND)
|
||||
|
@ -148,6 +189,7 @@ if(ENABLE_GUI)
|
|||
endif(SRSGUI_FOUND)
|
||||
endif(ENABLE_GUI)
|
||||
|
||||
# VOLK
|
||||
include(CheckFunctionExistsMath)
|
||||
if(ENABLE_VOLK)
|
||||
find_package(Volk)
|
||||
|
@ -162,7 +204,6 @@ else(ENABLE_VOLK)
|
|||
message(STATUS "VOLK library disabled")
|
||||
endif(ENABLE_VOLK)
|
||||
|
||||
|
||||
########################################################################
|
||||
# Install Dirs
|
||||
########################################################################
|
||||
|
|
|
@ -7,7 +7,7 @@ SET(CTEST_CUSTOM_MEMCHECK_IGNORE
|
|||
realplot_test
|
||||
complexplot_test
|
||||
|
||||
# Ignore these to, they take too lonk
|
||||
# Ignore these to, they take too long
|
||||
fft_normal
|
||||
fft_extened
|
||||
chest_test_all_cellids
|
||||
|
|
11
README.md
11
README.md
|
@ -15,11 +15,12 @@ srsLTE is released under the AGPLv3 license and uses software from the OpenLTE p
|
|||
Common Features
|
||||
---------------
|
||||
|
||||
* LTE Release 8 compliant
|
||||
* LTE Release 8 compliant (with selected features of Release 9)
|
||||
* FDD configuration
|
||||
* Tested bandwidths: 1.4, 3, 5, 10, 15 and 20 MHz
|
||||
* Transmission mode 1 (single antenna) and 2 (transmit diversity)
|
||||
* Transmission mode 1 (single antenna), 2 (transmit diversity), 3 (transmit diversity/CCD) and 4 (closed-loop spatial multiplexing)
|
||||
* Frequency-based ZF and MMSE equalizer
|
||||
* Evolved multimedia broadcast and multicast service (eMBMS)
|
||||
* Highly optimized Turbo Decoder available in Intel SSE4.1/AVX (+100 Mbps) and standard C (+25 Mbps)
|
||||
* MAC, RLC, PDCP, RRC, NAS, S1AP and GW layers
|
||||
* Detailed log system with per-layer log levels and hex dumps
|
||||
|
@ -33,6 +34,7 @@ srsUE Features
|
|||
* Cell search and synchronization procedure for the UE
|
||||
* Soft USIM supporting Milenage and XOR authentication
|
||||
* Virtual network interface *tun_srsue* created upon network attach
|
||||
* +100 Mbps DL in 20 MHz MIMO TM4 configuration in i7 Quad-Core CPU.
|
||||
* 75 Mbps DL in 20 MHz SISO configuration in i7 Quad-Core CPU.
|
||||
* 36 Mbps DL in 10 MHz SISO configuration in i5 Dual-Core CPU.
|
||||
|
||||
|
@ -65,13 +67,14 @@ We have tested the following hardware:
|
|||
* USRP B210
|
||||
* USRP X300
|
||||
* bladeRF
|
||||
* limeSDR
|
||||
* limeSDR (currently, only the PHY-layer examples, i.e., pdsch_enodeb/ue are supported)
|
||||
|
||||
Build Instructions
|
||||
------------------
|
||||
|
||||
* Mandatory requirements:
|
||||
* Common:
|
||||
* cmake https://cmake.org/
|
||||
* libfftw http://www.fftw.org/
|
||||
* PolarSSL/mbedTLS https://tls.mbed.org
|
||||
* srsUE:
|
||||
|
@ -83,7 +86,7 @@ Build Instructions
|
|||
|
||||
For example, on Ubuntu 17.04, one can install the required libraries with:
|
||||
```
|
||||
sudo apt-get install libfftw3-dev libmbedtls-dev libboost-all-dev libconfig++-dev libsctp-dev
|
||||
sudo apt-get install cmake libfftw3-dev libmbedtls-dev libboost-all-dev libconfig++-dev libsctp-dev
|
||||
```
|
||||
Note that depending on your flavor and version of Linux, the actual package names may be different.
|
||||
|
||||
|
|
|
@ -15,6 +15,12 @@ find_path(FFTW3F_INCLUDE_DIR
|
|||
PATHS /usr/local/include
|
||||
/usr/include )
|
||||
|
||||
find_library(FFTW3F_STATIC_LIBRARY
|
||||
NAMES fftw3f.a libfftw3f.a libfftw3f-3.a
|
||||
HINTS ${PC_FFTW3F_LIBDIR} ${PC_FFTW3F_LIBRARY_DIRS} $ENV{FFTW3_DIR}/lib
|
||||
PATHS /usr/local/lib
|
||||
/usr/lib)
|
||||
|
||||
find_library(FFTW3F_LIBRARY
|
||||
NAMES fftw3f libfftw3f libfftw3f-3
|
||||
HINTS ${PC_FFTW3F_LIBDIR} ${PC_FFTW3F_LIBRARY_DIRS} $ENV{FFTW3_DIR}/lib
|
||||
|
@ -22,12 +28,17 @@ find_library(FFTW3F_LIBRARY
|
|||
/usr/lib)
|
||||
|
||||
set(FFTW3F_LIBRARIES ${FFTW3F_LIBRARY} )
|
||||
set(FFTW3F_STATIC_LIBRARIES ${FFTW3F_STATIC_LIBRARY} )
|
||||
set(FFTW3F_INCLUDE_DIRS ${FFTW3F_INCLUDE_DIR} )
|
||||
|
||||
message(STATUS "FFTW3F LIBRARIES: " ${FFTW3F_LIBRARIES})
|
||||
message(STATUS "FFTW3F STATIC LIBRARIES: " ${FFTW3F_STATIC_LIBRARIES})
|
||||
message(STATUS "FFTW3F INCLUDE DIRS: " ${FFTW3F_INCLUDE_DIRS})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set FFTW3F_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(fftw3f DEFAULT_MSG
|
||||
FFTW3F_LIBRARY FFTW3F_INCLUDE_DIR)
|
||||
FFTW3F_LIBRARY FFTW3F_STATIC_LIBRARY FFTW3F_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(FFTW3F_INCLUDE_DIR FFTW3F_LIBRARY )
|
||||
mark_as_advanced(FFTW3F_INCLUDE_DIR FFTW3F_STATIC_LIBRARY FFTW3F_LIBRARY )
|
||||
|
|
|
@ -32,9 +32,23 @@ FIND_LIBRARY(
|
|||
/usr/lib64
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
MBEDTLS_STATIC_LIBRARIES
|
||||
NAMES libmbedcrypto.a
|
||||
HINTS $ENV{MBEDTLS_DIR}/lib
|
||||
${PC_MBEDTLS_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
message(STATUS "MBEDTLS LIBRARIES: " ${MBEDTLS_LIBRARIES})
|
||||
message(STATUS "MBEDTLS STATIC LIBRARIES: " ${MBEDTLS_STATIC_LIBRARIES})
|
||||
message(STATUS "MBEDTLS INCLUDE DIRS: " ${MBEDTLS_INCLUDE_DIRS})
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MBEDTLS DEFAULT_MSG MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(MBEDTLS_LIBRARIES MBEDTLS_STATIC_LIBRARIES MBEDTLS_INCLUDE_DIRS)
|
||||
|
|
|
@ -31,9 +31,23 @@ FIND_LIBRARY(
|
|||
/usr/lib64
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
POLARSSL_STATIC_LIBRARIES
|
||||
NAMES libpolarssl.a
|
||||
HINTS $ENV{POLARSSL_DIR}/lib
|
||||
${PC_POLARSSL_LIBDIR}
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
message(STATUS "POLARSSL LIBRARIES: " ${POLARSSL_LIBRARIES})
|
||||
message(STATUS "POLARSSL STATIC LIBRARIES: " ${POLARSSL_STATIC_LIBRARIES})
|
||||
message(STATUS "POLARSSL INCLUDE DIRS: " ${POLARSSL_INCLUDE_DIRS})
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(POLARSSL DEFAULT_MSG POLARSSL_LIBRARIES POLARSSL_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(POLARSSL_LIBRARIES POLARSSL_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(POLARSSL_STATIC_LIBRARIES POLARSSL_LIBRARIES POLARSSL_INCLUDE_DIRS)
|
||||
|
|
|
@ -7,6 +7,7 @@ include(CheckCSourceRuns)
|
|||
option(ENABLE_SSE "Enable compile-time SSE4.1 support." ON)
|
||||
option(ENABLE_AVX "Enable compile-time AVX support." ON)
|
||||
option(ENABLE_AVX2 "Enable compile-time AVX2 support." ON)
|
||||
option(ENABLE_FMA "Enable compile-time FMA support." ON)
|
||||
|
||||
if (ENABLE_SSE)
|
||||
#
|
||||
|
@ -97,8 +98,43 @@ if (ENABLE_SSE)
|
|||
if (HAVE_AVX2)
|
||||
message(STATUS "AVX2 is enabled - target CPU must support it")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ENABLE_FMA)
|
||||
|
||||
#
|
||||
# Check compiler for AVX intrinsics
|
||||
#
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG )
|
||||
set(CMAKE_REQUIRED_FLAGS "-mfma")
|
||||
check_c_source_runs("
|
||||
#include <immintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m256 a, b, c, r;
|
||||
const float src[8] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
|
||||
float dst[8];
|
||||
a = _mm256_loadu_ps( src );
|
||||
b = _mm256_loadu_ps( src );
|
||||
c = _mm256_loadu_ps( src );
|
||||
r = _mm256_fmadd_ps( a, b, c );
|
||||
_mm256_storeu_ps( dst, r );
|
||||
int i = 0;
|
||||
for( i = 0; i < 8; i++ ){
|
||||
if( ( src[i] * src[i] + src[i] ) != dst[i] ){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}"
|
||||
HAVE_FMA)
|
||||
endif()
|
||||
|
||||
if (HAVE_FMA)
|
||||
message(STATUS "FMA is enabled - target CPU must support it")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
mark_as_advanced(HAVE_SSE, HAVE_AVX, HAVE_AVX2)
|
||||
mark_as_advanced(HAVE_SSE, HAVE_AVX, HAVE_AVX2, HAVE_FMA)
|
||||
|
|
|
@ -16,6 +16,7 @@ FIND_LIBRARY(
|
|||
HINTS $ENV{UHD_DIR}/lib
|
||||
PATHS /usr/local/lib
|
||||
/usr/lib
|
||||
/usr/lib/x86_64-linux-gnu
|
||||
/usr/local/lib64
|
||||
/usr/local/lib32
|
||||
)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
SET(SRSLTE_VERSION_MAJOR 002)
|
||||
SET(SRSLTE_VERSION_MINOR 000)
|
||||
SET(SRSLTE_VERSION_PATCH 000)
|
||||
SET(SRSLTE_VERSION_MAJOR 17)
|
||||
SET(SRSLTE_VERSION_MINOR 9)
|
||||
SET(SRSLTE_VERSION_PATCH 0)
|
||||
SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}")
|
||||
|
|
|
@ -118,7 +118,7 @@ int parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
/**********************************************************************/
|
||||
|
||||
/* TODO: Do something with the output data */
|
||||
uint8_t data[1000000];
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS];
|
||||
|
||||
bool go_exit = false;
|
||||
void sig_int_handler(int signo)
|
||||
|
@ -161,6 +161,7 @@ int main(int argc, char **argv) {
|
|||
float rssi_utra=0,rssi=0, rsrp=0, rsrq=0, snr=0;
|
||||
cf_t *ce[SRSLTE_MAX_PORTS];
|
||||
float cfo = 0;
|
||||
bool acks[SRSLTE_MAX_CODEWORDS] = {false};
|
||||
|
||||
if (parse_args(&prog_args, argc, argv)) {
|
||||
exit(-1);
|
||||
|
@ -183,6 +184,9 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
|
||||
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
data[i] = srslte_vec_malloc(sizeof(uint8_t) * 1500*8);
|
||||
}
|
||||
|
||||
sigset_t sigset;
|
||||
sigemptyset(&sigset);
|
||||
|
@ -237,15 +241,27 @@ int main(int argc, char **argv) {
|
|||
srslte_rf_stop_rx_stream(&rf);
|
||||
srslte_rf_flush_buffer(&rf);
|
||||
|
||||
if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
|
||||
if (srslte_ue_sync_init_multi(&ue_sync, cell.nof_prb, cell.id==1000, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) {
|
||||
if (srslte_ue_sync_set_cell(&ue_sync, cell)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_ue_dl_init(&ue_dl, cell.nof_prb, 1)) {
|
||||
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_ue_mib_init(&ue_mib, cell)) {
|
||||
if (srslte_ue_dl_set_cell(&ue_dl, cell)) {
|
||||
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_ue_mib_init(&ue_mib, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initaiting UE MIB decoder\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_ue_mib_set_cell(&ue_mib, cell)) {
|
||||
fprintf(stderr, "Error initaiting UE MIB decoder\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -260,7 +276,11 @@ int main(int argc, char **argv) {
|
|||
fprintf(stderr, "Error initiating FFT\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_chest_dl_init(&chest, cell)) {
|
||||
if (srslte_chest_dl_init(&chest, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initiating channel estimator\n");
|
||||
return -1;
|
||||
}
|
||||
if (srslte_chest_dl_set_cell(&chest, cell)) {
|
||||
fprintf(stderr, "Error initiating channel estimator\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -310,19 +330,18 @@ int main(int argc, char **argv) {
|
|||
case DECODE_SIB:
|
||||
/* We are looking for SI Blocks, search only in appropiate places */
|
||||
if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
|
||||
n = srslte_ue_dl_decode_multi(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
|
||||
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, 0, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), acks);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
||||
return -1;
|
||||
} else if (n == 0) {
|
||||
printf("CFO: %+6.4f kHz, SFO: %+6.4f kHz, NOI: %.2f, PDCCH-Det: %.3f\r",
|
||||
printf("CFO: %+6.4f kHz, SFO: %+6.4f kHz, PDCCH-Det: %.3f\r",
|
||||
srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000,
|
||||
srslte_sch_average_noi(&ue_dl.pdsch.dl_sch),
|
||||
(float) ue_dl.nof_detected/nof_trials);
|
||||
nof_trials++;
|
||||
} else {
|
||||
printf("Decoded SIB1. Payload: ");
|
||||
srslte_vec_fprint_byte(stdout, data, n/8);;
|
||||
srslte_vec_fprint_byte(stdout, data[0], n/8);;
|
||||
state = MEASURE;
|
||||
}
|
||||
}
|
||||
|
@ -386,6 +405,12 @@ int main(int argc, char **argv) {
|
|||
sf_cnt++;
|
||||
} // Main loop
|
||||
|
||||
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
if (data[i]) {
|
||||
free(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
srslte_ue_sync_free(&ue_sync);
|
||||
srslte_rf_close(&rf);
|
||||
printf("\nBye\n");
|
||||
|
|
|
@ -188,6 +188,18 @@ int main(int argc, char **argv) {
|
|||
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
signal(SIGINT, sig_int_handler);
|
||||
|
||||
if (srslte_ue_cellsearch_init_multi(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
|
||||
fprintf(stderr, "Error initiating UE cell detect\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (cell_detect_config.max_frames_pss) {
|
||||
srslte_ue_cellsearch_set_nof_valid_frames(&cs, cell_detect_config.nof_valid_pss_frames);
|
||||
}
|
||||
if (cell_detect_config.init_agc) {
|
||||
srslte_ue_sync_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_wrapper, cell_detect_config.init_agc);
|
||||
}
|
||||
|
||||
for (freq=0;freq<nof_freqs && !go_exit;freq++) {
|
||||
|
||||
/* set rf_freq */
|
||||
|
@ -204,25 +216,12 @@ int main(int argc, char **argv) {
|
|||
|
||||
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
|
||||
|
||||
if (srslte_ue_cellsearch_init_multi(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
|
||||
fprintf(stderr, "Error initiating UE cell detect\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (cell_detect_config.max_frames_pss) {
|
||||
srslte_ue_cellsearch_set_nof_valid_frames(&cs, cell_detect_config.nof_valid_pss_frames);
|
||||
}
|
||||
if (cell_detect_config.init_agc) {
|
||||
srslte_ue_sync_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_wrapper, cell_detect_config.init_agc);
|
||||
}
|
||||
|
||||
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);
|
||||
srslte_rf_set_rx_srate(&rf, SRSLTE_CS_SAMP_FREQ);
|
||||
INFO("Starting receiver...\n", 0);
|
||||
srslte_rf_start_rx_stream(&rf);
|
||||
|
||||
n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL);
|
||||
srslte_ue_cellsearch_free(&cs);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error searching cell\n");
|
||||
exit(-1);
|
||||
|
@ -269,6 +268,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
printf("\nBye\n");
|
||||
|
||||
srslte_ue_cellsearch_free(&cs);
|
||||
srslte_rf_close(&rf);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -33,15 +33,18 @@
|
|||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
#include <srslte/phy/phch/pdsch_cfg.h>
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
|
||||
#define UE_CRNTI 0x1234
|
||||
|
||||
#define M_CRNTI 0xFFFD
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
#include "srslte/phy/rf/rf.h"
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
srslte_rf_t rf;
|
||||
#else
|
||||
#warning Compiling pdsch_ue with no RF support
|
||||
|
@ -55,36 +58,51 @@ char *output_file_name = NULL;
|
|||
#define DOWN_KEY 66
|
||||
|
||||
srslte_cell_t cell = {
|
||||
25, // nof_prb
|
||||
1, // nof_ports
|
||||
0, // cell_id
|
||||
SRSLTE_CP_NORM, // cyclic prefix
|
||||
SRSLTE_PHICH_R_1, // PHICH resources
|
||||
SRSLTE_PHICH_NORM // PHICH length
|
||||
25, // nof_prb
|
||||
1, // nof_ports
|
||||
0, // cell_id
|
||||
SRSLTE_CP_NORM, // cyclic prefix
|
||||
SRSLTE_PHICH_NORM, // PHICH length
|
||||
SRSLTE_PHICH_R_1 // PHICH resources
|
||||
};
|
||||
|
||||
uint16_t c = -1;
|
||||
|
||||
int net_port = -1; // -1 generates random dataThat means there is some problem sending samples to the device
|
||||
|
||||
uint32_t cfi=3;
|
||||
uint32_t cfi = 2;
|
||||
uint32_t mcs_idx = 1, last_mcs_idx = 1;
|
||||
int nof_frames = -1;
|
||||
|
||||
|
||||
char mimo_type_str[32] = "single";
|
||||
uint32_t nof_tb = 1;
|
||||
uint32_t multiplex_pmi = 0;
|
||||
uint32_t multiplex_nof_layers = 1;
|
||||
|
||||
int mbsfn_area_id = -1;
|
||||
char *rf_args = "";
|
||||
float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 2400000000;
|
||||
|
||||
bool null_file_sink=false;
|
||||
srslte_filesink_t fsink;
|
||||
srslte_ofdm_t ifft;
|
||||
srslte_ofdm_t ifft_mbsfn;
|
||||
srslte_pbch_t pbch;
|
||||
srslte_pcfich_t pcfich;
|
||||
srslte_pdcch_t pdcch;
|
||||
srslte_pdsch_t pdsch;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_softbuffer_tx_t softbuffer;
|
||||
srslte_pmch_t pmch;
|
||||
srslte_pdsch_cfg_t pmch_cfg;
|
||||
srslte_softbuffer_tx_t *softbuffers[SRSLTE_MAX_CODEWORDS];
|
||||
srslte_regs_t regs;
|
||||
srslte_ra_dl_dci_t ra_dl;
|
||||
int rvidx[SRSLTE_MAX_CODEWORDS] = {0, 0};
|
||||
|
||||
cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL}, *output_buffer [SRSLTE_MAX_PORTS] = {NULL};
|
||||
|
||||
|
||||
cf_t *sf_buffer = NULL, *output_buffer = NULL;
|
||||
int sf_n_re, sf_n_samples;
|
||||
|
||||
pthread_t net_thread;
|
||||
|
@ -94,12 +112,20 @@ bool net_packet_ready = false;
|
|||
srslte_netsource_t net_source;
|
||||
srslte_netsink_t net_sink;
|
||||
|
||||
|
||||
int prbset_num = 1, last_prbset_num = 1;
|
||||
int prbset_orig = 0;
|
||||
//#define DATA_BUFF_SZ 1024*128
|
||||
//uint8_t data[8*DATA_BUFF_SZ], data2[DATA_BUFF_SZ];
|
||||
//uint8_t data_tmp[DATA_BUFF_SZ];
|
||||
|
||||
|
||||
#define DATA_BUFF_SZ 1024*1024
|
||||
uint8_t *data[2], data2[DATA_BUFF_SZ];
|
||||
uint8_t data_tmp[DATA_BUFF_SZ];
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [agmfoncvpu]\n", prog);
|
||||
printf("Usage: %s [agmfoncvpuxb]\n", prog);
|
||||
#ifndef DISABLE_RF
|
||||
printf("\t-a RF args [Default %s]\n", rf_args);
|
||||
printf("\t-l RF amplitude [Default %.2f]\n", rf_amp);
|
||||
|
@ -113,13 +139,20 @@ void usage(char *prog) {
|
|||
printf("\t-n number of frames [Default %d]\n", nof_frames);
|
||||
printf("\t-c cell id [Default %d]\n", cell.id);
|
||||
printf("\t-p nof_prb [Default %d]\n", cell.nof_prb);
|
||||
printf("\t-M MBSFN area id [Default %d]\n", mbsfn_area_id);
|
||||
printf("\t-x Transmission mode[single|diversity|cdd|multiplex] [Default %s]\n", mimo_type_str);
|
||||
printf("\t-b Precoding Matrix Index (multiplex mode only)* [Default %d]\n", multiplex_pmi);
|
||||
printf("\t-w Number of codewords/layers (multiplex mode only)* [Default %d]\n", multiplex_nof_layers);
|
||||
printf("\t-u listen TCP port for input data (-1 is random) [Default %d]\n", net_port);
|
||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||
printf("\n");
|
||||
printf("\t*: See 3GPP 36.212 Table 5.3.3.1.5-4 for more information\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "aglfmoncpvu")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "aglfmoncpvutxbwM")) != -1) {
|
||||
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
rf_args = argv[optind];
|
||||
|
@ -151,6 +184,18 @@ void parse_args(int argc, char **argv) {
|
|||
case 'c':
|
||||
cell.id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'x':
|
||||
strncpy(mimo_type_str, argv[optind], 32);
|
||||
break;
|
||||
case 'b':
|
||||
multiplex_pmi = (uint32_t) atoi(argv[optind]);
|
||||
break;
|
||||
case 'w':
|
||||
multiplex_nof_layers = (uint32_t) atoi(argv[optind]);
|
||||
break;
|
||||
case 'M':
|
||||
mbsfn_area_id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
break;
|
||||
|
@ -168,18 +213,62 @@ void parse_args(int argc, char **argv) {
|
|||
}
|
||||
|
||||
void base_init() {
|
||||
int i;
|
||||
|
||||
/* Select transmission mode */
|
||||
if (srslte_str2mimotype(mimo_type_str, &pdsch_cfg.mimo_type)) {
|
||||
ERROR("Wrong transmission mode! Allowed modes: single, diversity, cdd and multiplex");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Configure cell and PDSCH in function of the transmission mode */
|
||||
switch(pdsch_cfg.mimo_type) {
|
||||
case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA:
|
||||
cell.nof_ports = 1;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_TX_DIVERSITY:
|
||||
cell.nof_ports = 2;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_CDD:
|
||||
cell.nof_ports = 2;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX:
|
||||
cell.nof_ports = 2;
|
||||
break;
|
||||
default:
|
||||
ERROR("Transmission mode not implemented.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
for(i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
data[i] = srslte_vec_malloc(sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
||||
if (!data[i]) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
bzero(data[i], sizeof(uint8_t) * SOFTBUFFER_SIZE);
|
||||
}
|
||||
|
||||
/* init memory */
|
||||
sf_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_re);
|
||||
if (!sf_buffer) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
sf_buffer[i] = srslte_vec_malloc(sizeof(cf_t) * sf_n_re);
|
||||
if (!sf_buffer[i]) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
output_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_samples);
|
||||
if (!output_buffer) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
|
||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
output_buffer[i] = srslte_vec_malloc(sizeof(cf_t) * sf_n_samples);
|
||||
if (!output_buffer[i]) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
bzero(output_buffer[i], sizeof(cf_t) * sf_n_samples);
|
||||
}
|
||||
|
||||
|
||||
/* open file or USRP */
|
||||
if (output_file_name) {
|
||||
if (strcmp(output_file_name, "NULL")) {
|
||||
|
@ -194,7 +283,7 @@ void base_init() {
|
|||
} else {
|
||||
#ifndef DISABLE_RF
|
||||
printf("Opening RF device...\n");
|
||||
if (srslte_rf_open(&rf, rf_args)) {
|
||||
if (srslte_rf_open_multi(&rf, rf_args, cell.nof_ports)) {
|
||||
fprintf(stderr, "Error opening rf\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -226,18 +315,36 @@ void base_init() {
|
|||
fprintf(stderr, "Error creating iFFT object\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSLTE_CP_EXT, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error creating iFFT object\n");
|
||||
exit(-1);
|
||||
}
|
||||
srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn, 2);
|
||||
srslte_ofdm_set_normalize(&ifft_mbsfn, true);
|
||||
srslte_ofdm_set_normalize(&ifft, true);
|
||||
if (srslte_pbch_init(&pbch, cell)) {
|
||||
|
||||
|
||||
if (srslte_pbch_init(&pbch)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_pbch_set_cell(&pbch, cell)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (srslte_regs_init(®s, cell)) {
|
||||
fprintf(stderr, "Error initiating regs\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_pcfich_init(&pcfich, ®s, cell)) {
|
||||
if (srslte_pcfich_init(&pcfich, 1)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_pcfich_set_cell(&pcfich, ®s, cell)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -247,39 +354,82 @@ void base_init() {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_pdcch_init(&pdcch, ®s, cell)) {
|
||||
if (srslte_pdcch_init_enb(&pdcch, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error creating PDCCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_pdcch_set_cell(&pdcch, ®s, cell)) {
|
||||
fprintf(stderr, "Error creating PDCCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_pdsch_init(&pdsch, cell)) {
|
||||
if (srslte_pdsch_init_enb(&pdsch, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_pdsch_set_cell(&pdsch, cell)) {
|
||||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
srslte_pdsch_set_rnti(&pdsch, UE_CRNTI);
|
||||
|
||||
if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
exit(-1);
|
||||
|
||||
if(mbsfn_area_id > -1){
|
||||
if (srslte_pmch_init(&pmch, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error creating PMCH object\n");
|
||||
}
|
||||
srslte_pmch_set_area_id(&pmch, mbsfn_area_id);
|
||||
}
|
||||
|
||||
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
softbuffers[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1);
|
||||
if (!softbuffers[i]) {
|
||||
fprintf(stderr, "Error allocating soft buffer\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_softbuffer_tx_init(softbuffers[i], cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initiating soft buffer\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void base_free() {
|
||||
|
||||
srslte_softbuffer_tx_free(&softbuffer);
|
||||
void base_free() {
|
||||
int i;
|
||||
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
srslte_softbuffer_tx_free(softbuffers[i]);
|
||||
if (softbuffers[i]) {
|
||||
free(softbuffers[i]);
|
||||
}
|
||||
}
|
||||
srslte_pdsch_free(&pdsch);
|
||||
srslte_pdcch_free(&pdcch);
|
||||
srslte_regs_free(®s);
|
||||
srslte_pbch_free(&pbch);
|
||||
|
||||
if(mbsfn_area_id > -1){
|
||||
srslte_pmch_free(&pmch);
|
||||
}
|
||||
srslte_ofdm_tx_free(&ifft_mbsfn);
|
||||
srslte_ofdm_tx_free(&ifft);
|
||||
|
||||
if (sf_buffer) {
|
||||
free(sf_buffer);
|
||||
|
||||
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
if (data[i]) {
|
||||
free(data[i]);
|
||||
}
|
||||
}
|
||||
if (output_buffer) {
|
||||
free(output_buffer);
|
||||
|
||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
if (sf_buffer[i]) {
|
||||
free(sf_buffer[i]);
|
||||
}
|
||||
|
||||
if (output_buffer[i]) {
|
||||
free(output_buffer[i]);
|
||||
}
|
||||
}
|
||||
if (output_file_name) {
|
||||
if (!null_file_sink) {
|
||||
|
@ -333,22 +483,65 @@ uint32_t prbset_to_bitmask() {
|
|||
|
||||
int update_radl() {
|
||||
|
||||
/* Configure cell and PDSCH in function of the transmission mode */
|
||||
switch(pdsch_cfg.mimo_type) {
|
||||
case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA:
|
||||
pdsch_cfg.nof_layers = 1;
|
||||
nof_tb = 1;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_TX_DIVERSITY:
|
||||
pdsch_cfg.nof_layers = 2;
|
||||
nof_tb = 1;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_CDD:
|
||||
pdsch_cfg.nof_layers = 2;
|
||||
nof_tb = 2;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX:
|
||||
pdsch_cfg.nof_layers = multiplex_nof_layers;
|
||||
nof_tb = multiplex_nof_layers;
|
||||
break;
|
||||
default:
|
||||
ERROR("Transmission mode not implemented.");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t));
|
||||
ra_dl.harq_process = 0;
|
||||
ra_dl.mcs_idx = mcs_idx;
|
||||
ra_dl.ndi = 0;
|
||||
ra_dl.rv_idx = 0;
|
||||
ra_dl.rv_idx = rvidx[0];
|
||||
ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
|
||||
ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask();
|
||||
ra_dl.tb_en[0] = 1;
|
||||
|
||||
if (nof_tb > 1) {
|
||||
ra_dl.mcs_idx_1 = mcs_idx;
|
||||
ra_dl.ndi_1 = 0;
|
||||
ra_dl.rv_idx_1 = rvidx[1];
|
||||
ra_dl.tb_en[1] = 1;
|
||||
}
|
||||
|
||||
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
|
||||
srslte_ra_dl_grant_t dummy_grant;
|
||||
srslte_ra_nbits_t dummy_nbits;
|
||||
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &dummy_grant);
|
||||
srslte_ra_dl_grant_to_nbits(&dummy_grant, cfi, cell, 0, &dummy_nbits);
|
||||
srslte_ra_dl_grant_fprint(stdout, &dummy_grant);
|
||||
printf("Type new MCS index and press Enter: "); fflush(stdout);
|
||||
dummy_grant.sf_type = SRSLTE_SF_NORM;
|
||||
if (pdsch_cfg.mimo_type != SRSLTE_MIMO_TYPE_SINGLE_ANTENNA) {
|
||||
printf("\nTransmission mode key table:\n");
|
||||
printf(" Mode | 1TB | 2TB |\n");
|
||||
printf("----------+---------+-----+\n");
|
||||
printf("Diversity | x | |\n");
|
||||
printf(" CDD | | z |\n");
|
||||
printf("Multiplex | q,w,e,r | a,s |\n");
|
||||
printf("\n");
|
||||
printf("Type new MCS index (0-28) or mode key and press Enter: ");
|
||||
} else {
|
||||
printf("Type new MCS index (0-28) and press Enter: ");
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -390,8 +583,47 @@ int update_control() {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
last_mcs_idx = mcs_idx;
|
||||
mcs_idx = atoi(input);
|
||||
switch (input[0]) {
|
||||
case 'q':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
||||
multiplex_pmi = 0;
|
||||
multiplex_nof_layers = 1;
|
||||
break;
|
||||
case 'w':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
||||
multiplex_pmi = 1;
|
||||
multiplex_nof_layers = 1;
|
||||
break;
|
||||
case 'e':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
||||
multiplex_pmi = 2;
|
||||
multiplex_nof_layers = 1;
|
||||
break;
|
||||
case 'r':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
||||
multiplex_pmi = 3;
|
||||
multiplex_nof_layers = 1;
|
||||
break;
|
||||
case 'a':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
||||
multiplex_pmi = 0;
|
||||
multiplex_nof_layers = 2;
|
||||
break;
|
||||
case 's':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
|
||||
multiplex_pmi = 1;
|
||||
multiplex_nof_layers = 2;
|
||||
break;
|
||||
case 'z':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_CDD;
|
||||
break;
|
||||
case 'x':
|
||||
pdsch_cfg.mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
|
||||
break;
|
||||
default:
|
||||
last_mcs_idx = mcs_idx;
|
||||
mcs_idx = atoi(input);
|
||||
}
|
||||
}
|
||||
bzero(input,sizeof(input));
|
||||
if (update_radl()) {
|
||||
|
@ -411,9 +643,6 @@ int update_control() {
|
|||
}
|
||||
}
|
||||
|
||||
#define DATA_BUFF_SZ 1024*128
|
||||
uint8_t data[8*DATA_BUFF_SZ], data2[DATA_BUFF_SZ];
|
||||
uint8_t data_tmp[DATA_BUFF_SZ];
|
||||
|
||||
/** Function run in a separate thread to receive UDP data */
|
||||
void *net_thread_fnc(void *arg) {
|
||||
|
@ -423,14 +652,16 @@ void *net_thread_fnc(void *arg) {
|
|||
do {
|
||||
n = srslte_netsource_read(&net_source, &data2[rpm], DATA_BUFF_SZ-rpm);
|
||||
if (n > 0) {
|
||||
int nbytes = 1+(pdsch_cfg.grant.mcs.tbs-1)/8;
|
||||
// FIXME: I assume that both transport blocks have same size in case of 2 tb are active
|
||||
int nbytes = 1 + (pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs - 1) / 8;
|
||||
rpm += n;
|
||||
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
|
||||
wpm = 0;
|
||||
while (rpm >= nbytes) {
|
||||
// wait for packet to be transmitted
|
||||
sem_wait(&net_sem);
|
||||
memcpy(data, &data2[wpm], nbytes);
|
||||
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);
|
||||
rpm -= nbytes;
|
||||
wpm += nbytes;
|
||||
|
@ -450,6 +681,7 @@ void *net_thread_fnc(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int nf=0, sf_idx=0, N_id_2=0;
|
||||
cf_t pss_signal[SRSLTE_PSS_LEN];
|
||||
|
@ -462,7 +694,8 @@ int main(int argc, char **argv) {
|
|||
srslte_dci_msg_t dci_msg;
|
||||
srslte_dci_location_t locations[SRSLTE_NSUBFRAMES_X_FRAME][30];
|
||||
uint32_t sfn;
|
||||
srslte_chest_dl_t est;
|
||||
srslte_refsignal_t csr_refs;
|
||||
srslte_refsignal_t mbsfn_refs;
|
||||
|
||||
#ifdef DISABLE_RF
|
||||
if (argc < 3) {
|
||||
|
@ -491,17 +724,31 @@ int main(int argc, char **argv) {
|
|||
srslte_pss_generate(pss_signal, N_id_2);
|
||||
srslte_sss_generate(sss_signal0, sss_signal5, cell.id);
|
||||
|
||||
/* Generate CRS signals */
|
||||
if (srslte_chest_dl_init(&est, cell)) {
|
||||
|
||||
/* Generate reference signals */
|
||||
if(srslte_refsignal_cs_init(&csr_refs, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) { // now there's only 1 port
|
||||
sf_symbols[i] = sf_buffer;
|
||||
slot1_symbols[i] = &sf_buffer[SRSLTE_SLOT_LEN_RE(cell.nof_prb, cell.cp)];
|
||||
if(mbsfn_area_id > -1) {
|
||||
if(srslte_refsignal_mbsfn_init(&mbsfn_refs, cell, mbsfn_area_id)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if(srslte_refsignal_cs_set_cell(&csr_refs, cell)){
|
||||
fprintf(stderr, "Error setting cell\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
sf_symbols[i] = sf_buffer[i%cell.nof_ports];
|
||||
slot1_symbols[i] = &sf_buffer[i%cell.nof_ports][SRSLTE_SLOT_LEN_RE(cell.nof_prb, cell.cp)];
|
||||
}
|
||||
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
|
||||
|
||||
|
@ -550,13 +797,15 @@ int main(int argc, char **argv) {
|
|||
/* Initiate valid DCI locations */
|
||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
srslte_pdcch_ue_locations(&pdcch, locations[i], 30, i, cfi, UE_CRNTI);
|
||||
|
||||
}
|
||||
|
||||
nf = 0;
|
||||
|
||||
bool send_data = false;
|
||||
srslte_softbuffer_tx_reset(&softbuffer);
|
||||
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
srslte_softbuffer_tx_reset(softbuffers[i]);
|
||||
}
|
||||
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
bool start_of_burst = true;
|
||||
|
@ -564,15 +813,28 @@ int main(int argc, char **argv) {
|
|||
|
||||
while ((nf < nof_frames || nof_frames == -1) && !go_exit) {
|
||||
for (sf_idx = 0; sf_idx < SRSLTE_NSUBFRAMES_X_FRAME && (nf < nof_frames || nof_frames == -1); sf_idx++) {
|
||||
bzero(sf_buffer, sizeof(cf_t) * sf_n_re);
|
||||
/* Set Antenna port resource elements to zero */
|
||||
bzero(sf_symbols[0], sizeof(cf_t) * sf_n_re);
|
||||
|
||||
|
||||
if (sf_idx == 0 || sf_idx == 5) {
|
||||
srslte_pss_put_slot(pss_signal, sf_buffer, cell.nof_prb, SRSLTE_CP_NORM);
|
||||
srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb,
|
||||
srslte_pss_put_slot(pss_signal, sf_symbols[0], cell.nof_prb, SRSLTE_CP_NORM);
|
||||
srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_symbols[0], cell.nof_prb,
|
||||
SRSLTE_CP_NORM);
|
||||
}
|
||||
|
||||
srslte_refsignal_cs_put_sf(cell, 0, est.csr_signal.pilots[0][sf_idx], sf_buffer);
|
||||
/* Copy zeros, SSS, PSS into the rest of antenna ports */
|
||||
for (i = 1; i < cell.nof_ports; i++) {
|
||||
memcpy(sf_symbols[i], sf_symbols[0], sizeof(cf_t) * sf_n_re);
|
||||
}
|
||||
|
||||
if(sf_idx == 1 && mbsfn_area_id > -1){
|
||||
srslte_refsignal_mbsfn_put_sf(cell, 0,csr_refs.pilots[0][sf_idx], mbsfn_refs.pilots[0][sf_idx], sf_symbols[0]);
|
||||
} else {
|
||||
for (i = 0; i < cell.nof_ports; i++) {
|
||||
srslte_refsignal_cs_put_sf(cell, (uint32_t) i, csr_refs.pilots[i / 2][sf_idx], sf_symbols[i]);
|
||||
}
|
||||
}
|
||||
|
||||
srslte_pbch_mib_pack(&cell, sfn, bch_payload);
|
||||
if (sf_idx == 0) {
|
||||
|
@ -593,9 +855,13 @@ int main(int argc, char **argv) {
|
|||
INFO("Transmitting packet\n",0);
|
||||
}
|
||||
} else {
|
||||
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs.tbs);
|
||||
for (i=0;i<pdsch_cfg.grant.mcs.tbs/8;i++) {
|
||||
data[i] = rand()%256;
|
||||
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs);
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
|
||||
if (pdsch_cfg.grant.tb_en[tb]) {
|
||||
for (i = 0; i < pdsch_cfg.grant.mcs[tb].tbs / 8; i++) {
|
||||
data[tb][i] = (uint8_t) rand();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Uncomment this to transmit on sf 0 and 5 only */
|
||||
if (sf_idx != 0 && sf_idx != 5) {
|
||||
|
@ -606,56 +872,131 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (send_data) {
|
||||
if(sf_idx != 1 || mbsfn_area_id < 0) { // PDCCH + PDSCH
|
||||
srslte_dci_format_t dci_format;
|
||||
switch(pdsch_cfg.mimo_type) {
|
||||
case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA:
|
||||
dci_format = SRSLTE_DCI_FORMAT1;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_TX_DIVERSITY:
|
||||
case SRSLTE_MIMO_TYPE_CDD:
|
||||
dci_format = SRSLTE_DCI_FORMAT2A;
|
||||
break;
|
||||
case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX:
|
||||
dci_format = SRSLTE_DCI_FORMAT2;
|
||||
if (multiplex_nof_layers == 1) {
|
||||
ra_dl.pinfo = (uint8_t) (multiplex_pmi + 1);
|
||||
} else {
|
||||
ra_dl.pinfo = (uint8_t) multiplex_pmi;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Wrong MIMO configuration\n");
|
||||
exit(SRSLTE_ERROR);
|
||||
}
|
||||
/* Encode PDCCH */
|
||||
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||
srslte_dci_msg_pack_pdsch(&ra_dl, dci_format, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
||||
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], UE_CRNTI, sf_symbols, sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error encoding DCI message\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Encode PDCCH */
|
||||
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||
srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
||||
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], UE_CRNTI, sf_symbols, sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error encoding DCI message\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Configure pdsch_cfg parameters */
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &grant);
|
||||
if (srslte_pdsch_cfg_mimo(&pdsch_cfg, cell, &grant, cfi, sf_idx, rvidx, pdsch_cfg.mimo_type, multiplex_pmi)) {
|
||||
fprintf(stderr, "Error configuring PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Configure pdsch_cfg parameters */
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &grant);
|
||||
if (srslte_pdsch_cfg(&pdsch_cfg, cell, &grant, cfi, sf_idx, 0)) {
|
||||
fprintf(stderr, "Error configuring PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Encode PDSCH */
|
||||
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, softbuffers, data, UE_CRNTI, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (net_port > 0 && net_packet_ready) {
|
||||
if (null_file_sink) {
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
|
||||
srslte_bit_pack_vector(data[tb], data_tmp, pdsch_cfg.grant.mcs[tb].tbs);
|
||||
if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pdsch_cfg.grant.mcs[tb].tbs - 1) / 8) < 0) {
|
||||
fprintf(stderr, "Error sending data through UDP socket\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
net_packet_ready = false;
|
||||
sem_post(&net_sem);
|
||||
}
|
||||
}else{ // We're sending MCH on subframe 1 - PDCCH + PMCH
|
||||
|
||||
/* Encode PDSCH */
|
||||
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, UE_CRNTI, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (net_port > 0 && net_packet_ready) {
|
||||
if (null_file_sink) {
|
||||
srslte_bit_pack_vector(data, data_tmp, pdsch_cfg.grant.mcs.tbs);
|
||||
if (srslte_netsink_write(&net_sink, data_tmp, 1+(pdsch_cfg.grant.mcs.tbs-1)/8) < 0) {
|
||||
fprintf(stderr, "Error sending data through UDP socket\n");
|
||||
/* Encode PDCCH */
|
||||
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
|
||||
srslte_dci_msg_pack_pdsch(&ra_dl, SRSLTE_DCI_FORMAT1, &dci_msg, cell.nof_prb, cell.nof_ports, false);
|
||||
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], M_CRNTI, sf_symbols, sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error encoding DCI message\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Configure pmch_cfg parameters */
|
||||
srslte_ra_dl_grant_t grant;
|
||||
grant.nof_tb = 1;
|
||||
grant.mcs[0].idx = 2;
|
||||
grant.mcs[0].mod = SRSLTE_MOD_QPSK;
|
||||
grant.nof_prb = cell.nof_prb;
|
||||
grant.sf_type = SRSLTE_SF_MBSFN;
|
||||
grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod);
|
||||
srslte_dl_fill_ra_mcs(&grant.mcs[0], cell.nof_prb);
|
||||
for(int i = 0; i < 2; i++){
|
||||
for(int j = 0; j < grant.nof_prb; j++){
|
||||
grant.prb_idx[i][j] = true;
|
||||
}
|
||||
}
|
||||
net_packet_ready = false;
|
||||
sem_post(&net_sem);
|
||||
|
||||
|
||||
if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, sf_idx)) {
|
||||
fprintf(stderr, "Error configuring PMCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Encode PMCH */
|
||||
if (srslte_pmch_encode(&pmch, &pmch_cfg, softbuffers[0], data[0], mbsfn_area_id, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding PDSCH\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (net_port > 0 && net_packet_ready) {
|
||||
if (null_file_sink) {
|
||||
srslte_bit_pack_vector(data[0], data_tmp, pmch_cfg.grant.mcs[0].tbs);
|
||||
if (srslte_netsink_write(&net_sink, data_tmp, 1+(pmch_cfg.grant.mcs[0].tbs-1)/8) < 0) {
|
||||
fprintf(stderr, "Error sending data through UDP socket\n");
|
||||
}
|
||||
}
|
||||
net_packet_ready = false;
|
||||
sem_post(&net_sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Transform to OFDM symbols */
|
||||
srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer);
|
||||
if(sf_idx != 1 || mbsfn_area_id < 0){
|
||||
for (i = 0; i < cell.nof_ports; i++) {
|
||||
srslte_ofdm_tx_sf(&ifft, sf_buffer[i], output_buffer[i]);
|
||||
}
|
||||
}else{
|
||||
srslte_ofdm_tx_sf(&ifft_mbsfn, sf_buffer[0], output_buffer[0]);
|
||||
}
|
||||
|
||||
/* send to file or usrp */
|
||||
if (output_file_name) {
|
||||
if (!null_file_sink) {
|
||||
srslte_filesink_write(&fsink, output_buffer, sf_n_samples);
|
||||
srslte_filesink_write_multi(&fsink, (void**) output_buffer, sf_n_samples, cell.nof_ports);
|
||||
}
|
||||
usleep(1000);
|
||||
} else {
|
||||
#ifndef DISABLE_RF
|
||||
// FIXME
|
||||
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb);
|
||||
srslte_vec_sc_prod_cfc(output_buffer, rf_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
srslte_rf_send2(&rf, output_buffer, sf_n_samples, true, start_of_burst, false);
|
||||
start_of_burst=false;
|
||||
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb);
|
||||
for (i = 0; i < cell.nof_ports; i++) {
|
||||
srslte_vec_sc_prod_cfc(output_buffer[i], rf_amp * norm_factor, output_buffer[i], SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
}
|
||||
srslte_rf_send_multi(&rf, (void**) output_buffer, sf_n_samples, true, start_of_burst, false);
|
||||
start_of_burst=false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
#include "srslte/phy/io/filesink.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#define ENABLE_AGC_DEFAULT
|
||||
|
@ -66,7 +67,7 @@ sem_t plot_sem;
|
|||
uint32_t plot_sf_idx=0;
|
||||
bool plot_track = true;
|
||||
#endif
|
||||
|
||||
char *output_file_name;
|
||||
#define PRINT_CHANGE_SCHEDULIGN
|
||||
|
||||
//#define CORRECT_SAMPLE_OFFSET
|
||||
|
@ -98,6 +99,9 @@ typedef struct {
|
|||
int net_port_signal;
|
||||
char *net_address_signal;
|
||||
int decimate;
|
||||
int32_t mbsfn_area_id;
|
||||
uint8_t non_mbsfn_region;
|
||||
int verbose;
|
||||
}prog_args_t;
|
||||
|
||||
void args_default(prog_args_t *args) {
|
||||
|
@ -128,10 +132,12 @@ void args_default(prog_args_t *args) {
|
|||
args->net_address_signal = "127.0.0.1";
|
||||
args->decimate = 0;
|
||||
args->cpu_affinity = -1;
|
||||
args->mbsfn_area_id = -1;
|
||||
args->non_mbsfn_region = 2;
|
||||
}
|
||||
|
||||
void usage(prog_args_t *args, char *prog) {
|
||||
printf("Usage: %s [agpPoOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
|
||||
printf("Usage: %s [agpPoOcildDnruMNv] -f rx_frequency (in Hz) | -i input_file\n", prog);
|
||||
#ifndef DISABLE_RF
|
||||
printf("\t-a RF args [Default %s]\n", args->rf_args);
|
||||
printf("\t-A Number of RX antennas [Default %d]\n", args->rf_nof_rx_ant);
|
||||
|
@ -165,13 +171,15 @@ void usage(prog_args_t *args, char *prog) {
|
|||
printf("\t-S remote UDP address to send input signal [Default %s]\n", args->net_address_signal);
|
||||
printf("\t-u remote TCP port to send data (-1 does nothing with it) [Default %d]\n", args->net_port);
|
||||
printf("\t-U remote TCP address to send data [Default %s]\n", args->net_address);
|
||||
printf("\t-M MBSFN area id [Default %d]\n", args->mbsfn_area_id);
|
||||
printf("\t-N Non-MBSFN region [Default %d]\n", args->non_mbsfn_region);
|
||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(prog_args_t *args, int argc, char **argv) {
|
||||
int opt;
|
||||
args_default(args);
|
||||
while ((opt = getopt(argc, argv, "aAoglipPcOCtdDnvrfuUsSZy")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "aAoglipPcOCtdDnvrfuUsSZyWMN")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
args->input_file_name = argv[optind];
|
||||
|
@ -238,6 +246,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
args->verbose = srslte_verbose;
|
||||
break;
|
||||
case 'Z':
|
||||
args->decimate = atoi(argv[optind]);
|
||||
|
@ -245,6 +254,15 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
case 'y':
|
||||
args->cpu_affinity = atoi(argv[optind]);
|
||||
break;
|
||||
case 'W':
|
||||
output_file_name = argv[optind];
|
||||
break;
|
||||
case 'M':
|
||||
args->mbsfn_area_id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'N':
|
||||
args->non_mbsfn_region = atoi(argv[optind]);
|
||||
break;
|
||||
default:
|
||||
usage(args, argv[0]);
|
||||
exit(-1);
|
||||
|
@ -258,7 +276,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
|
|||
/**********************************************************************/
|
||||
|
||||
/* TODO: Do something with the output data */
|
||||
uint8_t data[20000];
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS];
|
||||
|
||||
bool go_exit = false;
|
||||
void sig_int_handler(int signo)
|
||||
|
@ -266,10 +284,13 @@ void sig_int_handler(int signo)
|
|||
printf("SIGINT received. Exiting...\n");
|
||||
if (signo == SIGINT) {
|
||||
go_exit = true;
|
||||
} else if (signo == SIGSEGV) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
cf_t *sf_buffer[2] = {NULL, NULL};
|
||||
cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL};
|
||||
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
|
||||
|
@ -297,6 +318,12 @@ prog_args_t prog_args;
|
|||
|
||||
uint32_t sfn = 0; // system frame number
|
||||
srslte_netsink_t net_sink, net_sink_signal;
|
||||
/* Useful macros for printing lines which will disappear */
|
||||
|
||||
#define PRINT_LINE_INIT() int this_nof_lines = 0; static int prev_nof_lines = 0
|
||||
#define PRINT_LINE(_fmt, ...) printf("\033[K" _fmt "\n", ##__VA_ARGS__); this_nof_lines++
|
||||
#define PRINT_LINE_RESET_CURSOR() printf("\033[%dA", this_nof_lines); prev_nof_lines = this_nof_lines
|
||||
#define PRINT_LINE_ADVANCE_CURSOR() printf("\033[%dB", prev_nof_lines + 1)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int ret;
|
||||
|
@ -304,17 +331,26 @@ int main(int argc, char **argv) {
|
|||
srslte_cell_t cell;
|
||||
int64_t sf_cnt;
|
||||
srslte_ue_mib_t ue_mib;
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
srslte_rf_t rf;
|
||||
#endif
|
||||
uint32_t nof_trials = 0;
|
||||
int n;
|
||||
uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN];
|
||||
int sfn_offset;
|
||||
float cfo = 0;
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
for (int i = 0; i< SRSLTE_MAX_CODEWORDS; i++) {
|
||||
data[i] = srslte_vec_malloc(sizeof(uint8_t)*1500*8);
|
||||
if (!data[i]) {
|
||||
ERROR("Allocating data");
|
||||
go_exit = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(prog_args.cpu_affinity > -1) {
|
||||
|
||||
cpu_set_t cpuset;
|
||||
|
@ -379,10 +415,11 @@ int main(int argc, char **argv) {
|
|||
srslte_rf_set_master_clock_rate(&rf, 30.72e6);
|
||||
|
||||
/* set receiver frequency */
|
||||
printf("Tunning receiver to %.3f MHz\n", prog_args.rf_freq/1000000);
|
||||
srslte_rf_set_rx_freq(&rf, prog_args.rf_freq);
|
||||
printf("Tunning receiver to %.3f MHz\n", (prog_args.rf_freq + prog_args.file_offset_freq)/1000000);
|
||||
srslte_rf_set_rx_freq(&rf, prog_args.rf_freq + prog_args.file_offset_freq);
|
||||
srslte_rf_rx_wait_lo_locked(&rf);
|
||||
|
||||
|
||||
uint32_t ntrial=0;
|
||||
do {
|
||||
ret = rf_search_and_decode_mib(&rf, prog_args.rf_nof_rx_ant, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo);
|
||||
|
@ -435,8 +472,8 @@ int main(int argc, char **argv) {
|
|||
cell.nof_ports = prog_args.file_nof_ports;
|
||||
cell.nof_prb = prog_args.file_nof_prb;
|
||||
|
||||
if (srslte_ue_sync_init_file(&ue_sync, prog_args.file_nof_prb,
|
||||
prog_args.input_file_name, prog_args.file_offset_time, prog_args.file_offset_freq)) {
|
||||
if (srslte_ue_sync_init_file_multi(&ue_sync, prog_args.file_nof_prb,
|
||||
prog_args.input_file_name, prog_args.file_offset_time, prog_args.file_offset_freq, prog_args.rf_nof_rx_ant)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -455,19 +492,38 @@ int main(int argc, char **argv) {
|
|||
//ue_sync.decimate = prog_args.decimate;
|
||||
}
|
||||
}
|
||||
if (srslte_ue_sync_init_multi_decim(&ue_sync, cell, srslte_rf_recv_wrapper, prog_args.rf_nof_rx_ant, (void*) &rf,decimate)) {
|
||||
if (srslte_ue_sync_init_multi_decim(&ue_sync,
|
||||
cell.nof_prb,
|
||||
cell.id==1000,
|
||||
srslte_rf_recv_wrapper,
|
||||
prog_args.rf_nof_rx_ant,
|
||||
(void*) &rf,decimate))
|
||||
{
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_ue_sync_set_cell(&ue_sync, cell))
|
||||
{
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (srslte_ue_mib_init(&ue_mib, cell)) {
|
||||
if (srslte_ue_mib_init(&ue_mib, cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initaiting UE MIB decoder\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_ue_mib_set_cell(&ue_mib, cell)) {
|
||||
fprintf(stderr, "Error initaiting UE MIB decoder\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (srslte_ue_dl_init_multi(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI
|
||||
if (srslte_ue_dl_init(&ue_dl, cell.nof_prb, prog_args.rf_nof_rx_ant)) {
|
||||
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_ue_dl_set_cell(&ue_dl, cell)) {
|
||||
fprintf(stderr, "Error initiating UE downlink processing module\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -479,6 +535,11 @@ int main(int argc, char **argv) {
|
|||
/* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
|
||||
srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);
|
||||
|
||||
/* Configure MBSFN area id and non-MBSFN Region */
|
||||
if (prog_args.mbsfn_area_id > -1) {
|
||||
srslte_ue_dl_set_mbsfn_area_id(&ue_dl, prog_args.mbsfn_area_id);
|
||||
srslte_ue_dl_set_non_mbsfn_region(&ue_dl, prog_args.non_mbsfn_region);
|
||||
}
|
||||
/* Initialize subframe counter */
|
||||
sf_cnt = 0;
|
||||
|
||||
|
@ -498,9 +559,15 @@ int main(int argc, char **argv) {
|
|||
|
||||
// Variables for measurements
|
||||
uint32_t nframes=0;
|
||||
float rsrp=0.0, rsrq=0.0, noise=0.0;
|
||||
uint8_t ri = 0, pmi = 0;
|
||||
float rsrp0=0.0, rsrp1=0.0, rsrq=0.0, noise=0.0, enodebrate = 0.0, uerate = 0.0,
|
||||
sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS], cn = 0.0;
|
||||
bool decode_pdsch = false;
|
||||
|
||||
for (int i = 0; i < SRSLTE_MAX_LAYERS; i++) {
|
||||
bzero(sinr[i], sizeof(float)*SRSLTE_MAX_CODEBOOKS);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
if (prog_args.rf_gain < 0) {
|
||||
srslte_ue_sync_start_agc(&ue_sync, srslte_rf_set_rx_gain_th_wrapper_, cell_detect_config.init_agc);
|
||||
|
@ -521,6 +588,31 @@ int main(int argc, char **argv) {
|
|||
INFO("\nEntering main loop...\n\n", 0);
|
||||
/* Main loop */
|
||||
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
|
||||
bool acks [SRSLTE_MAX_CODEWORDS] = {false};
|
||||
char input[128];
|
||||
PRINT_LINE_INIT();
|
||||
|
||||
fd_set set;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(0, &set);
|
||||
|
||||
struct timeval to;
|
||||
to.tv_sec = 0;
|
||||
to.tv_usec = 0;
|
||||
|
||||
/* Set default verbose level */
|
||||
srslte_verbose = prog_args.verbose;
|
||||
int n = select(1, &set, NULL, NULL, &to);
|
||||
if (n == 1) {
|
||||
/* If a new line is detected set verbose level to Debug */
|
||||
if (fgets(input, sizeof(input), stdin)) {
|
||||
srslte_verbose = SRSLTE_VERBOSE_DEBUG;
|
||||
ue_dl.pkt_errors = 0;
|
||||
ue_dl.pkts_total = 0;
|
||||
ue_dl.nof_detected = 0;
|
||||
nof_trials = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
|
||||
if (ret < 0) {
|
||||
|
@ -534,9 +626,12 @@ int main(int argc, char **argv) {
|
|||
|
||||
/* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */
|
||||
if (ret == 1) {
|
||||
|
||||
uint32_t sfidx = srslte_ue_sync_get_sfidx(&ue_sync);
|
||||
|
||||
switch (state) {
|
||||
case DECODE_MIB:
|
||||
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
|
||||
if (sfidx == 0) {
|
||||
n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE MIB\n");
|
||||
|
@ -555,28 +650,64 @@ int main(int argc, char **argv) {
|
|||
decode_pdsch = true;
|
||||
} else {
|
||||
/* We are looking for SIB1 Blocks, search only in appropiate places */
|
||||
if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
|
||||
if ((sfidx == 5 && (sfn%2)==0) || sfidx == 1) {
|
||||
decode_pdsch = true;
|
||||
} else {
|
||||
decode_pdsch = false;
|
||||
}
|
||||
}
|
||||
if (decode_pdsch) {
|
||||
INFO("Attempting DL decode SFN=%d\n", sfn);
|
||||
n = srslte_ue_dl_decode_multi(&ue_dl,
|
||||
if(sfidx != 1 || prog_args.mbsfn_area_id < 0){ // Not an MBSFN subframe
|
||||
if (cell.nof_ports == 1) {
|
||||
/* Transmission mode 1 */
|
||||
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, 0, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), acks);
|
||||
} else {
|
||||
if (prog_args.rf_nof_rx_ant == 1) {
|
||||
/* Transmission mode 2 */
|
||||
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, 1, sfn * 10 + srslte_ue_sync_get_sfidx(&ue_sync),
|
||||
acks);
|
||||
} else {
|
||||
/* Transmission mode 3 */
|
||||
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, 2, sfn * 10 + srslte_ue_sync_get_sfidx(&ue_sync),
|
||||
acks);
|
||||
if (n < 1) {
|
||||
/* Transmission mode 4 */
|
||||
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, 3, sfn * 10 + srslte_ue_sync_get_sfidx(&ue_sync),
|
||||
acks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{ // MBSFN subframe
|
||||
n = srslte_ue_dl_decode_mbsfn(&ue_dl,
|
||||
sf_buffer,
|
||||
data,
|
||||
data[0],
|
||||
sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
|
||||
|
||||
if(n>0){
|
||||
if(output_file_name){
|
||||
//srslte_filesink_init(&sink, output_file_name, SRSLTE_BYTE_BIN);
|
||||
// srslte_filesink_write(&sink, data, n);
|
||||
//srslte_filesink_free(&sink);
|
||||
}
|
||||
INFO("mbsfn PDU size is %d\n", n);
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
// fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
||||
} else if (n > 0) {
|
||||
|
||||
/* Send data if socket active */
|
||||
if (prog_args.net_port > 0) {
|
||||
srslte_netsink_write(&net_sink, data, 1+(n-1)/8);
|
||||
if(sfidx == 1) {
|
||||
srslte_netsink_write(&net_sink, data[0], 1+(n-1)/8);
|
||||
} else {
|
||||
// FIXME: UDP Data transmission does not work
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
|
||||
if (ue_dl.pdsch_cfg.grant.tb_en[tb]) {
|
||||
srslte_netsink_write(&net_sink, data[tb], 1 + (ue_dl.pdsch_cfg.grant.mcs[tb].tbs - 1) / 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PRINT_CHANGE_SCHEDULIGN
|
||||
if (ue_dl.dl_dci.mcs_idx != old_dl_dci.mcs_idx ||
|
||||
memcmp(&ue_dl.dl_dci.type0_alloc, &old_dl_dci.type0_alloc, sizeof(srslte_ra_type0_t)) ||
|
||||
|
@ -595,9 +726,15 @@ int main(int argc, char **argv) {
|
|||
|
||||
nof_trials++;
|
||||
|
||||
rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1);
|
||||
rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&ue_dl.chest), rsrp, 0.05);
|
||||
noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05);
|
||||
|
||||
rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1f);
|
||||
rsrp0 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 0), rsrp0, 0.05f);
|
||||
rsrp1 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 1), rsrp1, 0.05f);
|
||||
noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05f);
|
||||
enodebrate = SRSLTE_VEC_EMA((ue_dl.pdsch_cfg.grant.mcs[0].tbs + ue_dl.pdsch_cfg.grant.mcs[1].tbs)/1000.0f, enodebrate, 0.05f);
|
||||
uerate = SRSLTE_VEC_EMA(((acks[0]?ue_dl.pdsch_cfg.grant.mcs[0].tbs:0) + (acks[1]?ue_dl.pdsch_cfg.grant.mcs[1].tbs:0))/1000.0f, uerate, 0.01f);
|
||||
|
||||
|
||||
nframes++;
|
||||
if (isnan(rsrq)) {
|
||||
rsrq = 0;
|
||||
|
@ -605,43 +742,104 @@ int main(int argc, char **argv) {
|
|||
if (isnan(noise)) {
|
||||
noise = 0;
|
||||
}
|
||||
if (isnan(rsrp)) {
|
||||
rsrp = 0;
|
||||
if (isnan(rsrp0)) {
|
||||
rsrp0 = 0;
|
||||
}
|
||||
if (isnan(rsrp1)) {
|
||||
rsrp1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Plot and Printf
|
||||
if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
|
||||
if (sfidx == 5) {
|
||||
float gain = prog_args.rf_gain;
|
||||
if (gain < 0) {
|
||||
gain = 10*log10(srslte_agc_get_gain(&ue_sync.agc));
|
||||
}
|
||||
printf("CFO: %+6.2f kHz, "
|
||||
"SNR: %4.1f dB, "
|
||||
"PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%%\r",
|
||||
|
||||
srslte_ue_sync_get_cfo(&ue_sync)/1000,
|
||||
10*log10(rsrp/noise),
|
||||
100*(1-(float) ue_dl.nof_detected/nof_trials),
|
||||
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total);
|
||||
/* Print transmission scheme */
|
||||
if (ue_dl.pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
|
||||
PRINT_LINE(" Tx scheme: %s (codebook_idx=%d)", srslte_mimotype2str(ue_dl.pdsch_cfg.mimo_type),
|
||||
ue_dl.pdsch_cfg.codebook_idx);
|
||||
} else {
|
||||
PRINT_LINE(" Tx scheme: %s", srslte_mimotype2str(ue_dl.pdsch_cfg.mimo_type));
|
||||
}
|
||||
|
||||
/* Print basic Parameters */
|
||||
PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers);
|
||||
PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant));
|
||||
PRINT_LINE(" CFO: %+5.2f kHz", srslte_ue_sync_get_cfo(&ue_sync) / 1000);
|
||||
PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise));
|
||||
PRINT_LINE(" Rb: %6.2f / %6.2f Mbps (net/maximum)", uerate, enodebrate);
|
||||
PRINT_LINE(" PDCCH-Miss: %5.2f%%", 100 * (1 - (float) ue_dl.nof_detected / nof_trials));
|
||||
PRINT_LINE(" PDSCH-BLER: %5.2f%%", (float) 100 * ue_dl.pdsch_pkt_errors / ue_dl.pdsch_pkts_total);
|
||||
if(prog_args.mbsfn_area_id > -1){
|
||||
PRINT_LINE(" PMCH-BLER: %5.2f%%", (float) 100 * ue_dl.pmch_pkt_errors/ue_dl.pmch_pkts_total);
|
||||
}
|
||||
PRINT_LINE(" TB 0: mcs=%d; tbs=%d", ue_dl.pdsch_cfg.grant.mcs[0].idx,
|
||||
ue_dl.pdsch_cfg.grant.mcs[0].tbs);
|
||||
PRINT_LINE(" TB 1: mcs=%d; tbs=%d", ue_dl.pdsch_cfg.grant.mcs[1].idx,
|
||||
ue_dl.pdsch_cfg.grant.mcs[1].tbs);
|
||||
|
||||
/* MIMO: if tx and rx antennas are bigger than 1 */
|
||||
if (cell.nof_ports > 1 && ue_dl.pdsch.nof_rx_antennas > 1) {
|
||||
/* Compute condition number */
|
||||
srslte_ue_dl_ri_select(&ue_dl, NULL, &cn);
|
||||
|
||||
/* Print condition number */
|
||||
PRINT_LINE(" κ: %.1f dB (Condition number, 0 dB => Best)", cn);
|
||||
}
|
||||
PRINT_LINE("");
|
||||
|
||||
/* Spatial multiplex only */
|
||||
if (ue_dl.pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) {
|
||||
|
||||
/* Compute Rank Indicator (RI) and Precoding Matrix Indicator (PMI) */
|
||||
srslte_ue_dl_ri_pmi_select(&ue_dl, &ri, &pmi, NULL);
|
||||
for (uint32_t nl = 0; nl < SRSLTE_MAX_LAYERS; nl++) {
|
||||
for (uint32_t cb = 0; cb < SRSLTE_MAX_CODEBOOKS; cb++) {
|
||||
sinr[nl][cb] = SRSLTE_VEC_EMA(ue_dl.sinr[nl][cb], sinr[nl][cb], 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Multiplex stats */
|
||||
PRINT_LINE("SINR (dB) Vs RI and PMI:");
|
||||
PRINT_LINE(" | RI | 1 | 2 |");
|
||||
PRINT_LINE(" -------+-------+-------+");
|
||||
PRINT_LINE(" P | 0 | %5.2f%c| %5.2f%c|", 10 * log10(sinr[0][0]), (ri == 1 && pmi == 0) ? '*' : ' ',
|
||||
10 * log10(sinr[1][0]), (ri == 2 && pmi == 0) ? '*' : ' ');
|
||||
PRINT_LINE(" M | 1 | %5.2f%c| %5.2f%c|", 10 * log10(sinr[0][1]), (ri == 1 && pmi == 1) ? '*' : ' ',
|
||||
10 * log10(sinr[1][1]), (ri == 2 && pmi == 1) ? '*' : ' ');
|
||||
PRINT_LINE(" I | 2 | %5.2f%c|-------+ ", 10 * log10(sinr[0][2]), (ri == 1 && pmi == 2) ? '*' : ' ');
|
||||
PRINT_LINE(" | 3 | %5.2f%c| ", 10 * log10(sinr[0][3]), (ri == 1 && pmi == 3) ? '*' : ' ');
|
||||
PRINT_LINE("");
|
||||
}
|
||||
PRINT_LINE("Press enter maximum printing debug log of 1 subframe.");
|
||||
PRINT_LINE("");
|
||||
PRINT_LINE_RESET_CURSOR();
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (srslte_ue_sync_get_sfidx(&ue_sync) == 9) {
|
||||
if (sfidx == 9) {
|
||||
sfn++;
|
||||
if (sfn == 1024) {
|
||||
sfn = 0;
|
||||
printf("\n");
|
||||
PRINT_LINE_ADVANCE_CURSOR();
|
||||
ue_dl.pdsch_pkt_errors = 0;
|
||||
ue_dl.pdsch_pkts_total = 0;
|
||||
/*
|
||||
ue_dl.pkt_errors = 0;
|
||||
ue_dl.pkts_total = 0;
|
||||
ue_dl.nof_detected = 0;
|
||||
nof_trials = 0;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!prog_args.disable_plots) {
|
||||
if ((sfn%4) == 0 && decode_pdsch) {
|
||||
if ((sfn%3) == 0 && decode_pdsch) {
|
||||
plot_sf_idx = srslte_ue_sync_get_sfidx(&ue_sync);
|
||||
plot_track = true;
|
||||
sem_post(&plot_sem);
|
||||
|
@ -674,6 +872,16 @@ int main(int argc, char **argv) {
|
|||
#endif
|
||||
srslte_ue_dl_free(&ue_dl);
|
||||
srslte_ue_sync_free(&ue_sync);
|
||||
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
if (data[i]) {
|
||||
free(data[i]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < prog_args.rf_nof_rx_ant; i++) {
|
||||
if (sf_buffer[i]) {
|
||||
free(sf_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_RF
|
||||
if (!prog_args.input_file_name) {
|
||||
|
@ -681,6 +889,7 @@ int main(int argc, char **argv) {
|
|||
srslte_rf_close(&rf);
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("\nBye\n");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -742,7 +951,7 @@ void *plot_thread_run(void *arg) {
|
|||
while(1) {
|
||||
sem_wait(&plot_sem);
|
||||
|
||||
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re;
|
||||
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits[0].nof_re;
|
||||
if (!prog_args.disable_plots_except_constellation) {
|
||||
for (i = 0; i < nof_re; i++) {
|
||||
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));
|
||||
|
@ -784,7 +993,7 @@ void *plot_thread_run(void *arg) {
|
|||
plot_scatter_setNewData(&pscatequal_pdcch, ue_dl.pdcch.d, 36*ue_dl.pdcch.nof_cce);
|
||||
}
|
||||
|
||||
plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.d, nof_symbols);
|
||||
plot_scatter_setNewData(&pscatequal, ue_dl.pdsch.d[0], nof_symbols);
|
||||
|
||||
if (plot_sf_idx == 1) {
|
||||
if (prog_args.net_port_signal > 0) {
|
||||
|
|
|
@ -44,6 +44,7 @@ char *output_file_name;
|
|||
char *rf_args="";
|
||||
float rf_gain=40.0, rf_freq=-1.0, rf_rate=0.96e6;
|
||||
int nof_samples = -1;
|
||||
int nof_rx_antennas = 1;
|
||||
|
||||
void int_handler(int dummy) {
|
||||
keep_running = false;
|
||||
|
@ -55,12 +56,13 @@ void usage(char *prog) {
|
|||
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
|
||||
printf("\t-r RF Rate [Default %.6f Hz]\n", rf_rate);
|
||||
printf("\t-n nof_samples [Default %d]\n", nof_samples);
|
||||
printf("\t-A nof_rx_antennas [Default %d]\n", nof_rx_antennas);
|
||||
printf("\t-v srslte_verbose\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "agrnvfo")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "agrnvfoA")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
output_file_name = argv[optind];
|
||||
|
@ -80,6 +82,9 @@ void parse_args(int argc, char **argv) {
|
|||
case 'n':
|
||||
nof_samples = atoi(argv[optind]);
|
||||
break;
|
||||
case 'A':
|
||||
nof_rx_antennas = atoi(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
break;
|
||||
|
@ -95,11 +100,11 @@ void parse_args(int argc, char **argv) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
cf_t *buffer;
|
||||
cf_t *buffer[SRSLTE_MAX_PORTS];
|
||||
int sample_count, n;
|
||||
srslte_rf_t rf;
|
||||
srslte_filesink_t sink;
|
||||
int32_t buflen;
|
||||
uint32_t buflen;
|
||||
|
||||
signal(SIGINT, int_handler);
|
||||
|
||||
|
@ -108,16 +113,18 @@ int main(int argc, char **argv) {
|
|||
buflen = 4800;
|
||||
sample_count = 0;
|
||||
|
||||
buffer = malloc(sizeof(cf_t) * buflen);
|
||||
if (!buffer) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
for (int i = 0; i < nof_rx_antennas; i++) {
|
||||
buffer[i] = malloc(sizeof(cf_t) * buflen);
|
||||
if (!buffer[i]) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
srslte_filesink_init(&sink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN);
|
||||
|
||||
printf("Opening RF device...\n");
|
||||
if (srslte_rf_open(&rf, rf_args)) {
|
||||
if (srslte_rf_open_multi(&rf, rf_args, nof_rx_antennas)) {
|
||||
fprintf(stderr, "Error opening rf\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -151,18 +158,23 @@ int main(int argc, char **argv) {
|
|||
|
||||
while((sample_count < nof_samples || nof_samples == -1)
|
||||
&& keep_running){
|
||||
n = srslte_rf_recv(&rf, buffer, buflen, 1);
|
||||
n = srslte_rf_recv_with_time_multi(&rf, (void**) buffer, buflen, true, NULL, NULL);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error receiving samples\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
srslte_filesink_write(&sink, buffer, buflen);
|
||||
srslte_filesink_write_multi(&sink, (void**) buffer, buflen, nof_rx_antennas);
|
||||
sample_count += buflen;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nof_rx_antennas; i++) {
|
||||
if (buffer[i]) {
|
||||
free(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
srslte_filesink_free(&sink);
|
||||
free(buffer);
|
||||
srslte_rf_close(&rf);
|
||||
|
||||
printf("Ok - wrote %d samples\n", sample_count);
|
||||
|
|
|
@ -45,6 +45,7 @@ float rf_gain=60.0, rf_freq=-1.0;
|
|||
int nof_prb = 6;
|
||||
int nof_subframes = -1;
|
||||
int N_id_2 = -1;
|
||||
uint32_t nof_rx_antennas = 1;
|
||||
|
||||
void int_handler(int dummy) {
|
||||
keep_running = false;
|
||||
|
@ -56,12 +57,13 @@ void usage(char *prog) {
|
|||
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
|
||||
printf("\t-p nof_prb [Default %d]\n", nof_prb);
|
||||
printf("\t-n nof_subframes [Default %d]\n", nof_subframes);
|
||||
printf("\t-A nof_rx_antennas [Default %d]\n", nof_rx_antennas);
|
||||
printf("\t-v verbose\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "agpnvfol")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "agpnvfolA")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
output_file_name = argv[optind];
|
||||
|
@ -84,6 +86,9 @@ void parse_args(int argc, char **argv) {
|
|||
case 'l':
|
||||
N_id_2 = atoi(argv[optind]);
|
||||
break;
|
||||
case 'A':
|
||||
nof_rx_antennas = (uint32_t) atoi(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
break;
|
||||
|
@ -100,7 +105,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);
|
||||
return srslte_rf_recv(h, data[0], nsamples, 1);
|
||||
return srslte_rf_recv_with_time_multi(h, (void**) data, nsamples, true, NULL, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -118,13 +123,15 @@ int main(int argc, char **argv) {
|
|||
srslte_filesink_init(&sink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN);
|
||||
|
||||
printf("Opening RF device...\n");
|
||||
if (srslte_rf_open(&rf, rf_args)) {
|
||||
if (srslte_rf_open_multi(&rf, rf_args, nof_rx_antennas)) {
|
||||
fprintf(stderr, "Error opening rf\n");
|
||||
exit(-1);
|
||||
}
|
||||
srslte_rf_set_master_clock_rate(&rf, 30.72e6);
|
||||
|
||||
buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
|
||||
for (int i = 0; i< SRSLTE_MAX_PORTS; i++) {
|
||||
buffer[i] = srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(100));
|
||||
}
|
||||
|
||||
sigset_t sigset;
|
||||
sigemptyset(&sigset);
|
||||
|
@ -158,7 +165,11 @@ int main(int argc, char **argv) {
|
|||
cell.nof_prb = nof_prb;
|
||||
cell.nof_ports = 1;
|
||||
|
||||
if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
|
||||
if (srslte_ue_sync_init_multi(&ue_sync, cell.nof_prb, cell.id==1000, srslte_rf_recv_wrapper, nof_rx_antennas, (void*) &rf)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (srslte_ue_sync_set_cell(&ue_sync, cell)) {
|
||||
fprintf(stderr, "Error initiating ue_sync\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -181,7 +192,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
} else {
|
||||
printf("Writing to file %6d subframes...\r", subframe_count);
|
||||
srslte_filesink_write(&sink, buffer[0], SRSLTE_SF_LEN_PRB(nof_prb));
|
||||
srslte_filesink_write_multi(&sink, (void**) buffer, SRSLTE_SF_LEN_PRB(nof_prb),nof_rx_antennas);
|
||||
subframe_count++;
|
||||
}
|
||||
}
|
||||
|
@ -196,6 +207,12 @@ int main(int argc, char **argv) {
|
|||
srslte_rf_close(&rf);
|
||||
srslte_ue_sync_free(&ue_sync);
|
||||
|
||||
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
||||
if (buffer[i]) {
|
||||
free(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Ok - wrote %d subframes\n", subframe_count);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <srslte/asn1/liblte_rrc.h>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
@ -112,6 +113,12 @@ inline bool mnc_to_string(uint16_t mnc, std::string *str)
|
|||
*str += (mnc & 0x000F) + '0';
|
||||
return true;
|
||||
}
|
||||
inline std::string plmn_id_to_c_str(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {
|
||||
std::string mcc_str, mnc_str;
|
||||
mnc_to_string(plmn_id.mnc, &mnc_str);
|
||||
mcc_to_string(plmn_id.mcc, &mcc_str);
|
||||
return mcc_str + mnc_str;
|
||||
}
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
|
|
|
@ -156,6 +156,9 @@ public:
|
|||
return pool->allocate(debug_name);
|
||||
}
|
||||
void deallocate(byte_buffer_t *b) {
|
||||
if(!b) {
|
||||
return;
|
||||
}
|
||||
b->reset();
|
||||
pool->deallocate(b);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756
|
||||
#define SRSLTE_BUFFER_HEADER_OFFSET 1024
|
||||
|
||||
#define SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
//#define SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
|
||||
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
|
||||
#define pool_allocate (pool->allocate(__FUNCTION__))
|
||||
|
@ -83,32 +83,6 @@ static const char error_text[ERROR_N_ITEMS][20] = { "None",
|
|||
"Can't start",
|
||||
"Already started"};
|
||||
|
||||
typedef enum{
|
||||
RB_ID_SRB0 = 0,
|
||||
RB_ID_SRB1,
|
||||
RB_ID_SRB2,
|
||||
RB_ID_DRB1,
|
||||
RB_ID_DRB2,
|
||||
RB_ID_DRB3,
|
||||
RB_ID_DRB4,
|
||||
RB_ID_DRB5,
|
||||
RB_ID_DRB6,
|
||||
RB_ID_DRB7,
|
||||
RB_ID_DRB8,
|
||||
RB_ID_N_ITEMS,
|
||||
}rb_id_t;
|
||||
static const char rb_id_text[RB_ID_N_ITEMS][20] = { "SRB0",
|
||||
"SRB1",
|
||||
"SRB2",
|
||||
"DRB1",
|
||||
"DRB2",
|
||||
"DRB3",
|
||||
"DRB4",
|
||||
"DRB5",
|
||||
"DRB6",
|
||||
"DRB7",
|
||||
"DRB8"};
|
||||
|
||||
/******************************************************************************
|
||||
* Byte and Bit buffers
|
||||
*
|
||||
|
|
|
@ -28,17 +28,52 @@
|
|||
#define INTERFACE_COMMON_H
|
||||
|
||||
#include "srslte/common/timers.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srslte/asn1/liblte_rrc.h"
|
||||
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class srslte_nas_config_t
|
||||
{
|
||||
public:
|
||||
srslte_nas_config_t(uint32_t lcid_ = 0)
|
||||
:lcid(lcid_)
|
||||
{}
|
||||
|
||||
uint32_t lcid;
|
||||
};
|
||||
|
||||
|
||||
class srslte_pdcp_config_t
|
||||
{
|
||||
public:
|
||||
srslte_pdcp_config_t(bool is_control_ = false, bool is_data_ = false, uint8_t direction_ = SECURITY_DIRECTION_UPLINK)
|
||||
:direction(direction_)
|
||||
,is_control(is_control_)
|
||||
,is_data(is_data_)
|
||||
,do_security(false)
|
||||
,sn_len(12) {}
|
||||
|
||||
uint8_t direction;
|
||||
bool is_control;
|
||||
bool is_data;
|
||||
bool do_security;
|
||||
uint8_t sn_len;
|
||||
|
||||
// TODO: Support the following configurations
|
||||
// bool do_rohc;
|
||||
};
|
||||
|
||||
class mac_interface_timers
|
||||
{
|
||||
public:
|
||||
/* Timer services with ms resolution.
|
||||
* timer_id must be lower than MAC_NOF_UPPER_TIMERS
|
||||
*/
|
||||
virtual timers::timer* get(uint32_t timer_id) = 0;
|
||||
virtual uint32_t get_unique_id() = 0;
|
||||
virtual timers::timer* timer_get(uint32_t timer_id) = 0;
|
||||
virtual void timer_release_id(uint32_t timer_id) = 0;
|
||||
virtual uint32_t timer_get_unique_id() = 0;
|
||||
};
|
||||
|
||||
class read_pdu_interface
|
||||
|
|
|
@ -38,15 +38,19 @@
|
|||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "srslte/common/log.h"
|
||||
#include "logger.h"
|
||||
#include "srslte/common/logger.h"
|
||||
#include "srslte/common/logger_stdout.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
typedef std::string* str_ptr;
|
||||
|
||||
class log_filter : public srslte::log
|
||||
{
|
||||
public:
|
||||
|
||||
log_filter();
|
||||
log_filter(std::string layer);
|
||||
log_filter(std::string layer, logger *logger_, bool tti=false);
|
||||
|
||||
void init(std::string layer, logger *logger_, bool tti=false);
|
||||
|
@ -71,6 +75,8 @@ private:
|
|||
logger *logger_h;
|
||||
bool do_tti;
|
||||
|
||||
logger_stdout def_logger_stdout;
|
||||
|
||||
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg);
|
||||
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg, uint8_t *hex, int size);
|
||||
void all_log_line(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string file, int line, char *msg);
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE 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.
|
||||
*
|
||||
* srsUE 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: log_stout.h
|
||||
*
|
||||
* Description: Logging service through standard output. Inherits log interface
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef LOGSTDOUT_H
|
||||
#define LOGSTDOUT_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "srslte/common/log.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class log_stdout : public log
|
||||
{
|
||||
public:
|
||||
|
||||
log_stdout(std::string service_name_) : log(service_name_) { }
|
||||
|
||||
void console(std::string message, ...);
|
||||
void error(std::string message, ...);
|
||||
void warning(std::string message, ...);
|
||||
void info(std::string message, ...);
|
||||
void debug(std::string message, ...);
|
||||
|
||||
// Same with hex dump
|
||||
void error_hex(uint8_t *hex, int size, std::string message, ...);
|
||||
void warning_hex(uint8_t *hex, int size, std::string message, ...);
|
||||
void info_hex(uint8_t *hex, int size, std::string message, ...);
|
||||
void debug_hex(uint8_t *hex, int size, std::string message, ...);
|
||||
|
||||
// Same with line and file info
|
||||
void error_line(std::string file, int line, std::string message, ...);
|
||||
void warning_line(std::string file, int line, std::string message, ...);
|
||||
void info_line(std::string file, int line, std::string message, ...);
|
||||
void debug_line(std::string file, int line, std::string message, ...);
|
||||
|
||||
private:
|
||||
void printlog(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string file, int line, std::string message, va_list args);
|
||||
void printlog(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string message, va_list args);
|
||||
|
||||
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg);
|
||||
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg, uint8_t *hex, int size);
|
||||
void all_log_line(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string file, int line, char *msg);
|
||||
std::string now_time();
|
||||
std::string hex_string(uint8_t *hex, int size);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -26,49 +26,23 @@
|
|||
|
||||
/******************************************************************************
|
||||
* File: logger.h
|
||||
* Description: Common log object. Maintains a queue of log messages
|
||||
* and runs a thread to read messages and write to file.
|
||||
* Multiple producers, single consumer. If full, producers
|
||||
* increase queue size. If empty, consumer blocks.
|
||||
* Description: Interface for logging output
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include "srslte/common/threads.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
typedef std::string* str_ptr;
|
||||
|
||||
class logger : public thread
|
||||
class logger
|
||||
{
|
||||
public:
|
||||
logger();
|
||||
logger(std::string file);
|
||||
~logger();
|
||||
void init(std::string file);
|
||||
void log(const char *msg);
|
||||
void log(str_ptr msg);
|
||||
|
||||
private:
|
||||
void run_thread();
|
||||
void flush();
|
||||
|
||||
FILE* logfile;
|
||||
bool inited;
|
||||
bool not_done;
|
||||
std::string filename;
|
||||
pthread_cond_t not_empty;
|
||||
pthread_cond_t not_full;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_t thread;
|
||||
std::deque<str_ptr> buffer;
|
||||
virtual void log(std::string *msg) = 0;
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
} // namespace srslte
|
||||
|
||||
#endif // LOGGER_H
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE 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.
|
||||
*
|
||||
* srsUE 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: logger_file.h
|
||||
* Description: Common log object. Maintains a queue of log messages
|
||||
* and runs a thread to read messages and write to file.
|
||||
* Multiple producers, single consumer. If full, producers
|
||||
* increase queue size. If empty, consumer blocks.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef LOGGER_FILE_H
|
||||
#define LOGGER_FILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include "srslte/common/logger.h"
|
||||
#include "srslte/common/threads.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
typedef std::string* str_ptr;
|
||||
|
||||
class logger_file : public thread, public logger
|
||||
{
|
||||
public:
|
||||
logger_file();
|
||||
logger_file(std::string file);
|
||||
~logger_file();
|
||||
void init(std::string file);
|
||||
// Implementation of log_out
|
||||
void log(str_ptr msg);
|
||||
void log(const char *msg);
|
||||
|
||||
private:
|
||||
void run_thread();
|
||||
void flush();
|
||||
|
||||
FILE* logfile;
|
||||
bool inited;
|
||||
bool not_done;
|
||||
std::string filename;
|
||||
pthread_cond_t not_empty;
|
||||
pthread_cond_t not_full;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_t thread;
|
||||
std::deque<str_ptr> buffer;
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
||||
#endif // LOGGER_H
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE 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.
|
||||
*
|
||||
* srsUE 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: logger_stdout.h
|
||||
* Description: Interface for logging output
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef LOGGER_STDOUT_H
|
||||
#define LOGGER_STDOUT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include "srslte/common/logger.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
class logger_stdout : public logger
|
||||
{
|
||||
public:
|
||||
void log(std::string *msg) {
|
||||
fprintf(stdout, "%s", msg->c_str());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
#endif // LOGGER_H
|
|
@ -24,7 +24,7 @@ template<typename metrics_t>
|
|||
class metrics_listener
|
||||
{
|
||||
public:
|
||||
virtual void set_metrics(metrics_t &m) = 0;
|
||||
virtual void set_metrics(metrics_t &m, float report_period_secs=1.0) = 0;
|
||||
};
|
||||
|
||||
template<typename metrics_t>
|
||||
|
@ -34,9 +34,11 @@ public:
|
|||
bool init(metrics_interface<metrics_t> *m_, float report_period_secs=1.0) {
|
||||
m = m_;
|
||||
start_periodic(report_period_secs*1e6);
|
||||
return true;
|
||||
}
|
||||
void stop() {
|
||||
thread_cancel();
|
||||
wait_thread_finish();
|
||||
}
|
||||
|
||||
void add_listener(metrics_listener<metrics_t> *listener) {
|
||||
|
@ -46,8 +48,9 @@ public:
|
|||
private:
|
||||
void run_period() {
|
||||
metrics_t metric;
|
||||
bzero(&metric, sizeof(metrics_t));
|
||||
m->get_metrics(metric);
|
||||
for (int i=0;i<listeners.size();i++) {
|
||||
for (uint32_t i=0;i<listeners.size();i++) {
|
||||
listeners[i]->set_metrics(metric);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,11 +97,13 @@ public:
|
|||
bool running;
|
||||
};
|
||||
|
||||
timers(uint32_t nof_timers_) : timer_list(nof_timers_) {
|
||||
timers(uint32_t nof_timers_) : timer_list(nof_timers_),used_timers(nof_timers_) {
|
||||
nof_timers = nof_timers_;
|
||||
next_timer = 0;
|
||||
nof_used_timers = 0;
|
||||
for (uint32_t i=0;i<nof_timers;i++) {
|
||||
timer_list[i].id = i;
|
||||
used_timers[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,17 +135,36 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
uint32_t get_unique_id() {
|
||||
if (next_timer == nof_timers){
|
||||
printf("No more unique timer ids (Only %d timers available)\n", nof_timers);
|
||||
next_timer = 0;
|
||||
void release_id(uint32_t i) {
|
||||
if (nof_used_timers > 0 && i < nof_timers) {
|
||||
used_timers[i] = false;
|
||||
nof_used_timers--;
|
||||
} else {
|
||||
fprintf(stderr, "Error releasing timer: nof_used_timers=%d, nof_timers=%d\n", nof_used_timers, nof_timers);
|
||||
}
|
||||
}
|
||||
uint32_t get_unique_id() {
|
||||
if (nof_used_timers >= nof_timers) {
|
||||
fprintf(stderr, "Error getting unique timer id: no more timers available\n");
|
||||
return 0;
|
||||
} else {
|
||||
while(used_timers[next_timer]) {
|
||||
next_timer++;
|
||||
if (next_timer >= nof_timers) {
|
||||
next_timer=0;
|
||||
}
|
||||
}
|
||||
used_timers[next_timer] = true;
|
||||
nof_used_timers++;
|
||||
return next_timer;
|
||||
}
|
||||
return next_timer++;
|
||||
}
|
||||
private:
|
||||
uint32_t nof_timers;
|
||||
uint32_t next_timer;
|
||||
uint32_t nof_used_timers;
|
||||
uint32_t nof_timers;
|
||||
std::vector<timer> timer_list;
|
||||
std::vector<bool> used_timers;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srslte/common/interfaces_common.h"
|
||||
#include "srslte/interfaces/sched_interface.h"
|
||||
#include "srslte/upper/rlc_interface.h"
|
||||
#include "srslte/asn1/liblte_rrc.h"
|
||||
#include "srslte/asn1/liblte_s1ap.h"
|
||||
|
||||
|
@ -156,7 +158,7 @@ public:
|
|||
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) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0;
|
||||
};
|
||||
|
||||
// PDCP interface for GTPU
|
||||
|
@ -174,7 +176,7 @@ public:
|
|||
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::byte_buffer_t *sdu) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, srslte::srslte_pdcp_config_t cnfg) = 0;
|
||||
virtual void config_security(uint16_t rnti,
|
||||
uint32_t lcid,
|
||||
uint8_t *k_rrc_enc_,
|
||||
|
@ -242,7 +244,7 @@ public:
|
|||
class gtpu_interface_rrc
|
||||
{
|
||||
public:
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t teid_out, uint32_t *teid_in) = 0;
|
||||
virtual void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, uint32_t *teid_in) = 0;
|
||||
virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0;
|
||||
virtual void rem_user(uint16_t rnti) = 0;
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "upper/common_enb.h"
|
||||
#include "upper/s1ap_metrics.h"
|
||||
#include "upper/rrc_metrics.h"
|
||||
#include "srslte/upper/gw_metrics.h"
|
||||
#include "../../../../srsue/hdr/upper/gw_metrics.h"
|
||||
#include "srslte/upper/rlc_metrics.h"
|
||||
#include "mac/mac_metrics.h"
|
||||
#include "phy/phy_metrics.h"
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
int priority;
|
||||
int bsd;
|
||||
int pbr;
|
||||
int group;
|
||||
enum {IDLE = 0, UL, DL, BOTH} direction;
|
||||
} ue_bearer_cfg_t;
|
||||
|
||||
|
@ -231,7 +232,7 @@ public:
|
|||
/* UL information */
|
||||
virtual int ul_crc_info(uint32_t tti, uint16_t rnti, bool crc) = 0;
|
||||
virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0;
|
||||
virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr) = 0;
|
||||
virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value = true) = 0;
|
||||
virtual int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) = 0;
|
||||
virtual int ul_phr(uint16_t rnti, int phr) = 0;
|
||||
virtual int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code) = 0;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "srslte/common/interfaces_common.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srslte/upper/rlc_interface.h"
|
||||
|
||||
namespace srsue {
|
||||
|
||||
|
@ -97,18 +98,40 @@ class nas_interface_rrc
|
|||
{
|
||||
public:
|
||||
virtual bool is_attached() = 0;
|
||||
virtual bool is_attaching() = 0;
|
||||
virtual void notify_connection_setup() = 0;
|
||||
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual uint32_t get_ul_count() = 0;
|
||||
virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0;
|
||||
virtual void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0;
|
||||
};
|
||||
|
||||
// NAS interface for UE
|
||||
class nas_interface_ue
|
||||
{
|
||||
public:
|
||||
virtual void attach_request() = 0;
|
||||
virtual void deattach_request() = 0;
|
||||
};
|
||||
|
||||
// NAS interface for UE
|
||||
class nas_interface_gw
|
||||
{
|
||||
public:
|
||||
virtual void attach_request() = 0;
|
||||
};
|
||||
|
||||
// RRC interface for MAC
|
||||
class rrc_interface_mac
|
||||
class rrc_interface_mac_common
|
||||
{
|
||||
public:
|
||||
virtual void ra_problem() = 0;
|
||||
};
|
||||
|
||||
class rrc_interface_mac : public rrc_interface_mac_common
|
||||
{
|
||||
public:
|
||||
virtual void release_pucch_srs() = 0;
|
||||
virtual void ra_problem() = 0;
|
||||
};
|
||||
|
||||
// RRC interface for PHY
|
||||
|
@ -117,6 +140,7 @@ class rrc_interface_phy
|
|||
public:
|
||||
virtual void in_sync() = 0;
|
||||
virtual void out_of_sync() = 0;
|
||||
virtual void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) = 0;
|
||||
};
|
||||
|
||||
// RRC interface for NAS
|
||||
|
@ -127,15 +151,9 @@ public:
|
|||
virtual uint16_t get_mcc() = 0;
|
||||
virtual uint16_t get_mnc() = 0;
|
||||
virtual void enable_capabilities() = 0;
|
||||
};
|
||||
|
||||
// RRC interface for GW
|
||||
class rrc_interface_gw
|
||||
{
|
||||
public:
|
||||
virtual bool rrc_connected() = 0;
|
||||
virtual void rrc_connect() = 0;
|
||||
virtual bool have_drb() = 0;
|
||||
virtual void plmn_search() = 0;
|
||||
virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) = 0;
|
||||
virtual std::string get_rb_name(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// RRC interface for PDCP
|
||||
|
@ -146,6 +164,7 @@ public:
|
|||
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0;
|
||||
virtual std::string get_rb_name(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// RRC interface for RLC
|
||||
|
@ -153,6 +172,7 @@ class rrc_interface_rlc
|
|||
{
|
||||
public:
|
||||
virtual void max_retx_attempted() = 0;
|
||||
virtual std::string get_rb_name(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// PDCP interface for GW
|
||||
|
@ -160,6 +180,7 @@ class pdcp_interface_gw
|
|||
{
|
||||
public:
|
||||
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual bool is_drb_enabled(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
// PDCP interface for RRC
|
||||
|
@ -168,7 +189,7 @@ class pdcp_interface_rrc
|
|||
public:
|
||||
virtual void reset() = 0;
|
||||
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0;
|
||||
virtual void config_security(uint32_t lcid,
|
||||
uint8_t *k_rrc_enc_,
|
||||
uint8_t *k_rrc_int_,
|
||||
|
@ -193,7 +214,7 @@ class rlc_interface_rrc
|
|||
public:
|
||||
virtual void reset() = 0;
|
||||
virtual void add_bearer(uint32_t lcid) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, srslte::srslte_rlc_config_t cnfg) = 0;
|
||||
};
|
||||
|
||||
// RLC interface for PDCP
|
||||
|
@ -230,6 +251,31 @@ public:
|
|||
};
|
||||
|
||||
|
||||
//BSR interface for MUX
|
||||
class bsr_interface_mux
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
LONG_BSR,
|
||||
SHORT_BSR,
|
||||
TRUNC_BSR
|
||||
} bsr_format_t;
|
||||
|
||||
typedef struct {
|
||||
bsr_format_t format;
|
||||
uint32_t buff_size[4];
|
||||
} bsr_t;
|
||||
|
||||
/* MUX calls BSR to check if it can fit a BSR into PDU */
|
||||
virtual bool need_to_send_bsr_on_ul_grant(uint32_t grant_size, bsr_t *bsr) = 0;
|
||||
|
||||
/* MUX calls BSR to let it generate a padding BSR if there is space in PDU */
|
||||
virtual bool generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t *bsr) = 0;
|
||||
|
||||
/* MAX calls BSR to set the Tx TTI */
|
||||
virtual void set_tx_tti(uint32_t tti) = 0;
|
||||
};
|
||||
|
||||
|
||||
/** MAC interface
|
||||
*
|
||||
|
@ -243,10 +289,12 @@ public:
|
|||
uint32_t pid;
|
||||
uint32_t tti;
|
||||
uint32_t last_tti;
|
||||
bool ndi;
|
||||
bool last_ndi;
|
||||
uint32_t n_bytes;
|
||||
int rv;
|
||||
bool ndi[SRSLTE_MAX_CODEWORDS];
|
||||
bool last_ndi[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t n_bytes[SRSLTE_MAX_CODEWORDS];
|
||||
int rv[SRSLTE_MAX_CODEWORDS];
|
||||
bool tb_en[SRSLTE_MAX_CODEWORDS];
|
||||
bool tb_cw_swap;
|
||||
uint16_t rnti;
|
||||
bool is_from_rar;
|
||||
bool is_sps_release;
|
||||
|
@ -256,28 +304,29 @@ public:
|
|||
} mac_grant_t;
|
||||
|
||||
typedef struct {
|
||||
bool decode_enabled;
|
||||
int rv;
|
||||
bool decode_enabled[SRSLTE_MAX_TB];
|
||||
int rv[SRSLTE_MAX_TB];
|
||||
uint16_t rnti;
|
||||
bool generate_ack;
|
||||
bool default_ack;
|
||||
bool default_ack[SRSLTE_MAX_TB];
|
||||
// If non-null, called after tb_decoded_ok to determine if ack needs to be sent
|
||||
bool (*generate_ack_callback)(void*);
|
||||
void *generate_ack_callback_arg;
|
||||
uint8_t *payload_ptr;
|
||||
srslte_softbuffer_rx_t *softbuffer;
|
||||
uint8_t *payload_ptr[SRSLTE_MAX_TB];
|
||||
srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_TB];
|
||||
srslte_phy_grant_t phy_grant;
|
||||
} tb_action_dl_t;
|
||||
|
||||
typedef struct {
|
||||
bool tx_enabled;
|
||||
bool expect_ack;
|
||||
uint32_t rv;
|
||||
uint32_t rv[SRSLTE_MAX_TB];
|
||||
uint16_t rnti;
|
||||
uint32_t current_tx_nb;
|
||||
srslte_softbuffer_tx_t *softbuffer;
|
||||
int32_t tti_offset; // relative offset between grant and UL tx/HARQ rx
|
||||
srslte_softbuffer_tx_t *softbuffers;
|
||||
srslte_phy_grant_t phy_grant;
|
||||
uint8_t *payload_ptr;
|
||||
uint8_t *payload_ptr[SRSLTE_MAX_TB];
|
||||
} tb_action_ul_t;
|
||||
|
||||
/* Indicate reception of UL grant.
|
||||
|
@ -294,7 +343,7 @@ public:
|
|||
virtual void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) = 0;
|
||||
|
||||
/* Indicate successfull decoding of PDSCH TB. */
|
||||
virtual void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0;
|
||||
virtual void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0;
|
||||
|
||||
/* Indicate successfull decoding of BCH TB through PBCH */
|
||||
virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0;
|
||||
|
@ -309,20 +358,10 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
/* Interface RRC -> MAC */
|
||||
class mac_interface_rrc
|
||||
/* Interface RRC -> MAC shared between different RATs */
|
||||
class mac_interface_rrc_common
|
||||
{
|
||||
public:
|
||||
|
||||
typedef struct {
|
||||
LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT main;
|
||||
LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT rach;
|
||||
LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr;
|
||||
uint32_t prach_config_index;
|
||||
} mac_cfg_t;
|
||||
|
||||
|
||||
// Class to handle UE specific RNTIs between RRC and MAC
|
||||
typedef struct {
|
||||
uint16_t crnti;
|
||||
|
@ -332,6 +371,25 @@ public:
|
|||
uint64_t contention_id;
|
||||
} ue_rnti_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t max_harq_msg3_tx;
|
||||
uint32_t max_harq_tx;
|
||||
} ul_harq_params_t;
|
||||
};
|
||||
|
||||
/* Interface RRC -> MAC */
|
||||
class mac_interface_rrc : public mac_interface_rrc_common
|
||||
{
|
||||
public:
|
||||
|
||||
typedef struct {
|
||||
LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT main;
|
||||
LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT rach;
|
||||
LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr;
|
||||
ul_harq_params_t ul_harq_params;
|
||||
uint32_t prach_config_index;
|
||||
} mac_cfg_t;
|
||||
|
||||
/* Instructs the MAC to start receiving BCCH */
|
||||
virtual void bcch_start_rx() = 0;
|
||||
virtual void bcch_stop_rx() = 0;
|
||||
|
@ -392,27 +450,17 @@ typedef struct {
|
|||
bool rssi_sensor_enabled;
|
||||
} phy_args_t;
|
||||
|
||||
/* Interface MAC -> PHY */
|
||||
class phy_interface_mac
|
||||
|
||||
/* RAT agnostic Interface MAC -> PHY */
|
||||
class phy_interface_mac_common
|
||||
{
|
||||
public:
|
||||
/* Configure PRACH using parameters written by RRC */
|
||||
virtual void configure_prach_params() = 0;
|
||||
|
||||
/* Start synchronization with strongest cell in the current carrier frequency */
|
||||
virtual void sync_start() = 0;
|
||||
virtual void sync_stop() = 0;
|
||||
virtual bool sync_status() = 0;
|
||||
|
||||
/* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */
|
||||
virtual void set_crnti(uint16_t rnti) = 0;
|
||||
|
||||
virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0;
|
||||
virtual int prach_tx_tti() = 0;
|
||||
|
||||
/* Indicates the transmission of a SR signal in the next opportunity */
|
||||
virtual void sr_send() = 0;
|
||||
virtual int sr_last_tx_tti() = 0;
|
||||
|
||||
/* Time advance commands */
|
||||
virtual void set_timeadv_rar(uint32_t ta_cmd) = 0;
|
||||
virtual void set_timeadv(uint32_t ta_cmd) = 0;
|
||||
|
@ -420,17 +468,31 @@ public:
|
|||
/* Sets RAR grant payload */
|
||||
virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 0;
|
||||
|
||||
virtual uint32_t get_current_tti() = 0;
|
||||
|
||||
virtual float get_phr() = 0;
|
||||
virtual float get_pathloss_db() = 0;
|
||||
};
|
||||
|
||||
/* Interface MAC -> PHY */
|
||||
class phy_interface_mac : public phy_interface_mac_common
|
||||
{
|
||||
public:
|
||||
/* Configure PRACH using parameters written by RRC */
|
||||
virtual void configure_prach_params() = 0;
|
||||
|
||||
virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0;
|
||||
virtual int prach_tx_tti() = 0;
|
||||
|
||||
/* Indicates the transmission of a SR signal in the next opportunity */
|
||||
virtual void sr_send() = 0;
|
||||
virtual int sr_last_tx_tti() = 0;
|
||||
|
||||
/* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */
|
||||
virtual void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
|
||||
virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
|
||||
virtual void pdcch_ul_search_reset() = 0;
|
||||
virtual void pdcch_dl_search_reset() = 0;
|
||||
|
||||
virtual uint32_t get_current_tti() = 0;
|
||||
|
||||
virtual float get_phr() = 0;
|
||||
virtual float get_pathloss_db() = 0;
|
||||
|
||||
};
|
||||
|
||||
class phy_interface_rrc
|
||||
|
@ -463,16 +525,21 @@ public:
|
|||
virtual void set_config_tdd(LIBLTE_RRC_TDD_CONFIG_STRUCT *tdd) = 0;
|
||||
virtual void set_config_64qam_en(bool enable) = 0;
|
||||
|
||||
/* Cell search and selection procedures */
|
||||
virtual void cell_search_start() = 0;
|
||||
virtual void cell_search_stop() = 0;
|
||||
virtual void cell_search_next() = 0;
|
||||
virtual bool cell_select(uint32_t earfcn, srslte_cell_t cell) = 0;
|
||||
|
||||
/* Is the PHY downlink synchronized? */
|
||||
virtual bool status_is_sync() = 0;
|
||||
virtual bool sync_status() = 0;
|
||||
virtual void sync_reset() = 0;
|
||||
|
||||
/* Configure UL using parameters written with set_param() */
|
||||
virtual void configure_ul_params(bool pregen_disabled = false) = 0;
|
||||
|
||||
virtual void reset() = 0;
|
||||
|
||||
virtual void resync_sfn() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -60,7 +60,10 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
srslte_cell_t cell;
|
||||
srslte_refsignal_cs_t csr_signal;
|
||||
srslte_refsignal_t csr_refs;
|
||||
srslte_refsignal_t **mbsfn_refs;
|
||||
|
||||
|
||||
cf_t *pilot_estimates;
|
||||
cf_t *pilot_estimates_average;
|
||||
cf_t *pilot_recv_signal;
|
||||
|
@ -75,7 +78,7 @@ typedef struct {
|
|||
|
||||
srslte_interp_linsrslte_vec_t srslte_interp_linvec;
|
||||
srslte_interp_lin_t srslte_interp_lin;
|
||||
|
||||
srslte_interp_lin_t srslte_interp_lin_mbsfn;
|
||||
float rssi[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
|
||||
float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
|
||||
float noise_estimate[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
|
||||
|
@ -92,10 +95,17 @@ typedef struct {
|
|||
|
||||
|
||||
SRSLTE_API int srslte_chest_dl_init(srslte_chest_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_chest_dl_free(srslte_chest_dl_t *q);
|
||||
|
||||
|
||||
SRSLTE_API int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q,
|
||||
uint16_t mbsfn_area_id);
|
||||
SRSLTE_API int srslte_chest_dl_set_cell(srslte_chest_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
|
||||
SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q,
|
||||
float *filter,
|
||||
uint32_t filter_len);
|
||||
|
@ -106,6 +116,8 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q,
|
|||
SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q,
|
||||
srslte_chest_dl_noise_alg_t noise_estimation_alg);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
|
@ -117,6 +129,14 @@ SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q,
|
|||
cf_t *ce[SRSLTE_MAX_PORTS],
|
||||
uint32_t sf_idx);
|
||||
|
||||
SRSLTE_API int srslte_chest_dl_estimate_multi_mbsfn(srslte_chest_dl_t *q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
uint32_t sf_idx,
|
||||
uint32_t nof_rx_antennas,
|
||||
uint16_t mbsfn_area_id);
|
||||
|
||||
|
||||
SRSLTE_API int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q,
|
||||
cf_t *input,
|
||||
cf_t *ce,
|
||||
|
@ -132,6 +152,9 @@ SRSLTE_API float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q);
|
|||
|
||||
SRSLTE_API float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q);
|
||||
|
||||
SRSLTE_API float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q,
|
||||
uint32_t port);
|
||||
|
||||
SRSLTE_API float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -77,10 +77,14 @@ typedef struct {
|
|||
|
||||
|
||||
SRSLTE_API int srslte_chest_ul_init(srslte_chest_ul_t *q,
|
||||
srslte_cell_t cell);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_chest_ul_free(srslte_chest_ul_t *q);
|
||||
|
||||
SRSLTE_API int srslte_chest_ul_set_cell(srslte_chest_ul_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
|
||||
SRSLTE_API void srslte_chest_ul_set_cfg(srslte_chest_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg,
|
||||
|
|
|
@ -40,22 +40,34 @@
|
|||
|
||||
// Number of references in a subframe: there are 2 symbols for port_id=0,1 x 2 slots x 2 refs per prb
|
||||
#define SRSLTE_REFSIGNAL_NUM_SF(nof_prb, port_id) (((port_id)<2?8:4)*(nof_prb))
|
||||
#define SRSLTE_REFSIGNAL_NUM_SF_MBSFN(nof_prb, port_id) ((2 + 18)*(nof_prb))
|
||||
|
||||
#define SRSLTE_REFSIGNAL_MAX_NUM_SF(nof_prb) SRSLTE_REFSIGNAL_NUM_SF(nof_prb, 0)
|
||||
#define SRSLTE_REFSIGNAL_MAX_NUM_SF_MBSFN(nof_prb) SRSLTE_REFSIGNAL_NUM_SF_MBSFN(nof_prb,0)
|
||||
|
||||
#define SRSLTE_REFSIGNAL_PILOT_IDX(i,l,cell) (2*cell.nof_prb*(l)+(i))
|
||||
|
||||
#define SRSLTE_REFSIGNAL_PILOT_IDX_MBSFN(i,l,cell) ((6*cell.nof_prb*(l)+(i)))
|
||||
|
||||
|
||||
|
||||
/** Cell-Specific Reference Signal */
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cell_t cell;
|
||||
cf_t *pilots[2][SRSLTE_NSUBFRAMES_X_FRAME]; // Saves the reference signal per subframe for ports 0,1 and ports 2,3
|
||||
} srslte_refsignal_cs_t;
|
||||
cf_t *pilots[2][SRSLTE_NSUBFRAMES_X_FRAME]; // Saves the reference signal per subframe for ports 0,1 and ports 2,3
|
||||
srslte_sf_t type;
|
||||
uint16_t mbsfn_area_id;
|
||||
} srslte_refsignal_t;
|
||||
|
||||
|
||||
SRSLTE_API int srslte_refsignal_cs_init(srslte_refsignal_cs_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_refsignal_cs_free(srslte_refsignal_cs_t *q);
|
||||
SRSLTE_API int srslte_refsignal_cs_init(srslte_refsignal_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_cs_set_cell(srslte_refsignal_t * q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_refsignal_free(srslte_refsignal_t *q);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_cs_put_sf(srslte_cell_t cell,
|
||||
uint32_t port_id,
|
||||
|
@ -81,4 +93,29 @@ SRSLTE_API uint32_t srslte_refsignal_cs_v(uint32_t port_id,
|
|||
|
||||
SRSLTE_API uint32_t srslte_refsignal_cs_nof_symbols(uint32_t port_id);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_init(srslte_refsignal_t *q, srslte_cell_t cell,
|
||||
uint16_t mbsfn_area_id);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_get_sf(srslte_cell_t cell,
|
||||
uint32_t port_id,
|
||||
cf_t *sf_symbols,
|
||||
cf_t *pilots);
|
||||
|
||||
SRSLTE_API uint32_t srslte_refsignal_mbsfn_nsymbol(uint32_t l);
|
||||
|
||||
SRSLTE_API uint32_t srslte_refsignal_mbsfn_fidx(uint32_t l);
|
||||
|
||||
SRSLTE_API uint32_t srslte_refsignal_mbsfn_nof_symbols();
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_put_sf(srslte_cell_t cell,
|
||||
uint32_t port_id,
|
||||
cf_t *cs_pilots,
|
||||
cf_t *mbsfn_pilots,
|
||||
cf_t *sf_symbols);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_gen_seq(srslte_refsignal_t * q,
|
||||
srslte_cell_t cell,
|
||||
uint32_t N_mbsfn_id);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -94,7 +94,10 @@ typedef struct {
|
|||
} srslte_refsignal_srs_pregen_t;
|
||||
|
||||
SRSLTE_API int srslte_refsignal_ul_init(srslte_refsignal_ul_t *q,
|
||||
srslte_cell_t cell);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_ul_set_cell(srslte_refsignal_ul_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_refsignal_ul_free(srslte_refsignal_ul_t *q);
|
||||
|
||||
|
@ -117,6 +120,10 @@ SRSLTE_API bool srslte_refsignal_dmrs_pusch_cfg_isvalid(srslte_refsignal_ul_t *q
|
|||
srslte_refsignal_dmrs_pusch_cfg_t *cfg,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_dmrs_pusch_pregen_init(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_ul_dmrs_pregen_t *pregen,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_dmrs_pusch_pregen(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_ul_dmrs_pregen_t *pregen);
|
||||
|
||||
|
|
|
@ -52,13 +52,22 @@
|
|||
#define SRSLTE_MAX_PORTS 4
|
||||
#define SRSLTE_MAX_LAYERS 4
|
||||
#define SRSLTE_MAX_CODEWORDS 2
|
||||
#define SRSLTE_MAX_TB SRSLTE_MAX_CODEWORDS
|
||||
|
||||
#define SRSLTE_MAX_CODEBLOCKS 32
|
||||
|
||||
#define SRSLTE_MAX_CODEBOOKS 4
|
||||
|
||||
#define SRSLTE_LTE_CRC24A 0x1864CFB
|
||||
#define SRSLTE_LTE_CRC24B 0X1800063
|
||||
#define SRSLTE_LTE_CRC16 0x11021
|
||||
#define SRSLTE_LTE_CRC8 0x19B
|
||||
|
||||
#define SRSLTE_MAX_MBSFN_AREA_IDS 256
|
||||
#define SRSLTE_PMCH_RV 0
|
||||
|
||||
typedef enum {SRSLTE_CP_NORM, SRSLTE_CP_EXT} srslte_cp_t;
|
||||
typedef enum {SRSLTE_SF_NORM, SRSLTE_SF_MBSFN} srslte_sf_t;
|
||||
|
||||
|
||||
#define SRSLTE_CRNTI_START 0x000B
|
||||
|
@ -125,6 +134,13 @@ typedef enum {SRSLTE_CP_NORM, SRSLTE_CP_EXT} srslte_cp_t;
|
|||
|| l == SRSLTE_CP_NSYMB(cp) - 3)
|
||||
|
||||
|
||||
|
||||
#define SRSLTE_SYMBOL_HAS_REF_MBSFN(l, s) ((l == 2 && s == 0) || (l == 0 && s == 1) || (l == 4 && s == 1))
|
||||
|
||||
#define SRSLTE_NON_MBSFN_REGION_GUARD_LENGTH(non_mbsfn_region,symbol_sz) ((non_mbsfn_region == 1)?(SRSLTE_CP_LEN_EXT(symbol_sz) - SRSLTE_CP_LEN_NORM(0, symbol_sz)):(2*SRSLTE_CP_LEN_EXT(symbol_sz) - SRSLTE_CP_LEN_NORM(0, symbol_sz)- SRSLTE_CP_LEN_NORM(1, symbol_sz)))
|
||||
|
||||
|
||||
|
||||
#define SRSLTE_NOF_LTE_BANDS 38
|
||||
|
||||
#define SRSLTE_DEFAULT_MAX_FRAMES_PBCH 500
|
||||
|
@ -146,12 +162,13 @@ typedef enum SRSLTE_API {
|
|||
} srslte_phich_resources_t;
|
||||
|
||||
typedef enum {
|
||||
SRSLTE_RNTI_USER = 0,
|
||||
SRSLTE_RNTI_SI,
|
||||
SRSLTE_RNTI_RAR,
|
||||
SRSLTE_RNTI_TEMP,
|
||||
SRSLTE_RNTI_SPS,
|
||||
SRSLTE_RNTI_PCH,
|
||||
SRSLTE_RNTI_USER = 0, /* Cell RNTI */
|
||||
SRSLTE_RNTI_SI, /* System Information RNTI */
|
||||
SRSLTE_RNTI_RAR, /* Random Access RNTI */
|
||||
SRSLTE_RNTI_TEMP, /* Temporary C-RNTI */
|
||||
SRSLTE_RNTI_SPS, /* Semi-Persistent Scheduling C-RNTI */
|
||||
SRSLTE_RNTI_PCH, /* Paging RNTI */
|
||||
SRSLTE_RNTI_MBSFN,
|
||||
SRSLTE_RNTI_NOF_TYPES
|
||||
} srslte_rnti_type_t;
|
||||
|
||||
|
@ -171,6 +188,11 @@ typedef enum SRSLTE_API {
|
|||
SRSLTE_MIMO_TYPE_CDD
|
||||
} srslte_mimo_type_t;
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
SRSLTE_MIMO_DECODER_ZF,
|
||||
SRSLTE_MIMO_DECODER_MMSE
|
||||
} srslte_mimo_decoder_t;
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
SRSLTE_MOD_BPSK = 0,
|
||||
SRSLTE_MOD_QPSK,
|
||||
|
@ -240,8 +262,13 @@ SRSLTE_API uint32_t srslte_N_ta_new_rar(uint32_t ta);
|
|||
SRSLTE_API uint32_t srslte_N_ta_new(uint32_t N_ta_old,
|
||||
uint32_t ta);
|
||||
|
||||
SRSLTE_API float srslte_coderate(uint32_t tbs,
|
||||
uint32_t nof_re);
|
||||
|
||||
SRSLTE_API char *srslte_cp_string(srslte_cp_t cp);
|
||||
|
||||
SRSLTE_API srslte_mod_t srslte_str2mod (char * mod_str);
|
||||
|
||||
SRSLTE_API char *srslte_mod_string(srslte_mod_t mod);
|
||||
|
||||
SRSLTE_API uint32_t srslte_mod_bits_x_symbol(srslte_mod_t mod);
|
||||
|
@ -271,6 +298,8 @@ SRSLTE_API int srslte_band_get_fd_region(enum band_geographical_area region,
|
|||
SRSLTE_API int srslte_str2mimotype(char *mimo_type_str,
|
||||
srslte_mimo_type_t *type);
|
||||
|
||||
SRSLTE_API char *srslte_mimotype2str(srslte_mimo_type_t mimo_type);
|
||||
|
||||
SRSLTE_API uint32_t srslte_tti_interval(uint32_t tti1,
|
||||
uint32_t tti2);
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ typedef struct SRSLTE_API {
|
|||
uint8_t *c_bytes;
|
||||
float *c_float;
|
||||
short *c_short;
|
||||
uint32_t len;
|
||||
uint32_t cur_len;
|
||||
uint32_t max_len;
|
||||
} srslte_sequence_t;
|
||||
|
||||
SRSLTE_API int srslte_sequence_init(srslte_sequence_t *q, uint32_t len);
|
||||
|
@ -55,7 +56,8 @@ SRSLTE_API int srslte_sequence_LTE_pr(srslte_sequence_t *q,
|
|||
uint32_t len,
|
||||
uint32_t seed);
|
||||
|
||||
SRSLTE_API void srslte_sequence_set_LTE_pr(srslte_sequence_t *q,
|
||||
SRSLTE_API int srslte_sequence_set_LTE_pr(srslte_sequence_t *q,
|
||||
uint32_t len,
|
||||
uint32_t seed);
|
||||
|
||||
SRSLTE_API int srslte_sequence_pbch(srslte_sequence_t *seq,
|
||||
|
@ -92,4 +94,10 @@ SRSLTE_API int srslte_sequence_pucch(srslte_sequence_t *seq,
|
|||
uint16_t rnti,
|
||||
uint32_t nslot,
|
||||
uint32_t cell_id);
|
||||
|
||||
SRSLTE_API int srslte_sequence_pmch(srslte_sequence_t *seq,
|
||||
uint32_t nslot,
|
||||
uint32_t mbsfn_id,
|
||||
uint32_t len);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef enum {
|
|||
}srslte_dft_dir_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
int init_size; // DFT length used in the first initialization
|
||||
int size; // DFT length
|
||||
void *in; // Input buffer
|
||||
void *out; // Output buffer
|
||||
|
@ -71,7 +72,9 @@ typedef struct SRSLTE_API {
|
|||
srslte_dft_mode_t mode; // Complex/Real
|
||||
}srslte_dft_plan_t;
|
||||
|
||||
/* Create DFT plans */
|
||||
SRSLTE_API void srslte_dft_load();
|
||||
|
||||
SRSLTE_API void srslte_dft_exit();
|
||||
|
||||
SRSLTE_API int srslte_dft_plan(srslte_dft_plan_t *plan,
|
||||
int dft_points,
|
||||
|
@ -86,6 +89,16 @@ SRSLTE_API int srslte_dft_plan_r(srslte_dft_plan_t *plan,
|
|||
int dft_points,
|
||||
srslte_dft_dir_t dir);
|
||||
|
||||
SRSLTE_API int srslte_dft_replan(srslte_dft_plan_t *plan,
|
||||
const int new_dft_points);
|
||||
|
||||
SRSLTE_API int srslte_dft_replan_c(srslte_dft_plan_t *plan,
|
||||
int new_dft_points);
|
||||
|
||||
SRSLTE_API int srslte_dft_replan_r(srslte_dft_plan_t *plan,
|
||||
int new_dft_points);
|
||||
|
||||
|
||||
SRSLTE_API void srslte_dft_plan_free(srslte_dft_plan_t *plan);
|
||||
|
||||
/* Set options */
|
||||
|
|
|
@ -45,12 +45,18 @@ typedef struct SRSLTE_API {
|
|||
|
||||
uint32_t max_prb;
|
||||
srslte_dft_plan_t dft_plan[SRSLTE_MAX_PRB+1];
|
||||
srslte_dft_plan_t idft_plan[SRSLTE_MAX_PRB+1];
|
||||
|
||||
}srslte_dft_precoding_t;
|
||||
|
||||
SRSLTE_API int srslte_dft_precoding_init(srslte_dft_precoding_t *q,
|
||||
uint32_t max_prb);
|
||||
uint32_t max_prb,
|
||||
bool is_tx);
|
||||
|
||||
SRSLTE_API int srslte_dft_precoding_init_tx(srslte_dft_precoding_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_dft_precoding_init_rx(srslte_dft_precoding_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_dft_precoding_free(srslte_dft_precoding_t *q);
|
||||
|
||||
|
@ -62,10 +68,4 @@ SRSLTE_API int srslte_dft_precoding(srslte_dft_precoding_t *q,
|
|||
uint32_t nof_prb,
|
||||
uint32_t nof_symbols);
|
||||
|
||||
SRSLTE_API int srslte_dft_predecoding(srslte_dft_precoding_t *q,
|
||||
cf_t *input,
|
||||
cf_t *output,
|
||||
uint32_t nof_prb,
|
||||
uint32_t nof_symbols);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
/* This is common for both directions */
|
||||
typedef struct SRSLTE_API{
|
||||
srslte_dft_plan_t fft_plan;
|
||||
uint32_t max_prb;
|
||||
uint32_t nof_symbols;
|
||||
uint32_t symbol_sz;
|
||||
uint32_t nof_guards;
|
||||
|
@ -55,7 +56,14 @@ typedef struct SRSLTE_API{
|
|||
srslte_cp_t cp;
|
||||
cf_t *tmp; // for removing zero padding
|
||||
|
||||
bool mbsfn_subframe;
|
||||
uint32_t mbsfn_guard_len;
|
||||
uint32_t nof_symbols_mbsfn;
|
||||
uint8_t non_mbsfn_region;
|
||||
|
||||
|
||||
bool freq_shift;
|
||||
float freq_shift_f;
|
||||
cf_t *shift_buffer;
|
||||
}srslte_ofdm_t;
|
||||
|
||||
|
@ -65,9 +73,30 @@ SRSLTE_API int srslte_ofdm_init_(srslte_ofdm_t *q,
|
|||
int nof_prb,
|
||||
srslte_dft_dir_t dir);
|
||||
|
||||
SRSLTE_API int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp,
|
||||
int symbol_sz,
|
||||
int nof_prb,
|
||||
srslte_dft_dir_t dir,
|
||||
srslte_sf_t sf_type);
|
||||
|
||||
SRSLTE_API int srslte_ofdm_rx_init_mbsfn(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp_type,
|
||||
uint32_t nof_prb);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API int srslte_ofdm_rx_init(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp_type,
|
||||
uint32_t nof_prb);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_ofdm_tx_set_prb(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API int srslte_ofdm_rx_set_prb(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API void srslte_ofdm_rx_free(srslte_ofdm_t *q);
|
||||
|
||||
|
@ -85,12 +114,22 @@ SRSLTE_API int srslte_ofdm_tx_init(srslte_ofdm_t *q,
|
|||
srslte_cp_t cp_type,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API int srslte_ofdm_tx_init_mbsfn(srslte_ofdm_t *q,
|
||||
srslte_cp_t cp,
|
||||
uint32_t nof_prb);
|
||||
|
||||
|
||||
SRSLTE_API void srslte_ofdm_tx_free(srslte_ofdm_t *q);
|
||||
|
||||
SRSLTE_API void srslte_ofdm_tx_slot(srslte_ofdm_t *q,
|
||||
cf_t *input,
|
||||
cf_t *output);
|
||||
|
||||
SRSLTE_API void srslte_ofdm_tx_slot_mbsfn(srslte_ofdm_t *q,
|
||||
cf_t *input,
|
||||
cf_t *output);
|
||||
|
||||
|
||||
SRSLTE_API void srslte_ofdm_tx_sf(srslte_ofdm_t *q,
|
||||
cf_t *input,
|
||||
cf_t *output);
|
||||
|
@ -101,4 +140,8 @@ SRSLTE_API int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q,
|
|||
SRSLTE_API void srslte_ofdm_set_normalize(srslte_ofdm_t *q,
|
||||
bool normalize_enable);
|
||||
|
||||
SRSLTE_API void srslte_ofdm_set_non_mbsfn_region(srslte_ofdm_t *q,
|
||||
uint8_t non_mbsfn_region);
|
||||
|
||||
|
||||
#endif
|
|
@ -76,7 +76,7 @@ typedef struct SRSLTE_API {
|
|||
srslte_pdsch_t pdsch;
|
||||
srslte_phich_t phich;
|
||||
|
||||
srslte_refsignal_cs_t csr_signal;
|
||||
srslte_refsignal_t csr_signal;
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_ra_dl_dci_t dl_dci;
|
||||
|
||||
|
@ -89,6 +89,8 @@ typedef struct SRSLTE_API {
|
|||
|
||||
float tx_amp;
|
||||
|
||||
uint8_t tmp[1024*128];
|
||||
|
||||
} srslte_enb_dl_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -108,10 +110,13 @@ typedef struct {
|
|||
|
||||
/* This function shall be called just after the initial synchronization */
|
||||
SRSLTE_API int srslte_enb_dl_init(srslte_enb_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q);
|
||||
|
||||
SRSLTE_API int srslte_enb_dl_set_cell(srslte_enb_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q,
|
||||
uint32_t cfi);
|
||||
|
||||
|
@ -152,11 +157,13 @@ SRSLTE_API void srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q,
|
|||
|
||||
SRSLTE_API int srslte_enb_dl_put_pdsch(srslte_enb_dl_t *q,
|
||||
srslte_ra_dl_grant_t *grant,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
srslte_softbuffer_tx_t *softbuffer[SRSLTE_MAX_CODEWORDS],
|
||||
uint16_t rnti,
|
||||
uint32_t rv_idx,
|
||||
int rv_idx[SRSLTE_MAX_CODEWORDS],
|
||||
uint32_t sf_idx,
|
||||
uint8_t *data);
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
srslte_mimo_type_t mimo_type,
|
||||
uint32_t pmi);
|
||||
|
||||
SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q,
|
||||
srslte_ra_dl_dci_t *grant,
|
||||
|
@ -171,5 +178,12 @@ SRSLTE_API int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q,
|
|||
uint16_t rnti,
|
||||
uint32_t sf_idx);
|
||||
|
||||
SRSLTE_API void srslte_enb_dl_save_signal(srslte_enb_dl_t *q,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
uint32_t tti,
|
||||
uint32_t rv_idx,
|
||||
uint16_t rnti,
|
||||
uint32_t cfi);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -101,14 +101,17 @@ typedef struct {
|
|||
|
||||
/* This function shall be called just after the initial synchronization */
|
||||
SRSLTE_API int srslte_enb_ul_init(srslte_enb_ul_t *q,
|
||||
srslte_cell_t cell,
|
||||
srslte_prach_cfg_t* prach_cfg,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg,
|
||||
srslte_pusch_hopping_cfg_t *hopping_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_enb_ul_free(srslte_enb_ul_t *q);
|
||||
|
||||
SRSLTE_API int srslte_enb_ul_set_cell(srslte_enb_ul_t *q,
|
||||
srslte_cell_t cell,
|
||||
srslte_prach_cfg_t* prach_cfg,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg,
|
||||
srslte_pusch_hopping_cfg_t *hopping_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg);
|
||||
|
||||
SRSLTE_API int srslte_enb_ul_add_rnti(srslte_enb_ul_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
|
|
|
@ -50,18 +50,14 @@
|
|||
#define SRSLTE_TCOD_MAX_LEN_CODED (SRSLTE_TCOD_RATE*SRSLTE_TCOD_MAX_LEN_CB+SRSLTE_TCOD_TOTALTAIL)
|
||||
|
||||
#include "srslte/phy/fec/turbodecoder_gen.h"
|
||||
|
||||
#ifdef LV_HAVE_SSE
|
||||
#include "srslte/phy/fec/turbodecoder_sse.h"
|
||||
#endif
|
||||
#include "srslte/phy/fec/turbodecoder_simd.h"
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
#ifdef LV_HAVE_SSE
|
||||
srslte_tdec_sse_t tdec_sse;
|
||||
#else
|
||||
float *input_conv;
|
||||
srslte_tdec_gen_t tdec_gen;
|
||||
#endif
|
||||
union {
|
||||
srslte_tdec_simd_t tdec_simd;
|
||||
srslte_tdec_gen_t tdec_gen;
|
||||
};
|
||||
} srslte_tdec_t;
|
||||
|
||||
SRSLTE_API int srslte_tdec_init(srslte_tdec_t * h,
|
||||
|
@ -69,7 +65,16 @@ SRSLTE_API int srslte_tdec_init(srslte_tdec_t * h,
|
|||
|
||||
SRSLTE_API void srslte_tdec_free(srslte_tdec_t * h);
|
||||
|
||||
SRSLTE_API int srslte_tdec_reset(srslte_tdec_t * h, uint32_t long_cb);
|
||||
SRSLTE_API int srslte_tdec_reset(srslte_tdec_t * h,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API int srslte_tdec_reset_cb(srslte_tdec_t * h,
|
||||
uint32_t cb_idx);
|
||||
|
||||
SRSLTE_API int srslte_tdec_get_nof_iterations_cb(srslte_tdec_t * h,
|
||||
uint32_t cb_idx);
|
||||
|
||||
SRSLTE_API uint32_t srslte_tdec_get_nof_parallel(srslte_tdec_t * h);
|
||||
|
||||
SRSLTE_API void srslte_tdec_iteration(srslte_tdec_t * h,
|
||||
int16_t* input,
|
||||
|
@ -89,4 +94,27 @@ SRSLTE_API int srslte_tdec_run_all(srslte_tdec_t * h,
|
|||
uint32_t nof_iterations,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_iteration_par(srslte_tdec_t * h,
|
||||
int16_t* input[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_decision_par(srslte_tdec_t * h,
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_decision_byte_par(srslte_tdec_t * h,
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_decision_byte_par_cb(srslte_tdec_t * h,
|
||||
uint8_t *output,
|
||||
uint32_t cb_idx,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API int srslte_tdec_run_all_par(srslte_tdec_t * h,
|
||||
int16_t * input[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t nof_iterations,
|
||||
uint32_t long_cb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,8 @@ typedef struct SRSLTE_API {
|
|||
float *parity;
|
||||
|
||||
int current_cbidx;
|
||||
uint32_t current_cb_len;
|
||||
uint32_t n_iter;
|
||||
srslte_tc_interl_t interleaver[SRSLTE_NOF_TC_CB_SIZES];
|
||||
} srslte_tdec_gen_t;
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* 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: turbodecoder.h
|
||||
*
|
||||
* Description: Turbo Decoder.
|
||||
* Parallel Concatenated Convolutional Code (PCCC) with two 8-state constituent
|
||||
* encoders and one turbo code internal interleaver. The coding rate of turbo
|
||||
* encoder is 1/3.
|
||||
* MAP_GEN is the MAX-LOG-MAP generic implementation of the decoder.
|
||||
*
|
||||
* Reference: 3GPP TS 36.212 version 10.0.0 Release 10 Sec. 5.1.3.2
|
||||
*********************************************************************************************/
|
||||
|
||||
#ifndef TURBODECODER_SSE_
|
||||
#define TURBODECODER_SSE_
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/phy/fec/tc_interl.h"
|
||||
#include "srslte/phy/fec/cbsegm.h"
|
||||
|
||||
// Define maximum number of CB decoded in parallel (2 for AVX2)
|
||||
#define SRSLTE_TDEC_MAX_NPAR 2
|
||||
|
||||
#define SRSLTE_TCOD_RATE 3
|
||||
#define SRSLTE_TCOD_TOTALTAIL 12
|
||||
|
||||
#define SRSLTE_TCOD_MAX_LEN_CB 6144
|
||||
#define SRSLTE_TCOD_MAX_LEN_CODED (SRSLTE_TCOD_RATE*SRSLTE_TCOD_MAX_LEN_CB+SRSLTE_TCOD_TOTALTAIL)
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_long_cb;
|
||||
uint32_t max_par_cb;
|
||||
int16_t *alpha;
|
||||
int16_t *branch;
|
||||
} map_gen_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_long_cb;
|
||||
uint32_t max_par_cb;
|
||||
|
||||
map_gen_t dec;
|
||||
|
||||
int16_t *app1[SRSLTE_TDEC_MAX_NPAR];
|
||||
int16_t *app2[SRSLTE_TDEC_MAX_NPAR];
|
||||
int16_t *ext1[SRSLTE_TDEC_MAX_NPAR];
|
||||
int16_t *ext2[SRSLTE_TDEC_MAX_NPAR];
|
||||
int16_t *syst[SRSLTE_TDEC_MAX_NPAR];
|
||||
int16_t *parity0[SRSLTE_TDEC_MAX_NPAR];
|
||||
int16_t *parity1[SRSLTE_TDEC_MAX_NPAR];
|
||||
|
||||
int cb_mask;
|
||||
int current_cbidx;
|
||||
srslte_tc_interl_t interleaver[SRSLTE_NOF_TC_CB_SIZES];
|
||||
int n_iter[SRSLTE_TDEC_MAX_NPAR];
|
||||
} srslte_tdec_simd_t;
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_init(srslte_tdec_simd_t * h,
|
||||
uint32_t max_par_cb,
|
||||
uint32_t max_long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_free(srslte_tdec_simd_t * h);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_reset(srslte_tdec_simd_t * h,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_get_nof_iterations_cb(srslte_tdec_simd_t * h,
|
||||
uint32_t cb_idx);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_reset_cb(srslte_tdec_simd_t * h,
|
||||
uint32_t cb_idx);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_iteration(srslte_tdec_simd_t * h,
|
||||
int16_t * input[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_decision(srslte_tdec_simd_t * h,
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_decision_byte(srslte_tdec_simd_t * h,
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_decision_byte_cb(srslte_tdec_simd_t * h,
|
||||
uint8_t *output,
|
||||
uint32_t cbidx,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_run_all(srslte_tdec_simd_t * h,
|
||||
int16_t * input[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t nof_iterations,
|
||||
uint32_t long_cb);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* 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: turbodecoder.h
|
||||
*
|
||||
* Description: Turbo Decoder.
|
||||
* Parallel Concatenated Convolutional Code (PCCC) with two 8-state constituent
|
||||
* encoders and one turbo code internal interleaver. The coding rate of turbo
|
||||
* encoder is 1/3.
|
||||
* MAP_GEN is the MAX-LOG-MAP generic implementation of the decoder.
|
||||
*
|
||||
* Reference: 3GPP TS 36.212 version 10.0.0 Release 10 Sec. 5.1.3.2
|
||||
*********************************************************************************************/
|
||||
|
||||
#ifndef TURBODECODER_SSE_INTER_
|
||||
#define TURBODECODER_SSE_INTER_
|
||||
|
||||
|
||||
/** This is an simd inter-frame parallel turbo decoder. Parallizes 8 code-blocks using SSE
|
||||
* This implementation is currently not functional and not used by the rest of the code
|
||||
*/
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/phy/fec/tc_interl.h"
|
||||
#include "srslte/phy/fec/cbsegm.h"
|
||||
|
||||
#if LV_HAVE_AVX2
|
||||
#define SRSLTE_TDEC_MAX_NPAR 16
|
||||
#else
|
||||
#define SRSLTE_TDEC_MAX_NPAR 8
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
int max_long_cb;
|
||||
|
||||
int16_t *syst0;
|
||||
int16_t *parity0;
|
||||
int16_t *syst1;
|
||||
int16_t *parity1;
|
||||
int16_t *llr1;
|
||||
int16_t *llr2;
|
||||
int16_t *w;
|
||||
int16_t *alpha;
|
||||
|
||||
uint32_t max_par_cb;
|
||||
int current_cbidx;
|
||||
uint32_t current_long_cb;
|
||||
srslte_tc_interl_t interleaver[SRSLTE_NOF_TC_CB_SIZES];
|
||||
int n_iter[SRSLTE_TDEC_MAX_NPAR];
|
||||
} srslte_tdec_simd_inter_t;
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_inter_init(srslte_tdec_simd_inter_t * h,
|
||||
uint32_t max_par_cb,
|
||||
uint32_t max_long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_inter_free(srslte_tdec_simd_inter_t * h);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_inter_reset(srslte_tdec_simd_inter_t * h,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_inter_get_nof_iterations_cb(srslte_tdec_simd_inter_t * h,
|
||||
uint32_t cb_idx);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_inter_reset_cb(srslte_tdec_simd_inter_t * h,
|
||||
uint32_t cb_idx);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_inter_iteration(srslte_tdec_simd_inter_t * h,
|
||||
int16_t * input[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t nof_cb,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_inter_decision(srslte_tdec_simd_inter_t * h,
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t nof_cb,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_inter_decision_byte(srslte_tdec_simd_inter_t * h,
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t nof_cb,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API void srslte_tdec_simd_inter_decision_byte_cb(srslte_tdec_simd_inter_t * h,
|
||||
uint8_t *output,
|
||||
uint32_t cbidx,
|
||||
uint32_t long_cb);
|
||||
|
||||
SRSLTE_API int srslte_tdec_simd_inter_run_all(srslte_tdec_simd_inter_t * h,
|
||||
int16_t *input[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint8_t *output[SRSLTE_TDEC_MAX_NPAR],
|
||||
uint32_t nof_iterations,
|
||||
uint32_t nof_cb,
|
||||
uint32_t long_cb);
|
||||
|
||||
#endif
|
|
@ -59,4 +59,9 @@ SRSLTE_API int srslte_filesink_write(srslte_filesink_t *q,
|
|||
void *buffer,
|
||||
int nsamples);
|
||||
|
||||
SRSLTE_API int srslte_filesink_write_multi(srslte_filesink_t *q,
|
||||
void **buffer,
|
||||
int nsamples,
|
||||
int nchannels);
|
||||
|
||||
#endif // FILESINK_
|
||||
|
|
|
@ -62,4 +62,9 @@ SRSLTE_API int srslte_filesource_read(srslte_filesource_t *q,
|
|||
void *buffer,
|
||||
int nsamples);
|
||||
|
||||
SRSLTE_API int srslte_filesource_read_multi(srslte_filesource_t *q,
|
||||
void **buffer,
|
||||
int nsamples,
|
||||
int nof_channels);
|
||||
|
||||
#endif // FILESOURCE_
|
||||
|
|
|
@ -66,6 +66,7 @@ SRSLTE_API int srslte_precoding_type(cf_t *x[SRSLTE_MAX_LAYERS],
|
|||
cf_t *y[SRSLTE_MAX_PORTS],
|
||||
int nof_layers,
|
||||
int nof_ports,
|
||||
int codebook_idx,
|
||||
int nof_symbols,
|
||||
srslte_mimo_type_t type);
|
||||
|
||||
|
@ -106,14 +107,31 @@ SRSLTE_API int srslte_predecoding_type(cf_t *y,
|
|||
srslte_mimo_type_t type,
|
||||
float noise_estimate);
|
||||
|
||||
SRSLTE_API void srslte_predecoding_set_mimo_decoder (srslte_mimo_decoder_t _mimo_decoder);
|
||||
|
||||
SRSLTE_API int srslte_predecoding_type_multi(cf_t *y[SRSLTE_MAX_PORTS],
|
||||
cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
cf_t *x[SRSLTE_MAX_LAYERS],
|
||||
int nof_rxant,
|
||||
int nof_ports,
|
||||
int nof_layers,
|
||||
int codebook_idx,
|
||||
int nof_symbols,
|
||||
srslte_mimo_type_t type,
|
||||
float noise_estimate);
|
||||
|
||||
SRSLTE_API int srslte_precoding_pmi_select(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
uint32_t nof_symbols,
|
||||
float noise_estimate,
|
||||
int nof_layers,
|
||||
uint32_t *pmi,
|
||||
float sinr[SRSLTE_MAX_CODEBOOKS]);
|
||||
|
||||
SRSLTE_API int srslte_precoding_cn(cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
uint32_t nof_tx_antennas,
|
||||
uint32_t nof_rx_antennas,
|
||||
uint32_t nof_symbols,
|
||||
float *cn);
|
||||
|
||||
|
||||
#endif /* PRECODING_H_ */
|
||||
|
|
|
@ -41,10 +41,14 @@
|
|||
#include "srslte/phy/common/phy_common.h"
|
||||
|
||||
#define SRSLTE_CQI_MAX_BITS 64
|
||||
#define SRSLTE_DIF_CQI_MAX_BITS 3
|
||||
#define SRSLTE_PMI_MAX_BITS 4
|
||||
|
||||
typedef struct {
|
||||
bool configured;
|
||||
uint32_t pmi_idx;
|
||||
uint32_t ri_idx;
|
||||
bool ri_idx_present;
|
||||
bool simul_cqi_ack;
|
||||
bool format_is_subband;
|
||||
uint32_t subband_size;
|
||||
|
@ -139,6 +143,10 @@ SRSLTE_API int srslte_cqi_format2_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BIT
|
|||
SRSLTE_API bool srslte_cqi_send(uint32_t I_cqi_pmi,
|
||||
uint32_t tti);
|
||||
|
||||
SRSLTE_API bool srslte_ri_send(uint32_t I_cqi_pmi,
|
||||
uint32_t I_ri,
|
||||
uint32_t tti);
|
||||
|
||||
SRSLTE_API uint8_t srslte_cqi_from_snr(float snr);
|
||||
|
||||
SRSLTE_API float srslte_cqi_to_coderate(uint32_t cqi);
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#define SRSLTE_BCH_PAYLOADCRC_LEN (SRSLTE_BCH_PAYLOAD_LEN+16)
|
||||
#define SRSLTE_BCH_ENCODED_LEN 3*(SRSLTE_BCH_PAYLOADCRC_LEN)
|
||||
|
||||
#define SRSLTE_PBCH_MAX_RE 256 // make it avx2-aligned
|
||||
|
||||
/* PBCH object */
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cell_t cell;
|
||||
|
@ -83,11 +85,13 @@ typedef struct SRSLTE_API {
|
|||
|
||||
} srslte_pbch_t;
|
||||
|
||||
SRSLTE_API int srslte_pbch_init(srslte_pbch_t *q,
|
||||
srslte_cell_t cell);
|
||||
SRSLTE_API int srslte_pbch_init(srslte_pbch_t *q);
|
||||
|
||||
SRSLTE_API void srslte_pbch_free(srslte_pbch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_pbch_set_cell(srslte_pbch_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_pbch_decode(srslte_pbch_t *q,
|
||||
cf_t *slot1_symbols,
|
||||
cf_t *ce_slot1[SRSLTE_MAX_PORTS],
|
||||
|
|
|
@ -79,13 +79,11 @@ typedef struct SRSLTE_API {
|
|||
} srslte_pcfich_t;
|
||||
|
||||
SRSLTE_API int srslte_pcfich_init(srslte_pcfich_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell);
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API int srslte_pcfich_init_multi(srslte_pcfich_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell,
|
||||
uint32_t nof_rx_antennas);
|
||||
SRSLTE_API int srslte_pcfich_set_cell(srslte_pcfich_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_pcfich_free(srslte_pcfich_t *q);
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef struct SRSLTE_API {
|
|||
uint32_t nof_cce;
|
||||
uint32_t max_bits;
|
||||
uint32_t nof_rx_antennas;
|
||||
bool is_ue;
|
||||
|
||||
srslte_regs_t *regs;
|
||||
|
||||
|
@ -84,14 +85,16 @@ typedef struct SRSLTE_API {
|
|||
|
||||
} srslte_pdcch_t;
|
||||
|
||||
SRSLTE_API int srslte_pdcch_init(srslte_pdcch_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell);
|
||||
SRSLTE_API int srslte_pdcch_init_ue(srslte_pdcch_t *q,
|
||||
uint32_t max_prb,
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API int srslte_pdcch_init_multi(srslte_pdcch_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell,
|
||||
uint32_t nof_rx_antennas);
|
||||
SRSLTE_API int srslte_pdcch_init_enb(srslte_pdcch_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_pdcch_set_cell(srslte_pdcch_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_pdcch_free(srslte_pdcch_t *q);
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@
|
|||
#include "srslte/phy/phch/pdsch_cfg.h"
|
||||
|
||||
typedef struct {
|
||||
srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME];
|
||||
srslte_sequence_t seq[SRSLTE_MAX_CODEWORDS][SRSLTE_NSUBFRAMES_X_FRAME];
|
||||
uint32_t cell_id;
|
||||
bool sequence_generated;
|
||||
} srslte_pdsch_user_t;
|
||||
|
||||
|
@ -57,16 +58,20 @@ typedef struct SRSLTE_API {
|
|||
srslte_cell_t cell;
|
||||
|
||||
uint32_t nof_rx_antennas;
|
||||
uint32_t last_nof_iterations[SRSLTE_MAX_CODEWORDS];
|
||||
|
||||
uint32_t max_re;
|
||||
|
||||
uint16_t ue_rnti;
|
||||
bool is_ue;
|
||||
|
||||
/* buffers */
|
||||
// void buffers are shared for tx and rx
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
|
||||
cf_t *symbols[SRSLTE_MAX_PORTS];
|
||||
cf_t *x[SRSLTE_MAX_PORTS];
|
||||
cf_t *d;
|
||||
void *e;
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; /* Channel estimation (Rx only) */
|
||||
cf_t *symbols[SRSLTE_MAX_PORTS]; /* PDSCH Encoded/Decoded Symbols */
|
||||
cf_t *x[SRSLTE_MAX_LAYERS]; /* Layer mapped */
|
||||
cf_t *d[SRSLTE_MAX_CODEWORDS]; /* Modulated/Demodulated codewords */
|
||||
void *e[SRSLTE_MAX_CODEWORDS];
|
||||
|
||||
/* tx & rx objects */
|
||||
srslte_modem_table_t mod[4];
|
||||
|
@ -74,62 +79,83 @@ typedef struct SRSLTE_API {
|
|||
// This is to generate the scrambling seq for multiple CRNTIs
|
||||
srslte_pdsch_user_t **users;
|
||||
|
||||
srslte_sequence_t tmp_seq;
|
||||
|
||||
srslte_sch_t dl_sch;
|
||||
|
||||
} srslte_pdsch_t;
|
||||
|
||||
SRSLTE_API int srslte_pdsch_init(srslte_pdsch_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_init_multi(srslte_pdsch_t *q,
|
||||
srslte_cell_t cell,
|
||||
uint32_t nof_rx_antennas);
|
||||
SRSLTE_API int srslte_pdsch_init_ue(srslte_pdsch_t *q,
|
||||
uint32_t max_prb,
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_init_enb(srslte_pdsch_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_set_cell(srslte_pdsch_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API void srslte_pdsch_free_rnti(srslte_pdsch_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API float srslte_pdsch_coderate(uint32_t tbs,
|
||||
uint32_t nof_re);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg,
|
||||
srslte_cell_t cell,
|
||||
srslte_ra_dl_grant_t *grant,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
uint32_t rvidx);
|
||||
int rvidx);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_cfg_mimo(srslte_pdsch_cfg_t *cfg,
|
||||
srslte_cell_t cell,
|
||||
srslte_ra_dl_grant_t *grant,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
int rvidx[SRSLTE_MAX_CODEWORDS],
|
||||
srslte_mimo_type_t mimo_type,
|
||||
uint32_t pmi);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_encode(srslte_pdsch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
uint16_t rnti,
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS]);
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffers[SRSLTE_MAX_CODEWORDS],
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
uint16_t rnti,
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS]);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_decode(srslte_pdsch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
cf_t *sf_symbols,
|
||||
cf_t *ce[SRSLTE_MAX_PORTS],
|
||||
srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS],
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint16_t rnti,
|
||||
uint8_t *data);
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
bool acks[SRSLTE_MAX_CODEWORDS]);
|
||||
|
||||
SRSLTE_API int srslte_pdsch_decode_multi(srslte_pdsch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint16_t rnti,
|
||||
uint8_t *data);
|
||||
SRSLTE_API int srslte_pdsch_pmi_select(srslte_pdsch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint32_t nof_ce,
|
||||
uint32_t pmi[SRSLTE_MAX_LAYERS],
|
||||
float sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS]);
|
||||
|
||||
SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q);
|
||||
SRSLTE_API int srslte_pdsch_cn_compute(srslte_pdsch_t *q,
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
uint32_t nof_ce,
|
||||
float *cn);
|
||||
|
||||
SRSLTE_API uint32_t srslte_pdsch_last_noi(srslte_pdsch_t *q);
|
||||
SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q,
|
||||
uint32_t max_iter);
|
||||
|
||||
SRSLTE_API float srslte_pdsch_last_noi(srslte_pdsch_t *q);
|
||||
|
||||
SRSLTE_API uint32_t srslte_pdsch_last_noi_cw(srslte_pdsch_t *q,
|
||||
uint32_t cw_idx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,11 +40,14 @@
|
|||
#include "srslte/phy/fec/cbsegm.h"
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cbsegm_t cb_segm;
|
||||
srslte_cbsegm_t cb_segm[SRSLTE_MAX_CODEWORDS];
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_nbits_t nbits;
|
||||
uint32_t rv;
|
||||
srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t rv[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t sf_idx;
|
||||
uint32_t nof_layers;
|
||||
uint32_t codebook_idx;
|
||||
srslte_mimo_type_t mimo_type;
|
||||
} srslte_pdsch_cfg_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -86,16 +86,14 @@ typedef struct SRSLTE_API {
|
|||
} srslte_phich_t;
|
||||
|
||||
SRSLTE_API int srslte_phich_init(srslte_phich_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_phich_init_multi(srslte_phich_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell,
|
||||
uint32_t nof_rx_antennas);
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API void srslte_phich_free(srslte_phich_t *q);
|
||||
|
||||
SRSLTE_API int srslte_phich_set_cell(srslte_phich_t *q,
|
||||
srslte_regs_t *regs,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_phich_calc(srslte_phich_t *q,
|
||||
uint32_t n_prb_lowest,
|
||||
uint32_t n_dmrs,
|
||||
|
@ -103,8 +101,8 @@ SRSLTE_API void srslte_phich_calc(srslte_phich_t *q,
|
|||
uint32_t *nseq);
|
||||
|
||||
SRSLTE_API int srslte_phich_decode(srslte_phich_t *q,
|
||||
cf_t *slot_symbols,
|
||||
cf_t *ce[SRSLTE_MAX_PORTS],
|
||||
cf_t *slot_symbols[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint32_t ngroup,
|
||||
uint32_t nseq,
|
||||
|
@ -112,16 +110,6 @@ SRSLTE_API int srslte_phich_decode(srslte_phich_t *q,
|
|||
uint8_t *ack,
|
||||
float *distance);
|
||||
|
||||
SRSLTE_API int srslte_phich_decode_multi(srslte_phich_t *q,
|
||||
cf_t *slot_symbols[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint32_t ngroup,
|
||||
uint32_t nseq,
|
||||
uint32_t nsubframe,
|
||||
uint8_t *ack,
|
||||
float *distance);
|
||||
|
||||
SRSLTE_API int srslte_phich_encode(srslte_phich_t *q,
|
||||
uint8_t ack,
|
||||
uint32_t ngroup,
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* 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: pmch.h
|
||||
*
|
||||
* Description: Physical multicast channel
|
||||
*
|
||||
* Reference: 3GPP TS 36.211 version 10.0.0 Release 10 Sec. 6.5
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef PMCH_
|
||||
#define PMCH_
|
||||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
#include "srslte/phy/mimo/precoding.h"
|
||||
#include "srslte/phy/mimo/layermap.h"
|
||||
#include "srslte/phy/modem/mod.h"
|
||||
#include "srslte/phy/modem/demod_soft.h"
|
||||
#include "srslte/phy/scrambling/scrambling.h"
|
||||
#include "srslte/phy/phch/dci.h"
|
||||
#include "srslte/phy/phch/regs.h"
|
||||
#include "srslte/phy/phch/sch.h"
|
||||
#include "srslte/phy/common/sequence.h"
|
||||
|
||||
typedef struct {
|
||||
srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME];
|
||||
} srslte_pmch_seq_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cbsegm_t cb_segm;
|
||||
srslte_ra_dl_grant_t grant;
|
||||
srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t sf_idx;
|
||||
} srslte_pmch_cfg_t;
|
||||
|
||||
/* PMCH object */
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cell_t cell;
|
||||
|
||||
uint32_t nof_rx_antennas;
|
||||
|
||||
uint32_t max_re;
|
||||
|
||||
/* buffers */
|
||||
// void buffers are shared for tx and rx
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
|
||||
cf_t *symbols[SRSLTE_MAX_PORTS];
|
||||
cf_t *x[SRSLTE_MAX_PORTS];
|
||||
cf_t *d;
|
||||
void *e;
|
||||
|
||||
/* tx & rx objects */
|
||||
srslte_modem_table_t mod[4];
|
||||
|
||||
// This is to generate the scrambling seq for multiple MBSFN Area IDs
|
||||
srslte_pmch_seq_t **seqs;
|
||||
|
||||
srslte_sch_t dl_sch;
|
||||
|
||||
} srslte_pmch_t;
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pmch_init(srslte_pmch_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_pmch_init_multi(srslte_pmch_t *q,
|
||||
uint32_t max_prb,
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API void srslte_pmch_free(srslte_pmch_t *q);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pmch_set_area_id(srslte_pmch_t *q, uint16_t area_id);
|
||||
|
||||
SRSLTE_API void srslte_pmch_free_area_id(srslte_pmch_t *q, uint16_t area_id);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pmch_get(srslte_pmch_t *q, cf_t *sf_symbols, cf_t *symbols, uint32_t lstart);
|
||||
|
||||
SRSLTE_API int srslte_pmch_put(srslte_pmch_t *q, cf_t *symbols, cf_t *sf_symbols, uint32_t lstart);
|
||||
|
||||
SRSLTE_API int srslte_pmch_cp(srslte_pmch_t *q, cf_t *input, cf_t *output, uint32_t lstart_grant, bool put);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API float srslte_pmch_coderate(uint32_t tbs,
|
||||
uint32_t nof_re);
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pmch_cfg(srslte_pdsch_cfg_t *cfg,
|
||||
srslte_cell_t cell,
|
||||
srslte_ra_dl_grant_t *grant,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx);
|
||||
|
||||
SRSLTE_API int srslte_pmch_encode(srslte_pmch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
uint16_t area_id,
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS]);
|
||||
|
||||
SRSLTE_API int srslte_pmch_decode(srslte_pmch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
cf_t *sf_symbols,
|
||||
cf_t *ce[SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint16_t area_id,
|
||||
uint8_t *data);
|
||||
|
||||
SRSLTE_API int srslte_pmch_decode_multi(srslte_pmch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
cf_t *sf_symbols[SRSLTE_MAX_PORTS],
|
||||
cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
|
||||
float noise_estimate,
|
||||
uint16_t area_id,
|
||||
uint8_t *data);
|
||||
|
||||
SRSLTE_API float srslte_pmch_average_noi(srslte_pmch_t *q);
|
||||
|
||||
SRSLTE_API uint32_t srslte_pmch_last_noi(srslte_pmch_t *q);
|
||||
|
||||
#endif
|
|
@ -44,6 +44,8 @@
|
|||
#include "srslte/phy/common/phy_common.h"
|
||||
|
||||
|
||||
#define SRSLTE_PRACH_MAX_LEN (2*24576+21024) // Maximum Tcp + Tseq
|
||||
|
||||
/** Generation and detection of RACH signals for uplink.
|
||||
* Currently only supports preamble formats 0-3.
|
||||
* Does not currently support high speed flag.
|
||||
|
@ -60,6 +62,8 @@ typedef struct SRSLTE_API {
|
|||
uint32_t N_ifft_ul; // IFFT size for uplink
|
||||
uint32_t N_ifft_prach; // IFFT size for PRACH generation
|
||||
|
||||
uint32_t max_N_ifft_ul;
|
||||
|
||||
// Working parameters
|
||||
uint32_t N_zc; // PRACH sequence length
|
||||
uint32_t N_cs; // Cyclic shift size
|
||||
|
@ -82,12 +86,12 @@ typedef struct SRSLTE_API {
|
|||
float *corr;
|
||||
|
||||
// PRACH IFFT
|
||||
srslte_dft_plan_t *fft;
|
||||
srslte_dft_plan_t *ifft;
|
||||
srslte_dft_plan_t fft;
|
||||
srslte_dft_plan_t ifft;
|
||||
|
||||
// ZC-sequence FFT and IFFT
|
||||
srslte_dft_plan_t *zc_fft;
|
||||
srslte_dft_plan_t *zc_ifft;
|
||||
srslte_dft_plan_t zc_fft;
|
||||
srslte_dft_plan_t zc_ifft;
|
||||
|
||||
cf_t *signal_fft;
|
||||
float detect_factor;
|
||||
|
@ -129,11 +133,14 @@ SRSLTE_API void srslte_prach_sf_config(uint32_t config_idx,
|
|||
srslte_prach_sf_config_t *sf_config);
|
||||
|
||||
SRSLTE_API int srslte_prach_init(srslte_prach_t *p,
|
||||
uint32_t N_ifft_ul,
|
||||
uint32_t config_idx,
|
||||
uint32_t root_seq_index,
|
||||
bool high_speed_flag,
|
||||
uint32_t zero_corr_zone_config);
|
||||
uint32_t max_N_ifft_ul);
|
||||
|
||||
SRSLTE_API int srslte_prach_set_cell(srslte_prach_t *p,
|
||||
uint32_t N_ifft_ul,
|
||||
uint32_t config_idx,
|
||||
uint32_t root_seq_index,
|
||||
bool high_speed_flag,
|
||||
uint32_t zero_corr_zone_config);
|
||||
|
||||
SRSLTE_API int srslte_prach_init_cfg(srslte_prach_t* p,
|
||||
srslte_prach_cfg_t* cfg,
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define SRSLTE_PUCCH_N_SEQ 12
|
||||
#define SRSLTE_PUCCH2_NOF_BITS SRSLTE_UCI_CQI_CODED_PUCCH_B
|
||||
#define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS
|
||||
#define SRSLTE_PUCCH_MAX_SYMBOLS 120
|
||||
#define SRSLTE_PUCCH_MAX_SYMBOLS 128
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
SRSLTE_PUCCH_FORMAT_1 = 0,
|
||||
|
@ -108,7 +108,6 @@ typedef struct SRSLTE_API {
|
|||
bool group_hopping_en;
|
||||
|
||||
float threshold_format1;
|
||||
float threshold_format1a;
|
||||
float last_corr;
|
||||
uint32_t last_n_prb;
|
||||
uint32_t last_n_pucch;
|
||||
|
@ -116,18 +115,19 @@ typedef struct SRSLTE_API {
|
|||
}srslte_pucch_t;
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pucch_init(srslte_pucch_t *q,
|
||||
srslte_cell_t cell);
|
||||
SRSLTE_API int srslte_pucch_init(srslte_pucch_t *q);
|
||||
|
||||
SRSLTE_API void srslte_pucch_free(srslte_pucch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_pucch_set_cell(srslte_pucch_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API bool srslte_pucch_set_cfg(srslte_pucch_t* q,
|
||||
srslte_pucch_cfg_t* cfg,
|
||||
bool group_hopping_en);
|
||||
|
||||
SRSLTE_API void srslte_pucch_set_threshold(srslte_pucch_t *q,
|
||||
float format1,
|
||||
float format1a);
|
||||
float format1_threshold);
|
||||
|
||||
SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q,
|
||||
uint16_t c_rnti);
|
||||
|
|
|
@ -62,13 +62,16 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
srslte_sequence_t seq[SRSLTE_NSUBFRAMES_X_FRAME];
|
||||
bool sequences_generated;
|
||||
uint32_t cell_id;
|
||||
bool sequence_generated;
|
||||
} srslte_pusch_user_t;
|
||||
|
||||
/* PUSCH object */
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_cell_t cell;
|
||||
|
||||
bool is_ue;
|
||||
uint16_t ue_rnti;
|
||||
uint32_t max_re;
|
||||
|
||||
srslte_dft_precoding_t dft_precoding;
|
||||
|
@ -96,11 +99,17 @@ typedef struct SRSLTE_API {
|
|||
}srslte_pusch_t;
|
||||
|
||||
|
||||
SRSLTE_API int srslte_pusch_init(srslte_pusch_t *q,
|
||||
srslte_cell_t cell);
|
||||
SRSLTE_API int srslte_pusch_init_ue(srslte_pusch_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API int srslte_pusch_init_enb(srslte_pusch_t *q,
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_pusch_free(srslte_pusch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_pusch_set_cell(srslte_pusch_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_pusch_cfg(srslte_pusch_t *q,
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
srslte_ra_ul_grant_t *grant,
|
||||
|
@ -114,7 +123,7 @@ SRSLTE_API int srslte_pusch_cfg(srslte_pusch_t *q,
|
|||
SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API void srslte_pusch_clear_rnti(srslte_pusch_t *q,
|
||||
SRSLTE_API void srslte_pusch_free_rnti(srslte_pusch_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API int srslte_pusch_encode(srslte_pusch_t *q,
|
||||
|
|
|
@ -102,13 +102,18 @@ typedef struct SRSLTE_API {
|
|||
typedef struct SRSLTE_API {
|
||||
bool prb_idx[2][SRSLTE_MAX_PRB];
|
||||
uint32_t nof_prb;
|
||||
uint32_t Qm;
|
||||
uint32_t Qm2;
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_mcs_t mcs2;
|
||||
uint32_t Qm[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t Qm2[SRSLTE_MAX_CODEWORDS];
|
||||
srslte_ra_mcs_t mcs[SRSLTE_MAX_CODEWORDS];
|
||||
srslte_ra_mcs_t mcs2[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t nof_tb;
|
||||
srslte_sf_t sf_type;
|
||||
bool tb_en[SRSLTE_MAX_CODEWORDS];
|
||||
uint32_t pinfo;
|
||||
} srslte_ra_dl_grant_t;
|
||||
|
||||
#define SRSLTE_RA_DL_GRANT_NOF_TB(G) ((((G)->tb_en[0])?1:0)+(((G)->tb_en[1])?1:0))
|
||||
|
||||
/** Unpacked DCI message for DL grant */
|
||||
typedef struct SRSLTE_API {
|
||||
|
||||
|
@ -207,7 +212,7 @@ SRSLTE_API void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant,
|
|||
uint32_t cfi,
|
||||
srslte_cell_t cell,
|
||||
uint32_t sf_idx,
|
||||
srslte_ra_nbits_t *nbits);
|
||||
srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS]);
|
||||
|
||||
SRSLTE_API uint32_t srslte_ra_dl_approx_nof_re(srslte_cell_t cell,
|
||||
uint32_t nof_prb,
|
||||
|
@ -289,4 +294,9 @@ SRSLTE_API void srslte_ra_pusch_fprint(FILE *f,
|
|||
SRSLTE_API void srslte_ra_ul_grant_fprint(FILE *f,
|
||||
srslte_ra_ul_grant_t *grant);
|
||||
|
||||
SRSLTE_API int srslte_dl_fill_ra_mcs_pmch(srslte_ra_mcs_t *mcs, uint32_t nprb);
|
||||
|
||||
SRSLTE_API int srslte_dl_fill_ra_mcs(srslte_ra_mcs_t *mcs, uint32_t nprb);
|
||||
|
||||
|
||||
#endif /* RB_ALLOC_H_ */
|
||||
|
|
|
@ -58,7 +58,6 @@ typedef struct SRSLTE_API {
|
|||
|
||||
uint32_t max_iterations;
|
||||
uint32_t nof_iterations;
|
||||
float average_nof_iterations;
|
||||
|
||||
/* buffers */
|
||||
uint8_t *cb_in;
|
||||
|
@ -77,6 +76,7 @@ typedef struct SRSLTE_API {
|
|||
srslte_uci_cqi_pusch_t uci_cqi;
|
||||
|
||||
} srslte_sch_t;
|
||||
#include "srslte/phy/phch/pmch.h"
|
||||
|
||||
SRSLTE_API int srslte_sch_init(srslte_sch_t *q);
|
||||
|
||||
|
@ -86,8 +86,6 @@ SRSLTE_API void srslte_sch_free(srslte_sch_t *q);
|
|||
SRSLTE_API void srslte_sch_set_max_noi(srslte_sch_t *q,
|
||||
uint32_t max_iterations);
|
||||
|
||||
SRSLTE_API float srslte_sch_average_noi(srslte_sch_t *q);
|
||||
|
||||
SRSLTE_API uint32_t srslte_sch_last_noi(srslte_sch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_dlsch_encode(srslte_sch_t *q,
|
||||
|
@ -96,12 +94,26 @@ SRSLTE_API int srslte_dlsch_encode(srslte_sch_t *q,
|
|||
uint8_t *data,
|
||||
uint8_t *e_bits);
|
||||
|
||||
SRSLTE_API int srslte_dlsch_encode2(srslte_sch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
uint8_t *data,
|
||||
uint8_t *e_bits,
|
||||
int codeword_idx);
|
||||
|
||||
SRSLTE_API int srslte_dlsch_decode(srslte_sch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
int16_t *e_bits,
|
||||
uint8_t *data);
|
||||
|
||||
SRSLTE_API int srslte_dlsch_decode2(srslte_sch_t *q,
|
||||
srslte_pdsch_cfg_t *cfg,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
int16_t *e_bits,
|
||||
uint8_t *data,
|
||||
int codeword_idx);
|
||||
|
||||
SRSLTE_API int srslte_ulsch_encode(srslte_sch_t *q,
|
||||
srslte_pusch_cfg_t *cfg,
|
||||
srslte_softbuffer_tx_t *softbuffer,
|
||||
|
|
|
@ -64,6 +64,10 @@ typedef struct SRSLTE_API {
|
|||
typedef struct SRSLTE_API {
|
||||
uint8_t uci_cqi[SRSLTE_CQI_MAX_BITS];
|
||||
uint32_t uci_cqi_len;
|
||||
uint8_t uci_dif_cqi[SRSLTE_DIF_CQI_MAX_BITS];
|
||||
uint32_t uci_dif_cqi_len;
|
||||
uint8_t uci_pmi[SRSLTE_PMI_MAX_BITS];
|
||||
uint8_t uci_pmi_len;
|
||||
uint8_t uci_ri; // Only 1-bit supported for RI
|
||||
uint32_t uci_ri_len;
|
||||
uint8_t uci_ack; // 1st codeword bit for HARQ-ACK
|
||||
|
@ -119,7 +123,8 @@ SRSLTE_API int srslte_uci_decode_cqi_pusch(srslte_uci_cqi_pusch_t *q,
|
|||
bool *cqi_ack);
|
||||
|
||||
SRSLTE_API int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
||||
uint8_t data,
|
||||
uint8_t acks[2],
|
||||
uint32_t nof_acks,
|
||||
uint32_t O_cqi,
|
||||
float beta,
|
||||
uint32_t H_prime_total,
|
||||
|
@ -132,7 +137,8 @@ SRSLTE_API int srslte_uci_decode_ack(srslte_pusch_cfg_t *cfg,
|
|||
uint32_t H_prime_total,
|
||||
uint32_t O_cqi,
|
||||
srslte_uci_bit_t *ack_bits,
|
||||
uint8_t *data);
|
||||
uint8_t acks[2],
|
||||
uint32_t nof_acks);
|
||||
|
||||
SRSLTE_API int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
|
||||
uint8_t data,
|
||||
|
|
|
@ -68,6 +68,7 @@ SRSLTE_API void srslte_interp_linear_f(float *input,
|
|||
typedef struct {
|
||||
cf_t *diff_vec;
|
||||
uint32_t vector_len;
|
||||
uint32_t max_vector_len;
|
||||
} srslte_interp_linsrslte_vec_t;
|
||||
|
||||
SRSLTE_API int srslte_interp_linear_vector_init(srslte_interp_linsrslte_vec_t *q,
|
||||
|
@ -75,6 +76,9 @@ SRSLTE_API int srslte_interp_linear_vector_init(srslte_interp_linsrslte_vec_t *q
|
|||
|
||||
SRSLTE_API void srslte_interp_linear_vector_free(srslte_interp_linsrslte_vec_t *q);
|
||||
|
||||
SRSLTE_API int srslte_interp_linear_vector_resize(srslte_interp_linsrslte_vec_t *q,
|
||||
uint32_t vector_len);
|
||||
|
||||
SRSLTE_API void srslte_interp_linear_vector(srslte_interp_linsrslte_vec_t *q,
|
||||
cf_t *in0,
|
||||
cf_t *in1,
|
||||
|
@ -108,6 +112,8 @@ typedef struct {
|
|||
float *ramp;
|
||||
uint32_t vector_len;
|
||||
uint32_t M;
|
||||
uint32_t max_vector_len;
|
||||
uint32_t max_M;
|
||||
} srslte_interp_lin_t;
|
||||
|
||||
SRSLTE_API int srslte_interp_linear_init(srslte_interp_lin_t *q,
|
||||
|
@ -116,6 +122,10 @@ SRSLTE_API int srslte_interp_linear_init(srslte_interp_lin_t *q,
|
|||
|
||||
SRSLTE_API void srslte_interp_linear_free(srslte_interp_lin_t *q);
|
||||
|
||||
SRSLTE_API int srslte_interp_linear_resize(srslte_interp_lin_t *q,
|
||||
uint32_t vector_len,
|
||||
uint32_t M);
|
||||
|
||||
SRSLTE_API void srslte_interp_linear_offset(srslte_interp_lin_t *q,
|
||||
cf_t *input,
|
||||
cf_t *output,
|
||||
|
|
|
@ -200,5 +200,21 @@ SRSLTE_API int srslte_rf_send_timed2(srslte_rf_t *h,
|
|||
bool is_start_of_burst,
|
||||
bool is_end_of_burst);
|
||||
|
||||
SRSLTE_API int srslte_rf_send_timed_multi(srslte_rf_t *rf,
|
||||
void *data[4],
|
||||
int nsamples,
|
||||
time_t secs,
|
||||
double frac_secs,
|
||||
bool blocking,
|
||||
bool is_start_of_burst,
|
||||
bool is_end_of_burst);
|
||||
|
||||
SRSLTE_API int srslte_rf_send_multi(srslte_rf_t *rf,
|
||||
void *data[4],
|
||||
int nsamples,
|
||||
bool blocking,
|
||||
bool is_start_of_burst,
|
||||
bool is_end_of_burst);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct SRSLTE_API {
|
|||
float last_freq;
|
||||
float tol;
|
||||
int nsamples;
|
||||
int max_samples;
|
||||
srslte_cexptab_t tab;
|
||||
cf_t *cur_cexp;
|
||||
}srslte_cfo_t;
|
||||
|
@ -58,8 +59,8 @@ SRSLTE_API int srslte_cfo_init(srslte_cfo_t *h,
|
|||
|
||||
SRSLTE_API void srslte_cfo_free(srslte_cfo_t *h);
|
||||
|
||||
SRSLTE_API int srslte_cfo_realloc(srslte_cfo_t *h,
|
||||
uint32_t samples);
|
||||
SRSLTE_API int srslte_cfo_resize(srslte_cfo_t *h,
|
||||
uint32_t samples);
|
||||
|
||||
SRSLTE_API void srslte_cfo_set_tol(srslte_cfo_t *h,
|
||||
float tol);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
typedef struct {
|
||||
cf_t *corr;
|
||||
uint32_t symbol_sz;
|
||||
uint32_t max_symbol_sz;
|
||||
} srslte_cp_synch_t;
|
||||
|
||||
SRSLTE_API int srslte_cp_synch_init(srslte_cp_synch_t *q,
|
||||
|
@ -42,6 +43,9 @@ SRSLTE_API int srslte_cp_synch_init(srslte_cp_synch_t *q,
|
|||
|
||||
SRSLTE_API void srslte_cp_synch_free(srslte_cp_synch_t *q);
|
||||
|
||||
SRSLTE_API int srslte_cp_synch_resize(srslte_cp_synch_t *q,
|
||||
uint32_t symbol_sz);
|
||||
|
||||
SRSLTE_API uint32_t srslte_cp_synch(srslte_cp_synch_t *q,
|
||||
cf_t *input,
|
||||
uint32_t max_offset,
|
||||
|
|
|
@ -79,6 +79,10 @@ typedef struct SRSLTE_API {
|
|||
|
||||
#endif
|
||||
int decimate;
|
||||
|
||||
uint32_t max_frame_size;
|
||||
uint32_t max_fft_size;
|
||||
|
||||
uint32_t frame_size;
|
||||
uint32_t N_id_2;
|
||||
uint32_t fft_size;
|
||||
|
@ -113,6 +117,10 @@ SRSLTE_API int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q,
|
|||
int cfo_i,
|
||||
int decimate);
|
||||
|
||||
SRSLTE_API int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size,
|
||||
uint32_t fft_size,
|
||||
int offset);
|
||||
|
||||
SRSLTE_API int srslte_pss_synch_init(srslte_pss_synch_t *q,
|
||||
uint32_t frame_size);
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct SRSLTE_API {
|
|||
srslte_dft_plan_t dftp_input;
|
||||
|
||||
uint32_t fft_size;
|
||||
uint32_t max_fft_size;
|
||||
|
||||
float corr_peak_threshold;
|
||||
uint32_t symbol_sz;
|
||||
|
@ -89,7 +90,7 @@ typedef struct SRSLTE_API {
|
|||
SRSLTE_API int srslte_sss_synch_init(srslte_sss_synch_t *q,
|
||||
uint32_t fft_size);
|
||||
|
||||
SRSLTE_API int srslte_sss_synch_realloc(srslte_sss_synch_t *q,
|
||||
SRSLTE_API int srslte_sss_synch_resize(srslte_sss_synch_t *q,
|
||||
uint32_t fft_size);
|
||||
|
||||
SRSLTE_API void srslte_sss_synch_free(srslte_sss_synch_t *q);
|
||||
|
|
|
@ -75,6 +75,8 @@ typedef struct SRSLTE_API {
|
|||
uint32_t frame_size;
|
||||
uint32_t max_offset;
|
||||
bool enable_cfo_corr;
|
||||
bool mean_cfo2_isunset;
|
||||
bool mean_cfo_isunset;
|
||||
float mean_cfo;
|
||||
float mean_cfo2;
|
||||
int cfo_i;
|
||||
|
@ -85,6 +87,7 @@ typedef struct SRSLTE_API {
|
|||
uint32_t cp_len;
|
||||
srslte_cfo_t cfocorr;
|
||||
srslte_cfo_t cfocorr2;
|
||||
float current_cfo_tol;
|
||||
sss_alg_t sss_alg;
|
||||
bool detect_cp;
|
||||
bool sss_en;
|
||||
|
@ -97,6 +100,8 @@ typedef struct SRSLTE_API {
|
|||
float M_ext_avg;
|
||||
cf_t *temp;
|
||||
|
||||
uint32_t max_frame_size;
|
||||
|
||||
}srslte_sync_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -121,6 +126,11 @@ SRSLTE_API int srslte_sync_init_decim(srslte_sync_t *q,
|
|||
|
||||
SRSLTE_API void srslte_sync_free(srslte_sync_t *q);
|
||||
|
||||
SRSLTE_API int srslte_sync_resize(srslte_sync_t *q,
|
||||
uint32_t frame_size,
|
||||
uint32_t max_offset,
|
||||
uint32_t fft_size);
|
||||
|
||||
SRSLTE_API void srslte_sync_reset(srslte_sync_t *q);
|
||||
|
||||
/* Finds a correlation peak in the input signal around position find_offset */
|
||||
|
@ -138,6 +148,9 @@ SRSLTE_API srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q,
|
|||
SRSLTE_API void srslte_sync_set_threshold(srslte_sync_t *q,
|
||||
float threshold);
|
||||
|
||||
SRSLTE_API void srslte_sync_set_cfo_tol(srslte_sync_t *q,
|
||||
float tol);
|
||||
|
||||
/* Gets the subframe idx (0 or 5) */
|
||||
SRSLTE_API uint32_t srslte_sync_get_sf_idx(srslte_sync_t *q);
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "srslte/phy/phch/pcfich.h"
|
||||
#include "srslte/phy/phch/pdcch.h"
|
||||
#include "srslte/phy/phch/pdsch.h"
|
||||
#include "srslte/phy/phch/pmch.h"
|
||||
#include "srslte/phy/phch/pdsch_cfg.h"
|
||||
#include "srslte/phy/phch/phich.h"
|
||||
#include "srslte/phy/phch/ra.h"
|
||||
|
@ -76,15 +77,18 @@ typedef struct SRSLTE_API {
|
|||
srslte_pcfich_t pcfich;
|
||||
srslte_pdcch_t pdcch;
|
||||
srslte_pdsch_t pdsch;
|
||||
srslte_pmch_t pmch;
|
||||
srslte_phich_t phich;
|
||||
srslte_regs_t regs;
|
||||
srslte_ofdm_t fft;
|
||||
srslte_ofdm_t fft_mbsfn;
|
||||
srslte_chest_dl_t chest;
|
||||
|
||||
srslte_cfo_t sfo_correct;
|
||||
|
||||
srslte_pdsch_cfg_t pdsch_cfg;
|
||||
srslte_softbuffer_rx_t softbuffer;
|
||||
srslte_pdsch_cfg_t pmch_cfg;
|
||||
srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS];
|
||||
srslte_ra_dl_dci_t dl_dci;
|
||||
srslte_cell_t cell;
|
||||
|
||||
|
@ -95,12 +99,22 @@ typedef struct SRSLTE_API {
|
|||
cf_t *ce[SRSLTE_MAX_PORTS]; // compatibility
|
||||
cf_t *ce_m[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
|
||||
|
||||
/* RI, PMI and SINR for MIMO statistics */
|
||||
float sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS];
|
||||
uint32_t pmi[SRSLTE_MAX_LAYERS];
|
||||
uint32_t ri;
|
||||
|
||||
srslte_dci_format_t dci_format;
|
||||
uint64_t pkt_errors;
|
||||
uint64_t pkts_total;
|
||||
uint64_t pdsch_pkt_errors;
|
||||
uint64_t pdsch_pkts_total;
|
||||
uint64_t pmch_pkt_errors;
|
||||
uint64_t pmch_pkts_total;
|
||||
uint64_t nof_detected;
|
||||
|
||||
uint16_t current_rnti;
|
||||
uint16_t current_mbsfn_area_id;
|
||||
dci_blind_search_t current_ss_ue[3][10];
|
||||
dci_blind_search_t current_ss_common[3];
|
||||
srslte_dci_location_t last_location;
|
||||
|
@ -114,33 +128,41 @@ typedef struct SRSLTE_API {
|
|||
|
||||
/* This function shall be called just after the initial synchronization */
|
||||
SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_init_multi(srslte_ue_dl_t *q,
|
||||
srslte_cell_t cell,
|
||||
uint32_t nof_rx_antennas);
|
||||
uint32_t max_prb,
|
||||
uint32_t nof_rx_antennas);
|
||||
|
||||
SRSLTE_API void srslte_ue_dl_free(srslte_ue_dl_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q,
|
||||
cf_t *input,
|
||||
uint32_t sf_idx,
|
||||
uint32_t *cfi);
|
||||
SRSLTE_API int srslte_ue_dl_set_cell(srslte_ue_dl_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_fft_estimate_multi(srslte_ue_dl_t *q,
|
||||
int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
uint32_t sf_idx,
|
||||
uint32_t *cfi);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_fft_estimate_mbsfn(srslte_ue_dl_t *q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
uint32_t sf_idx,
|
||||
uint32_t *cfi);
|
||||
uint32_t *cfi,
|
||||
srslte_sf_t sf_type);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q,
|
||||
|
||||
int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q,
|
||||
uint32_t sf_idx,
|
||||
uint32_t *cfi);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_estimate_mbsfn(srslte_ue_dl_t *q,
|
||||
uint32_t sf_idx,
|
||||
uint32_t *cfi);
|
||||
uint32_t *cfi,
|
||||
srslte_sf_t sf_type);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q,
|
||||
srslte_ra_dl_grant_t *grant,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
uint32_t rvidx);
|
||||
int rvidx[SRSLTE_MAX_CODEWORDS],
|
||||
srslte_mimo_type_t mimo_type);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q,
|
||||
uint32_t cfi,
|
||||
|
@ -149,12 +171,14 @@ SRSLTE_API int srslte_ue_dl_find_ul_dci(srslte_ue_dl_t *q,
|
|||
srslte_dci_msg_t *dci_msg);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_find_dl_dci(srslte_ue_dl_t *q,
|
||||
uint32_t tm,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
uint16_t rnti,
|
||||
srslte_dci_msg_t *dci_msg);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q,
|
||||
uint32_t tm,
|
||||
uint32_t cfi,
|
||||
uint32_t sf_idx,
|
||||
uint16_t rnti,
|
||||
|
@ -166,27 +190,41 @@ SRSLTE_API uint32_t srslte_ue_dl_get_ncce(srslte_ue_dl_t *q);
|
|||
SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q,
|
||||
float sample_offset);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q,
|
||||
cf_t *input,
|
||||
uint8_t *data,
|
||||
uint32_t tti);
|
||||
SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t *q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
uint32_t tm,
|
||||
uint32_t tti,
|
||||
bool acks[SRSLTE_MAX_CODEWORDS]);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_multi(srslte_ue_dl_t * q,
|
||||
SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
uint8_t *data[SRSLTE_MAX_CODEWORDS],
|
||||
uint32_t tm,
|
||||
uint32_t tti,
|
||||
uint16_t rnti,
|
||||
bool acks[SRSLTE_MAX_CODEWORDS]);
|
||||
|
||||
/* Used by example applications - full PMCH decode for a given MBSFN area ID
|
||||
* srslte_ue_dl_decode_fft_estimate_multi,
|
||||
* srslte_chest_dl_get_noise_estimate,
|
||||
* srslte_ue_dl_cfg_grant,
|
||||
* srslte_pmch_decode_multi
|
||||
*/
|
||||
SRSLTE_API int srslte_ue_dl_decode_mbsfn(srslte_ue_dl_t * q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
uint8_t *data,
|
||||
uint32_t tti);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q,
|
||||
cf_t *input,
|
||||
uint8_t *data,
|
||||
uint32_t tti,
|
||||
uint16_t rnti);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t * q,
|
||||
cf_t *input[SRSLTE_MAX_PORTS],
|
||||
uint8_t *data,
|
||||
uint32_t tti,
|
||||
uint16_t rnti);
|
||||
SRSLTE_API int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q,
|
||||
uint8_t *ri,
|
||||
uint8_t *pmi,
|
||||
float *current_sinr);
|
||||
|
||||
SRSLTE_API int srslte_ue_dl_ri_select(srslte_ue_dl_t *q,
|
||||
uint8_t *ri,
|
||||
float *cn);
|
||||
|
||||
SRSLTE_API bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q,
|
||||
uint32_t sf_idx,
|
||||
|
@ -198,6 +236,15 @@ SRSLTE_API void srslte_ue_dl_reset(srslte_ue_dl_t *q);
|
|||
SRSLTE_API void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q,
|
||||
uint16_t rnti);
|
||||
|
||||
/* Generate signals if required, store in q->current_mbsfn_area_id */
|
||||
SRSLTE_API int srslte_ue_dl_set_mbsfn_area_id(srslte_ue_dl_t *q,
|
||||
uint16_t mbsfn_area_id);
|
||||
|
||||
SRSLTE_API void srslte_ue_dl_set_non_mbsfn_region(srslte_ue_dl_t *q,
|
||||
uint8_t non_mbsfn_region_length);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API void srslte_ue_dl_save_signal(srslte_ue_dl_t *q,
|
||||
srslte_softbuffer_rx_t *softbuffer,
|
||||
uint32_t tti,
|
||||
|
|
|
@ -79,10 +79,13 @@ typedef struct SRSLTE_API {
|
|||
} srslte_ue_mib_t;
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_init(srslte_ue_mib_t *q,
|
||||
srslte_cell_t cell);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_ue_mib_free(srslte_ue_mib_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_set_cell(srslte_ue_mib_t * q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_ue_mib_reset(srslte_ue_mib_t * q);
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_decode(srslte_ue_mib_t * q,
|
||||
|
@ -104,21 +107,17 @@ typedef struct {
|
|||
uint32_t nof_rx_antennas;
|
||||
} srslte_ue_mib_sync_t;
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q,
|
||||
uint32_t cell_id,
|
||||
srslte_cp_t cp,
|
||||
int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t *),
|
||||
void *stream_handler);
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q,
|
||||
uint32_t cell_id,
|
||||
srslte_cp_t cp,
|
||||
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t *),
|
||||
uint32_t nof_rx_antennas,
|
||||
void *stream_handler);
|
||||
|
||||
SRSLTE_API void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_sync_set_cell(srslte_ue_mib_sync_t *q,
|
||||
uint32_t cell_id,
|
||||
srslte_cp_t cp);
|
||||
|
||||
SRSLTE_API void srslte_ue_mib_sync_reset(srslte_ue_mib_sync_t * q);
|
||||
|
||||
SRSLTE_API int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q,
|
||||
|
|
|
@ -70,6 +70,8 @@ typedef struct SRSLTE_API {
|
|||
srslte_sync_t sfind;
|
||||
srslte_sync_t strack;
|
||||
|
||||
uint32_t max_prb;
|
||||
|
||||
srslte_agc_t agc;
|
||||
bool do_agc;
|
||||
uint32_t agc_period;
|
||||
|
@ -125,22 +127,25 @@ typedef struct SRSLTE_API {
|
|||
} srslte_ue_sync_t;
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_init(srslte_ue_sync_t *q,
|
||||
srslte_cell_t cell,
|
||||
uint32_t max_prb,
|
||||
bool search_cell,
|
||||
int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*),
|
||||
void *stream_handler);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_init_multi(srslte_ue_sync_t *q,
|
||||
srslte_cell_t cell,
|
||||
uint32_t max_prb,
|
||||
bool search_cell,
|
||||
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*),
|
||||
uint32_t nof_rx_antennas,
|
||||
void *stream_handler);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q,
|
||||
srslte_cell_t cell,
|
||||
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*),
|
||||
uint32_t nof_rx_antennas,
|
||||
void *stream_handler,
|
||||
int decimate);
|
||||
uint32_t max_prb,
|
||||
bool search_cell,
|
||||
int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*),
|
||||
uint32_t nof_rx_antennas,
|
||||
void *stream_handler,
|
||||
int decimate);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q,
|
||||
uint32_t nof_prb,
|
||||
|
@ -148,8 +153,18 @@ SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q,
|
|||
int offset_time,
|
||||
float offset_freq);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_init_file_multi(srslte_ue_sync_t *q,
|
||||
uint32_t nof_prb,
|
||||
char *file_name,
|
||||
int offset_time,
|
||||
float offset_freq,
|
||||
uint32_t nof_rx_ant);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_free(srslte_ue_sync_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_set_cell(srslte_ue_sync_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
|
||||
double (set_gain_callback)(void*, double),
|
||||
float init_gain_value);
|
||||
|
@ -166,6 +181,9 @@ SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q,
|
|||
SRSLTE_API int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q,
|
||||
cf_t *input_buffer[SRSLTE_MAX_PORTS]);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_set_cfo_tol(srslte_ue_sync_t *q,
|
||||
float tol);
|
||||
|
||||
SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q,
|
||||
float cfo);
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ typedef struct SRSLTE_API {
|
|||
bool normalize_en;
|
||||
bool cfo_en;
|
||||
|
||||
float current_cfo_tol;
|
||||
float current_cfo;
|
||||
srslte_pucch_format_t last_pucch_format;
|
||||
|
||||
|
@ -107,10 +108,16 @@ typedef struct SRSLTE_API {
|
|||
|
||||
/* This function shall be called just after the initial synchronization */
|
||||
SRSLTE_API int srslte_ue_ul_init(srslte_ue_ul_t *q,
|
||||
srslte_cell_t cell);
|
||||
uint32_t max_prb);
|
||||
|
||||
SRSLTE_API void srslte_ue_ul_free(srslte_ue_ul_t *q);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_set_cell(srslte_ue_ul_t *q,
|
||||
srslte_cell_t cell);
|
||||
|
||||
SRSLTE_API void srslte_ue_ul_set_cfo_tol(srslte_ue_ul_t *q,
|
||||
float tol);
|
||||
|
||||
SRSLTE_API void srslte_ue_ul_set_cfo(srslte_ue_ul_t *q,
|
||||
float cur_cfo);
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ typedef struct SRSLTE_API {
|
|||
uint32_t input_len;
|
||||
uint32_t filter_len;
|
||||
uint32_t output_len;
|
||||
uint32_t max_input_len;
|
||||
uint32_t max_filter_len;
|
||||
srslte_dft_plan_t input_plan;
|
||||
srslte_dft_plan_t filter_plan;
|
||||
srslte_dft_plan_t output_plan;
|
||||
|
@ -58,6 +60,9 @@ SRSLTE_API int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t *q,
|
|||
uint32_t input_len,
|
||||
uint32_t filter_len);
|
||||
|
||||
SRSLTE_API int srslte_conv_fft_cc_replan(srslte_conv_fft_cc_t *q,
|
||||
uint32_t input_len,
|
||||
uint32_t filter_len);
|
||||
|
||||
SRSLTE_API void srslte_conv_fft_cc_free(srslte_conv_fft_cc_t *q);
|
||||
|
||||
|
|
|
@ -58,10 +58,16 @@ SRSLTE_API extern int srslte_verbose;
|
|||
#define PRINT_NONE srslte_verbose=SRSLTE_VERBOSE_NONE
|
||||
|
||||
#define DEBUG(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG) \
|
||||
fprintf(stdout, "[DEBUG]: " _fmt, __VA_ARGS__)
|
||||
fprintf(stdout, "[DEBUG]: " _fmt, ##__VA_ARGS__)
|
||||
|
||||
#define INFO(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO) \
|
||||
fprintf(stdout, "[INFO]: " _fmt, __VA_ARGS__)
|
||||
fprintf(stdout, "[INFO]: " _fmt, ##__VA_ARGS__)
|
||||
|
||||
#if CMAKE_BUILD_TYPE==Debug
|
||||
/* In debug mode, it prints out the */
|
||||
#define ERROR(_fmt, ...) fprintf(stderr, "%s.%d: " _fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define ERROR(_fmt, ...) fprintf(stderr, "[ERROR in %s]:" _fmt "\n", __FUNCTION__, ##__VA_ARGS__)
|
||||
#endif /* CMAKE_BUILD_TYPE==Debug */
|
||||
|
||||
#endif // DEBUG_H
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* 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_MAT_H
|
||||
#define SRSLTE_MAT_H
|
||||
|
||||
#include "srslte/phy/utils/simd.h"
|
||||
#include "srslte/config.h"
|
||||
|
||||
|
||||
/*
|
||||
* Generic Macros
|
||||
*/
|
||||
#define RANDOM_CF() (((float)rand())/((float)RAND_MAX) + _Complex_I*((float)rand())/((float)RAND_MAX))
|
||||
|
||||
/* Generic implementation for complex reciprocal */
|
||||
SRSLTE_API cf_t srslte_mat_cf_recip_gen(cf_t a);
|
||||
|
||||
/* Generic implementation for 2x2 determinant */
|
||||
SRSLTE_API cf_t srslte_mat_2x2_det_gen(cf_t a00, cf_t a01, cf_t a10, cf_t a11);
|
||||
|
||||
/* Generic implementation for 2x2 Matrix Inversion */
|
||||
SRSLTE_API void srslte_mat_2x2_inv_gen(cf_t a00, cf_t a01, cf_t a10, cf_t a11,
|
||||
cf_t *r00, cf_t *r01, cf_t *r10, cf_t *r11);
|
||||
|
||||
/* Generic implementation for Zero Forcing (ZF) solver */
|
||||
SRSLTE_API void srslte_mat_2x2_zf_gen(cf_t y0, cf_t y1,
|
||||
cf_t h00, cf_t h01, cf_t h10, cf_t h11,
|
||||
cf_t *x0, cf_t *x1,
|
||||
float norm);
|
||||
|
||||
/* Generic implementation for Minimum Mean Squared Error (MMSE) solver */
|
||||
SRSLTE_API void srslte_mat_2x2_mmse_gen(cf_t y0, cf_t y1,
|
||||
cf_t h00, cf_t h01, cf_t h10, cf_t h11,
|
||||
cf_t *x0, cf_t *x1,
|
||||
float noise_estimate,
|
||||
float norm);
|
||||
|
||||
SRSLTE_API float srslte_mat_2x2_cn(cf_t h00,
|
||||
cf_t h01,
|
||||
cf_t h10,
|
||||
cf_t h11);
|
||||
|
||||
|
||||
#ifdef LV_HAVE_SSE
|
||||
#include <smmintrin.h>
|
||||
|
||||
/* SSE implementation for complex reciprocal */
|
||||
SRSLTE_API __m128 srslte_mat_cf_recip_sse(__m128 a);
|
||||
|
||||
/* SSE implementation for 2x2 determinant */
|
||||
SRSLTE_API __m128 srslte_mat_2x2_det_sse(__m128 a00, __m128 a01, __m128 a10, __m128 a11);
|
||||
|
||||
/* SSE implementation for Zero Forcing (ZF) solver */
|
||||
SRSLTE_API void srslte_mat_2x2_zf_sse(__m128 y0, __m128 y1,
|
||||
__m128 h00, __m128 h01, __m128 h10, __m128 h11,
|
||||
__m128 *x0, __m128 *x1,
|
||||
float norm);
|
||||
|
||||
/* SSE implementation for Minimum Mean Squared Error (MMSE) solver */
|
||||
SRSLTE_API void srslte_mat_2x2_mmse_sse(__m128 y0, __m128 y1,
|
||||
__m128 h00, __m128 h01, __m128 h10, __m128 h11,
|
||||
__m128 *x0, __m128 *x1,
|
||||
float noise_estimate, float norm);
|
||||
|
||||
#endif /* LV_HAVE_SSE */
|
||||
|
||||
#ifdef LV_HAVE_AVX
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
/* AVX implementation for complex reciprocal */
|
||||
SRSLTE_API __m256 srslte_mat_cf_recip_avx(__m256 a);
|
||||
|
||||
/* AVX implementation for 2x2 determinant */
|
||||
SRSLTE_API __m256 srslte_mat_2x2_det_avx(__m256 a00, __m256 a01, __m256 a10, __m256 a11);
|
||||
|
||||
/* AVX implementation for Zero Forcing (ZF) solver */
|
||||
SRSLTE_API void srslte_mat_2x2_zf_avx(__m256 y0, __m256 y1,
|
||||
__m256 h00, __m256 h01, __m256 h10, __m256 h11,
|
||||
__m256 *x0, __m256 *x1,
|
||||
float norm);
|
||||
|
||||
/* AVX implementation for Minimum Mean Squared Error (MMSE) solver */
|
||||
SRSLTE_API void srslte_mat_2x2_mmse_avx(__m256 y0, __m256 y1,
|
||||
__m256 h00, __m256 h01, __m256 h10, __m256 h11,
|
||||
__m256 *x0, __m256 *x1,
|
||||
float noise_estimate, float norm);
|
||||
|
||||
#endif /* LV_HAVE_AVX */
|
||||
|
||||
#endif /* SRSLTE_MAT_H */
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* 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_SIMD_H_H
|
||||
#define SRSLTE_SIMD_H_H
|
||||
|
||||
/*
|
||||
* SSE Macros
|
||||
*/
|
||||
#ifdef LV_HAVE_SSE
|
||||
#define _MM_SWAP(X) ((__m128)_mm_shuffle_ps(X, X, _MM_SHUFFLE(2,3,0,1)))
|
||||
#define _MM_PERM(X) ((__m128)_mm_shuffle_ps(X, X, _MM_SHUFFLE(2,1,3,0)))
|
||||
#define _MM_MULJ_PS(X) _MM_SWAP(_MM_CONJ_PS(X))
|
||||
#define _MM_CONJ_PS(X) (_mm_xor_ps(X, _mm_set_ps(-0.0f, 0.0f, -0.0f, 0.0f)))
|
||||
#define _MM_SQMOD_PS(X) _MM_PERM(_mm_hadd_ps(_mm_mul_ps(X,X), _mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f)))
|
||||
#define _MM_PROD_PS(a, b) _mm_addsub_ps(_mm_mul_ps(a,_mm_moveldup_ps(b)),_mm_mul_ps(\
|
||||
_mm_shuffle_ps(a,a,0xB1),_mm_movehdup_ps(b)))
|
||||
|
||||
#endif /* LV_HAVE_SSE */
|
||||
|
||||
/*
|
||||
* AVX Macros
|
||||
*/
|
||||
#ifdef LV_HAVE_AVX
|
||||
|
||||
#define _MM256_MULJ_PS(X) _mm256_permute_ps(_MM256_CONJ_PS(X), 0b10110001)
|
||||
#define _MM256_CONJ_PS(X) (_mm256_xor_ps(X, _mm256_set_ps(-0.0f, 0.0f, -0.0f, 0.0f, -0.0f, 0.0f, -0.0f, 0.0f)))
|
||||
|
||||
#ifdef LV_HAVE_FMA
|
||||
#define _MM256_SQMOD_PS(A, B) _mm256_permute_ps(_mm256_hadd_ps(_mm256_fmadd_ps(A, A, _mm256_mul_ps(B,B)), \
|
||||
_mm256_set_ps(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)), 0b11011100)
|
||||
#define _MM256_PROD_PS(a, b) _mm256_fmaddsub_ps(a,_mm256_moveldup_ps(b),\
|
||||
_mm256_mul_ps(_mm256_shuffle_ps(a,a,0xB1),_mm256_movehdup_ps(b)))
|
||||
#else
|
||||
#define _MM256_SQMOD_PS(A, B) _mm256_permute_ps(_mm256_hadd_ps(_mm256_add_ps(_mm256_mul_ps(A,A), _mm256_mul_ps(B,B)), \
|
||||
_mm256_set_ps(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)), 0b11011100)
|
||||
#define _MM256_PROD_PS(a, b) _mm256_addsub_ps(_mm256_mul_ps(a,_mm256_moveldup_ps(b)),\
|
||||
_mm256_mul_ps(_mm256_shuffle_ps(a,a,0xB1),_mm256_movehdup_ps(b)))
|
||||
#endif /* LV_HAVE_FMA */
|
||||
#endif /* LV_HAVE_AVX */
|
||||
|
||||
|
||||
/*
|
||||
* AVX extension with FMA Macros
|
||||
*/
|
||||
#ifdef LV_HAVE_FMA
|
||||
|
||||
#define _MM256_SQMOD_ADD_PS(A, B, C) _mm256_permute_ps(_mm256_hadd_ps(_mm256_fmadd_ps(A, A, _mm256_fmadd_ps(B, B, C)),\
|
||||
_mm256_set_ps(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)), 0b11011100)
|
||||
|
||||
#define _MM256_PROD_ADD_PS(A, B, C) _mm256_fmaddsub_ps(A,_mm256_moveldup_ps(B),\
|
||||
_mm256_fmaddsub_ps(_mm256_shuffle_ps(A,A,0xB1),_mm256_movehdup_ps(B), C))
|
||||
|
||||
#define _MM256_PROD_SUB_PS(A, B, C) _mm256_fmaddsub_ps(A,_mm256_moveldup_ps(B),\
|
||||
_mm256_fmsubadd_ps(_mm256_shuffle_ps(A,A,0xB1),_mm256_movehdup_ps(B), C))
|
||||
#endif /* LV_HAVE_FMA */
|
||||
|
||||
#endif //SRSLTE_SIMD_H_H
|
|
@ -152,6 +152,9 @@ SRSLTE_API void srslte_vec_conj_cc(cf_t *x, cf_t *y, uint32_t len);
|
|||
/* average vector power */
|
||||
SRSLTE_API float srslte_vec_avg_power_cf(cf_t *x, uint32_t len);
|
||||
|
||||
/* Correlation between complex vectors x and y */
|
||||
SRSLTE_API float srslte_vec_corr_ccc(cf_t *x, cf_t *y, uint32_t len);
|
||||
|
||||
/* return the index of the maximum value in the vector */
|
||||
SRSLTE_API uint32_t srslte_vec_max_fi(float *x, uint32_t len);
|
||||
SRSLTE_API uint32_t srslte_vec_max_abs_ci(cf_t *x, uint32_t len);
|
||||
|
@ -172,6 +175,9 @@ SRSLTE_API void srslte_vec_abs_square_cf(cf_t *x, float *abs_square, uint32_t le
|
|||
/* argument of each vector element */
|
||||
SRSLTE_API void srslte_vec_arg_cf(cf_t *x, float *arg, uint32_t len);
|
||||
|
||||
/* Copy 256 bit aligned vector */
|
||||
SRSLTE_API void srs_vec_cf_cpy(cf_t *src, cf_t *dst, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,22 +39,14 @@ SRSLTE_API int srslte_vec_dot_prod_sss_sse(short *x, short *y, uint32_t len);
|
|||
|
||||
SRSLTE_API int srslte_vec_dot_prod_sss_avx2(short *x, short *y, uint32_t len);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API void srslte_vec_sum_sss_sse(short *x, short *y, short *z, uint32_t len);
|
||||
|
||||
SRSLTE_API void srslte_vec_sum_sss_avx2(short *x, short *y, short *z, uint32_t len);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API void srslte_vec_sub_sss_sse(short *x, short *y, short *z, uint32_t len);
|
||||
|
||||
SRSLTE_API void srslte_vec_sub_sss_avx2(short *x, short *y, short *z, uint32_t len);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SRSLTE_API void srslte_vec_prod_sss_sse(short *x, short *y, short *z, uint32_t len);
|
||||
|
||||
SRSLTE_API void srslte_vec_prod_sss_avx2(short *x, short *y, short *z, uint32_t len);
|
||||
|
@ -64,17 +56,11 @@ SRSLTE_API void srslte_vec_sc_div2_sss_sse(short *x, int n_rightshift, short *z,
|
|||
|
||||
SRSLTE_API void srslte_vec_sc_div2_sss_avx2(short *x, int k, short *z, uint32_t len);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SRSLTE_API void srslte_vec_lut_sss_sse(short *x, unsigned short *lut, short *y, uint32_t len);
|
||||
|
||||
SRSLTE_API void srslte_vec_convert_fi_sse(float *x, int16_t *z, float scale, uint32_t len);
|
||||
|
||||
|
||||
|
||||
SRSLTE_API void srslte_vec_mult_scalar_cf_f_avx( cf_t *z,const cf_t *x,const float h,const uint32_t len);
|
||||
SRSLTE_API void srslte_vec_sc_prod_cfc_avx(const cf_t *x,const float h,cf_t *y,const uint32_t len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,6 @@ namespace srslte {
|
|||
bzero(&end_of_burst_time, sizeof(srslte_timestamp_t));
|
||||
bzero(zeros, burst_preamble_max_samples*sizeof(cf_t));
|
||||
|
||||
sf_len = 0;
|
||||
burst_preamble_sec = 0;
|
||||
is_start_of_burst = false;
|
||||
burst_preamble_samples = 0;
|
||||
|
@ -73,12 +72,11 @@ namespace srslte {
|
|||
trace_enabled = false;
|
||||
tti = 0;
|
||||
agc_enabled = false;
|
||||
offset = 0;
|
||||
|
||||
};
|
||||
|
||||
bool init(char *args = NULL, char *devname = NULL);
|
||||
void stop();
|
||||
void reset();
|
||||
bool start_agc(bool tx_gain_same_rx);
|
||||
|
||||
void set_burst_preamble(double preamble_us);
|
||||
|
@ -98,15 +96,16 @@ namespace srslte {
|
|||
void set_tx_rx_gain_offset(float offset);
|
||||
double set_rx_gain_th(float gain);
|
||||
|
||||
void set_tx_freq(float freq);
|
||||
void set_rx_freq(float freq);
|
||||
void set_freq_offset(double freq);
|
||||
void set_tx_freq(double freq);
|
||||
void set_rx_freq(double freq);
|
||||
|
||||
float get_tx_freq();
|
||||
float get_rx_freq();
|
||||
double get_tx_freq();
|
||||
double get_rx_freq();
|
||||
|
||||
void set_master_clock_rate(float rate);
|
||||
void set_tx_srate(float srate);
|
||||
void set_rx_srate(float srate);
|
||||
void set_master_clock_rate(double rate);
|
||||
void set_tx_srate(double srate);
|
||||
void set_rx_srate(double srate);
|
||||
|
||||
float get_tx_gain();
|
||||
float get_rx_gain();
|
||||
|
@ -122,9 +121,8 @@ namespace srslte {
|
|||
void stop_rx();
|
||||
|
||||
void set_tti(uint32_t tti);
|
||||
void tx_offset(int offset);
|
||||
void set_tti_len(uint32_t sf_len);
|
||||
uint32_t get_tti_len();
|
||||
|
||||
bool is_first_of_burst();
|
||||
|
||||
void register_error_handler(srslte_rf_error_handler_t h);
|
||||
|
||||
|
@ -158,7 +156,7 @@ namespace srslte {
|
|||
const static double blade_default_tx_adv_samples = 27;
|
||||
const static double blade_default_tx_adv_offset_sec = 1e-6;
|
||||
|
||||
float tx_freq, rx_freq;
|
||||
double tx_freq, rx_freq, freq_offset;
|
||||
|
||||
trace<uint32_t> tr_local_time;
|
||||
trace<uint32_t> tr_usrp_time;
|
||||
|
@ -167,8 +165,10 @@ namespace srslte {
|
|||
bool trace_enabled;
|
||||
uint32_t tti;
|
||||
bool agc_enabled;
|
||||
int offset;
|
||||
uint32_t sf_len;
|
||||
|
||||
char saved_args[128];
|
||||
char saved_devname[128];
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -46,13 +46,17 @@ public:
|
|||
srsue::rrc_interface_pdcp *rrc_,
|
||||
srsue::gw_interface_pdcp *gw_,
|
||||
log *pdcp_log_,
|
||||
uint32_t lcid_,
|
||||
uint8_t direction_);
|
||||
void stop();
|
||||
|
||||
// GW interface
|
||||
bool is_drb_enabled(uint32_t lcid);
|
||||
|
||||
// RRC interface
|
||||
void reset();
|
||||
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg = NULL);
|
||||
void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
|
||||
void config_security(uint32_t lcid,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
|
@ -66,14 +70,14 @@ public:
|
|||
void write_pdu_pcch(byte_buffer_t *sdu);
|
||||
|
||||
private:
|
||||
log *pdcp_log;
|
||||
pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS];
|
||||
|
||||
srsue::rlc_interface_pdcp *rlc;
|
||||
srsue::rrc_interface_pdcp *rrc;
|
||||
srsue::gw_interface_pdcp *gw;
|
||||
|
||||
uint8_t direction;
|
||||
log *pdcp_log;
|
||||
pdcp_entity pdcp_array[SRSLTE_N_RADIO_BEARERS];
|
||||
uint32_t lcid; // default LCID that is maintained active by PDCP instance
|
||||
uint8_t direction;
|
||||
|
||||
bool valid_lcid(uint32_t lcid);
|
||||
};
|
||||
|
|
|
@ -67,9 +67,7 @@ public:
|
|||
srsue::gw_interface_pdcp *gw_,
|
||||
srslte::log *log_,
|
||||
uint32_t lcid_,
|
||||
uint8_t direction_,
|
||||
LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg = NULL
|
||||
);
|
||||
srslte_pdcp_config_t cfg_);
|
||||
void reset();
|
||||
|
||||
bool is_active();
|
||||
|
@ -94,12 +92,7 @@ private:
|
|||
|
||||
bool active;
|
||||
uint32_t lcid;
|
||||
bool do_security;
|
||||
u_int8_t direction;
|
||||
|
||||
uint8_t sn_len;
|
||||
// TODO: Support the following configurations
|
||||
// bool do_rohc;
|
||||
srslte_pdcp_config_t cfg;
|
||||
|
||||
uint32_t rx_count;
|
||||
uint32_t tx_count;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "srslte/common/msg_queue.h"
|
||||
#include "srslte/upper/rlc_entity.h"
|
||||
#include "srslte/upper/rlc_metrics.h"
|
||||
#include "srslte/upper/rlc_common.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
@ -55,13 +56,15 @@ public:
|
|||
srsue::rrc_interface_rlc *rrc_,
|
||||
srsue::ue_interface *ue_,
|
||||
log *rlc_log_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
mac_interface_timers *mac_timers_,
|
||||
uint32_t lcid_);
|
||||
void stop();
|
||||
|
||||
void get_metrics(rlc_metrics_t &m);
|
||||
|
||||
// PDCP interface
|
||||
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
std::string get_rb_name(uint32_t lcid);
|
||||
|
||||
// MAC interface
|
||||
uint32_t get_buffer_state(uint32_t lcid);
|
||||
|
@ -74,8 +77,9 @@ public:
|
|||
|
||||
// RRC interface
|
||||
void reset();
|
||||
void empty_queue();
|
||||
void add_bearer(uint32_t lcid);
|
||||
void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
|
||||
void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg);
|
||||
|
||||
private:
|
||||
void reset_metrics();
|
||||
|
@ -87,6 +91,7 @@ private:
|
|||
srslte::mac_interface_timers *mac_timers;
|
||||
srsue::ue_interface *ue;
|
||||
srslte::rlc_entity rlc_array[SRSLTE_N_RADIO_BEARERS];
|
||||
uint32_t default_lcid;
|
||||
|
||||
long ul_tput_bytes[SRSLTE_N_RADIO_BEARERS];
|
||||
long dl_tput_bytes[SRSLTE_N_RADIO_BEARERS];
|
||||
|
|
|
@ -76,8 +76,9 @@ public:
|
|||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers);
|
||||
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
void stop();
|
||||
void empty_queue();
|
||||
|
||||
rlc_mode_t get_mode();
|
||||
|
@ -128,15 +129,7 @@ private:
|
|||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||
***************************************************************************/
|
||||
|
||||
// TX configs
|
||||
int32_t t_poll_retx; // Poll retx timeout (ms)
|
||||
int32_t poll_pdu; // Insert poll bit after this many PDUs
|
||||
int32_t poll_byte; // Insert poll bit after this much data (KB)
|
||||
uint32_t max_retx_thresh; // Max number of retx
|
||||
|
||||
// RX configs
|
||||
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
|
||||
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
|
||||
srslte_rlc_am_config_t cfg;
|
||||
|
||||
/****************************************************************************
|
||||
* State variables and counters
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#ifndef RLC_COMMON_H
|
||||
#define RLC_COMMON_H
|
||||
|
||||
#include "srslte/upper/rlc_interface.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -66,14 +68,6 @@ typedef enum{
|
|||
static const char rlc_dc_field_text[RLC_DC_FIELD_N_ITEMS][20] = {"Control PDU",
|
||||
"Data PDU"};
|
||||
|
||||
typedef enum{
|
||||
RLC_UMD_SN_SIZE_5_BITS = 0,
|
||||
RLC_UMD_SN_SIZE_10_BITS,
|
||||
RLC_UMD_SN_SIZE_N_ITEMS,
|
||||
}rlc_umd_sn_size_t;
|
||||
static const char rlc_umd_sn_size_text[RLC_UMD_SN_SIZE_N_ITEMS][20] = {"5 bits", "10 bits"};
|
||||
static const uint16_t rlc_umd_sn_size_num[RLC_UMD_SN_SIZE_N_ITEMS] = {5, 10};
|
||||
|
||||
// UMD PDU Header
|
||||
typedef struct{
|
||||
uint8_t fi; // Framing info
|
||||
|
@ -162,8 +156,9 @@ public:
|
|||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
srslte::mac_interface_timers *mac_timers_) = 0;
|
||||
virtual void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
|
||||
virtual void configure(srslte_rlc_config_t cnfg) = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void empty_queue() = 0;
|
||||
|
||||
virtual rlc_mode_t get_mode() = 0;
|
||||
|
|
|
@ -54,8 +54,10 @@ public:
|
|||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
|
||||
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
void stop();
|
||||
void empty_queue();
|
||||
bool active();
|
||||
|
||||
rlc_mode_t get_mode();
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE 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.
|
||||
*
|
||||
* srsUE 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 RLC_INTERFACE_H
|
||||
#define RLC_INTERFACE_H
|
||||
|
||||
// for custom constructors
|
||||
#include "srslte/asn1/liblte_rrc.h"
|
||||
|
||||
namespace srslte {
|
||||
|
||||
|
||||
typedef enum{
|
||||
RLC_UMD_SN_SIZE_5_BITS = 0,
|
||||
RLC_UMD_SN_SIZE_10_BITS,
|
||||
RLC_UMD_SN_SIZE_N_ITEMS,
|
||||
}rlc_umd_sn_size_t;
|
||||
static const char rlc_umd_sn_size_text[RLC_UMD_SN_SIZE_N_ITEMS][20] = {"5 bits", "10 bits"};
|
||||
static const uint16_t rlc_umd_sn_size_num[RLC_UMD_SN_SIZE_N_ITEMS] = {5, 10};
|
||||
|
||||
|
||||
typedef struct {
|
||||
/****************************************************************************
|
||||
* Configurable parameters
|
||||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||
***************************************************************************/
|
||||
|
||||
// TX configs
|
||||
int32_t t_poll_retx; // Poll retx timeout (ms)
|
||||
int32_t poll_pdu; // Insert poll bit after this many PDUs
|
||||
int32_t poll_byte; // Insert poll bit after this much data (KB)
|
||||
uint32_t max_retx_thresh; // Max number of retx
|
||||
|
||||
// RX configs
|
||||
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
|
||||
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
|
||||
} srslte_rlc_am_config_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/****************************************************************************
|
||||
* Configurable parameters
|
||||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||
***************************************************************************/
|
||||
|
||||
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
|
||||
rlc_umd_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number
|
||||
rlc_umd_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number
|
||||
|
||||
uint32_t rx_window_size;
|
||||
uint32_t rx_mod; // Rx counter modulus
|
||||
uint32_t tx_mod; // Tx counter modulus
|
||||
} srslte_rlc_um_config_t;
|
||||
|
||||
|
||||
class srslte_rlc_config_t
|
||||
{
|
||||
public:
|
||||
LIBLTE_RRC_RLC_MODE_ENUM rlc_mode;
|
||||
srslte_rlc_am_config_t am;
|
||||
srslte_rlc_um_config_t um;
|
||||
|
||||
// Constructor based on liblte's RLC config
|
||||
srslte_rlc_config_t(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) : rlc_mode(cnfg->rlc_mode), am(), um()
|
||||
{
|
||||
switch(rlc_mode)
|
||||
{
|
||||
case LIBLTE_RRC_RLC_MODE_AM:
|
||||
am.t_poll_retx = liblte_rrc_t_poll_retransmit_num[cnfg->ul_am_rlc.t_poll_retx];
|
||||
am.poll_pdu = liblte_rrc_poll_pdu_num[cnfg->ul_am_rlc.poll_pdu];
|
||||
am.poll_byte = liblte_rrc_poll_byte_num[cnfg->ul_am_rlc.poll_byte]*1000; // KB
|
||||
am.max_retx_thresh = liblte_rrc_max_retx_threshold_num[cnfg->ul_am_rlc.max_retx_thresh];
|
||||
am.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_am_rlc.t_reordering];
|
||||
am.t_status_prohibit = liblte_rrc_t_status_prohibit_num[cnfg->dl_am_rlc.t_status_prohibit];
|
||||
break;
|
||||
case LIBLTE_RRC_RLC_MODE_UM_BI:
|
||||
um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_bi_rlc.t_reordering];
|
||||
um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_bi_rlc.sn_field_len;
|
||||
um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512;
|
||||
um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024;
|
||||
um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_bi_rlc.sn_field_len;
|
||||
um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024;
|
||||
break;
|
||||
case LIBLTE_RRC_RLC_MODE_UM_UNI_UL:
|
||||
um.tx_sn_field_length = (rlc_umd_sn_size_t)cnfg->ul_um_uni_rlc.sn_field_len;
|
||||
um.tx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.tx_sn_field_length) ? 32 : 1024;
|
||||
break;
|
||||
case LIBLTE_RRC_RLC_MODE_UM_UNI_DL:
|
||||
um.t_reordering = liblte_rrc_t_reordering_num[cnfg->dl_um_uni_rlc.t_reordering];
|
||||
um.rx_sn_field_length = (rlc_umd_sn_size_t)cnfg->dl_um_uni_rlc.sn_field_len;
|
||||
um.rx_window_size = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 16 : 512;
|
||||
um.rx_mod = (RLC_UMD_SN_SIZE_5_BITS == um.rx_sn_field_length) ? 32 : 1024;
|
||||
break;
|
||||
default:
|
||||
// Handle default case
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
||||
#endif // RLC_INTERFACE_H
|
|
@ -46,8 +46,9 @@ public:
|
|||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers);
|
||||
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
void stop();
|
||||
void empty_queue();
|
||||
|
||||
rlc_mode_t get_mode();
|
||||
|
|
|
@ -56,8 +56,9 @@ public:
|
|||
srsue::pdcp_interface_rlc *pdcp_,
|
||||
srsue::rrc_interface_rlc *rrc_,
|
||||
mac_interface_timers *mac_timers_);
|
||||
void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg);
|
||||
void configure(srslte_rlc_config_t cnfg);
|
||||
void reset();
|
||||
void stop();
|
||||
void empty_queue();
|
||||
|
||||
rlc_mode_t get_mode();
|
||||
|
@ -92,9 +93,6 @@ private:
|
|||
|
||||
// Rx window
|
||||
std::map<uint32_t, rlc_umd_pdu_t> rx_window;
|
||||
uint32_t rx_window_size;
|
||||
uint32_t rx_mod; // Rx counter modulus
|
||||
uint32_t tx_mod; // Tx counter modulus
|
||||
|
||||
// RX SDU buffers
|
||||
byte_buffer_t *rx_sdu;
|
||||
|
@ -108,9 +106,7 @@ private:
|
|||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||
***************************************************************************/
|
||||
|
||||
int32_t t_reordering; // Timer used by rx to detect PDU loss (ms)
|
||||
rlc_umd_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number
|
||||
rlc_umd_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number
|
||||
srslte_rlc_um_config_t cfg;
|
||||
|
||||
/****************************************************************************
|
||||
* State variables and counters
|
||||
|
@ -129,7 +125,8 @@ private:
|
|||
* Timers
|
||||
* Ref: 3GPP TS 36.322 v10.0.0 Section 7
|
||||
***************************************************************************/
|
||||
uint32_t reordering_timeout_id;
|
||||
srslte::timers::timer *reordering_timer;
|
||||
uint32_t reordering_timer_id;
|
||||
|
||||
bool pdu_lost;
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@ log_filter::log_filter()
|
|||
do_tti = false;
|
||||
}
|
||||
|
||||
log_filter::log_filter(std::string layer)
|
||||
{
|
||||
init(layer, &def_logger_stdout, tti);
|
||||
}
|
||||
|
||||
log_filter::log_filter(std::string layer, logger *logger_, bool tti)
|
||||
{
|
||||
init(layer, logger_, tti);
|
||||
|
|
|
@ -1,290 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE 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.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
|
||||
#include "srslte/common/log_stdout.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace srslte {
|
||||
|
||||
void log_stdout::all_log(srslte::LOG_LEVEL_ENUM level,
|
||||
uint32_t tti,
|
||||
char *msg)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << now_time() << " ";
|
||||
ss << "[" <<get_service_name() << "] ";
|
||||
ss << log_level_text[level] << " ";
|
||||
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||
ss << msg;
|
||||
|
||||
cout << ss.str();
|
||||
}
|
||||
|
||||
void log_stdout::all_log(srslte::LOG_LEVEL_ENUM level,
|
||||
uint32_t tti,
|
||||
char *msg,
|
||||
uint8_t *hex,
|
||||
int size)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << now_time() << " ";
|
||||
ss << "[" <<get_service_name() << "] ";
|
||||
ss << log_level_text[level] << " ";
|
||||
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||
ss << msg << std::endl;
|
||||
ss << hex_string(hex, size);
|
||||
|
||||
cout << ss.str();
|
||||
}
|
||||
|
||||
void log_stdout::all_log_line(srslte::LOG_LEVEL_ENUM level,
|
||||
uint32_t tti,
|
||||
std::string file,
|
||||
int line,
|
||||
char *msg)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << now_time() << " ";
|
||||
ss << "[" <<get_service_name() << "] ";
|
||||
ss << log_level_text[level] << " ";
|
||||
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||
ss << msg;
|
||||
|
||||
cout << ss.str();
|
||||
}
|
||||
|
||||
void log_stdout::console(std::string message, ...) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
printf("%s",args_msg); // Print directly to stdout
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
|
||||
void log_stdout::error(std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_ERROR) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_ERROR, tti, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
void log_stdout::warning(std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_WARNING) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_WARNING, tti, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
void log_stdout::info(std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_INFO, tti, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
void log_stdout::debug(std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_DEBUG, tti, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::error_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_ERROR) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_ERROR, tti, args_msg, hex, size);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
void log_stdout::warning_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_WARNING) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_WARNING, tti, args_msg, hex, size);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
void log_stdout::info_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_INFO, tti, args_msg, hex, size);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
void log_stdout::debug_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log(LOG_LEVEL_DEBUG, tti, args_msg, hex, size);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::error_line(std::string file, int line, std::string message, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_ERROR) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log_line(LOG_LEVEL_ERROR, tti, file, line, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::warning_line(std::string file, int line, std::string message, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_WARNING) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log_line(LOG_LEVEL_WARNING, tti, file, line, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::info_line(std::string file, int line, std::string message, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_INFO) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log_line(LOG_LEVEL_INFO, tti, file, line, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void log_stdout::debug_line(std::string file, int line, std::string message, ...)
|
||||
{
|
||||
if (level >= LOG_LEVEL_DEBUG) {
|
||||
char *args_msg;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||
all_log_line(LOG_LEVEL_DEBUG, tti, file, line, args_msg);
|
||||
va_end(args);
|
||||
free(args_msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string log_stdout::now_time()
|
||||
{
|
||||
struct timeval rawtime;
|
||||
struct tm * timeinfo;
|
||||
char buffer[64];
|
||||
char us[16];
|
||||
|
||||
gettimeofday(&rawtime, NULL);
|
||||
timeinfo = localtime(&rawtime.tv_sec);
|
||||
|
||||
strftime(buffer,64,"%H:%M:%S",timeinfo);
|
||||
strcat(buffer,".");
|
||||
snprintf(us,16,"%ld",rawtime.tv_usec);
|
||||
strcat(buffer,us);
|
||||
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
std::string log_stdout::hex_string(uint8_t *hex, int size)
|
||||
{
|
||||
std::stringstream ss;
|
||||
int c = 0;
|
||||
|
||||
ss << std::hex << std::setfill('0');
|
||||
if(hex_limit >= 0) {
|
||||
size = (size > hex_limit) ? hex_limit : size;
|
||||
}
|
||||
while(c < size) {
|
||||
ss << " " << std::setw(4) << static_cast<unsigned>(c) << ": ";
|
||||
int tmp = (size-c < 16) ? size-c : 16;
|
||||
for(int i=0;i<tmp;i++) {
|
||||
ss << std::setw(2) << static_cast<unsigned>(hex[c++]) << " ";
|
||||
}
|
||||
ss << "\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -27,20 +27,20 @@
|
|||
|
||||
#define LOG_BUFFER_SIZE 1024*32
|
||||
|
||||
#include "srslte/common/logger.h"
|
||||
#include "srslte/common/logger_file.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace srslte{
|
||||
|
||||
logger::logger()
|
||||
logger_file::logger_file()
|
||||
:inited(false)
|
||||
,not_done(true)
|
||||
{}
|
||||
|
||||
logger::~logger() {
|
||||
logger_file::~logger_file() {
|
||||
not_done = false;
|
||||
log("Closing log");
|
||||
log(new std::string("Closing log"));
|
||||
if(inited) {
|
||||
wait_thread_finish();
|
||||
flush();
|
||||
|
@ -48,7 +48,7 @@ logger::~logger() {
|
|||
}
|
||||
}
|
||||
|
||||
void logger::init(std::string file) {
|
||||
void logger_file::init(std::string file) {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
pthread_cond_init(¬_empty, NULL);
|
||||
pthread_cond_init(¬_full, NULL);
|
||||
|
@ -61,19 +61,18 @@ void logger::init(std::string file) {
|
|||
inited = true;
|
||||
}
|
||||
|
||||
void logger::log(const char *msg) {
|
||||
str_ptr s_ptr(new std::string(msg));
|
||||
log(s_ptr);
|
||||
void logger_file::log(const char *msg) {
|
||||
log(new std::string(msg));
|
||||
}
|
||||
|
||||
void logger::log(str_ptr msg) {
|
||||
void logger_file::log(str_ptr msg) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
buffer.push_back(msg);
|
||||
pthread_cond_signal(¬_empty);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
void logger::run_thread() {
|
||||
void logger_file::run_thread() {
|
||||
while(not_done) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
while(buffer.empty()) {
|
||||
|
@ -89,7 +88,7 @@ void logger::run_thread() {
|
|||
}
|
||||
}
|
||||
|
||||
void logger::flush() {
|
||||
void logger_file::flush() {
|
||||
std::deque<str_ptr>::iterator it;
|
||||
for(it=buffer.begin();it!=buffer.end();it++)
|
||||
{
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
// Table 6.1.3.1-1 Buffer size levels for BSR
|
||||
static uint32_t btable[64] = {
|
||||
0, 5, 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132,
|
||||
0, 1, 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132,
|
||||
1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, 4667, 5476, 6411, 7505, 8787, 10287, 12043, 14099, 16507, 19325, 22624, 26487, 31009, 36304,
|
||||
42502, 49759, 58255, 68201, 79846, 93479, 109439, 128125, 150000};
|
||||
|
||||
|
@ -428,12 +428,16 @@ int sch_subh::get_bsr(uint32_t buff_size[4])
|
|||
buff_size[2] = (payload[1]&0x0F) << 4 | (payload[1]&0xC0) >> 6;
|
||||
buff_size[3] = (payload[2]&0x3F);
|
||||
} else {
|
||||
uint32_t nonzero_lcg = (payload[0]&0xc0) >> 6;
|
||||
nonzero_lcg = (payload[0]&0xc0) >> 6;
|
||||
buff_size[nonzero_lcg%4] = payload[0]&0x3f;
|
||||
}
|
||||
for (int i=0;i<4;i++) {
|
||||
if (buff_size[i]) {
|
||||
buff_size[i] = btable[buff_size[i]%64];
|
||||
if (buff_size[i]<63) {
|
||||
buff_size[i] = btable[1+buff_size[i]];
|
||||
} else {
|
||||
buff_size[i] = btable[63];
|
||||
}
|
||||
}
|
||||
}
|
||||
return nonzero_lcg;
|
||||
|
@ -515,8 +519,8 @@ bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
|
|||
bool sch_subh::set_c_rnti(uint16_t crnti)
|
||||
{
|
||||
if (((sch_pdu*)parent)->has_space_ce(2)) {
|
||||
w_payload_ce[0] = (uint8_t) (crnti&0xff00)>>8;
|
||||
w_payload_ce[1] = (uint8_t) (crnti&0x00ff);
|
||||
w_payload_ce[0] = (uint8_t) ((crnti&0xff00)>>8);
|
||||
w_payload_ce[1] = (uint8_t) ((crnti&0x00ff));
|
||||
lcid = CRNTI;
|
||||
((sch_pdu*)parent)->update_space_ce(2);
|
||||
nof_bytes = 2;
|
||||
|
|
|
@ -66,7 +66,7 @@ uint8_t* pdu_queue::request(uint32_t len)
|
|||
void pdu_queue::deallocate(uint8_t* pdu)
|
||||
{
|
||||
if (!pool.deallocate((pdu_t*) pdu)) {
|
||||
log_h->warning("Error deallocating from buffer pool: buffer not created in this pool.\n");
|
||||
log_h->warning("Error deallocating from buffer pool in deallocate(): buffer not created in this pool.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ bool pdu_queue::process_pdus()
|
|||
callback->process_pdu(pdu->ptr, pdu->len, pdu->tstamp);
|
||||
}
|
||||
if (!pool.deallocate(pdu)) {
|
||||
log_h->warning("Error deallocating from buffer pool: buffer not created in this pool.\n");
|
||||
log_h->warning("Error deallocating from buffer pool in process_pdus(): buffer not created in this pool.\n");
|
||||
}
|
||||
cnt++;
|
||||
have_data = true;
|
||||
|
|
|
@ -55,32 +55,7 @@ set(srslte_srcs $<TARGET_OBJECTS:srslte_agc>
|
|||
)
|
||||
|
||||
add_library(srslte_phy STATIC ${srslte_srcs})
|
||||
set_target_properties(srslte_phy PROPERTIES
|
||||
VERSION ${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR})
|
||||
|
||||
find_package(MKL)
|
||||
if(MKL_FOUND)
|
||||
include_directories(${MKL_INCLUDE_DIRS})
|
||||
link_directories(${MKL_LIBRARY_DIRS})
|
||||
else(MKL_FOUND)
|
||||
find_package(FFTW3F REQUIRED)
|
||||
if(FFTW3F_FOUND)
|
||||
include_directories(${FFTW3F_INCLUDE_DIRS})
|
||||
link_directories(${FFTW3F_LIBRARY_DIRS})
|
||||
endif(FFTW3F_FOUND)
|
||||
endif(MKL_FOUND)
|
||||
|
||||
|
||||
if(MKL_FOUND)
|
||||
if(STATIC_MKL)
|
||||
target_link_libraries(srslte_phy ${MKL_STATIC_LIBRARIES})
|
||||
else(STATIC_MKL)
|
||||
target_link_libraries(srslte_phy ${MKL_LIBRARIES})
|
||||
endif(STATIC_MKL)
|
||||
else(MKL_FOUND)
|
||||
target_link_libraries(srslte_phy ${FFTW3F_LIBRARIES})
|
||||
endif(MKL_FOUND)
|
||||
|
||||
target_link_libraries(srslte_phy ${FFT_LIBRARIES})
|
||||
|
||||
if(VOLK_FOUND)
|
||||
target_link_libraries(srslte_phy ${VOLK_LIBRARIES})
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <string.h>
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
#include <srslte/srslte.h>
|
||||
|
||||
#include "srslte/config.h"
|
||||
|
||||
|
@ -72,54 +74,70 @@ static void set_default_filter(srslte_chest_dl_t *q, int filter_len) {
|
|||
*
|
||||
* This object depends on the srslte_refsignal_t object for creating the LTE CSR signal.
|
||||
*/
|
||||
|
||||
int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell)
|
||||
int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
if (q != NULL)
|
||||
{
|
||||
bzero(q, sizeof(srslte_chest_dl_t));
|
||||
|
||||
ret = srslte_refsignal_cs_init(&q->csr_signal, cell);
|
||||
|
||||
ret = srslte_refsignal_cs_init(&q->csr_refs, max_prb);
|
||||
if (ret != SRSLTE_SUCCESS) {
|
||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
q->tmp_noise = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb));
|
||||
q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t*));
|
||||
if (!q->mbsfn_refs) {
|
||||
fprintf(stderr, "Calloc error initializing mbsfn_refs (%d)\n", ret);
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
int pilot_vec_size;
|
||||
if(SRSLTE_REFSIGNAL_MAX_NUM_SF_MBSFN(max_prb)>SRSLTE_REFSIGNAL_MAX_NUM_SF(max_prb)) {
|
||||
pilot_vec_size = SRSLTE_REFSIGNAL_MAX_NUM_SF_MBSFN(max_prb);
|
||||
}else{
|
||||
pilot_vec_size = SRSLTE_REFSIGNAL_MAX_NUM_SF(max_prb);
|
||||
}
|
||||
|
||||
q->tmp_noise = srslte_vec_malloc(sizeof(cf_t) * pilot_vec_size);
|
||||
|
||||
|
||||
if (!q->tmp_noise) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
q->pilot_estimates = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb));
|
||||
q->pilot_estimates = srslte_vec_malloc(sizeof(cf_t) * pilot_vec_size);
|
||||
|
||||
if (!q->pilot_estimates) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
q->pilot_estimates_average = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb));
|
||||
q->pilot_estimates_average = srslte_vec_malloc(sizeof(cf_t) * pilot_vec_size);
|
||||
if (!q->pilot_estimates_average) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb));
|
||||
q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * pilot_vec_size);
|
||||
|
||||
if (!q->pilot_recv_signal) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, SRSLTE_NRE*cell.nof_prb)) {
|
||||
if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, SRSLTE_NRE*max_prb)) {
|
||||
fprintf(stderr, "Error initializing vector interpolator\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
if (srslte_interp_linear_init(&q->srslte_interp_lin, 2*cell.nof_prb, SRSLTE_NRE/2)) {
|
||||
if (srslte_interp_linear_init(&q->srslte_interp_lin, 2*max_prb, SRSLTE_NRE/2)) {
|
||||
fprintf(stderr, "Error initializing interpolator\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
if (srslte_pss_generate(q->pss_signal, cell.id%3)) {
|
||||
fprintf(stderr, "Error initializing PSS signal for noise estimation\n");
|
||||
if (srslte_interp_linear_init(&q->srslte_interp_lin_mbsfn, 6*max_prb, SRSLTE_NRE/6)) {
|
||||
fprintf(stderr, "Error initializing interpolator\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
|
@ -128,7 +146,6 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell)
|
|||
q->smooth_filter_len = 3;
|
||||
srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1);
|
||||
|
||||
q->cell = cell;
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
|
@ -142,14 +159,25 @@ clean_exit:
|
|||
|
||||
void srslte_chest_dl_free(srslte_chest_dl_t *q)
|
||||
{
|
||||
srslte_refsignal_cs_free(&q->csr_signal);
|
||||
int i;
|
||||
if(&q->csr_refs)
|
||||
srslte_refsignal_free(&q->csr_refs);
|
||||
|
||||
if (q->mbsfn_refs) {
|
||||
for (i=0; i<SRSLTE_MAX_MBSFN_AREA_IDS; i++) {
|
||||
if (q->mbsfn_refs[i]) {
|
||||
srslte_refsignal_free(q->mbsfn_refs[i]);
|
||||
}
|
||||
}
|
||||
free(q->mbsfn_refs);
|
||||
}
|
||||
|
||||
if (q->tmp_noise) {
|
||||
free(q->tmp_noise);
|
||||
}
|
||||
srslte_interp_linear_vector_free(&q->srslte_interp_linvec);
|
||||
srslte_interp_linear_free(&q->srslte_interp_lin);
|
||||
|
||||
srslte_interp_linear_free(&q->srslte_interp_lin_mbsfn);
|
||||
if (q->pilot_estimates) {
|
||||
free(q->pilot_estimates);
|
||||
}
|
||||
|
@ -162,10 +190,57 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q)
|
|||
bzero(q, sizeof(srslte_chest_dl_t));
|
||||
}
|
||||
|
||||
|
||||
int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q, uint16_t mbsfn_area_id){
|
||||
if(!q->mbsfn_refs[mbsfn_area_id]){
|
||||
q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t));
|
||||
}
|
||||
if(q->mbsfn_refs[mbsfn_area_id]) {
|
||||
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
{
|
||||
if (q->cell.id != cell.id || q->cell.nof_prb == 0) {
|
||||
memcpy(&q->cell, &cell, sizeof(srslte_cell_t));
|
||||
ret = srslte_refsignal_cs_set_cell(&q->csr_refs, cell);
|
||||
if (ret != SRSLTE_SUCCESS) {
|
||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
if (srslte_pss_generate(q->pss_signal, cell.id%3)) {
|
||||
fprintf(stderr, "Error initializing PSS signal for noise estimation\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
if (srslte_interp_linear_vector_resize(&q->srslte_interp_linvec, SRSLTE_NRE*q->cell.nof_prb)) {
|
||||
fprintf(stderr, "Error initializing vector interpolator\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (srslte_interp_linear_resize(&q->srslte_interp_lin, 2*q->cell.nof_prb, SRSLTE_NRE/2)) {
|
||||
fprintf(stderr, "Error initializing interpolator\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Uses the difference between the averaged and non-averaged pilot estimates */
|
||||
static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id)
|
||||
{
|
||||
int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id);
|
||||
|
||||
/* Substract noisy pilot estimates */
|
||||
srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref);
|
||||
|
||||
|
@ -223,46 +298,70 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) {
|
|||
|
||||
#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)]
|
||||
|
||||
static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id)
|
||||
static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id, srslte_sf_t ch_mode)
|
||||
{
|
||||
/* interpolate the symbols with references in the freq domain */
|
||||
uint32_t l;
|
||||
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
|
||||
|
||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN ) ? srslte_refsignal_mbsfn_nof_symbols() + 1 : srslte_refsignal_cs_nof_symbols(port_id);
|
||||
uint32_t fidx_offset = 0;
|
||||
/* Interpolate in the frequency domain */
|
||||
for (l=0;l<nsymbols;l++) {
|
||||
uint32_t fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l],
|
||||
&ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
||||
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
||||
|
||||
// we add one to nsymbols to allow for inclusion of the non-mbms references in the channel estimation
|
||||
for (l=0;l<(nsymbols);l++) {
|
||||
if (ch_mode == SRSLTE_SF_MBSFN) {
|
||||
if (l == 0) {
|
||||
fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l],
|
||||
&ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
||||
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
||||
} else {
|
||||
fidx_offset = srslte_refsignal_mbsfn_fidx(l - 1);
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin_mbsfn, &pilot_estimates[(2*q->cell.nof_prb) + 6*q->cell.nof_prb*(l - 1)],
|
||||
&ce[srslte_refsignal_mbsfn_nsymbol(l - 1) * q->cell.nof_prb * SRSLTE_NRE],
|
||||
fidx_offset, SRSLTE_NRE/6-fidx_offset);
|
||||
}
|
||||
} else {
|
||||
fidx_offset = srslte_refsignal_cs_fidx(q->cell, l, port_id, 0);
|
||||
srslte_interp_linear_offset(&q->srslte_interp_lin, &pilot_estimates[2*q->cell.nof_prb*l],
|
||||
&ce[srslte_refsignal_cs_nsymbol(l,q->cell.cp, port_id) * q->cell.nof_prb * SRSLTE_NRE],
|
||||
fidx_offset, SRSLTE_NRE/2-fidx_offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now interpolate in the time domain between symbols */
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
if (nsymbols == 4) {
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3);
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2);
|
||||
if (ch_mode == SRSLTE_SF_MBSFN) {
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(2), &cesymb(1), 2, 1);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(2), &cesymb(6), &cesymb(3), 4, 3);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(10), &cesymb(7), 4, 3);
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(10), &cesymb(10), &cesymb(11), 4, 1);
|
||||
} else {
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
if (nsymbols == 4) {
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 4, 3);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 3, 2);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 4, 3);
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 4, 2);
|
||||
} else {
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5);
|
||||
}
|
||||
} else {
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(1), &cesymb(0), 7, 1);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 7, 6);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 7, 5);
|
||||
}
|
||||
} else {
|
||||
if (nsymbols == 4) {
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2);
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2);
|
||||
} else {
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4);
|
||||
if (nsymbols == 4) {
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 3, 2);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 3, 2);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 3, 2);
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 3, 2);
|
||||
} else {
|
||||
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(1), &cesymb(0), 6, 1);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 6, 5);
|
||||
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 6, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) {
|
||||
if (filter_len < SRSLTE_CHEST_MAX_SMOOTH_FIL_LEN) {
|
||||
if (filter) {
|
||||
|
@ -289,9 +388,9 @@ void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w)
|
|||
q->smooth_filter[1] = 1-2*w;
|
||||
}
|
||||
|
||||
static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) {
|
||||
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
|
||||
uint32_t nref = 2*q->cell.nof_prb;
|
||||
static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id, srslte_sf_t ch_mode) {
|
||||
uint32_t nsymbols = (ch_mode == SRSLTE_SF_MBSFN)?srslte_refsignal_mbsfn_nof_symbols(port_id):srslte_refsignal_cs_nof_symbols(port_id);
|
||||
uint32_t nref = (ch_mode == SRSLTE_SF_MBSFN)?6*q->cell.nof_prb:2*q->cell.nof_prb;
|
||||
|
||||
// Average in the frequency domain
|
||||
for (int l=0;l<nsymbols;l++) {
|
||||
|
@ -311,22 +410,14 @@ float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id)
|
|||
return rssi/nsymbols;
|
||||
}
|
||||
|
||||
int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id)
|
||||
{
|
||||
/* Get references from the input signal */
|
||||
srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal);
|
||||
|
||||
/* Use the known CSR signal to compute Least-squares estimates */
|
||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_signal.pilots[port_id/2][sf_idx],
|
||||
q->pilot_estimates, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id));
|
||||
if (ce != NULL) {
|
||||
|
||||
void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id, srslte_sf_t ch_mode){
|
||||
if (ce != NULL) {
|
||||
/* Smooth estimates (if applicable) and interpolate */
|
||||
if (q->smooth_filter_len == 0 || (q->smooth_filter_len == 3 && q->smooth_filter[0] == 0)) {
|
||||
interpolate_pilots(q, q->pilot_estimates, ce, port_id);
|
||||
interpolate_pilots(q, q->pilot_estimates, ce, port_id, ch_mode);
|
||||
} else {
|
||||
average_pilots(q, q->pilot_estimates, q->pilot_estimates_average, port_id);
|
||||
interpolate_pilots(q, q->pilot_estimates_average, ce, port_id);
|
||||
average_pilots(q, q->pilot_estimates, q->pilot_estimates_average, port_id, ch_mode);
|
||||
interpolate_pilots(q, q->pilot_estimates_average, ce, port_id, ch_mode);
|
||||
}
|
||||
|
||||
/* Estimate noise power */
|
||||
|
@ -341,7 +432,6 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u
|
|||
q->noise_estimate[rxant_id][port_id] = estimate_noise_empty_sc(q, input);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Compute RSRP for the channel estimates in this port */
|
||||
|
@ -350,9 +440,43 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u
|
|||
/* compute rssi only for port 0 */
|
||||
q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id);
|
||||
}
|
||||
}
|
||||
|
||||
int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id)
|
||||
{
|
||||
/* Get references from the input signal */
|
||||
srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal);
|
||||
|
||||
/* Use the known CSR signal to compute Least-squares estimates */
|
||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx],
|
||||
q->pilot_estimates, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id));
|
||||
|
||||
chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_NORM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int srslte_chest_dl_estimate_port_mbsfn(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id, uint16_t mbsfn_area_id)
|
||||
{
|
||||
|
||||
/* Use the known CSR signal to compute Least-squares estimates */
|
||||
srslte_refsignal_mbsfn_get_sf(q->cell, port_id, input, q->pilot_recv_signal);
|
||||
// estimate for non-mbsfn section of subframe
|
||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx],
|
||||
q->pilot_estimates, (2*q->cell.nof_prb));
|
||||
|
||||
srslte_vec_prod_conj_ccc(q->pilot_recv_signal+(2*q->cell.nof_prb), q->mbsfn_refs[mbsfn_area_id]->pilots[port_id/2][sf_idx],
|
||||
q->pilot_estimates+(2*q->cell.nof_prb), SRSLTE_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id)-(2*q->cell.nof_prb));
|
||||
|
||||
|
||||
|
||||
chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_MBSFN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t nof_rx_antennas)
|
||||
{
|
||||
|
@ -380,6 +504,21 @@ int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, cf_t *ce[SRSLTE_
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_chest_dl_estimate_multi_mbsfn(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t nof_rx_antennas, uint16_t mbsfn_area_id)
|
||||
{
|
||||
for (uint32_t rxant_id=0;rxant_id<nof_rx_antennas;rxant_id++) {
|
||||
for (uint32_t port_id=0;port_id<q->cell.nof_ports;port_id++) {
|
||||
if (srslte_chest_dl_estimate_port_mbsfn(q, input[rxant_id], ce[port_id][rxant_id], sf_idx, port_id, rxant_id, mbsfn_area_id)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
q->last_nof_antennas = nof_rx_antennas;
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) {
|
||||
float n = 0;
|
||||
for (int i=0;i<q->last_nof_antennas;i++) {
|
||||
|
@ -417,12 +556,15 @@ float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q) {
|
|||
|
||||
}
|
||||
|
||||
float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) {
|
||||
// Note: use only port 0 but average across antennas
|
||||
float srslte_chest_dl_get_rsrp_port(srslte_chest_dl_t *q, uint32_t port) {
|
||||
float n = 0;
|
||||
for (int i=0;i<q->last_nof_antennas;i++) {
|
||||
n += q->rsrp[i][0];
|
||||
for (int i = 0; i < q->last_nof_antennas; i++) {
|
||||
n += q->rsrp[i][port];
|
||||
}
|
||||
return n/q->last_nof_antennas;
|
||||
return n / q->last_nof_antennas;
|
||||
}
|
||||
|
||||
float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) {
|
||||
// Note: use only port 0 but average across antennas
|
||||
return srslte_chest_dl_get_rsrp_port(q, 0);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <string.h>
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
#include <srslte/srslte.h>
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
|
||||
#include "srslte/config.h"
|
||||
|
||||
|
@ -43,6 +45,9 @@
|
|||
#define NOF_REFS_SYM (q->cell.nof_prb*SRSLTE_NRE)
|
||||
#define NOF_REFS_SF (NOF_REFS_SYM*2) // 2 reference symbols per subframe
|
||||
|
||||
#define MAX_REFS_SYM (max_prb*SRSLTE_NRE)
|
||||
#define MAX_REFS_SF (max_prb*SRSLTE_NRE*2) // 2 reference symbols per subframe
|
||||
|
||||
/** 3GPP LTE Downlink channel estimator and equalizer.
|
||||
* Estimates the channel in the resource elements transmitting references and interpolates for the rest
|
||||
* of the resource grid.
|
||||
|
@ -52,52 +57,49 @@
|
|||
* This object depends on the srslte_refsignal_t object for creating the LTE CSR signal.
|
||||
*/
|
||||
|
||||
int srslte_chest_ul_init(srslte_chest_ul_t *q, srslte_cell_t cell)
|
||||
int srslte_chest_ul_init(srslte_chest_ul_t *q, uint32_t max_prb)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
if (q != NULL)
|
||||
{
|
||||
bzero(q, sizeof(srslte_chest_ul_t));
|
||||
|
||||
q->cell = cell;
|
||||
|
||||
ret = srslte_refsignal_ul_init(&q->dmrs_signal, cell);
|
||||
ret = srslte_refsignal_ul_init(&q->dmrs_signal, max_prb);
|
||||
if (ret != SRSLTE_SUCCESS) {
|
||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
q->tmp_noise = srslte_vec_malloc(sizeof(cf_t) * NOF_REFS_SF);
|
||||
q->tmp_noise = srslte_vec_malloc(sizeof(cf_t) * MAX_REFS_SF);
|
||||
if (!q->tmp_noise) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
q->pilot_estimates = srslte_vec_malloc(sizeof(cf_t) * NOF_REFS_SF);
|
||||
q->pilot_estimates = srslte_vec_malloc(sizeof(cf_t) * MAX_REFS_SF);
|
||||
if (!q->pilot_estimates) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
for (int i=0;i<4;i++) {
|
||||
q->pilot_estimates_tmp[i] = srslte_vec_malloc(sizeof(cf_t) * NOF_REFS_SF);
|
||||
q->pilot_estimates_tmp[i] = srslte_vec_malloc(sizeof(cf_t) * MAX_REFS_SF);
|
||||
if (!q->pilot_estimates_tmp[i]) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
}
|
||||
q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * (NOF_REFS_SF+1));
|
||||
q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * (MAX_REFS_SF+1));
|
||||
if (!q->pilot_recv_signal) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
q->pilot_known_signal = srslte_vec_malloc(sizeof(cf_t) * (NOF_REFS_SF+1));
|
||||
q->pilot_known_signal = srslte_vec_malloc(sizeof(cf_t) * (MAX_REFS_SF+1));
|
||||
if (!q->pilot_known_signal) {
|
||||
perror("malloc");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, NOF_REFS_SYM)) {
|
||||
if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, MAX_REFS_SYM)) {
|
||||
fprintf(stderr, "Error initializing vector interpolator\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
@ -107,6 +109,11 @@ int srslte_chest_ul_init(srslte_chest_ul_t *q, srslte_cell_t cell)
|
|||
|
||||
q->dmrs_signal_configured = false;
|
||||
|
||||
if (srslte_refsignal_dmrs_pusch_pregen_init(&q->dmrs_signal, &q->dmrs_pregen, max_prb)) {
|
||||
fprintf(stderr, "Error allocating memory for pregenerated signals\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
|
@ -120,9 +127,8 @@ clean_exit:
|
|||
|
||||
void srslte_chest_ul_free(srslte_chest_ul_t *q)
|
||||
{
|
||||
if (q->dmrs_signal_configured) {
|
||||
srslte_refsignal_dmrs_pusch_pregen_free(&q->dmrs_signal, &q->dmrs_pregen);
|
||||
}
|
||||
srslte_refsignal_dmrs_pusch_pregen_free(&q->dmrs_signal, &q->dmrs_pregen);
|
||||
|
||||
srslte_refsignal_ul_free(&q->dmrs_signal);
|
||||
if (q->tmp_noise) {
|
||||
free(q->tmp_noise);
|
||||
|
@ -146,6 +152,30 @@ void srslte_chest_ul_free(srslte_chest_ul_t *q)
|
|||
bzero(q, sizeof(srslte_chest_ul_t));
|
||||
}
|
||||
|
||||
int srslte_chest_ul_set_cell(srslte_chest_ul_t *q, srslte_cell_t cell)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
{
|
||||
if (cell.id != q->cell.id || q->cell.nof_prb == 0) {
|
||||
memcpy(&q->cell, &cell, sizeof(srslte_cell_t));
|
||||
ret = srslte_refsignal_ul_set_cell(&q->dmrs_signal, cell);
|
||||
if (ret != SRSLTE_SUCCESS) {
|
||||
fprintf(stderr, "Error initializing CSR signal (%d)\n",ret);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (srslte_interp_linear_vector_resize(&q->srslte_interp_linvec, NOF_REFS_SYM)) {
|
||||
fprintf(stderr, "Error initializing vector interpolator\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_chest_ul_set_cfg(srslte_chest_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg,
|
||||
|
|
|
@ -75,17 +75,44 @@ uint32_t srslte_refsignal_cs_v(uint32_t port_id, uint32_t ref_symbol_idx)
|
|||
|
||||
uint32_t srslte_refsignal_cs_nof_symbols(uint32_t port_id)
|
||||
{
|
||||
uint32_t ret;
|
||||
if (port_id < 2) {
|
||||
return 4;
|
||||
ret = 4;
|
||||
} else {
|
||||
return 2;
|
||||
ret = 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t srslte_refsignal_mbsfn_nof_symbols()
|
||||
{
|
||||
if(false){
|
||||
return 3;
|
||||
}else{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline uint32_t srslte_refsignal_cs_fidx(srslte_cell_t cell, uint32_t l, uint32_t port_id, uint32_t m) {
|
||||
return 6*m + ((srslte_refsignal_cs_v(port_id, l) + (cell.id % 6)) % 6);
|
||||
}
|
||||
|
||||
inline uint32_t srslte_refsignal_mbsfn_fidx(uint32_t l)
|
||||
{
|
||||
|
||||
uint32_t ret = 0;
|
||||
if(l == 0){
|
||||
ret = 0;
|
||||
}else if (l == 1){
|
||||
ret = 1;
|
||||
}else if(l == 2){
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline uint32_t srslte_refsignal_cs_nsymbol(uint32_t l, srslte_cp_t cp, uint32_t port_id) {
|
||||
if (port_id < 2) {
|
||||
if (l % 2) {
|
||||
|
@ -97,12 +124,134 @@ inline uint32_t srslte_refsignal_cs_nsymbol(uint32_t l, srslte_cp_t cp, uint32_t
|
|||
return 1+l*SRSLTE_CP_NSYMB(cp);
|
||||
}
|
||||
}
|
||||
inline uint32_t srslte_refsignal_mbsfn_nsymbol(uint32_t l)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
if(l == 0){
|
||||
ret = 2;
|
||||
} else if (l == 1) {
|
||||
ret = 6;
|
||||
} else if (l == 2){
|
||||
ret = 10;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srslte_refsignal_mbsfn_gen_seq(srslte_refsignal_t * q, srslte_cell_t cell, uint32_t N_mbsfn_id)
|
||||
{
|
||||
uint32_t c_init;
|
||||
uint32_t i, ns, l, p;
|
||||
uint32_t mp;
|
||||
int ret = SRSLTE_ERROR;
|
||||
|
||||
srslte_sequence_t seq_mbsfn;
|
||||
bzero(&seq_mbsfn, sizeof(srslte_sequence_t));
|
||||
if (srslte_sequence_init(&seq_mbsfn, 20* SRSLTE_MAX_PRB)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
for(ns=0; ns<SRSLTE_NSUBFRAMES_X_FRAME;ns++){
|
||||
for(p=0;p<2;p++) {
|
||||
uint32_t nsymbols = 3; // replace with function
|
||||
for(l=0;l<nsymbols;l++) {
|
||||
uint32_t lp = (srslte_refsignal_mbsfn_nsymbol(l))%6;
|
||||
uint32_t slot =(l)?(ns*2+1):(ns*2);
|
||||
c_init = 512*(7*(slot+1)+lp+1)*(2*N_mbsfn_id + 1) + N_mbsfn_id;
|
||||
srslte_sequence_set_LTE_pr(&seq_mbsfn,SRSLTE_MAX_PRB*20 ,c_init);
|
||||
for(i=0;i< 6*q->cell.nof_prb;i++) {
|
||||
mp = i + 3*(SRSLTE_MAX_PRB - cell.nof_prb);
|
||||
q->pilots[p][ns][ SRSLTE_REFSIGNAL_PILOT_IDX_MBSFN(i, l ,q->cell)] = (1 - 2 * (float) seq_mbsfn.c[2 * mp]) / sqrt(2) +_Complex_I * (1 - 2 * (float) seq_mbsfn.c[2 * mp + 1]) / sqrt(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srslte_sequence_free(&seq_mbsfn);
|
||||
ret = SRSLTE_SUCCESS;
|
||||
|
||||
free_and_exit:
|
||||
if (ret == SRSLTE_ERROR) {
|
||||
srslte_sequence_free(&seq_mbsfn);
|
||||
srslte_refsignal_free(q);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int srslte_refsignal_mbsfn_init(srslte_refsignal_t * q, srslte_cell_t cell, uint16_t mbsfn_area_id)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
uint32_t i, p;
|
||||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
bzero(q, sizeof(srslte_refsignal_t));
|
||||
q->cell = cell;
|
||||
q->type = SRSLTE_SF_MBSFN;
|
||||
q->mbsfn_area_id = mbsfn_area_id;
|
||||
|
||||
for (p=0;p<2;p++) {
|
||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * q->cell.nof_prb * 18);
|
||||
if (!q->pilots[p][i]) {
|
||||
perror("malloc");
|
||||
goto free_and_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(srslte_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
free_and_exit:
|
||||
if (ret == SRSLTE_ERROR) {
|
||||
srslte_refsignal_free(q);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** Allocates memory for the 20 slots in a subframe
|
||||
*/
|
||||
int srslte_refsignal_cs_init(srslte_refsignal_t * q, uint32_t max_prb)
|
||||
{
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL)
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
bzero(q, sizeof(srslte_refsignal_t));
|
||||
for (int p=0;p<2;p++) {
|
||||
for (int i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_NUM_SF(max_prb, 2*p));
|
||||
if (!q->pilots[p][i]) {
|
||||
perror("malloc");
|
||||
goto free_and_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
free_and_exit:
|
||||
if (ret == SRSLTE_ERROR) {
|
||||
srslte_refsignal_free(q);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Allocates and precomputes the Cell-Specific Reference (CSR) signal for
|
||||
* the 20 slots in a subframe
|
||||
*/
|
||||
int srslte_refsignal_cs_init(srslte_refsignal_cs_t * q, srslte_cell_t cell)
|
||||
int srslte_refsignal_cs_set_cell(srslte_refsignal_t * q, srslte_cell_t cell)
|
||||
{
|
||||
|
||||
uint32_t c_init;
|
||||
|
@ -114,83 +263,66 @@ int srslte_refsignal_cs_init(srslte_refsignal_cs_t * q, srslte_cell_t cell)
|
|||
if (q != NULL &&
|
||||
srslte_cell_isvalid(&cell))
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
if (cell.id != q->cell.id || q->cell.nof_prb == 0) {
|
||||
memcpy(&q->cell, &cell, sizeof(srslte_cell_t));
|
||||
|
||||
bzero(q, sizeof(srslte_refsignal_cs_t));
|
||||
bzero(&seq, sizeof(srslte_sequence_t));
|
||||
if (srslte_sequence_init(&seq, 2 * 2 * SRSLTE_MAX_PRB)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
if (SRSLTE_CP_ISNORM(cell.cp)) {
|
||||
N_cp = 1;
|
||||
} else {
|
||||
N_cp = 0;
|
||||
}
|
||||
|
||||
q->cell = cell;
|
||||
|
||||
for (p=0;p<2;p++) {
|
||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
q->pilots[p][i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, 2*p));
|
||||
if (!q->pilots[p][i]) {
|
||||
perror("malloc");
|
||||
goto free_and_exit;
|
||||
}
|
||||
bzero(&seq, sizeof(srslte_sequence_t));
|
||||
if (srslte_sequence_init(&seq, 2*2*SRSLTE_MAX_PRB)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
for (ns=0;ns<SRSLTE_NSLOTS_X_FRAME;ns++) {
|
||||
for (p=0;p<2;p++) {
|
||||
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(2*p)/2;
|
||||
for (l = 0; l < nsymbols; l++) {
|
||||
/* Compute sequence init value */
|
||||
uint32_t lp = srslte_refsignal_cs_nsymbol(l, cell.cp, 2*p);
|
||||
c_init = 1024 * (7 * (ns + 1) + lp + 1) * (2 * cell.id + 1)
|
||||
+ 2 * cell.id + N_cp;
|
||||
if (SRSLTE_CP_ISNORM(cell.cp)) {
|
||||
N_cp = 1;
|
||||
} else {
|
||||
N_cp = 0;
|
||||
}
|
||||
|
||||
/* generate sequence for this symbol and slot */
|
||||
srslte_sequence_set_LTE_pr(&seq, c_init);
|
||||
for (ns=0;ns<SRSLTE_NSLOTS_X_FRAME;ns++) {
|
||||
for (p=0;p<2;p++) {
|
||||
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(2*p)/2;
|
||||
for (l = 0; l < nsymbols; l++) {
|
||||
/* Compute sequence init value */
|
||||
uint32_t lp = srslte_refsignal_cs_nsymbol(l, cell.cp, 2*p);
|
||||
c_init = 1024 * (7 * (ns + 1) + lp + 1) * (2 * cell.id + 1)
|
||||
+ 2 * cell.id + N_cp;
|
||||
|
||||
/* Compute signal */
|
||||
for (i = 0; i < 2*q->cell.nof_prb; i++) {
|
||||
mp = i + SRSLTE_MAX_PRB - cell.nof_prb;
|
||||
/* save signal */
|
||||
q->pilots[p][ns/2][SRSLTE_REFSIGNAL_PILOT_IDX(i,(ns%2)*nsymbols+l,q->cell)] =
|
||||
(1 - 2 * (float) seq.c[2 * mp]) / sqrt(2) +
|
||||
_Complex_I * (1 - 2 * (float) seq.c[2 * mp + 1]) / sqrt(2);
|
||||
/* generate sequence for this symbol and slot */
|
||||
srslte_sequence_set_LTE_pr(&seq, 2*2*SRSLTE_MAX_PRB, c_init);
|
||||
|
||||
/* Compute signal */
|
||||
for (i = 0; i < 2*q->cell.nof_prb; i++) {
|
||||
mp = i + SRSLTE_MAX_PRB - cell.nof_prb;
|
||||
/* save signal */
|
||||
q->pilots[p][ns/2][SRSLTE_REFSIGNAL_PILOT_IDX(i,(ns%2)*nsymbols+l,q->cell)] =
|
||||
(1 - 2 * (float) seq.c[2 * mp]) / sqrt(2) +
|
||||
_Complex_I * (1 - 2 * (float) seq.c[2 * mp + 1]) / sqrt(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
srslte_sequence_free(&seq);
|
||||
}
|
||||
srslte_sequence_free(&seq);
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
free_and_exit:
|
||||
if (ret == SRSLTE_ERROR) {
|
||||
srslte_sequence_free(&seq);
|
||||
srslte_refsignal_cs_free(q);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Deallocates a srslte_refsignal_cs_t object allocated with srslte_refsignal_cs_init */
|
||||
void srslte_refsignal_cs_free(srslte_refsignal_cs_t * q)
|
||||
void srslte_refsignal_free(srslte_refsignal_t * q)
|
||||
{
|
||||
int i, p;
|
||||
|
||||
for (p=0;p<2;p++) {
|
||||
for (i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
for (int p=0;p<2;p++) {
|
||||
for (int i=0;i<SRSLTE_NSUBFRAMES_X_FRAME;i++) {
|
||||
if (q->pilots[p][i]) {
|
||||
free(q->pilots[p][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
bzero(q, sizeof(srslte_refsignal_cs_t));
|
||||
bzero(q, sizeof(srslte_refsignal_t));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Maps a reference signal initialized with srslte_refsignal_cs_init() into an array of subframe symbols */
|
||||
int srslte_refsignal_cs_put_sf(srslte_cell_t cell, uint32_t port_id, cf_t *pilots, cf_t *sf_symbols)
|
||||
{
|
||||
|
@ -218,6 +350,45 @@ int srslte_refsignal_cs_put_sf(srslte_cell_t cell, uint32_t port_id, cf_t *pilot
|
|||
}
|
||||
}
|
||||
|
||||
SRSLTE_API int srslte_refsignal_mbsfn_put_sf(srslte_cell_t cell,
|
||||
uint32_t port_id,
|
||||
cf_t *cs_pilots,
|
||||
cf_t *mbsfn_pilots,
|
||||
cf_t *sf_symbols)
|
||||
{
|
||||
uint32_t i, l;
|
||||
uint32_t fidx;
|
||||
|
||||
if (srslte_cell_isvalid(&cell) &&
|
||||
srslte_portid_isvalid(port_id) &&
|
||||
cs_pilots != NULL &&
|
||||
mbsfn_pilots != NULL &&
|
||||
sf_symbols != NULL)
|
||||
{
|
||||
// adding CS refs for the non-mbsfn section of the sub-frame
|
||||
fidx = ((srslte_refsignal_cs_v(port_id, 0) + (cell.id % 6)) % 6);
|
||||
for (i = 0; i < 2*cell.nof_prb; i++) {
|
||||
sf_symbols[SRSLTE_RE_IDX(cell.nof_prb, 0, fidx)] = cs_pilots[SRSLTE_REFSIGNAL_PILOT_IDX(i,0,cell)];
|
||||
fidx += SRSLTE_NRE/2; // 1 reference every 6 RE
|
||||
}
|
||||
|
||||
for (l = 0; l<srslte_refsignal_mbsfn_nof_symbols(); l++) {
|
||||
uint32_t nsymbol = srslte_refsignal_mbsfn_nsymbol(l);
|
||||
fidx = srslte_refsignal_mbsfn_fidx(l);
|
||||
for (i = 0; i < 6*cell.nof_prb; i++) {
|
||||
sf_symbols[SRSLTE_RE_IDX(cell.nof_prb, nsymbol, fidx)] = mbsfn_pilots[SRSLTE_REFSIGNAL_PILOT_IDX_MBSFN(i,l,cell)];
|
||||
fidx += SRSLTE_NRE/6;
|
||||
}
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
} else {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Copies the RE containing references from an array of subframe symbols to the pilots array. */
|
||||
int srslte_refsignal_cs_get_sf(srslte_cell_t cell, uint32_t port_id, cf_t *sf_symbols, cf_t *pilots)
|
||||
{
|
||||
|
@ -244,4 +415,39 @@ int srslte_refsignal_cs_get_sf(srslte_cell_t cell, uint32_t port_id, cf_t *sf_sy
|
|||
}
|
||||
}
|
||||
|
||||
int srslte_refsignal_mbsfn_get_sf(srslte_cell_t cell, uint32_t port_id, cf_t *sf_symbols, cf_t *pilots)
|
||||
{
|
||||
uint32_t i, l;
|
||||
uint32_t fidx;
|
||||
uint32_t nsymbol;
|
||||
if (srslte_cell_isvalid(&cell) &&
|
||||
srslte_portid_isvalid(port_id) &&
|
||||
pilots != NULL &&
|
||||
sf_symbols != NULL)
|
||||
{
|
||||
// getting refs from non mbsfn section of subframe
|
||||
nsymbol = srslte_refsignal_cs_nsymbol(0, cell.cp, port_id);
|
||||
fidx = ((srslte_refsignal_cs_v(port_id, 0) + (cell.id % 6)) % 6);
|
||||
for (i = 0; i < 2*cell.nof_prb; i++) {
|
||||
pilots[SRSLTE_REFSIGNAL_PILOT_IDX(i,0,cell)] = sf_symbols[SRSLTE_RE_IDX(cell.nof_prb, nsymbol, fidx)];
|
||||
fidx += SRSLTE_NRE/2; // 2 references per PRB
|
||||
}
|
||||
|
||||
for (l = 0; l< srslte_refsignal_mbsfn_nof_symbols() ;l++){
|
||||
nsymbol = srslte_refsignal_mbsfn_nsymbol(l);
|
||||
fidx = srslte_refsignal_mbsfn_fidx(l);
|
||||
for (i = 0; i < 6*cell.nof_prb; i++) {
|
||||
pilots[SRSLTE_REFSIGNAL_PILOT_IDX_MBSFN(i,l,cell) + (2*cell.nof_prb)] = sf_symbols[SRSLTE_RE_IDX(cell.nof_prb, nsymbol, fidx)];
|
||||
fidx += SRSLTE_NRE/6;
|
||||
}
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
} else {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <complex.h>
|
||||
#include <srslte/phy/common/phy_common.h>
|
||||
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
#include "srslte/phy/ch_estimation/refsignal_ul.h"
|
||||
|
@ -138,8 +139,8 @@ static int generate_n_prs(srslte_refsignal_ul_t * q) {
|
|||
}
|
||||
q->n_prs_pusch[delta_ss][ns] = n_prs;
|
||||
}
|
||||
srslte_sequence_free(&seq);
|
||||
}
|
||||
srslte_sequence_free(&seq);
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
@ -160,9 +161,9 @@ static int generate_srslte_sequence_hopping_v(srslte_refsignal_ul_t *q) {
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
q->v_pusch[ns][delta_ss] = seq.c[ns];
|
||||
srslte_sequence_free(&seq);
|
||||
}
|
||||
}
|
||||
srslte_sequence_free(&seq);
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -170,46 +171,24 @@ static int generate_srslte_sequence_hopping_v(srslte_refsignal_ul_t *q) {
|
|||
/** Initializes srslte_refsignal_ul_t object according to 3GPP 36.211 5.5
|
||||
*
|
||||
*/
|
||||
int srslte_refsignal_ul_init(srslte_refsignal_ul_t * q, srslte_cell_t cell)
|
||||
int srslte_refsignal_ul_init(srslte_refsignal_ul_t * q, uint32_t max_prb)
|
||||
{
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL && srslte_cell_isvalid(&cell)) {
|
||||
if (q != NULL) {
|
||||
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
bzero(q, sizeof(srslte_refsignal_ul_t));
|
||||
q->cell = cell;
|
||||
|
||||
// Allocate temporal buffer for computing signal argument
|
||||
q->tmp_arg = srslte_vec_malloc(SRSLTE_NRE * q->cell.nof_prb * sizeof(cf_t));
|
||||
q->tmp_arg = srslte_vec_malloc(SRSLTE_NRE * max_prb * sizeof(cf_t));
|
||||
if (!q->tmp_arg) {
|
||||
perror("malloc");
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
srslte_pucch_cfg_default(&q->pucch_cfg);
|
||||
|
||||
// Precompute n_prs
|
||||
if (generate_n_prs(q)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
// Precompute group hopping values u.
|
||||
if (srslte_group_hopping_f_gh(q->f_gh, q->cell.id)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
// Precompute sequence hopping values v. Uses f_ss_pusch
|
||||
if (generate_srslte_sequence_hopping_v(q)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
if (srslte_pucch_n_cs_cell(q->cell, q->n_cs_cell)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
free_and_exit:
|
||||
|
@ -226,6 +205,45 @@ void srslte_refsignal_ul_free(srslte_refsignal_ul_t * q) {
|
|||
bzero(q, sizeof(srslte_refsignal_ul_t));
|
||||
}
|
||||
|
||||
/** Initializes srslte_refsignal_ul_t object according to 3GPP 36.211 5.5
|
||||
*
|
||||
*/
|
||||
int srslte_refsignal_ul_set_cell(srslte_refsignal_ul_t * q, srslte_cell_t cell)
|
||||
{
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL && srslte_cell_isvalid(&cell)) {
|
||||
|
||||
if (cell.id != q->cell.id || q->cell.nof_prb == 0) {
|
||||
memcpy(&q->cell, &cell, sizeof(srslte_cell_t));
|
||||
|
||||
srslte_pucch_cfg_default(&q->pucch_cfg);
|
||||
|
||||
// Precompute n_prs
|
||||
if (generate_n_prs(q)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Precompute group hopping values u.
|
||||
if (srslte_group_hopping_f_gh(q->f_gh, q->cell.id)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Precompute sequence hopping values v. Uses f_ss_pusch
|
||||
if (generate_srslte_sequence_hopping_v(q)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (srslte_pucch_n_cs_cell(q->cell, q->n_cs_cell)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_refsignal_ul_set_cfg(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg,
|
||||
srslte_pucch_cfg_t *pucch_cfg,
|
||||
|
@ -363,15 +381,38 @@ void compute_r(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t ns, uint32_t
|
|||
|
||||
}
|
||||
|
||||
int srslte_refsignal_dmrs_pusch_pregen_init(srslte_refsignal_ul_t *q, srslte_refsignal_ul_dmrs_pregen_t *pregen,
|
||||
uint32_t max_prb)
|
||||
{
|
||||
for (uint32_t sf_idx=0;sf_idx<SRSLTE_NSUBFRAMES_X_FRAME;sf_idx++) {
|
||||
for (uint32_t cs=0;cs<SRSLTE_NOF_CSHIFT;cs++) {
|
||||
pregen->r[cs][sf_idx] = (cf_t**) calloc(sizeof(cf_t*), max_prb + 1);
|
||||
if (pregen->r[cs][sf_idx]) {
|
||||
for (uint32_t n=0;n<=max_prb;n++) {
|
||||
if (srslte_dft_precoding_valid_prb(n)) {
|
||||
pregen->r[cs][sf_idx][n] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*n*2*SRSLTE_NRE);
|
||||
if (pregen->r[cs][sf_idx][n]) {
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int srslte_refsignal_dmrs_pusch_pregen(srslte_refsignal_ul_t *q, srslte_refsignal_ul_dmrs_pregen_t *pregen)
|
||||
{
|
||||
for (uint32_t sf_idx=0;sf_idx<SRSLTE_NSUBFRAMES_X_FRAME;sf_idx++) {
|
||||
for (uint32_t cs=0;cs<SRSLTE_NOF_CSHIFT;cs++) {
|
||||
pregen->r[cs][sf_idx] = (cf_t**) calloc(sizeof(cf_t*), q->cell.nof_prb + 1);
|
||||
if (pregen->r[cs][sf_idx]) {
|
||||
for (uint32_t n=0;n<=q->cell.nof_prb;n++) {
|
||||
if (srslte_dft_precoding_valid_prb(n)) {
|
||||
pregen->r[cs][sf_idx][n] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*n*2*SRSLTE_NRE);
|
||||
if (pregen->r[cs][sf_idx][n]) {
|
||||
if (srslte_refsignal_dmrs_pusch_gen(q, n, sf_idx, cs, pregen->r[cs][sf_idx][n])) {
|
||||
return SRSLTE_ERROR;
|
||||
|
|
|
@ -52,4 +52,3 @@ add_test(chest_test_ul_cellid1 chest_test_ul -c 2 -r 50)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue