Merge branch 'next'

master
Ismael Gomez 8 years ago
commit 590fff9c69

@ -1,6 +1,15 @@
Change Log for Releases Change Log for Releases
============================== ==============================
## 002.000.000
* Added fully functional srsENB to srsLTE code
* Merged srsUE code into srsLTE and reestructured PHY code
* Added support for SoapySDR devices (eg LimeSDR)
* Fixed issues in RLC AM
* Added support for NEON and AVX in many kernels and Viterbi decoder
* Added support for CPU affinity
* Other minor bug-fixes and new features
## 001.004.000 ## 001.004.000
* Fixed issue in rv for format1C causing incorrect SIB1 decoding in some networks * Fixed issue in rv for format1C causing incorrect SIB1 decoding in some networks
* Improved PDCCH decoding BER (fixed incorrect trellis initialization) * Improved PDCCH decoding BER (fixed incorrect trellis initialization)

@ -1,7 +1,7 @@
# #
# Copyright 2013-2015 Software Radio Systems Limited # Copyright 2013-2017 Software Radio Systems Limited
# #
# This file is part of the srsLTE library. # This file is part of srsLTE
# #
# srsLTE is free software: you can redistribute it and/or modify # srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -30,26 +30,137 @@ endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
######################################################################## ########################################################################
# Project setup # Project setup
######################################################################## ########################################################################
CMAKE_MINIMUM_REQUIRED (VERSION 2.6) cmake_minimum_required(VERSION 2.6)
PROJECT (SRSLTE) project( SRSLTE )
MESSAGE( STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM} ) message( STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM} )
MESSAGE( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR} ) message( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR} )
MESSAGE( STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER} ) message( STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER} )
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
include(SRSLTEVersion) #sets version information include(SRSLTEVersion) #sets version information
include(SRSLTEPackage) #setup cpack include(SRSLTEPackage) #setup cpack
include(CTest) include(CTest)
set( CTEST_MEMORYCHECK_COMMAND valgrind ) set(CTEST_MEMORYCHECK_COMMAND valgrind)
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in" "${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake" "${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake"
IMMEDIATE @ONLY) IMMEDIATE @ONLY)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
message(STATUS "Build type not specified: defaulting to Release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
######################################################################## ########################################################################
# Options # Options
######################################################################## ########################################################################
option(ENABLE_SRSUE "Build srsUE application" ON)
option(ENABLE_SRSENB "Build srsENB application" ON)
option(ENABLE_VOLK "Enable use of VOLK SIMD library" ON)
option(ENABLE_GUI "Enable GUI (using srsGUI)" ON)
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)
set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.")
########################################################################
# Find dependencies
########################################################################
find_package(Threads REQUIRED)
find_package(Polarssl)
if (POLARSSL_FOUND)
set(SEC_INCLUDE_DIRS "${POLARSSL_INCLUDE_DIRS}")
set(SEC_LIBRARIES "${POLARSSL_LIBRARIES}")
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}")
add_definitions(-DHAVE_MBEDTLS)
endif (MBEDTLS_FOUND)
endif(POLARSSL_FOUND)
find_package(UHD)
if(UHD_FOUND)
include_directories(${UHD_INCLUDE_DIRS})
link_directories(${UHD_LIBRARY_DIRS})
endif(UHD_FOUND)
if(ENABLE_BLADERF)
find_package(bladeRF)
if(BLADERF_FOUND)
include_directories(${BLADERF_INCLUDE_DIRS})
link_directories(${BLADERF_LIBRARY_DIRS})
endif(BLADERF_FOUND)
endif(ENABLE_BLADERF)
find_package(SoapySDR)
if(SOAPYSDR_FOUND)
include_directories(${SOAPYSDR_INCLUDE_DIRS})
link_directories(${SOAPYSDR_LIBRARY_DIRS})
endif(SOAPYSDR_FOUND)
if(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
set(RF_FOUND TRUE CACHE INTERNAL "RF frontend found")
else(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
set(RF_FOUND FALSE CACHE INTERNAL "RF frontend found")
add_definitions(-DDISABLE_RF)
endif(BLADERF_FOUND OR UHD_FOUND OR SOAPYSDR_FOUND)
if(ENABLE_SRSUE OR ENABLE_SRSENB)
# Find Boost
set(BOOST_REQUIRED_COMPONENTS
program_options
system
)
if(UNIX AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
endif(UNIX AND EXISTS "/usr/lib64")
set(Boost_ADDITIONAL_VERSIONS
"1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
"1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
"1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
"1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
)
find_package(Boost "1.35" COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
endif(ENABLE_SRSUE OR ENABLE_SRSENB)
if(ENABLE_GUI)
find_package(SRSGUI)
if(SRSGUI_FOUND)
add_definitions(-DENABLE_GUI)
include_directories(${SRSGUI_INCLUDE_DIRS})
link_directories(${SRSGUI_LIBRARY_DIRS})
endif(SRSGUI_FOUND)
endif(ENABLE_GUI)
include(CheckFunctionExistsMath)
if(ENABLE_VOLK)
find_package(Volk)
if(VOLK_FOUND)
include_directories(${VOLK_INCLUDE_DIRS})
link_directories(${VOLK_LIBRARY_DIRS})
message(STATUS "Compiling with VOLK SIMD library.")
else(VOLK_FOUND)
message(STATUS "VOLK SIMD library NOT found. Using generic implementation.")
endif(VOLK_FOUND)
else(ENABLE_VOLK)
message(STATUS "VOLK library disabled")
endif(ENABLE_VOLK)
######################################################################## ########################################################################
@ -71,13 +182,6 @@ set(INCLUDE_DIR include)
set(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}") set(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}")
set(DATA_DIR share/${CPACK_PACKAGE_NAME}) set(DATA_DIR share/${CPACK_PACKAGE_NAME})
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
message(STATUS "Build type not specified: defaulting to Release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
######################################################################## ########################################################################
# Compiler specific setup # Compiler specific setup
######################################################################## ########################################################################
@ -89,56 +193,79 @@ macro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
endif(${have}) endif(${have})
endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) endmacro(ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
#Any additional flags for CXX set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable -std=c++03")
endif(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE -g")
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
find_package(SSE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -DDEBUG_MODE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
find_package(SSE)
if (HAVE_AVX2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE")
else (HAVE_AVX2)
if(HAVE_AVX) if(HAVE_AVX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE")
elseif(HAVE_SSE) elseif(HAVE_SSE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mfpmath=sse -msse4.1 -DLV_HAVE_SSE") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse4.1 -DLV_HAVE_SSE")
endif(HAVE_AVX) endif(HAVE_AVX)
endif (HAVE_AVX2)
endif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${GCC_ARCH} -Wall -Wno-comment -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE")
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -DDEBUG_MODE")
else(${CMAKE_BUILD_TYPE} STREQUAL "Debug") else(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
find_package(SSE) endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if (USE_LTE_RATES)
message(STATUS "Using standard LTE sampling rates")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFORCE_STANDARD_RATE")
endif (USE_LTE_RATES)
find_package(SSE)
if (HAVE_AVX2)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE")
else (HAVE_AVX2)
if(HAVE_AVX) if(HAVE_AVX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE")
elseif(HAVE_SSE) elseif(HAVE_SSE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -msse4.1 -DLV_HAVE_SSE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse -msse4.1 -DLV_HAVE_SSE")
endif(HAVE_AVX) endif(HAVE_AVX)
endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") endif (HAVE_AVX2)
if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if(HAVE_SSE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Ofast -funroll-loops")
endif(HAVE_SSE)
endif(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=native -DIS_ARM -DHAVE_NEON")
message(STATUS "have ARM")
endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CMAKE_REQUIRED_FLAGS ${CMAKE_C_FLAGS})
if(NOT WIN32) if(NOT WIN32)
ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN)
endif(NOT WIN32) endif(NOT WIN32)
endif(CMAKE_COMPILER_IS_GNUCC) endif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
if(MSVC)
include_directories(${PROJECT_SOURCE_DIR}/msvc) #missing headers
add_definitions(-D_WIN32_WINNT=0x0501) #minimum version required is windows xp
add_definitions(-DNOMINMAX) #disables stupidity and enables std::min and std::max
add_definitions( #stop all kinds of compatibility warnings
-D_SCL_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_DEPRECATE
-D_CRT_NONSTDC_NO_DEPRECATE
)
add_definitions(/MP) #build with multiple processors
endif(MSVC)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# The following is needed for weak linking to work under OS X # The following is needed for weak linking to work under OS X
set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup") set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
message(STATUS "CMAKE_C_FLAGS is ${CMAKE_C_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
######################################################################## ########################################################################
# Create uninstall targets # Create uninstall targets
######################################################################## ########################################################################
@ -151,11 +278,9 @@ add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
######################################################################## ########################################################################
# Macro to add -fPIC property to static libs # Add -fPIC property to all targets
######################################################################## ########################################################################
macro(SRSLTE_SET_PIC) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set_target_properties(${ARGV} PROPERTIES COMPILE_FLAGS -fPIC)
endmacro(SRSLTE_SET_PIC)
######################################################################## ########################################################################
# Print summary # Print summary
@ -166,10 +291,41 @@ message(STATUS "Building for version: ${VERSION}")
######################################################################## ########################################################################
# Add general includes and dependencies # Add general includes and dependencies
######################################################################## ########################################################################
include_directories(${PROJECT_BINARY_DIR}/srslte/include/) include_directories(${PROJECT_BINARY_DIR}/lib/include)
include_directories(${PROJECT_SOURCE_DIR}/srslte/include/) include_directories(${PROJECT_SOURCE_DIR}/lib/include)
########################################################################
# Add headers to cmake project (useful for IDEs)
########################################################################
set(HEADERS_ALL "")
file(GLOB headers *)
foreach(_header ${headers})
if(IS_DIRECTORY ${_header})
file(GLOB_RECURSE tmp "${_header}/*.h")
list(APPEND HEADERS_ALL ${tmp})
endif(IS_DIRECTORY ${_header})
endforeach()
add_custom_target(add_srslte_headers SOURCES ${HEADERS_ALL})
######################################################################## ########################################################################
# Add the subdirectories # Add the subdirectories
######################################################################## ########################################################################
add_subdirectory(srslte) add_subdirectory(lib)
if(RF_FOUND)
if(ENABLE_SRSUE)
message(STATUS "Building with srsUE")
add_subdirectory(srsue)
else(ENABLE_SRSUE)
message(STATUS "srsUE build disabled")
endif(ENABLE_SRSUE)
if(ENABLE_SRSENB)
message(STATUS "Building with srsENB")
add_subdirectory(srsenb)
else(ENABLE_SRSENB)
message(STATUS "srsUE build disabled")
endif(ENABLE_SRSENB)
else(RF_FOUND)
message(STATUS "srsUE and srsENB builds disabled due to missing RF driver")
endif(RF_FOUND)

@ -3,31 +3,61 @@ srsLTE
[![Coverity Scan Build Status](https://scan.coverity.com/projects/10045/badge.svg)](https://scan.coverity.com/projects/10045) [![Coverity Scan Build Status](https://scan.coverity.com/projects/10045/badge.svg)](https://scan.coverity.com/projects/10045)
srsLTE is a free and open-source LTE library for SDR UE and eNodeB developed by SRS (www.softwareradiosystems.com). The library is highly modular with minimum inter-module or external dependencies. It is entirely written in C and, if available in the system, uses the acceleration library VOLK distributed in GNURadio. srsLTE is a free and open-source LTE software suite developed by SRS (www.softwareradiosystems.com).
**srsLTE is used by srsUE, a full stack (PHY to IP) implementation of an LTE UE. srsUE is available at https://github.com/srslte/srsue** It includes:
* srsUE - a complete SDR LTE UE application featuring all layers from PHY to IP
* srsENB - a complete SDR LTE eNodeB application
* a highly modular set of common libraries for PHY, MAC, RLC, PDCP, RRC, NAS, S1AP and GW layers.
srsLTE is released under the AGPLv3 license and uses software from the OpenLTE project (http://sourceforge.net/projects/openlte) for some security functions and for RRC/NAS message parsing.
The srsLTE software license is AGPLv3. Common Features
---------------
Current Features:
* LTE Release 8 compliant * LTE Release 8 compliant
* FDD configuration * FDD configuration
* Tested bandwidths: 1.4, 3, 5, 10, 15 and 20 MHz * 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) and 2 (transmit diversity)
* Cell search and synchronization procedure for the UE
* All DL channels/signals are supported for UE and eNodeB side: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH
* All UL channels/signals are supported for UE side: PRACH, PUSCH, PUCCH, SRS
* Frequency-based ZF and MMSE equalizer * Frequency-based ZF and MMSE equalizer
* Highly optimized Turbo Decoder available in Intel SSE4.1/AVX (+100 Mbps) and standard C (+25 Mbps) * Highly optimized Turbo Decoder available in Intel SSE4.1/AVX (+100 Mbps) and standard C (+25 Mbps)
* UE receiver tested and verified with Amarisoft LTE 100 eNodeB and commercial LTE networks (Telefonica Spain, Three.ie and Eircom in Ireland) * MAC, RLC, PDCP, RRC, NAS, S1AP and GW layers
* Detailed log system with per-layer log levels and hex dumps
Missing Features: * MAC layer wireshark packet capture
* Closed-loop power control * Command-line trace metrics
* Semi-Persistent Scheduling * Detailed input configuration files
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
* 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.
srsUE has been fully tested and validated with the following network equipment:
* Amarisoft LTE100 eNodeB and EPC
* Nokia FlexiRadio family FSMF system module with 1800MHz FHED radio module and TravelHawk EPC simulator
* Huawei DBS3900
* Octasic Flexicell LTE-FDD NIB
srsENB Features
---------------
* Round Robin MAC scheduler with FAPI-like C++ API
* SR support
* Periodic and Aperiodic CQI feedback support
* Standard S1AP and GTP-U interfaces to the Core Network
* Tested up to 75 Mbps DL in SISO configuration with commercial UEs
srsENB has been tested and validated with the following handsets:
* LG Nexus 5
* LG Nexus 4
* Motorola Moto G4 plus
Hardware Hardware
======== --------
The library currently supports the Ettus Universal Hardware Driver (UHD) and the bladeRF driver. Thus, any hardware supported by UHD or bladeRF can be used. There is no sampling rate conversion, therefore the hardware should support 30.72 MHz clock in order to work correctly with LTE sampling frequencies and decode signals from live LTE base stations. The library currently supports the Ettus Universal Hardware Driver (UHD) and the bladeRF driver. Thus, any hardware supported by UHD or bladeRF can be used. There is no sampling rate conversion, therefore the hardware should support 30.72 MHz clock in order to work correctly with LTE sampling frequencies and decode signals from live LTE base stations.
@ -35,15 +65,28 @@ We have tested the following hardware:
* USRP B210 * USRP B210
* USRP X300 * USRP X300
* bladeRF * bladeRF
* limeSDR
Download & Install Instructions Build Instructions
================================= ------------------
* Mandatory requirements:
* Common:
* libfftw http://www.fftw.org/
* PolarSSL/mbedTLS https://tls.mbed.org
* srsUE:
* Boost: http://www.boost.org
* srsENB:
* Boost: http://www.boost.org
* lksctp: http://lksctp.sourceforge.net/
* Mandatory dependencies:
* libfftw
* Optional requirements: * Optional requirements:
* srsgui: for real-time plotting. Download it here: https://github.com/srslte/srsgui * srsgui: https://github.com/srslte/srsgui - for real-time plotting.
* VOLK: if the VOLK library and headers are detected, they will be used for accelerating some signal processing functions. * VOLK: https://github.com/gnuradio/volk - if the VOLK library and headers are detected, they will be used to accelerate some signal processing functions.
* RF front-end driver:
* UHD: https://github.com/EttusResearch/uhd
* BladeRF: https://github.com/Nuand/bladeRF
Download and build srsLTE: Download and build srsLTE:
``` ```
@ -55,64 +98,27 @@ cmake ../
make make
``` ```
The library can also be installed using the command ```sudo make install```. The software suite can also be installed using the command ```sudo make install```.
Running srsLTE Examples
========================
* SIB1 reception and UE measurement from commercial LTE networks:
```
lte/examples/pdsch_ue -f [frequency_in_Hz]
```
Where -f is the LTE channel frequency.
* eNodeB to UE Downlink PHY test
You will need two computers, each equipped with a USRP. At the transmitter side, run:
```
lte/examples/pdsch_enodeb -f [frequency_in_Hz] [-h for more commands]
```
At the receiver run:
```
lte/examples/pdsch_ue -r 1234 -f [frequency_in_Hz]
```
At the transmitter console, it is possible to change the Modulation and Coding Scheme (MCS) by typing a new number (between 0 and 28) and pressing Enter.
The output at the receiver should look something similar to the following video. In this example, we removed the transmitter and receiver antennas in the middle of the demonstration, showing how reception is still possible (despite with some erros).
https://www.dropbox.com/s/txh1nuzdb0igq5n/demo_pbch.ogv Execution Instructions
----------------------
![Screenshopt of the PBCH example output](pbch_capture.png "Screenshopt of the PBCH example output") The srsUE and srsENB applications include example configuration files. Execute the applications with root privileges to enable real-time thread priorities and to permit creation of virtual network interfaces.
* Video over Downlink PHY (eNodeB to UE) ### srsUE
The previous example sends random bits to the UE. It is possible to open a TCP socket and stream video over the LTE PHY DL wireless connection. At the transmitter side, run the following command:
Run the srsUE application as follows:
``` ```
lte/examples/pdsch_enodeb -f [frequency_in_Hz] -u 2000 [-h for more commands] sudo ./srsue ue.conf
``` ```
The argument -u 2000 will open port 2000 for listening for TCP connections. Set a high-order MCS, like 16 by typing 16 in the eNodeB console and pressing Enter. ### srsENB
As the srsLTE software suite does not include EPC functionality, a separate EPC is required to run srsENB. Run the application as follows:
``` ```
lte/examples/pdsch_ue -r 1234 -u 2001 -U 127.0.0.1 -f [frequency_in_Hz] sudo ./srsenb enb.conf
``` ```
The arguments -u 2001 -U 127.0.0.1 will forward the data that was injected at the eNodeB to address:port indicated by the argument. Once you have the system running, you can transmit some useful data, like a video stream. At the transmitter side, run:
```
avconv -f video4linux2 -i /dev/video0 -c:v mp4 -f mpegts tcp://127.0.0.1:2000
```
to stream the video captured from the webcam throught the local host port 2000. At the receiver, run:
```
avplay tcp://127.0.0.1:2001?listen -analyzeduration 100 -loglevel verbose
```
to watch the video.
Support Support
======== ========

@ -0,0 +1,75 @@
# Find the CUnit includes and library
#
# This module defines
# LIBCONFIG_INCLUDE_DIR, where to find cppunit include files, etc.
# LIBCONFIG_LIBRARIES, the libraries to link against to use CppUnit.
# LIBCONFIG_STATIC_LIBRARIY_PATH
# LIBCONFIG_FOUND, If false, do not try to use CppUnit.
# also defined, but not for general use are
# LIBCONFIG_LIBRARY, where to find the CUnit library.
#MESSAGE("Searching for libconfig library")
FIND_PATH(LIBCONFIG_INCLUDE_DIR libconfig.h
/usr/local/include
/usr/include
)
FIND_PATH(LIBCONFIGPP_INCLUDE_DIR libconfig.h++
/usr/local/include
/usr/include
)
FIND_LIBRARY(LIBCONFIG_LIBRARY config
/usr/local/lib
/usr/lib
)
FIND_LIBRARY(LIBCONFIGPP_LIBRARY config++
/usr/local/lib
/usr/lib
)
FIND_LIBRARY(LIBCONFIG_STATIC_LIBRARY "libconfig${CMAKE_STATIC_LIBRARY_SUFFIX}"
/usr/local/lib
/usr/lib
)
FIND_LIBRARY(LIBCONFIGPP_STATIC_LIBRARY "libconfig++${CMAKE_STATIC_LIBRARY_SUFFIX}"
/usr/local/lib
/usr/lib
)
IF(LIBCONFIG_INCLUDE_DIR)
IF(LIBCONFIG_LIBRARY)
SET(LIBCONFIG_FOUND TRUE)
SET(LIBCONFIG_LIBRARIES ${LIBCONFIG_LIBRARY})
SET(LIBCONFIG_STATIC_LIBRARY_PATH ${LIBCONFIG_STATIC_LIBRARY})
ENDIF(LIBCONFIG_LIBRARY)
ENDIF(LIBCONFIG_INCLUDE_DIR)
IF(LIBCONFIGPP_INCLUDE_DIR)
IF(LIBCONFIGPP_LIBRARY)
SET(LIBCONFIGPP_FOUND TRUE)
SET(LIBCONFIGPP_LIBRARIES ${LIBCONFIGPP_LIBRARY})
SET(LIBCONFIGPP_STATIC_LIBRARY_PATH ${LIBCONFIGPP_STATIC_LIBRARY})
ENDIF(LIBCONFIGPP_LIBRARY)
ENDIF(LIBCONFIGPP_INCLUDE_DIR)
IF (LIBCONFIGPP_FOUND)
IF (NOT LibConfig_FIND_QUIETLY)
MESSAGE(STATUS "Found LibConfig++: ${LIBCONFIGPP_LIBRARIES}" )
MESSAGE(STATUS "static LibConfig++ path: ${LIBCONFIGPP_STATIC_LIBRARY_PATH}")
MESSAGE(STATUS "Found LibConfig: ${LIBCONFIG_LIBRARIES}")
MESSAGE(STATUS "static LibConfig path: ${LIBCONFIG_STATIC_LIBRARY_PATH}")
ENDIF (NOT LibConfig_FIND_QUIETLY)
ELSE (LIBCONFIGPP_FOUND)
IF (LibConfig_FIND_REQUIRED)
MESSAGE(SEND_ERROR "Could NOT find LibConfig")
ENDIF (LibConfig_FIND_REQUIRED)
ENDIF (LIBCONFIGPP_FOUND)
MARK_AS_ADVANCED(LIBCONFIG_INCLUDE_DIR LIBCONFIG_LIBRARY LIBCONFIG_STATIC_LIBRARY)
MARK_AS_ADVANCED(LIBCONFIGPP_INCLUDE_DIR LIBCONFIGPP_LIBRARY LIBCONFIGPP_STATIC_LIBRARY)

@ -0,0 +1,28 @@
if(NOT LIMESDR_FOUND)
pkg_check_modules (LIMESDR_PKG LimeSuite)
find_path(LIMESDR_INCLUDE_DIRS
NAMES LimeSuite.h
PATHS ${LIMESDR_PKG_INCLUDE_DIRS}
/usr/include/lime
/usr/local/include/lime
)
find_library(LIMESDR_LIBRARIES
NAMES LimeSuite
PATHS ${LIMESDR_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
)
if(LIMESDR_INCLUDE_DIRS AND LIMESDR_LIBRARIES)
set(LIMESDR_FOUND TRUE CACHE INTERNAL "libLimeSuite found")
message(STATUS "Found libLimeSuite: ${LIMESDR_INCLUDE_DIRS}, ${LIMESDR_LIBRARIES}")
else(LIMESDR_INCLUDE_DIRS AND LIMESDR_LIBRARIES)
set(LIMESDR_FOUND FALSE CACHE INTERNAL "libLimeSuite found")
message(STATUS "libLimeSuite not found.")
endif(LIMESDR_INCLUDE_DIRS AND LIMESDR_LIBRARIES)
mark_as_advanced(LIMESDR_LIBRARIES LIMESDR_INCLUDE_DIRS)
endif(NOT LIMESDR_FOUND)

@ -5,23 +5,49 @@
# MKL_LIBRARIES - The libraries needed to use mkl # MKL_LIBRARIES - The libraries needed to use mkl
# MKL_DEFINITIONS - Compiler switches required for using mkl # MKL_DEFINITIONS - Compiler switches required for using mkl
find_path(MKL_INCLUDE_DIR find_path(MKL_INCLUDE_DIR
NAMES mkl.h NAMES mkl.h
HINTS $ENV{MKL_DIR}/include HINTS $ENV{MKL_DIR}/include
PATHS) PATHS)
find_library(MKL_LIBRARY find_path(MKL_FFTW_INCLUDE_DIR
NAMES fftw3.h
HINTS $ENV{MKL_DIR}/include/fftw
PATHS)
find_library(MKL_LIBRARIES
NAMES mkl_rt NAMES mkl_rt
HINTS $ENV{MKL_DIR}/lib/intel64 HINTS $ENV{MKL_DIR}/lib/intel64
PATHS) PATHS)
set(MKL_LIBRARIES ${MKL_LIBRARY} ) find_library(MKL_CORE
set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR} ) NAMES libmkl_core.a
HINTS $ENV{MKL_DIR}/lib/intel64
PATHS)
find_library(MKL_ILP
NAMES libmkl_intel_ilp64.a
HINTS $ENV{MKL_DIR}/lib/intel64
PATHS)
find_library(MKL_SEQ
NAMES libmkl_sequential.a
HINTS $ENV{MKL_DIR}/lib/intel64
PATHS)
set(MKL_STATIC_LIBRARIES -Wl,--start-group ${MKL_CORE} ${MKL_ILP} ${MKL_SEQ} -Wl,--end-group -lpthread -lm -ldl)
set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR} ${MKL_FFTW_INCLUDE_DIR})
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE # handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE
# if all listed variables are TRUE # if all listed variables are TRUE
find_package_handle_standard_args(mkl DEFAULT_MSG find_package_handle_standard_args(mkl DEFAULT_MSG
MKL_LIBRARY MKL_INCLUDE_DIR) MKL_LIBRARIES MKL_CORE MKL_ILP MKL_SEQ MKL_INCLUDE_DIRS)
if(MKL_FOUND)
MESSAGE(STATUS "Found MKL_INCLUDE_DIRS: ${MKL_INCLUDE_DIRS}" )
MESSAGE(STATUS "Found MKL_LIBRARIES: ${MKL_LIBRARIES}" )
MESSAGE(STATUS "Found MKL_STATIC_LIBRARIES: ${MKL_STATIC_LIBRARIES}" )
endif(MKL_FOUND)
mark_as_advanced(MKL_INCLUDE_DIR MKL_LIBRARY ) mark_as_advanced(MKL_INCLUDE_DIR MKL_FFTW_INCLUDE_DIR MKL_LIBRARIES MKL_CORE MKL_ILP MKL_SEQ)

@ -0,0 +1,40 @@
# - Try to find mbedtls
#
# Once done this will define
# MBEDTLS_FOUND - System has mbedtls
# MBEDTLS_INCLUDE_DIRS - The mbedtls include directories
# MBEDTLS_LIBRARIES - The mbedtls library
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_MBEDTLS mbedtls)
#find Mbedtls
FIND_PATH(
MBEDTLS_INCLUDE_DIRS
NAMES mbedtls/md.h
HINTS $ENV{MBEDTLS_DIR}/include
${PC_MBEDTLS_INCLUDEDIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
MBEDTLS_LIBRARIES
NAMES mbedcrypto
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 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)

@ -0,0 +1,39 @@
# - Try to find polarssl
#
# Once done this will define
# POLARSSL_FOUND - System has polarssl
# POLARSSL_INCLUDE_DIRS - The polarssl include directories
# POLARSSL_LIBRARIES - The polarssl library
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_POLARSSL polarssl)
FIND_PATH(
POLARSSL_INCLUDE_DIRS
NAMES polarssl/version.h
HINTS $ENV{POLARSSL_DIR}/include
${PC_POLARSSL_INCLUDEDIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
POLARSSL_LIBRARIES
NAMES polarssl
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 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)

@ -0,0 +1,38 @@
# - Try to find sctp
#
# Once done this will define
# SCTP_FOUND - System has mbedtls
# SCTP_INCLUDE_DIRS - The mbedtls include directories
# SCTP_LIBRARIES - The mbedtls library
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_SCTP sctp)
#find Mbedtls
FIND_PATH(
SCTP_INCLUDE_DIRS
NAMES netinet/sctp.h
HINTS ${PC_SCTP_INCLUDEDIR}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
SCTP_LIBRARIES
NAMES sctp
HINTS ${PC_SCTP_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib
${CMAKE_INSTALL_PREFIX}/lib64
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
message(STATUS "SCTP LIBRARIES: " ${SCTP_LIBRARIES})
message(STATUS "SCTP INCLUDE DIRS: " ${SCTP_INCLUDE_DIRS})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SCTP DEFAULT_MSG SCTP_LIBRARIES SCTP_INCLUDE_DIRS)
MARK_AS_ADVANCED(SCTP_LIBRARIES SCTP_INCLUDE_DIRS)

@ -1,11 +1,12 @@
if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|^i[3,9]86$") #if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|^i[3,9]86$")
return() # return()
endif() #endif()
include(CheckCSourceRuns) include(CheckCSourceRuns)
option(ENABLE_SSE "Enable compile-time SSE4.1 support." ON) option(ENABLE_SSE "Enable compile-time SSE4.1 support." ON)
option(ENABLE_AVX "Enable compile-time AVX support." ON) option(ENABLE_AVX "Enable compile-time AVX support." ON)
option(ENABLE_AVX2 "Enable compile-time AVX2 support." ON)
if (ENABLE_SSE) if (ENABLE_SSE)
# #
@ -39,11 +40,22 @@ if (ENABLE_SSE)
set(CMAKE_REQUIRED_FLAGS "-mavx") set(CMAKE_REQUIRED_FLAGS "-mavx")
check_c_source_runs(" check_c_source_runs("
#include <immintrin.h> #include <immintrin.h>
int main() int main()
{ {
__m256i a = _mm256_setzero_si256(); __m256 a, b, c;
return 0; 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_add_ps( a, b );
_mm256_storeu_ps( dst, c );
int i = 0;
for( i = 0; i < 8; i++ ){
if( ( src[i] + src[i] ) != dst[i] ){
return -1;
}
}
return 0;
}" }"
HAVE_AVX) HAVE_AVX)
endif() endif()
@ -52,7 +64,41 @@ if (ENABLE_SSE)
message(STATUS "AVX is enabled - target CPU must support it") message(STATUS "AVX is enabled - target CPU must support it")
endif() endif()
endif() endif()
if (ENABLE_AVX2)
#
# Check compiler for AVX intrinsics
#
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG )
set(CMAKE_REQUIRED_FLAGS "-mavx2")
check_c_source_runs("
#include <immintrin.h>
int main()
{
__m256i a, b, c;
const int src[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int dst[8];
a = _mm256_loadu_si256( (__m256i*)src );
b = _mm256_loadu_si256( (__m256i*)src );
c = _mm256_add_epi32( a, b );
_mm256_storeu_si256( (__m256i*)dst, c );
int i = 0;
for( i = 0; i < 8; i++ ){
if( ( src[i] + src[i] ) != dst[i] ){
return -1;
}
}
return 0;
}"
HAVE_AVX2)
endif()
if (HAVE_AVX2)
message(STATUS "AVX2 is enabled - target CPU must support it")
endif()
endif()
endif() endif()
mark_as_advanced(HAVE_SSE, HAVE_AVX) mark_as_advanced(HAVE_SSE, HAVE_AVX, HAVE_AVX2)

@ -0,0 +1,32 @@
message(STATUS "FINDING SOAPY.")
if(NOT SOAPYSDR_FOUND)
pkg_check_modules (SOAPYSDR_PKG SoapySDR)
find_path(SOAPYSDR_INCLUDE_DIRS
NAMES Device.h
PATHS ${SOAPYSDR_PKG_INCLUDE_DIRS}
/usr/include/SoapySDR
/usr/local/include/SoapySDR
)
find_library(SOAPYSDR_LIBRARIES
NAMES SoapySDR
PATHS ${LIMESDR_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
/usr/lib/arm-linux-gnueabihf
)
if(SOAPYSDR_INCLUDE_DIRS AND SOAPYSDR_LIBRARIES)
set(SOAPYSDR_FOUND TRUE CACHE INTERNAL "libSOAPYSDR found")
message(STATUS "Found libSOAPYSDR: ${SOAPYSDR_INCLUDE_DIRS}, ${SOAPYSDR_LIBRARIES}")
else(SOAPYSDR_INCLUDE_DIRS AND SOAPYSDR_LIBRARIES)
set(SOAPYSDR_FOUND FALSE CACHE INTERNAL "libSOAPYSDR found")
message(STATUS "libSOAPYSDR not found.")
endif(SOAPYSDR_INCLUDE_DIRS AND SOAPYSDR_LIBRARIES)
mark_as_advanced(SOAPYSDR_LIBRARIES SOAPYSDR_INCLUDE_DIRS)
endif(NOT SOAPYSDR_FOUND)

@ -54,7 +54,7 @@ IF(VOLK_FOUND)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_add_32f HAVE_VOLK_ADD_FLOAT_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_add_32f HAVE_VOLK_ADD_FLOAT_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_x2_square_dist_32f HAVE_VOLK_SQUARE_DIST_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_x2_square_dist_32f HAVE_VOLK_SQUARE_DIST_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_index_max_16u HAVE_VOLK_MAX_ABS_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_index_max_16u HAVE_VOLK_MAX_ABS_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_multiply_32f HAVE_VOLK_MULT_REAL2_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_multiply_32f HAVE_VOLK_MULT_REAL2_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_16i_max_star_16i HAVE_VOLK_MAX_STAR_S_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_16i_max_star_16i HAVE_VOLK_MAX_STAR_S_FUNCTION)
@ -63,6 +63,12 @@ IF(VOLK_FOUND)
SET(VOLK_DEFINITIONS "HAVE_VOLK") SET(VOLK_DEFINITIONS "HAVE_VOLK")
IF(${HAVE_VOLK_CONVERT_IF_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_IF_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_MULT_REAL2_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_MULT_REAL2_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_CONVERT_CI_FUNCTION}) IF(${HAVE_VOLK_CONVERT_CI_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_CI_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_CI_FUNCTION")
ENDIF() ENDIF()
@ -99,8 +105,8 @@ IF(VOLK_FOUND)
IF(${HAVE_VOLK_MULT2_CONJ_FUNCTION}) IF(${HAVE_VOLK_MULT2_CONJ_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_MULT2_CONJ_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_MULT2_CONJ_FUNCTION")
ENDIF() ENDIF()
IF(${HAVE_VOLK_DEINTERLEAVE_FUNCTION}) IF(${HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION")
ENDIF() ENDIF()
IF(${HAVE_VOLK_CONVERT_FI_FUNCTION}) IF(${HAVE_VOLK_CONVERT_FI_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_FI_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_FI_FUNCTION")
@ -135,6 +141,9 @@ IF(VOLK_FOUND)
IF(${HAVE_VOLK_DOTPROD_FC_FUNCTION}) IF(${HAVE_VOLK_DOTPROD_FC_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_FC_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_FC_FUNCTION")
ENDIF() ENDIF()
IF(${HAVE_VOLK_DOTPROD_CFC_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_CFC_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_DOTPROD_F_FUNCTION}) IF(${HAVE_VOLK_DOTPROD_F_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_F_FUNCTION") SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_F_FUNCTION")
ENDIF() ENDIF()

@ -18,7 +18,7 @@
# and at http://www.gnu.org/licenses/. # and at http://www.gnu.org/licenses/.
# #
SET(SRSLTE_VERSION_MAJOR 001) SET(SRSLTE_VERSION_MAJOR 002)
SET(SRSLTE_VERSION_MINOR 004) SET(SRSLTE_VERSION_MINOR 000)
SET(SRSLTE_VERSION_PATCH 000) SET(SRSLTE_VERSION_PATCH 000)
SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}")

@ -0,0 +1,34 @@
#
# Copyright 2013-2017 Software Radio Systems Limited
#
# This file is part of srsLTE
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(src)
add_subdirectory(include)
add_subdirectory(examples)
add_subdirectory(test)
########################################################################
# Install library headers
########################################################################
INSTALL( DIRECTORY include/
DESTINATION "${INCLUDE_DIR}"
FILES_MATCHING PATTERN "*.h" )

@ -1,7 +1,7 @@
# #
# Copyright 2013-2015 Software Radio Systems Limited # Copyright 2013-2017 Software Radio Systems Limited
# #
# This file is part of the srsLTE library. # This file is part of srsLTE
# #
# srsLTE is free software: you can redistribute it and/or modify # srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -24,22 +24,26 @@
################################################################# #################################################################
add_executable(synch_file synch_file.c) add_executable(synch_file synch_file.c)
target_link_libraries(synch_file srslte) target_link_libraries(synch_file srslte_phy)
################################################################# #################################################################
# These can be compiled without UHD or graphics support # These can be compiled without UHD or graphics support
################################################################# #################################################################
add_executable(pdsch_ue pdsch_ue.c)
target_link_libraries(pdsch_ue srslte pthread)
add_executable(pdsch_enodeb pdsch_enodeb.c)
target_link_libraries(pdsch_enodeb srslte pthread)
if(RF_FOUND) if(RF_FOUND)
add_executable(pdsch_ue pdsch_ue.c)
target_link_libraries(pdsch_ue srslte_phy srslte_rf pthread)
add_executable(pdsch_enodeb pdsch_enodeb.c)
target_link_libraries(pdsch_enodeb srslte_phy srslte_rf pthread)
else(RF_FOUND) else(RF_FOUND)
add_definitions(-DDISABLE_RF) add_definitions(-DDISABLE_RF)
add_executable(pdsch_ue pdsch_ue.c)
target_link_libraries(pdsch_ue srslte_phy pthread)
add_executable(pdsch_enodeb pdsch_enodeb.c)
target_link_libraries(pdsch_enodeb srslte_phy pthread)
endif(RF_FOUND) endif(RF_FOUND)
find_package(SRSGUI) find_package(SRSGUI)
@ -59,19 +63,19 @@ endif(SRSGUI_FOUND)
if(RF_FOUND) if(RF_FOUND)
add_executable(cell_search cell_search.c) add_executable(cell_search cell_search.c)
target_link_libraries(cell_search srslte) target_link_libraries(cell_search srslte_phy srslte_rf)
add_executable(cell_measurement cell_measurement.c) add_executable(cell_measurement cell_measurement.c)
target_link_libraries(cell_measurement srslte) target_link_libraries(cell_measurement srslte_phy srslte_rf)
add_executable(usrp_capture usrp_capture.c) add_executable(usrp_capture usrp_capture.c)
target_link_libraries(usrp_capture srslte) target_link_libraries(usrp_capture srslte_phy srslte_rf)
add_executable(usrp_capture_sync usrp_capture_sync.c) add_executable(usrp_capture_sync usrp_capture_sync.c)
target_link_libraries(usrp_capture_sync srslte) target_link_libraries(usrp_capture_sync srslte_phy srslte_rf)
add_executable(usrp_txrx usrp_txrx.c) add_executable(usrp_txrx usrp_txrx.c)
target_link_libraries(usrp_txrx srslte) target_link_libraries(usrp_txrx srslte_phy srslte_rf)
message(STATUS " examples will be installed.") message(STATUS " examples will be installed.")
@ -79,6 +83,4 @@ else(RF_FOUND)
message(STATUS " examples will NOT BE INSTALLED.") message(STATUS " examples will NOT BE INSTALLED.")
endif(RF_FOUND) endif(RF_FOUND)
# Add subdirectories
add_subdirectory(tutorial_examples)

@ -38,8 +38,8 @@
#define ENABLE_AGC_DEFAULT #define ENABLE_AGC_DEFAULT
#include "srslte/srslte.h" #include "srslte/srslte.h"
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
#include "srslte/rf/rf_utils.h" #include "srslte/phy/rf/rf_utils.h"
cell_search_cfg_t cell_detect_config = { cell_search_cfg_t cell_detect_config = {
SRSLTE_DEFAULT_MAX_FRAMES_PBCH, SRSLTE_DEFAULT_MAX_FRAMES_PBCH,
@ -129,9 +129,10 @@ void sig_int_handler(int signo)
} }
} }
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *q) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *q) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv(h, data, nsamples, 1);
return srslte_rf_recv(h, data[0], nsamples, 1);
} }
enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state;
@ -141,7 +142,7 @@ enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state;
int main(int argc, char **argv) { int main(int argc, char **argv) {
int ret; int ret;
cf_t *sf_buffer; cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL, NULL};
prog_args_t prog_args; prog_args_t prog_args;
srslte_cell_t cell; srslte_cell_t cell;
int64_t sf_cnt; int64_t sf_cnt;
@ -180,6 +181,8 @@ int main(int argc, char **argv) {
} }
srslte_rf_set_rx_gain(&rf, 50); srslte_rf_set_rx_gain(&rf, 50);
} }
sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
sigset_t sigset; sigset_t sigset;
sigemptyset(&sigset); sigemptyset(&sigset);
@ -198,7 +201,7 @@ int main(int argc, char **argv) {
uint32_t ntrial=0; uint32_t ntrial=0;
do { do {
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); ret = rf_search_and_decode_mib(&rf, 1, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error searching for cell\n"); fprintf(stderr, "Error searching for cell\n");
exit(-1); exit(-1);
@ -234,11 +237,11 @@ int main(int argc, char **argv) {
srslte_rf_stop_rx_stream(&rf); srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf); srslte_rf_flush_buffer(&rf);
if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
return -1; return -1;
} }
if (srslte_ue_dl_init(&ue_dl, cell)) { if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) {
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
return -1; return -1;
} }
@ -280,7 +283,7 @@ int main(int argc, char **argv) {
/* Main loop */ /* Main loop */
while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) {
ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
} }
@ -292,7 +295,7 @@ int main(int argc, char **argv) {
case DECODE_MIB: case DECODE_MIB:
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
srslte_pbch_decode_reset(&ue_mib.pbch); srslte_pbch_decode_reset(&ue_mib.pbch);
n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n"); fprintf(stderr, "Error decoding UE MIB\n");
return -1; return -1;
@ -307,7 +310,7 @@ int main(int argc, char **argv) {
case DECODE_SIB: case DECODE_SIB:
/* We are looking for SI Blocks, search only in appropiate places */ /* We are looking for SI Blocks, search only in appropiate places */
if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); n = srslte_ue_dl_decode_multi(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
return -1; return -1;
@ -329,11 +332,11 @@ int main(int argc, char **argv) {
if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
/* Run FFT for all subframe data */ /* Run FFT for all subframe data */
srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols); srslte_ofdm_rx_sf(&fft, sf_buffer[0], sf_symbols);
srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync));
rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer,SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05);
rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05); rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05);
rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05); rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05);
rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05); rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05);
@ -345,7 +348,7 @@ int main(int argc, char **argv) {
if ((nframes%100) == 0 || rx_gain_offset == 0) { if ((nframes%100) == 0 || rx_gain_offset == 0) {
if (srslte_rf_has_rssi(&rf)) { if (srslte_rf_has_rssi(&rf)) {
rx_gain_offset = 10*log10(rssi)-srslte_rf_get_rssi(&rf); rx_gain_offset = 10*log10(rssi*1000)-srslte_rf_get_rssi(&rf);
} else { } else {
rx_gain_offset = srslte_rf_get_rx_gain(&rf); rx_gain_offset = srslte_rf_get_rx_gain(&rf);
} }
@ -354,10 +357,10 @@ int main(int argc, char **argv) {
// Plot and Printf // Plot and Printf
if ((nframes%10) == 0) { if ((nframes%10) == 0) {
printf("CFO: %+8.4f kHz, SFO: %+8.4f kHz, RSSI: %5.1f dBm, RSSI/ref-symbol: %+5.1f dBm, " printf("CFO: %+8.4f kHz, SFO: %+8.4f Hz, RSSI: %5.1f dBm, RSSI/ref-symbol: %+5.1f dBm, "
"RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r", "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r",
srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync), srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync),
10*log10(rssi*1000) - rx_gain_offset, 10*log10(rssi*1000) - rx_gain_offset,
10*log10(rssi_utra*1000)- rx_gain_offset, 10*log10(rssi_utra*1000)- rx_gain_offset,
10*log10(rsrp*1000) - rx_gain_offset, 10*log10(rsrp*1000) - rx_gain_offset,
10*log10(rsrq), 10*log10(snr)); 10*log10(rsrq), 10*log10(snr));

@ -37,11 +37,11 @@
#include "srslte/srslte.h" #include "srslte/srslte.h"
#include "srslte/rf/rf_utils.h" #include "srslte/phy/rf/rf_utils.h"
#ifndef DISABLE_RF #ifndef DISABLE_RF
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
#endif #endif
#define MHZ 1000000 #define MHZ 1000000
@ -120,9 +120,13 @@ void parse_args(int argc, char **argv) {
} }
} }
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv((srslte_rf_t*) h, data, nsamples, 1); void *ptr[SRSLTE_MAX_PORTS];
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
ptr[i] = data[i];
}
return srslte_rf_recv_with_time_multi((srslte_rf_t*) h, ptr, nsamples, 1, NULL, NULL);
} }
bool go_exit = false; bool go_exit = false;
@ -200,7 +204,7 @@ int main(int argc, char **argv) {
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, (void*) &rf)) { 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"); fprintf(stderr, "Error initiating UE cell detect\n");
exit(-1); exit(-1);
} }
@ -228,7 +232,7 @@ int main(int argc, char **argv) {
srslte_cell_t cell; srslte_cell_t cell;
cell.id = found_cells[i].cell_id; cell.id = found_cells[i].cell_id;
cell.cp = found_cells[i].cp; cell.cp = found_cells[i].cp;
int ret = rf_mib_decoder(&rf, &cell_detect_config, &cell, NULL); int ret = rf_mib_decoder(&rf, 1, &cell_detect_config, &cell, NULL);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error decoding MIB\n"); fprintf(stderr, "Error decoding MIB\n");
exit(-1); exit(-1);

@ -41,7 +41,7 @@
#ifndef DISABLE_RF #ifndef DISABLE_RF
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
srslte_rf_t rf; srslte_rf_t rf;
#else #else
#warning Compiling pdsch_ue with no RF support #warning Compiling pdsch_ue with no RF support
@ -57,7 +57,6 @@ char *output_file_name = NULL;
srslte_cell_t cell = { srslte_cell_t cell = {
25, // nof_prb 25, // nof_prb
1, // nof_ports 1, // nof_ports
0, // bw idx
0, // cell_id 0, // cell_id
SRSLTE_CP_NORM, // cyclic prefix SRSLTE_CP_NORM, // cyclic prefix
SRSLTE_PHICH_R_1, // PHICH resources SRSLTE_PHICH_R_1, // PHICH resources
@ -341,6 +340,7 @@ int update_radl() {
ra_dl.rv_idx = 0; ra_dl.rv_idx = 0;
ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0; ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask(); ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask();
ra_dl.tb_en[0] = 1;
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
srslte_ra_dl_grant_t dummy_grant; srslte_ra_dl_grant_t dummy_grant;
@ -609,7 +609,7 @@ int main(int argc, char **argv) {
/* Encode PDCCH */ /* Encode PDCCH */
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L); INFO("Putting DCI to location: n=%d, L=%d\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, false); 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)) { 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"); fprintf(stderr, "Error encoding DCI message\n");
exit(-1); exit(-1);
@ -624,7 +624,7 @@ int main(int argc, char **argv) {
} }
/* Encode PDSCH */ /* Encode PDSCH */
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, sf_symbols)) { if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, UE_CRNTI, sf_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n"); fprintf(stderr, "Error encoding PDSCH\n");
exit(-1); exit(-1);
} }

@ -42,8 +42,8 @@
#define ENABLE_AGC_DEFAULT #define ENABLE_AGC_DEFAULT
#ifndef DISABLE_RF #ifndef DISABLE_RF
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
#include "srslte/rf/rf_utils.h" #include "srslte/phy/rf/rf_utils.h"
cell_search_cfg_t cell_detect_config = { cell_search_cfg_t cell_detect_config = {
SRSLTE_DEFAULT_MAX_FRAMES_PBCH, SRSLTE_DEFAULT_MAX_FRAMES_PBCH,
@ -76,6 +76,7 @@ bool plot_track = true;
***********************************************************************/ ***********************************************************************/
typedef struct { typedef struct {
int nof_subframes; int nof_subframes;
int cpu_affinity;
bool disable_plots; bool disable_plots;
bool disable_plots_except_constellation; bool disable_plots_except_constellation;
bool disable_cfo; bool disable_cfo;
@ -89,12 +90,14 @@ typedef struct {
uint32_t file_nof_ports; uint32_t file_nof_ports;
uint32_t file_cell_id; uint32_t file_cell_id;
char *rf_args; char *rf_args;
uint32_t rf_nof_rx_ant;
double rf_freq; double rf_freq;
float rf_gain; float rf_gain;
int net_port; int net_port;
char *net_address; char *net_address;
int net_port_signal; int net_port_signal;
char *net_address_signal; char *net_address_signal;
int decimate;
}prog_args_t; }prog_args_t;
void args_default(prog_args_t *args) { void args_default(prog_args_t *args) {
@ -113,6 +116,7 @@ void args_default(prog_args_t *args) {
args->file_offset_freq = 0; args->file_offset_freq = 0;
args->rf_args = ""; args->rf_args = "";
args->rf_freq = -1.0; args->rf_freq = -1.0;
args->rf_nof_rx_ant = 1;
#ifdef ENABLE_AGC_DEFAULT #ifdef ENABLE_AGC_DEFAULT
args->rf_gain = -1.0; args->rf_gain = -1.0;
#else #else
@ -122,12 +126,15 @@ void args_default(prog_args_t *args) {
args->net_address = "127.0.0.1"; args->net_address = "127.0.0.1";
args->net_port_signal = -1; args->net_port_signal = -1;
args->net_address_signal = "127.0.0.1"; args->net_address_signal = "127.0.0.1";
args->decimate = 0;
args->cpu_affinity = -1;
} }
void usage(prog_args_t *args, char *prog) { 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 [agpPoOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
#ifndef DISABLE_RF #ifndef DISABLE_RF
printf("\t-a RF args [Default %s]\n", args->rf_args); 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);
#ifdef ENABLE_AGC_DEFAULT #ifdef ENABLE_AGC_DEFAULT
printf("\t-g RF fix RX gain [Default AGC]\n"); printf("\t-g RF fix RX gain [Default AGC]\n");
#else #else
@ -152,6 +159,7 @@ void usage(prog_args_t *args, char *prog) {
#else #else
printf("\t plots are disabled. Graphics library not available\n"); printf("\t plots are disabled. Graphics library not available\n");
#endif #endif
printf("\t-y set the cpu affinity mask [Default %d] \n ",args->cpu_affinity);
printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes); printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes);
printf("\t-s remote UDP port to send input signal (-1 does nothing with it) [Default %d]\n", args->net_port_signal); printf("\t-s remote UDP port to send input signal (-1 does nothing with it) [Default %d]\n", args->net_port_signal);
printf("\t-S remote UDP address to send input signal [Default %s]\n", args->net_address_signal); printf("\t-S remote UDP address to send input signal [Default %s]\n", args->net_address_signal);
@ -163,7 +171,7 @@ void usage(prog_args_t *args, char *prog) {
void parse_args(prog_args_t *args, int argc, char **argv) { void parse_args(prog_args_t *args, int argc, char **argv) {
int opt; int opt;
args_default(args); args_default(args);
while ((opt = getopt(argc, argv, "aoglipPcOCtdDnvrfuUsS")) != -1) { while ((opt = getopt(argc, argv, "aAoglipPcOCtdDnvrfuUsSZy")) != -1) {
switch (opt) { switch (opt) {
case 'i': case 'i':
args->input_file_name = argv[optind]; args->input_file_name = argv[optind];
@ -186,6 +194,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'a': case 'a':
args->rf_args = argv[optind]; args->rf_args = argv[optind];
break; break;
case 'A':
args->rf_nof_rx_ant = atoi(argv[optind]);
break;
case 'g': case 'g':
args->rf_gain = atof(argv[optind]); args->rf_gain = atof(argv[optind]);
break; break;
@ -228,6 +239,12 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'v': case 'v':
srslte_verbose++; srslte_verbose++;
break; break;
case 'Z':
args->decimate = atoi(argv[optind]);
break;
case 'y':
args->cpu_affinity = atoi(argv[optind]);
break;
default: default:
usage(args, argv[0]); usage(args, argv[0]);
exit(-1); exit(-1);
@ -252,10 +269,16 @@ void sig_int_handler(int signo)
} }
} }
cf_t *sf_buffer[2] = {NULL, NULL};
#ifndef DISABLE_RF #ifndef DISABLE_RF
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv(h, data, nsamples, 1); void *ptr[SRSLTE_MAX_PORTS];
for (int i=0;i<SRSLTE_MAX_PORTS;i++) {
ptr[i] = data[i];
}
return srslte_rf_recv_with_time_multi(h, ptr, nsamples, true, NULL, NULL);
} }
double srslte_rf_set_rx_gain_th_wrapper_(void *h, double f) { double srslte_rf_set_rx_gain_th_wrapper_(void *h, double f) {
@ -273,11 +296,11 @@ srslte_ue_sync_t ue_sync;
prog_args_t prog_args; prog_args_t prog_args;
uint32_t sfn = 0; // system frame number uint32_t sfn = 0; // system frame number
cf_t *sf_buffer = NULL;
srslte_netsink_t net_sink, net_sink_signal; srslte_netsink_t net_sink, net_sink_signal;
int main(int argc, char **argv) { int main(int argc, char **argv) {
int ret; int ret;
int decimate = 1;
srslte_cell_t cell; srslte_cell_t cell;
int64_t sf_cnt; int64_t sf_cnt;
srslte_ue_mib_t ue_mib; srslte_ue_mib_t ue_mib;
@ -291,7 +314,25 @@ int main(int argc, char **argv) {
float cfo = 0; float cfo = 0;
parse_args(&prog_args, argc, argv); parse_args(&prog_args, argc, argv);
if(prog_args.cpu_affinity > -1) {
cpu_set_t cpuset;
pthread_t thread;
thread = pthread_self();
for(int i = 0; i < 8;i++){
if(((prog_args.cpu_affinity >> i) & 0x01) == 1){
printf("Setting pdsch_ue with affinity to core %d\n", i);
CPU_SET((size_t) i , &cpuset);
}
if(pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset)){
fprintf(stderr, "Error setting main thread affinity to %d \n", prog_args.cpu_affinity);
exit(-1);
}
}
}
if (prog_args.net_port > 0) { if (prog_args.net_port > 0) {
if (srslte_netsink_init(&net_sink, prog_args.net_address, prog_args.net_port, SRSLTE_NETSINK_TCP)) { if (srslte_netsink_init(&net_sink, prog_args.net_address, prog_args.net_port, SRSLTE_NETSINK_TCP)) {
fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address, prog_args.net_port); fprintf(stderr, "Error initiating UDP socket to %s:%d\n", prog_args.net_address, prog_args.net_port);
@ -311,8 +352,8 @@ int main(int argc, char **argv) {
#ifndef DISABLE_RF #ifndef DISABLE_RF
if (!prog_args.input_file_name) { if (!prog_args.input_file_name) {
printf("Opening RF device...\n"); printf("Opening RF device with %d RX antennas...\n", prog_args.rf_nof_rx_ant);
if (srslte_rf_open(&rf, prog_args.rf_args)) { if (srslte_rf_open_multi(&rf, prog_args.rf_args, prog_args.rf_nof_rx_ant)) {
fprintf(stderr, "Error opening rf\n"); fprintf(stderr, "Error opening rf\n");
exit(-1); exit(-1);
} }
@ -344,7 +385,7 @@ int main(int argc, char **argv) {
uint32_t ntrial=0; uint32_t ntrial=0;
do { do {
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); ret = rf_search_and_decode_mib(&rf, prog_args.rf_nof_rx_ant, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error searching for cell\n"); fprintf(stderr, "Error searching for cell\n");
exit(-1); exit(-1);
@ -354,8 +395,13 @@ int main(int argc, char **argv) {
} while (ret == 0 && !go_exit); } while (ret == 0 && !go_exit);
if (go_exit) { if (go_exit) {
srslte_rf_close(&rf);
exit(0); exit(0);
} }
srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf);
/* set sampling frequency */ /* set sampling frequency */
int srate = srslte_sampling_freq_hz(cell.nof_prb); int srate = srslte_sampling_freq_hz(cell.nof_prb);
if (srate != -1) { if (srate != -1) {
@ -376,8 +422,6 @@ int main(int argc, char **argv) {
} }
INFO("Stopping RF and flushing buffer...\r",0); INFO("Stopping RF and flushing buffer...\r",0);
srslte_rf_stop_rx_stream(&rf);
srslte_rf_flush_buffer(&rf);
} }
#endif #endif
@ -399,7 +443,19 @@ int main(int argc, char **argv) {
} else { } else {
#ifndef DISABLE_RF #ifndef DISABLE_RF
if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { if(prog_args.decimate)
{
if(prog_args.decimate > 4 || prog_args.decimate < 0)
{
printf("Invalid decimation factor, setting to 1 \n");
}
else
{
decimate = prog_args.decimate;
//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)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
exit(-1); exit(-1);
} }
@ -411,11 +467,15 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_ue_dl_init(&ue_dl, cell)) { // This is the User RNTI if (srslte_ue_dl_init_multi(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI
fprintf(stderr, "Error initiating UE downlink processing module\n"); fprintf(stderr, "Error initiating UE downlink processing module\n");
exit(-1); exit(-1);
} }
for (int i=0;i<prog_args.rf_nof_rx_ant;i++) {
sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
/* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ /* 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); srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);
@ -462,7 +522,7 @@ int main(int argc, char **argv) {
/* Main loop */ /* Main loop */
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
} }
@ -477,7 +537,7 @@ int main(int argc, char **argv) {
switch (state) { switch (state) {
case DECODE_MIB: case DECODE_MIB:
if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {
n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error decoding UE MIB\n"); fprintf(stderr, "Error decoding UE MIB\n");
exit(-1); exit(-1);
@ -503,10 +563,10 @@ int main(int argc, char **argv) {
} }
if (decode_pdsch) { if (decode_pdsch) {
INFO("Attempting DL decode SFN=%d\n", sfn); INFO("Attempting DL decode SFN=%d\n", sfn);
n = srslte_ue_dl_decode(&ue_dl, n = srslte_ue_dl_decode_multi(&ue_dl,
&sf_buffer[prog_args.time_offset], sf_buffer,
data, data,
sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); sfn*10+srslte_ue_sync_get_sfidx(&ue_sync));
if (n < 0) { if (n < 0) {
// fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);

@ -36,8 +36,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "srslte/srslte.h" #include "srslte/srslte.h"
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
#include "srslte/io/filesink.h" #include "srslte/phy/io/filesink.h"
static bool keep_running = true; static bool keep_running = true;
char *output_file_name; char *output_file_name;

@ -36,7 +36,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "srslte/srslte.h" #include "srslte/srslte.h"
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
static bool keep_running = true; static bool keep_running = true;
char *output_file_name = NULL; char *output_file_name = NULL;
@ -98,13 +98,13 @@ void parse_args(int argc, char **argv) {
} }
} }
int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples); DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return srslte_rf_recv(h, data, nsamples, 1); return srslte_rf_recv(h, data[0], nsamples, 1);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
cf_t *buffer; cf_t *buffer[SRSLTE_MAX_PORTS] = {NULL, NULL};
int n; int n;
srslte_rf_t rf; srslte_rf_t rf;
srslte_filesink_t sink; srslte_filesink_t sink;
@ -124,6 +124,8 @@ int main(int argc, char **argv) {
} }
srslte_rf_set_master_clock_rate(&rf, 30.72e6); srslte_rf_set_master_clock_rate(&rf, 30.72e6);
buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100));
sigset_t sigset; sigset_t sigset;
sigemptyset(&sigset); sigemptyset(&sigset);
sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGINT);
@ -156,7 +158,7 @@ int main(int argc, char **argv) {
cell.nof_prb = nof_prb; cell.nof_prb = nof_prb;
cell.nof_ports = 1; cell.nof_ports = 1;
if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n"); fprintf(stderr, "Error initiating ue_sync\n");
exit(-1); exit(-1);
} }
@ -167,7 +169,7 @@ int main(int argc, char **argv) {
while((subframe_count < nof_subframes || nof_subframes == -1) while((subframe_count < nof_subframes || nof_subframes == -1)
&& !stop_capture) && !stop_capture)
{ {
n = srslte_ue_sync_get_buffer(&ue_sync, &buffer); n = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer);
if (n < 0) { if (n < 0) {
fprintf(stderr, "Error receiving samples\n"); fprintf(stderr, "Error receiving samples\n");
exit(-1); exit(-1);
@ -179,7 +181,7 @@ int main(int argc, char **argv) {
} }
} else { } else {
printf("Writing to file %6d subframes...\r", subframe_count); printf("Writing to file %6d subframes...\r", subframe_count);
srslte_filesink_write(&sink, buffer, SRSLTE_SF_LEN_PRB(nof_prb)); srslte_filesink_write(&sink, buffer[0], SRSLTE_SF_LEN_PRB(nof_prb));
subframe_count++; subframe_count++;
} }
} }

@ -33,7 +33,7 @@
#include <time.h> #include <time.h>
#include <complex.h> #include <complex.h>
#include "srslte/rf/rf.h" #include "srslte/phy/rf/rf.h"
#include "srslte/srslte.h" #include "srslte/srslte.h"
uint32_t nof_prb = 25; uint32_t nof_prb = 25;

@ -1,7 +1,7 @@
# #
# Copyright 2013-2015 Software Radio Systems Limited # Copyright 2013-2017 Software Radio Systems Limited
# #
# This file is part of the srsLTE library. # This file is part of srsLTE
# #
# srsLTE is free software: you can redistribute it and/or modify # srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

@ -1,7 +1,7 @@
# #
# Copyright 2013-2015 Software Radio Systems Limited # Copyright 2013-2017 Software Radio Systems Limited
# #
# This file is part of the srsLTE library. # This file is part of srsLTE
# #
# srsLTE is free software: you can redistribute it and/or modify # srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

@ -0,0 +1,247 @@
/*******************************************************************************
Copyright 2012-2014 Ben Wojtowicz
This program 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.
This program 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.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************
File: liblte_common.h
Description: Contains all the common definitions for the LTE library.
Revision History
---------- ------------- --------------------------------------------
02/26/2012 Ben Wojtowicz Created file.
07/21/2013 Ben Wojtowicz Added a common message structure.
06/15/2014 Ben Wojtowicz Split LIBLTE_MSG_STRUCT into bit and byte
aligned messages.
08/03/2014 Ben Wojtowicz Commonized value_2_bits and bits_2_value.
11/29/2014 Ben Wojtowicz Added liblte prefix to value_2_bits and
bits_2_value.
*******************************************************************************/
#ifndef __LIBLTE_COMMON_H__
#define __LIBLTE_COMMON_H__
/*******************************************************************************
INCLUDES
*******************************************************************************/
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
/*******************************************************************************
DEFINES
*******************************************************************************/
// FIXME: This was chosen arbitrarily
#define LIBLTE_ASN1_OID_MAXSUBIDS 128
#define LIBLTE_MAX_MSG_SIZE_BITS 102048
#define LIBLTE_MAX_MSG_SIZE_BYTES 12756
#define LIBLTE_MSG_HEADER_OFFSET 1024
/*******************************************************************************
TYPEDEFS
*******************************************************************************/
typedef int8_t int8;
typedef uint8_t uint8;
typedef int16_t int16;
typedef uint16_t uint16;
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
typedef enum{
LIBLTE_SUCCESS = 0,
LIBLTE_ERROR_INVALID_INPUTS,
LIBLTE_ERROR_ENCODE_FAIL,
LIBLTE_ERROR_DECODE_FAIL,
LIBLTE_ERROR_INVALID_CRC,
LIBLTE_ERROR_N_ITEMS
}LIBLTE_ERROR_ENUM;
static const char liblte_error_text[LIBLTE_ERROR_N_ITEMS][64] = {
"Invalid inputs",
"Encode failure",
"Decode failure",
};
typedef void* LIBLTE_ASN1_OPEN_TYPE_STRUCT;
typedef struct {
uint32_t numids; // number of subidentifiers
uint32_t subid[LIBLTE_ASN1_OID_MAXSUBIDS]; // subidentifier values
} LIBLTE_ASN1_OID_STRUCT;
typedef struct{
bool data_valid;
bool data;
}LIBLTE_BOOL_MSG_STRUCT;
typedef struct{
uint32 N_bits;
uint8 msg[LIBLTE_MAX_MSG_SIZE_BITS];
}LIBLTE_SIMPLE_BIT_MSG_STRUCT;
typedef struct{
uint32 N_bytes;
uint8 msg[LIBLTE_MAX_MSG_SIZE_BYTES];
}LIBLTE_SIMPLE_BYTE_MSG_STRUCT;
struct LIBLTE_BYTE_MSG_STRUCT{
uint32 N_bytes;
uint8 buffer[LIBLTE_MAX_MSG_SIZE_BYTES];
uint8 *msg;
LIBLTE_BYTE_MSG_STRUCT():N_bytes(0)
{
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
}
LIBLTE_BYTE_MSG_STRUCT(const LIBLTE_BYTE_MSG_STRUCT& buf)
{
N_bytes = buf.N_bytes;
memcpy(msg, buf.msg, N_bytes);
}
LIBLTE_BYTE_MSG_STRUCT & operator= (const LIBLTE_BYTE_MSG_STRUCT & buf)
{
// avoid self assignment
if (&buf == this)
return *this;
N_bytes = buf.N_bytes;
memcpy(msg, buf.msg, N_bytes);
return *this;
}
uint32 get_headroom()
{
return msg-buffer;
}
void reset()
{
N_bytes = 0;
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
}
};
struct LIBLTE_BIT_MSG_STRUCT{
uint32 N_bits;
uint8 buffer[LIBLTE_MAX_MSG_SIZE_BITS];
uint8 *msg;
LIBLTE_BIT_MSG_STRUCT():N_bits(0)
{
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
while( (uint64_t)(msg) % 8 > 0) {
msg++;
}
}
LIBLTE_BIT_MSG_STRUCT(const LIBLTE_BIT_MSG_STRUCT& buf){
N_bits = buf.N_bits;
memcpy(msg, buf.msg, N_bits);
}
LIBLTE_BIT_MSG_STRUCT & operator= (const LIBLTE_BIT_MSG_STRUCT & buf){
// avoid self assignment
if (&buf == this)
return *this;
N_bits = buf.N_bits;
memcpy(msg, buf.msg, N_bits);
return *this;
}
uint32 get_headroom()
{
return msg-buffer;
}
void reset()
{
N_bits = 0;
msg = &buffer[LIBLTE_MSG_HEADER_OFFSET];
while( (uint64_t)(msg) % 8 > 0) {
msg++;
}
}
};
/*******************************************************************************
DECLARATIONS
*******************************************************************************/
/*********************************************************************
Name: liblte_value_2_bits
Description: Converts a value to a bit string
*********************************************************************/
void liblte_value_2_bits(uint32 value,
uint8 **bits,
uint32 N_bits);
/*********************************************************************
Name: liblte_bits_2_value
Description: Converts a bit string to a value
*********************************************************************/
uint32 liblte_bits_2_value(uint8 **bits,
uint32 N_bits);
/*********************************************************************
Name: liblte_pack
Description: Pack a bit array into a byte array
*********************************************************************/
void liblte_pack(LIBLTE_BIT_MSG_STRUCT *bits,
LIBLTE_BYTE_MSG_STRUCT *bytes);
/*********************************************************************
Name: liblte_unpack
Description: Unpack a byte array into a bit array
*********************************************************************/
void liblte_unpack(LIBLTE_BYTE_MSG_STRUCT *bytes,
LIBLTE_BIT_MSG_STRUCT *bits);
/*********************************************************************
Name: liblte_pack
Description: Pack a bit array into a byte array
*********************************************************************/
void liblte_pack(uint8_t *bits, uint32_t n_bits, uint8_t *bytes);
/*********************************************************************
Name: liblte_unpack
Description: Unpack a byte array into a bit array
*********************************************************************/
void liblte_unpack(uint8_t *bytes, uint32_t n_bytes, uint8_t *bits);
/*********************************************************************
Name: liblte_align_up
Description: Aligns a pointer to a multibyte boundary
*********************************************************************/
void liblte_align_up(uint8_t **ptr, uint32_t align);
/*********************************************************************
Name: liblte_align_up_zero
Description: Aligns a pointer to a multibyte boundary and zeros
bytes skipped
*********************************************************************/
void liblte_align_up_zero(uint8_t **ptr, uint32_t align);
#endif /* __LIBLTE_COMMON_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,118 @@
/**
*
* \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 BCD_HELPERS
#define BCD_HELPERS
#include <ctype.h>
#include <stdint.h>
#include <string>
namespace srslte {
/******************************************************************************
* Convert between string and BCD-coded MCC.
* Digits are represented by 4-bit nibbles. Unused nibbles are filled with 0xF.
* MCC 001 results in 0xF001
*****************************************************************************/
inline bool string_to_mcc(std::string str, uint16_t *mcc)
{
uint32_t len = str.size();
if(len != 3) {
return false;
}
if(!isdigit(str[0]) || !isdigit(str[1]) || !isdigit(str[2])) {
return false;
}
*mcc = 0xF000;
*mcc |= ((uint8_t)(str[0]-'0') << 8);
*mcc |= ((uint8_t)(str[1]-'0') << 4);
*mcc |= ((uint8_t)(str[2]-'0'));
return true;
}
inline bool mcc_to_string(uint16_t mcc, std::string *str)
{
if((mcc & 0xF000) != 0xF000) {
return false;
}
*str = "";
*str += ((mcc & 0x0F00) >> 8) + '0';
*str += ((mcc & 0x00F0) >> 4) + '0';
*str += (mcc & 0x000F) + '0';
return true;
}
/******************************************************************************
* Convert between string and BCD-coded MNC.
* Digits are represented by 4-bit nibbles. Unused nibbles are filled with 0xF.
* MNC 001 results in 0xF001
* MNC 01 results in 0xFF01
*****************************************************************************/
inline bool string_to_mnc(std::string str, uint16_t *mnc)
{
uint32_t len = str.size();
if(len != 3 && len != 2) {
return false;
}
if(len == 3) {
if(!isdigit(str[0]) || !isdigit(str[1]) || !isdigit(str[2])) {
return false;
}
*mnc = 0xF000;
*mnc |= ((uint8_t)(str[0]-'0') << 8);
*mnc |= ((uint8_t)(str[1]-'0') << 4);
*mnc |= ((uint8_t)(str[2]-'0'));
}
if(len == 2) {
if(!isdigit(str[0]) || !isdigit(str[1])) {
return false;
}
*mnc = 0xFF00;
*mnc |= ((uint8_t)(str[0]-'0') << 4);
*mnc |= ((uint8_t)(str[1]-'0'));
}
return true;
}
inline bool mnc_to_string(uint16_t mnc, std::string *str)
{
if((mnc & 0xF000) != 0xF000) {
return false;
}
*str = "";
if((mnc & 0xFF00) != 0xFF00) {
*str += ((mnc & 0x0F00) >> 8) + '0';
}
*str += ((mnc & 0x00F0) >> 4) + '0';
*str += (mnc & 0x000F) + '0';
return true;
}
} // namespace srslte
#endif // BCD_HELPERS

@ -0,0 +1,97 @@
/**
*
* \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 BLOCK_QUEUE
#define BLOCK_QUEUE
#include <queue>
#include <memory>
#include <utility>
#include <pthread.h>
#include <stdio.h>
namespace srslte {
template<typename myobj>
class block_queue {
public:
block_queue<myobj>() {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cvar, NULL);
}
void push(const myobj& value) {
pthread_mutex_lock(&mutex);
q.push(value);
pthread_cond_signal(&cvar);
pthread_mutex_unlock(&mutex);
}
bool try_pop(myobj *value) {
pthread_mutex_lock(&mutex);
if (q.empty()) {
pthread_mutex_unlock(&mutex);
return false;
}
if (value) {
*value = q.front();
q.pop();
}
pthread_mutex_unlock(&mutex);
return true;
}
myobj wait_pop() { // blocking pop
pthread_mutex_lock(&mutex);
while(q.empty()) {
pthread_cond_wait(&cvar, &mutex);
}
myobj value = q.front();
q.pop();
pthread_mutex_unlock(&mutex);
return value;
}
bool empty() const { // queue is empty?
pthread_mutex_lock(&mutex);
bool ret = q.empty();
pthread_mutex_unlock(&mutex);
return ret;
}
void clear() { // remove all items
myobj item;
while (try_pop(item));
}
private:
std::queue<myobj> q;
pthread_mutex_t mutex;
pthread_cond_t cvar;
};
}
#endif

@ -0,0 +1,169 @@
/**
*
* \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 BUFFER_POOL_H
#define BUFFER_POOL_H
#include <pthread.h>
#include <vector>
#include <stack>
#include <algorithm>
/*******************************************************************************
INCLUDES
*******************************************************************************/
#include "srslte/common/common.h"
namespace srslte {
/******************************************************************************
* Buffer pool
*
* Preallocates a large number of buffer_t and provides allocate and
* deallocate functions. Provides quick object creation and deletion as well
* as object reuse.
* Singleton class of byte_buffer_t (but other pools of different type can be created)
*****************************************************************************/
template <class buffer_t>
class buffer_pool{
public:
// non-static methods
buffer_pool(uint32_t nof_buffers = POOL_SIZE)
{
pthread_mutex_init(&mutex, NULL);
for(uint32_t i=0;i<nof_buffers;i++) {
buffer_t *b = new buffer_t;
available.push(b);
}
capacity = nof_buffers;
}
~buffer_pool() {
// this destructor assumes all buffers have been properly deallocated
while(available.size()) {
delete available.top();
available.pop();
}
}
void print_all_buffers()
{
printf("%d buffers in queue\n", (int) used.size());
for (uint32_t i=0;i<used.size();i++) {
printf("%s\n", strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined");
}
}
buffer_t* allocate(const char *debug_name = NULL)
{
pthread_mutex_lock(&mutex);
buffer_t* b = NULL;
if(available.size() > 0)
{
b = available.top();
used.push_back(b);
available.pop();
if (available.size() < capacity/20) {
printf("Warning buffer pool capacity is %f %%\n", (float) available.size()/capacity);
}
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
if (debug_name) {
strncpy(b->debug_name, debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN);
b->debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN-1] = 0;
}
#endif
} else {
printf("Error - buffer pool is empty\n");
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
print_all_buffers();
#endif
}
pthread_mutex_unlock(&mutex);
return b;
}
bool deallocate(buffer_t *b)
{
bool ret = false;
pthread_mutex_lock(&mutex);
typename std::vector<buffer_t*>::iterator elem = std::find(used.begin(), used.end(), b);
if (elem != used.end()) {
used.erase(elem);
available.push(b);
ret = true;
} else {
printf("Error deallocating from buffer pool: buffer not created in this pool.\n");
}
pthread_mutex_unlock(&mutex);
return ret;
}
private:
static const int POOL_SIZE = 2048;
std::stack<buffer_t*> available;
std::vector<buffer_t*> used;
pthread_mutex_t mutex;
uint32_t capacity;
};
class byte_buffer_pool {
public:
// Singleton static methods
static byte_buffer_pool *instance;
static byte_buffer_pool* get_instance(void);
static void cleanup(void);
byte_buffer_pool() {
pool = new buffer_pool<byte_buffer_t>;
}
~byte_buffer_pool() {
delete pool;
}
byte_buffer_t* allocate(const char *debug_name = NULL) {
return pool->allocate(debug_name);
}
void deallocate(byte_buffer_t *b) {
b->reset();
pool->deallocate(b);
}
private:
buffer_pool<byte_buffer_t> *pool;
};
} // namespace srsue
#endif // BUFFER_POOL_H

@ -0,0 +1,250 @@
/**
*
* \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 COMMON_H
#define COMMON_H
/*******************************************************************************
INCLUDES
*******************************************************************************/
#include <stdint.h>
#include <string.h>
/*******************************************************************************
DEFINES
*******************************************************************************/
#define SRSLTE_UE_CATEGORY 4
#define SRSLTE_N_SRB 3
#define SRSLTE_N_DRB 8
#define SRSLTE_N_RADIO_BEARERS 11
// Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI
// 3GPP 36.306 Table 4.1.1
#define SRSLTE_MAX_BUFFER_SIZE_BITS 102048
#define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756
#define SRSLTE_BUFFER_HEADER_OFFSET 1024
#define SRSLTE_BUFFER_POOL_LOG_ENABLED
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
#define pool_allocate (pool->allocate(__FUNCTION__))
#define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128
#else
#define pool_allocate (pool->allocate())
#endif
#include "srslte/srslte.h"
/*******************************************************************************
TYPEDEFS
*******************************************************************************/
namespace srslte {
typedef enum{
ERROR_NONE = 0,
ERROR_INVALID_PARAMS,
ERROR_INVALID_COMMAND,
ERROR_OUT_OF_BOUNDS,
ERROR_CANT_START,
ERROR_ALREADY_STARTED,
ERROR_N_ITEMS,
}error_t;
static const char error_text[ERROR_N_ITEMS][20] = { "None",
"Invalid parameters",
"Invalid command",
"Out of bounds",
"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
*
* Generic buffers with headroom to accommodate packet headers and custom
* copy constructors & assignment operators for quick copying. Byte buffer
* holds a next pointer to support linked lists.
*****************************************************************************/
class byte_buffer_t{
public:
uint32_t N_bytes;
uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BYTES];
uint8_t *msg;
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN];
#endif
byte_buffer_t():N_bytes(0)
{
timestamp_is_set = false;
msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET];
next = NULL;
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
debug_name[0] = 0;
#endif
}
byte_buffer_t(const byte_buffer_t& buf)
{
N_bytes = buf.N_bytes;
memcpy(msg, buf.msg, N_bytes);
}
byte_buffer_t & operator= (const byte_buffer_t & buf)
{
// avoid self assignment
if (&buf == this)
return *this;
N_bytes = buf.N_bytes;
memcpy(msg, buf.msg, N_bytes);
return *this;
}
void reset()
{
msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET];
N_bytes = 0;
timestamp_is_set = false;
}
uint32_t get_headroom()
{
return msg-buffer;
}
long get_latency_us()
{
if(!timestamp_is_set)
return 0;
gettimeofday(&timestamp[2], NULL);
get_time_interval(timestamp);
return timestamp[0].tv_usec;
}
void set_timestamp()
{
gettimeofday(&timestamp[1], NULL);
timestamp_is_set = true;
}
private:
void get_time_interval(struct timeval * tdata) {
tdata[0].tv_sec = tdata[2].tv_sec - tdata[1].tv_sec;
tdata[0].tv_usec = tdata[2].tv_usec - tdata[1].tv_usec;
if (tdata[0].tv_usec < 0) {
tdata[0].tv_sec--;
tdata[0].tv_usec += 1000000;
}
}
struct timeval timestamp[3];
bool timestamp_is_set;
byte_buffer_t *next;
};
struct bit_buffer_t{
uint32_t N_bits;
uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BITS];
uint8_t *msg;
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
char debug_name[128];
#endif
bit_buffer_t():N_bits(0)
{
msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET];
}
bit_buffer_t(const bit_buffer_t& buf){
N_bits = buf.N_bits;
memcpy(msg, buf.msg, N_bits);
}
bit_buffer_t & operator= (const bit_buffer_t & buf){
// avoid self assignment
if (&buf == this)
return *this;
N_bits = buf.N_bits;
memcpy(msg, buf.msg, N_bits);
return *this;
}
void reset()
{
msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET];
N_bits = 0;
timestamp_is_set = false;
}
uint32_t get_headroom()
{
return msg-buffer;
}
long get_latency_us()
{
if(!timestamp_is_set)
return 0;
gettimeofday(&timestamp[2], NULL);
return timestamp[0].tv_usec;
}
void set_timestamp()
{
gettimeofday(&timestamp[1], NULL);
timestamp_is_set = true;
}
private:
struct timeval timestamp[3];
bool timestamp_is_set;
};
} // namespace srsue
#endif // COMMON_H

@ -0,0 +1,57 @@
/**
*
* \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 CONFIG_H
#define CONFIG_H
// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
#define SRSAPPS_IMPORT __declspec(dllimport)
#define SRSAPPS_EXPORT __declspec(dllexport)
#define SRSAPPS_LOCAL
#else
#if __GNUC__ >= 4
#define SRSAPPS_IMPORT __attribute__ ((visibility ("default")))
#define SRSAPPS_EXPORT __attribute__ ((visibility ("default")))
#else
#define SRSAPPS_IMPORT
#define SRSAPPS_EXPORT
#define SRSAPPS_LOCAL
#endif
#endif
// Define SRSAPPS_API
// is used for the public API symbols.
#ifdef SRSAPPS_DLL_EXPORTS // defined if we are building the SRSAPPS DLL (instead of using it)
#define SRSAPPS_EXPORT
#else
#define SRSAPPS_IMPORT
#endif
// cf_t definition
typedef _Complex float cf_t;
#endif // CONFIG_H

@ -0,0 +1,52 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2017 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of srsLTE.
*
* 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 INTERFACE_COMMON_H
#define INTERFACE_COMMON_H
#include "srslte/common/timers.h"
namespace srslte {
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;
};
class read_pdu_interface
{
public:
virtual int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t requested_bytes) = 0;
};
}
#endif

@ -0,0 +1,270 @@
/*******************************************************************************
Copyright 2014 Ben Wojtowicz
This program 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.
This program 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.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************
File: liblte_security.h
Description: Contains all the definitions for the LTE security algorithm
library.
Revision History
---------- ------------- --------------------------------------------
08/03/2014 Ben Wojtowicz Created file.
09/03/2014 Ben Wojtowicz Added key generation and EIA2.
*******************************************************************************/
#ifndef __LIBLTE_SECURITY_H__
#define __LIBLTE_SECURITY_H__
/*******************************************************************************
INCLUDES
*******************************************************************************/
#include "srslte/asn1/liblte_common.h"
/*******************************************************************************
DEFINES
*******************************************************************************/
/*******************************************************************************
TYPEDEFS
*******************************************************************************/
/*******************************************************************************
DECLARATIONS
*******************************************************************************/
/*********************************************************************
Name: liblte_security_generate_k_asme
Description: Generate the security key Kasme.
Document Reference: 33.401 v10.0.0 Annex A.2
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_generate_k_asme(uint8 *ck,
uint8 *ik,
uint8 *ak,
uint8 *sqn,
uint16 mcc,
uint16 mnc,
uint8 *k_asme);
/*********************************************************************
Name: liblte_security_generate_k_enb
Description: Generate the security key Kenb.
Document Reference: 33.401 v10.0.0 Annex A.2
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_generate_k_enb(uint8 *k_asme,
uint32 nas_count,
uint8 *k_enb);
/*********************************************************************
Name: liblte_security_generate_k_nas
Description: Generate the NAS security keys KNASenc and KNASint.
Document Reference: 33.401 v10.0.0 Annex A.2
*********************************************************************/
// Defines
// Enums
typedef enum{
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_EEA0 = 0,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_128_EEA1,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_128_EEA2,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_N_ITEMS,
}LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM;
static const char liblte_security_ciphering_algorithm_id_text[LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {"EEA0",
"128-EEA1",
"128-EEA2"};
typedef enum{
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_EIA0 = 0,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_128_EIA1,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_128_EIA2,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_N_ITEMS,
}LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM;
static const char liblte_security_integrity_algorithm_id_text[LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {"EIA0",
"128-EIA1",
"128-EIA2"};
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_generate_k_nas(uint8 *k_asme,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8 *k_nas_enc,
uint8 *k_nas_int);
/*********************************************************************
Name: liblte_security_generate_k_rrc
Description: Generate the RRC security keys KRRCenc and KRRCint.
Document Reference: 33.401 v10.0.0 Annex A.2
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_generate_k_rrc(uint8 *k_enb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8 *k_rrc_enc,
uint8 *k_rrc_int);
/*********************************************************************
Name: liblte_security_generate_k_up
Description: Generate the user plane security keys KUPenc and
KUPint.
Document Reference: 33.401 v10.0.0 Annex A.2
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_generate_k_up(uint8 *k_enb,
LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8 *k_up_enc,
uint8 *k_up_int);
/*********************************************************************
Name: liblte_security_128_eia2
Description: 128-bit integrity algorithm EIA2.
Document Reference: 33.401 v10.0.0 Annex B.2.3
33.102 v10.0.0 Section 6.5.4
RFC4493
*********************************************************************/
// Defines
#define LIBLTE_SECURITY_DIRECTION_UPLINK 0
#define LIBLTE_SECURITY_DIRECTION_DOWNLINK 1
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_128_eia2(uint8 *key,
uint32 count,
uint8 bearer,
uint8 direction,
uint8 *msg,
uint32 msg_len,
uint8 *mac);
LIBLTE_ERROR_ENUM liblte_security_128_eia2(uint8 *key,
uint32 count,
uint8 bearer,
uint8 direction,
LIBLTE_BIT_MSG_STRUCT *msg,
uint8 *mac);
/*********************************************************************
Name: liblte_security_milenage_f1
Description: Milenage security function F1. Computes network
authentication code MAC-A from key K, random
challenge RAND, sequence number SQN, and
authentication management field AMF.
Document Reference: 35.206 v10.0.0 Annex 3
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_milenage_f1(uint8 *k,
uint8 *op,
uint8 *rand,
uint8 *sqn,
uint8 *amf,
uint8 *mac_a);
/*********************************************************************
Name: liblte_security_milenage_f1_star
Description: Milenage security function F1*. Computes resynch
authentication code MAC-S from key K, random
challenge RAND, sequence number SQN, and
authentication management field AMF.
Document Reference: 35.206 v10.0.0 Annex 3
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_milenage_f1_star(uint8 *k,
uint8 *op,
uint8 *rand,
uint8 *sqn,
uint8 *amf,
uint8 *mac_s);
/*********************************************************************
Name: liblte_security_milenage_f2345
Description: Milenage security functions F2, F3, F4, and F5.
Computes response RES, confidentiality key CK,
integrity key IK, and anonymity key AK from random
challenge RAND.
Document Reference: 35.206 v10.0.0 Annex 3
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_milenage_f2345(uint8 *k,
uint8 *op,
uint8 *rand,
uint8 *res,
uint8 *ck,
uint8 *ik,
uint8 *ak);
/*********************************************************************
Name: liblte_security_milenage_f5_star
Description: Milenage security function F5*. Computes resynch
anonymity key AK from key K and random challenge
RAND.
Document Reference: 35.206 v10.0.0 Annex 3
*********************************************************************/
// Defines
// Enums
// Structs
// Functions
LIBLTE_ERROR_ENUM liblte_security_milenage_f5_star(uint8 *k,
uint8 *op,
uint8 *rand,
uint8 *ak);
#endif /* __LIBLTE_SECURITY_H__ */

@ -0,0 +1,53 @@
#ifndef __LIBLTE_SSL_H__
#define __LIBLTE_SSL_H__
#ifdef HAVE_POLARSSL
#include "polarssl/sha256.h"
#include "polarssl/aes.h"
void sha256(const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[32], int is224 )
{
sha256_hmac(key, keylen, input, ilen, output, is224);
}
#endif // HAVE_POLARSSL
#ifdef HAVE_MBEDTLS
#include "mbedtls/md.h"
#include "mbedtls/aes.h"
typedef mbedtls_aes_context aes_context;
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize )
{
return mbedtls_aes_setkey_enc(ctx, key, keysize);
}
int aes_crypt_ecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
return mbedtls_aes_crypt_ecb(ctx, mode, input, output);
}
void sha256(const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[32], int is224 )
{
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
key, keylen,
input, ilen,
output );
}
#endif // HAVE_MBEDTLS
#endif // __LIBLTE_SSL_H__

@ -0,0 +1,127 @@
/**
*
* \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.h
*
* Description: Abstract logging service
*
* Reference:
*****************************************************************************/
#ifndef LOG_H
#define LOG_H
#include <stdint.h>
#include <string>
namespace srslte {
typedef enum {
LOG_LEVEL_NONE = 0,
LOG_LEVEL_ERROR,
LOG_LEVEL_WARNING,
LOG_LEVEL_INFO,
LOG_LEVEL_DEBUG,
LOG_LEVEL_N_ITEMS
} LOG_LEVEL_ENUM;
static const char log_level_text[LOG_LEVEL_N_ITEMS][16] = {"None ",
"Error ",
"Warning",
"Info ",
"Debug "};
class log
{
public:
log() {
service_name = "";
tti = 0;
level = LOG_LEVEL_NONE;
hex_limit = 0;
}
log(std::string service_name_) {
service_name = service_name_;
tti = 0;
level = LOG_LEVEL_NONE;
hex_limit = 0;
}
// This function shall be called at the start of every tti for printing tti
void step(uint32_t tti_) {
tti = tti_;
}
uint32_t get_tti() {
return tti;
}
void set_level(LOG_LEVEL_ENUM l) {
level = l;
}
LOG_LEVEL_ENUM get_level() {
return level;
}
void set_hex_limit(int limit) {
hex_limit = limit;
}
int get_hex_limit() {
return hex_limit;
}
// Pure virtual methods for logging
virtual void console(std::string message, ...) = 0;
virtual void error(std::string message, ...) = 0;
virtual void warning(std::string message, ...) = 0;
virtual void info(std::string message, ...) = 0;
virtual void debug(std::string message, ...) = 0;
// Same with hex dump
virtual void error_hex(uint8_t *hex, int size, std::string message, ...){error("error_hex not implemented.\n");}
virtual void warning_hex(uint8_t *hex, int size, std::string message, ...){error("warning_hex not implemented.\n");}
virtual void info_hex(uint8_t *hex, int size, std::string message, ...){error("info_hex not implemented.\n");}
virtual void debug_hex(uint8_t *hex, int size, std::string message, ...){error("debug_hex not implemented.\n");}
// Same with line and file info
virtual void error_line(std::string file, int line, std::string message, ...){error("error_line not implemented.\n");}
virtual void warning_line(std::string file, int line, std::string message, ...){error("warning_line not implemented.\n");}
virtual void info_line(std::string file, int line, std::string message, ...){error("info_line not implemented.\n");}
virtual void debug_line(std::string file, int line, std::string message, ...){error("debug_line not implemented.\n");}
protected:
std::string get_service_name() { return service_name; }
uint32_t tti;
LOG_LEVEL_ENUM level;
int hex_limit;
std::string service_name;
};
} // namespace srslte
#endif // LOG_H

@ -0,0 +1,83 @@
/**
*
* \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_filter.h
* Description: Log filter for a specific layer or element.
* Performs filtering based on log level, generates
* timestamped log strings and passes them to the
* common logger object.
*****************************************************************************/
#ifndef LOG_FILTER_H
#define LOG_FILTER_H
#include <stdarg.h>
#include <string>
#include "srslte/common/log.h"
#include "logger.h"
namespace srslte {
class log_filter : public srslte::log
{
public:
log_filter();
log_filter(std::string layer, logger *logger_, bool tti=false);
void init(std::string layer, logger *logger_, bool tti=false);
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, ...);
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, ...);
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:
logger *logger_h;
bool do_tti;
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);
};
} // namespace srsue
#endif // LOG_FILTER_H

@ -0,0 +1,82 @@
/**
*
* \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

@ -0,0 +1,74 @@
/**
*
* \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.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_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
{
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;
};
} // namespace srsue
#endif // LOGGER_H

@ -0,0 +1,61 @@
/**
*
* \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 MACPCAP_H
#define MACPCAP_H
#include <stdint.h>
#include "srslte/common/pcap.h"
namespace srslte {
class mac_pcap
{
public:
mac_pcap() {enable_write=false; ue_id=0; pcap_file = NULL; };
void enable(bool en);
void open(const char *filename, uint32_t ue_id = 0);
void close();
void write_ul_crnti(uint8_t *pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint32_t reTX, uint32_t tti);
void write_dl_crnti(uint8_t *pdu, uint32_t pdu_len_bytes, uint16_t crnti, bool crc_ok, uint32_t tti);
void write_dl_ranti(uint8_t *pdu, uint32_t pdu_len_bytes, uint16_t ranti, bool crc_ok, uint32_t tti);
// SI and BCH only for DL
void write_dl_sirnti(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
void write_dl_bch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
void write_dl_pch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
private:
bool enable_write;
FILE *pcap_file;
uint32_t ue_id;
void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint32_t reTX, bool crc_ok, uint32_t tti,
uint16_t crnti_, uint8_t direction, uint8_t rnti_type);
};
} // namespace srsue
#endif // MACPCAP_H

@ -0,0 +1,61 @@
/******************************************************************************
* File: metrics_hub.h
* Description: Centralizes metrics interfaces to allow different metrics clients
* to get metrics
*****************************************************************************/
#ifndef METRICS_HUB_H
#define METRICS_HUB_H
#include <vector>
#include "srslte/common/threads.h"
namespace srslte {
template<typename metrics_t>
class metrics_interface
{
public:
virtual bool get_metrics(metrics_t &m) = 0;
};
template<typename metrics_t>
class metrics_listener
{
public:
virtual void set_metrics(metrics_t &m) = 0;
};
template<typename metrics_t>
class metrics_hub : public periodic_thread
{
public:
bool init(metrics_interface<metrics_t> *m_, float report_period_secs=1.0) {
m = m_;
start_periodic(report_period_secs*1e6);
}
void stop() {
thread_cancel();
}
void add_listener(metrics_listener<metrics_t> *listener) {
listeners.push_back(listener);
}
private:
void run_period() {
metrics_t metric;
m->get_metrics(metric);
for (int i=0;i<listeners.size();i++) {
listeners[i]->set_metrics(metric);
}
}
metrics_interface<metrics_t> *m;
std::vector<metrics_listener<metrics_t>*> listeners;
};
} // namespace srslte
#endif // METRICS_HUB_H

@ -0,0 +1,152 @@
/**
*
* \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: msg_queue.h
* Description: Thread-safe bounded circular buffer of srsue_byte_buffer pointers.
* Reference:
*****************************************************************************/
#ifndef MSG_QUEUE_H
#define MSG_QUEUE_H
#include "srslte/common/common.h"
#include <pthread.h>
namespace srslte {
class msg_queue
{
public:
msg_queue(uint32_t capacity_ = 128)
:head(0)
,tail(0)
,unread(0)
,unread_bytes(0)
,capacity(capacity_)
{
buf = new byte_buffer_t*[capacity];
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&not_empty, NULL);
pthread_cond_init(&not_full, NULL);
}
~msg_queue()
{
delete [] buf;
}
void write(byte_buffer_t *msg)
{
pthread_mutex_lock(&mutex);
while(is_full()) {
pthread_cond_wait(&not_full, &mutex);
}
buf[head] = msg;
head = (head+1)%capacity;
unread++;
unread_bytes += msg->N_bytes;
pthread_cond_signal(&not_empty);
pthread_mutex_unlock(&mutex);
}
void read(byte_buffer_t **msg)
{
pthread_mutex_lock(&mutex);
while(is_empty()) {
pthread_cond_wait(&not_empty, &mutex);
}
*msg = buf[tail];
tail = (tail+1)%capacity;
unread--;
unread_bytes -= (*msg)->N_bytes;
pthread_cond_signal(&not_full);
pthread_mutex_unlock(&mutex);
}
bool try_read(byte_buffer_t **msg)
{
pthread_mutex_lock(&mutex);
if(is_empty())
{
pthread_mutex_unlock(&mutex);
return false;
}else{
*msg = buf[tail];
tail = (tail+1)%capacity;
unread--;
unread_bytes -= (*msg)->N_bytes;
pthread_cond_signal(&not_full);
pthread_mutex_unlock(&mutex);
return true;
}
}
uint32_t size()
{
pthread_mutex_lock(&mutex);
uint32_t r = unread;
pthread_mutex_unlock(&mutex);
return r;
}
uint32_t size_bytes()
{
pthread_mutex_lock(&mutex);
uint32_t r = unread_bytes;
pthread_mutex_unlock(&mutex);
return r;
}
uint32_t size_tail_bytes()
{
pthread_mutex_lock(&mutex);
uint32_t r = buf[tail]->N_bytes;
pthread_mutex_unlock(&mutex);
return r;
}
private:
bool is_empty() const { return unread == 0; }
bool is_full() const { return unread == capacity; }
pthread_cond_t not_empty;
pthread_cond_t not_full;
pthread_mutex_t mutex;
byte_buffer_t **buf;
uint32_t capacity;
uint32_t unread;
uint32_t unread_bytes;
uint32_t head;
uint32_t tail;
};
} // namespace srsue
#endif // MSG_QUEUE_H

@ -0,0 +1,218 @@
/**
*
* \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 UEPCAP_H
#define UEPCAP_H
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/time.h>
#define MAC_LTE_DLT 147
/* This structure gets written to the start of the file */
typedef struct pcap_hdr_s {
unsigned int magic_number; /* magic number */
unsigned short version_major; /* major version number */
unsigned short version_minor; /* minor version number */
unsigned int thiszone; /* GMT to local correction */
unsigned int sigfigs; /* accuracy of timestamps */
unsigned int snaplen; /* max length of captured packets, in octets */
unsigned int network; /* data link type */
} pcap_hdr_t;
/* This structure precedes each packet */
typedef struct pcaprec_hdr_s {
unsigned int ts_sec; /* timestamp seconds */
unsigned int ts_usec; /* timestamp microseconds */
unsigned int incl_len; /* number of octets of packet saved in file */
unsigned int orig_len; /* actual length of packet */
} pcaprec_hdr_t;
/* radioType */
#define FDD_RADIO 1
#define TDD_RADIO 2
/* Direction */
#define DIRECTION_UPLINK 0
#define DIRECTION_DOWNLINK 1
/* rntiType */
#define NO_RNTI 0 /* Used for BCH-BCH */
#define P_RNTI 1
#define RA_RNTI 2
#define C_RNTI 3
#define SI_RNTI 4
#define SPS_RNTI 5
#define M_RNTI 6
#define MAC_LTE_START_STRING "mac-lte"
#define MAC_LTE_RNTI_TAG 0x02
/* 2 bytes, network order */
#define MAC_LTE_UEID_TAG 0x03
/* 2 bytes, network order */
#define MAC_LTE_SUBFRAME_TAG 0x04
/* 2 bytes, network order */
#define MAC_LTE_PREDFINED_DATA_TAG 0x05
/* 1 byte */
#define MAC_LTE_RETX_TAG 0x06
/* 1 byte */
#define MAC_LTE_CRC_STATUS_TAG 0x07
/* 1 byte */
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
continues until the end of the frame) */
#define MAC_LTE_PAYLOAD_TAG 0x01
/* Context information for every MAC PDU that will be logged */
typedef struct MAC_Context_Info_t {
unsigned short radioType;
unsigned char direction;
unsigned char rntiType;
unsigned short rnti;
unsigned short ueid;
unsigned char isRetx;
unsigned char crcStatusOK;
unsigned short sysFrameNumber;
unsigned short subFrameNumber;
} MAC_Context_Info_t;
/**************************************************************************/
/* API functions for opening/writing/closing MAC-LTE PCAP files */
/* Open the file and write file header */
inline FILE *MAC_LTE_PCAP_Open(const char *fileName)
{
pcap_hdr_t file_header =
{
0xa1b2c3d4, /* magic number */
2, 4, /* version number is 2.4 */
0, /* timezone */
0, /* sigfigs - apparently all tools do this */
65535, /* snaplen - this should be long enough */
MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
};
FILE *fd = fopen(fileName, "w");
if (fd == NULL) {
printf("Failed to open file \"%s\" for writing\n", fileName);
return NULL;
}
/* Write the file header */
fwrite(&file_header, sizeof(pcap_hdr_t), 1, fd);
return fd;
}
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
inline int MAC_LTE_PCAP_WritePDU(FILE *fd, MAC_Context_Info_t *context,
const unsigned char *PDU, unsigned int length)
{
pcaprec_hdr_t packet_header;
char context_header[256];
int offset = 0;
unsigned short tmp16;
/* Can't write if file wasn't successfully opened */
if (fd == NULL) {
printf("Error: Can't write to empty file handle\n");
return 0;
}
/*****************************************************************/
/* Context information (same as written by UDP heuristic clients */
context_header[offset++] = context->radioType;
context_header[offset++] = context->direction;
context_header[offset++] = context->rntiType;
/* RNTI */
context_header[offset++] = MAC_LTE_RNTI_TAG;
tmp16 = htons(context->rnti);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* UEId */
context_header[offset++] = MAC_LTE_UEID_TAG;
tmp16 = htons(context->ueid);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* Subframe number */
context_header[offset++] = MAC_LTE_SUBFRAME_TAG;
tmp16 = htons(context->subFrameNumber);
memcpy(context_header+offset, &tmp16, 2);
offset += 2;
/* CRC Status */
context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
context_header[offset++] = context->crcStatusOK;
/* Data tag immediately preceding PDU */
context_header[offset++] = MAC_LTE_PAYLOAD_TAG;
/****************************************************************/
/* PCAP Header */
struct timeval t;
gettimeofday(&t, NULL);
packet_header.ts_sec = t.tv_sec;
packet_header.ts_usec = t.tv_usec;
packet_header.incl_len = offset + length;
packet_header.orig_len = offset + length;
/***************************************************************/
/* Now write everything to the file */
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, fd);
fwrite(context_header, 1, offset, fd);
fwrite(PDU, 1, length, fd);
return 1;
}
/* Close the PCAP file */
inline void MAC_LTE_PCAP_Close(FILE *fd)
{
if(fd)
fclose(fd);
}
#endif /* UEPCAP_H */

@ -0,0 +1,339 @@
/**
*
* \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 MACPDU_H
#define MACPDU_H
#include <stdint.h>
#include "srslte/common/log.h"
#include "srslte/common/interfaces_common.h"
#include <vector>
#include <stdio.h>
/* MAC PDU Packing/Unpacking functions. Section 6 of 36.321 */
namespace srslte {
template<class SubH>
class pdu
{
public:
pdu(uint32_t max_subheaders_) : subheaders(max_subheaders_) {
max_subheaders = max_subheaders_;
nof_subheaders = 0;
cur_idx = -1;
pdu_len = 0;
rem_len = 0;
last_sdu_idx = -1;
pdu_is_ul = false;
buffer_tx = NULL;
total_sdu_len = 0;
}
void fprint(FILE *stream) {
fprintf(stream, "Number of Subheaders: %d\n", nof_subheaders);
for (int i=0;i<nof_subheaders;i++) {
fprintf(stream, " -- Subheader %d: ", i);
subheaders[i].fprint(stream);
}
}
/* Resets the Read/Write position and remaining PDU length */
void reset() {
cur_idx = -1;
last_sdu_idx = -1;
rem_len = pdu_len;
}
void init_rx(uint32_t pdu_len_bytes, bool is_ulsch = false) {
init_(NULL, pdu_len_bytes, is_ulsch);
}
void init_tx(uint8_t *payload, uint32_t pdu_len_bytes, bool is_ulsch = false) {
init_(payload, pdu_len_bytes, is_ulsch);
}
uint32_t nof_subh() {
return nof_subheaders;
}
bool new_subh() {
if (nof_subheaders < (int)max_subheaders - 1 && rem_len > 0) {
nof_subheaders++;
next();
return true;
} else {
return false;
}
}
bool next() {
if (cur_idx < nof_subheaders - 1) {
cur_idx++;
return true;
} else {
return false;
}
}
void del_subh() {
if (nof_subheaders > 0) {
nof_subheaders--;
}
if (cur_idx > 0) {
cur_idx--;
}
}
SubH* get() {
if (cur_idx >= 0) {
return &subheaders[cur_idx];
} else {
return NULL;
}
}
bool is_ul() {
return pdu_is_ul;
}
uint8_t* get_current_sdu_ptr() {
return &buffer_tx[total_sdu_len+sdu_offset_start];
}
void add_sdu(uint32_t sdu_sz) {
total_sdu_len += sdu_sz;
}
// Section 6.1.2
void parse_packet(uint8_t *ptr) {
uint8_t *init_ptr = ptr;
nof_subheaders = 0;
while(subheaders[nof_subheaders].read_subheader(&ptr)) {
nof_subheaders++;
}
nof_subheaders++;
for (int i=0;i<nof_subheaders;i++) {
subheaders[i].read_payload(&ptr);
}
}
protected:
std::vector<SubH> subheaders;
uint32_t pdu_len;
uint32_t rem_len;
int cur_idx;
int nof_subheaders;
uint32_t max_subheaders;
bool pdu_is_ul;
uint8_t* buffer_tx;
uint32_t total_sdu_len;
uint32_t sdu_offset_start;
int last_sdu_idx;
private:
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
void init_(uint8_t *buffer_tx_ptr, uint32_t pdu_len_bytes, bool is_ulsch) {
nof_subheaders = 0;
pdu_len = pdu_len_bytes;
rem_len = pdu_len;
pdu_is_ul = is_ulsch;
buffer_tx = buffer_tx_ptr;
sdu_offset_start = max_subheaders*2 + 13; // Assuming worst-case 2 bytes per sdu subheader + all possible CE
total_sdu_len = 0;
last_sdu_idx = -1;
reset();
for (uint32_t i=0;i<max_subheaders;i++) {
subheaders[i].parent = this;
subheaders[i].init();
}
}
};
template<class SubH>
class subh
{
public:
virtual bool read_subheader(uint8_t** ptr) = 0;
virtual void read_payload(uint8_t **ptr) = 0;
virtual void write_subheader(uint8_t** ptr, bool is_last) = 0;
virtual void write_payload(uint8_t **ptr) = 0;
virtual void fprint(FILE *stream) = 0;
pdu<SubH>* parent;
private:
virtual void init() = 0;
};
class sch_subh : public subh<sch_subh>
{
public:
typedef enum {
PHR_REPORT = 26,
CRNTI = 27,
CON_RES_ID = 28,
TRUNC_BSR = 28,
TA_CMD = 29,
SHORT_BSR = 29,
DRX_CMD = 30,
LONG_BSR = 30,
PADDING = 31,
SDU = 0
} cetype;
// Size of MAC CEs
const static int MAC_CE_CONTRES_LEN = 6;
// Reading functions
bool is_sdu();
cetype ce_type();
uint32_t size_plus_header();
void set_payload_size(uint32_t size);
bool read_subheader(uint8_t** ptr);
void read_payload(uint8_t **ptr);
uint32_t get_sdu_lcid();
uint32_t get_payload_size();
uint32_t get_header_size(bool is_last);
uint8_t* get_sdu_ptr();
uint16_t get_c_rnti();
uint64_t get_con_res_id();
uint8_t get_ta_cmd();
float get_phr();
int get_bsr(uint32_t buff_size[4]);
// Writing functions
void write_subheader(uint8_t** ptr, bool is_last);
void write_payload(uint8_t **ptr);
int set_sdu(uint32_t lcid, uint32_t nof_bytes, uint8_t *payload);
int set_sdu(uint32_t lcid, uint32_t requested_bytes, read_pdu_interface *sdu_itf);
bool set_c_rnti(uint16_t crnti);
bool set_bsr(uint32_t buff_size[4], sch_subh::cetype format);
bool set_con_res_id(uint64_t con_res_id);
bool set_ta_cmd(uint8_t ta_cmd);
bool set_phr(float phr);
void set_padding();
void set_padding(uint32_t padding_len);
void init();
void fprint(FILE *stream);
private:
static const int MAX_CE_PAYLOAD_LEN = 8;
uint32_t lcid;
int nof_bytes;
uint8_t* payload;
uint8_t w_payload_ce[8];
bool F_bit;
uint32_t sizeof_ce(uint32_t lcid, bool is_ul);
static uint8_t buff_size_table(uint32_t buffer_size);
static uint8_t phr_report_table(float phr_value);
};
class sch_pdu : public pdu<sch_subh>
{
public:
sch_pdu(uint32_t max_subh) : pdu(max_subh) {}
void parse_packet(uint8_t *ptr);
uint8_t* write_packet();
uint8_t* write_packet(srslte::log *log_h);
bool has_space_ce(uint32_t nbytes);
bool has_space_sdu(uint32_t nbytes);
int get_pdu_len();
int rem_size();
int get_sdu_space();
static uint32_t size_header_sdu(uint32_t nbytes);
bool update_space_ce(uint32_t nbytes);
bool update_space_sdu(uint32_t nbytes);
void fprint(FILE *stream);
};
class rar_subh : public subh<rar_subh>
{
public:
static const uint32_t RAR_GRANT_LEN = 20;
// Reading functions
bool read_subheader(uint8_t** ptr);
void read_payload(uint8_t** ptr);
uint32_t get_rapid();
uint32_t get_ta_cmd();
uint16_t get_temp_crnti();
void get_sched_grant(uint8_t grant[RAR_GRANT_LEN]);
// Writing functoins
void write_subheader(uint8_t** ptr, bool is_last);
void write_payload(uint8_t** ptr);
void set_rapid(uint32_t rapid);
void set_ta_cmd(uint32_t ta);
void set_temp_crnti(uint16_t temp_rnti);
void set_sched_grant(uint8_t grant[RAR_GRANT_LEN]);
void init();
void fprint(FILE *stream);
private:
uint8_t grant[RAR_GRANT_LEN];
uint32_t ta;
uint16_t temp_rnti;
uint32_t preamble;
};
class rar_pdu : public pdu<rar_subh>
{
public:
rar_pdu(uint32_t max_rars = 16);
void set_backoff(uint8_t bi);
bool has_backoff();
uint8_t get_backoff();
bool write_packet(uint8_t* ptr);
void fprint(FILE *stream);
private:
bool has_backoff_indicator;
uint8_t backoff_indicator;
};
} // namespace srsue
#endif // MACPDU_H

@ -0,0 +1,85 @@
/**
*
* \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 PDUPROC_H
#define PDUPROC_H
#include "srslte/common/log.h"
#include "srslte/common/block_queue.h"
#include "srslte/common/buffer_pool.h"
#include "srslte/common/timers.h"
#include "srslte/common/pdu.h"
/* Logical Channel Demultiplexing and MAC CE dissassemble */
namespace srslte {
class pdu_queue
{
public:
class process_callback
{
public:
virtual void process_pdu(uint8_t *buff, uint32_t len, uint32_t tstamp) = 0;
};
pdu_queue(uint32_t pool_size = DEFAULT_POOL_SIZE) : pool(pool_size), callback(NULL), log_h(NULL) {}
void init(process_callback *callback, log* log_h_);
uint8_t* request(uint32_t len);
void deallocate(uint8_t* pdu);
void push(uint8_t *ptr, uint32_t len, uint32_t tstamp = 0);
bool process_pdus();
private:
const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total
const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps
typedef struct {
uint8_t ptr[MAX_PDU_LEN];
uint32_t len;
uint32_t tstamp;
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
char debug_name[128];
#endif
} pdu_t;
block_queue<pdu_t*> pdu_q;
buffer_pool<pdu_t> pool;
process_callback *callback;
log *log_h;
};
} // namespace srslte
#endif // PDUPROC_H

@ -0,0 +1,151 @@
/**
*
* \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 SECURITY_H
#define SECURITY_H
/******************************************************************************
* Common security header - wraps ciphering/integrity check algorithms.
*****************************************************************************/
#include "srslte/common/common.h"
#define SECURITY_DIRECTION_UPLINK 0
#define SECURITY_DIRECTION_DOWNLINK 1
namespace srslte {
typedef enum{
CIPHERING_ALGORITHM_ID_EEA0 = 0,
CIPHERING_ALGORITHM_ID_128_EEA1,
CIPHERING_ALGORITHM_ID_128_EEA2,
CIPHERING_ALGORITHM_ID_N_ITEMS,
}CIPHERING_ALGORITHM_ID_ENUM;
static const char ciphering_algorithm_id_text[CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {"EEA0",
"128-EEA1",
"128-EEA2"};
typedef enum{
INTEGRITY_ALGORITHM_ID_EIA0 = 0,
INTEGRITY_ALGORITHM_ID_128_EIA1,
INTEGRITY_ALGORITHM_ID_128_EIA2,
INTEGRITY_ALGORITHM_ID_N_ITEMS,
}INTEGRITY_ALGORITHM_ID_ENUM;
static const char integrity_algorithm_id_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {"EIA0",
"128-EIA1",
"128-EIA2"};
/******************************************************************************
* Key Generation
*****************************************************************************/
uint8_t security_generate_k_asme( uint8_t *ck,
uint8_t *ik,
uint8_t *ak,
uint8_t *sqn,
uint16_t mcc,
uint16_t mnc,
uint8_t *k_asme);
uint8_t security_generate_k_enb( uint8_t *k_asme,
uint32_t nas_count,
uint8_t *k_enb);
uint8_t security_generate_k_nas( uint8_t *k_asme,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t *k_nas_enc,
uint8_t *k_nas_int);
uint8_t security_generate_k_rrc( uint8_t *k_enb,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t *k_rrc_enc,
uint8_t *k_rrc_int);
uint8_t security_generate_k_up( uint8_t *k_enb,
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
uint8_t *k_up_enc,
uint8_t *k_up_int);
/******************************************************************************
* Integrity Protection
*****************************************************************************/
uint8_t security_128_eia1( uint8_t *key,
uint32_t count,
uint8_t bearer,
uint8_t direction,
uint8_t *msg,
uint32_t msg_len,
uint8_t *mac);
uint8_t security_128_eia2( uint8_t *key,
uint32_t count,
uint8_t bearer,
uint8_t direction,
uint8_t *msg,
uint32_t msg_len,
uint8_t *mac);
/******************************************************************************
* Authentication
*****************************************************************************/
uint8_t security_milenage_f1( uint8_t *k,
uint8_t *op,
uint8_t *rand,
uint8_t *sqn,
uint8_t *amf,
uint8_t *mac_a);
uint8_t security_milenage_f1_star( uint8_t *k,
uint8_t *op,
uint8_t *rand,
uint8_t *sqn,
uint8_t *amf,
uint8_t *mac_s);
uint8_t security_milenage_f2345( uint8_t *k,
uint8_t *op,
uint8_t *rand,
uint8_t *res,
uint8_t *ck,
uint8_t *ik,
uint8_t *ak);
uint8_t security_milenage_f5_star( uint8_t *k,
uint8_t *op,
uint8_t *rand,
uint8_t *ak);
} // namespace srsue
#endif // SECURITY_H

@ -0,0 +1,71 @@
/*---------------------------------------------------------
* snow_3g.h
*
* Adapted from ETSI/SAGE specifications:
* "Specification of the 3GPP Confidentiality and
* Integrity Algorithms UEA2 & UIA2.
* Document 1: UEA2 and UIA2 Specification"
* "Specification of the 3GPP Confidentiality
* and Integrity Algorithms UEA2 & UIA2.
* Document 2: SNOW 3G Specification"
*---------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef unsigned char u8;
typedef unsigned int u32;
typedef unsigned long long u64;
/* Initialization.
* Input k[4]: Four 32-bit words making up 128-bit key.
* Input IV[4]: Four 32-bit words making 128-bit initialization variable.
* Output: All the LFSRs and FSM are initialized for key generation.
* See Section 4.1.
*/
void snow3g_initialize(u32 k[4], u32 IV[4]);
/* Generation of Keystream.
* input n: number of 32-bit words of keystream.
* input z: space for the generated keystream, assumes
* memory is allocated already.
* output: generated keystream which is filled in z
* See section 4.2.
*/
void snow3g_generate_keystream(u32 n, u32 *z);
/* f8.
* Input key: 128 bit Confidentiality Key.
* Input count:32-bit Count, Frame dependent input.
* Input bearer: 5-bit Bearer identity (in the LSB side).
* Input dir:1 bit, direction of transmission.
* Input data: length number of bits, input bit stream.
* Input length: 32 bit Length, i.e., the number of bits to be encrypted or
* decrypted.
* Output data: Output bit stream. Assumes data is suitably memory
* allocated.
* Encrypts/decrypts blocks of data between 1 and 2^32 bits in length as
* defined in Section 3.
*/
void snow3g_f8( u8 *key, u32 count, u32 bearer, u32 dir, \
u8 *data, u32 length );
/* f9.
* Input key: 128 bit Integrity Key.
* Input count:32-bit Count, Frame dependent input.
* Input fresh: 32-bit Random number.
* Input dir:1 bit, direction of transmission (in the LSB).
* Input data: length number of bits, input bit stream.
* Input length: 64 bit Length, i.e., the number of bits to be MAC'd.
* Output : 32 bit block used as MAC
* Generates 32-bit MAC using UIA2 algorithm as defined in Section 4.
*/
u8* snow3g_f9( u8* key, u32 count, u32 fresh, u32 dir, \
u8 *data, u64 length);

@ -0,0 +1,61 @@
/**
*
* \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: task_dispatcher.h
* Description:
* Reference:
*****************************************************************************/
#ifndef TASK_DISPATCHER_H
#define TASK_DISPATCHER_H
#include <pthread.h>
#include <stdint.h>
#include <string>
#include <queue>
#include "srslte/common/threads.h"
namespace srslte {
class task_dispatcher : public thread
{
public:
task_dispatcher(uint32_t max_pending_tasks);
~task_dispatcher();
void push_task(uint32_t task_code);
virtual void run_task(uint32_t task_code) = 0;
private:
std::queue<uint32_t> pending_tasks;
void run_thread();
pthread_mutex_t mutex;
pthread_cond_t cvar;
bool running;
};
} // namespace srsue
#endif // TASK_DISPATCHER_H

@ -0,0 +1,105 @@
/**
*
* \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: thread_pool.h
* Description: Implements a pool of threads. Pending tasks to execute are
* identified by a pointer.
* Reference:
*****************************************************************************/
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <stdint.h>
#include <string>
#include <vector>
#include <stack>
#include "srslte/common/threads.h"
namespace srslte {
class thread_pool
{
public:
class worker : public thread
{
public:
void setup(uint32_t id, thread_pool *parent, uint32_t prio=0, uint32_t mask = 255);
void stop();
uint32_t get_id();
void release();
protected:
virtual void work_imp() = 0;
private:
uint32_t my_id;
thread_pool *my_parent;
bool running;
void run_thread();
void wait_to_start();
void finished();
};
thread_pool(uint32_t nof_workers);
void init_worker(uint32_t id, worker*, uint32_t prio = 0, uint32_t mask = 255);
void stop();
worker* wait_worker();
worker* wait_worker(uint32_t tti);
worker* wait_worker_nb(uint32_t tti);
void start_worker(worker*);
void start_worker(uint32_t id);
worker* get_worker(uint32_t id);
uint32_t get_nof_workers();
private:
bool find_finished_worker(uint32_t tti, uint32_t *id);
typedef enum {
IDLE,
START_WORK,
WORKER_READY,
WORKING
}worker_status;
std::vector<worker*> workers;
uint32_t nof_workers;
uint32_t max_workers;
bool running;
pthread_cond_t cvar_queue;
pthread_mutex_t mutex_queue;
std::vector<worker_status> status;
std::vector<pthread_cond_t> cvar;
std::vector<pthread_mutex_t> mutex;
std::stack<worker*> available_workers;
};
}
#endif

@ -0,0 +1,151 @@
/**
*
* \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 <pthread.h>
#include <stdint.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg);
bool threads_new_rt_prio(pthread_t *thread, void *(*start_routine) (void*), void *arg, int prio_offset);
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu, int prio_offset);
bool threads_new_rt_mask(pthread_t *thread, void *(*start_routine) (void*), void *arg, int mask, int prio_offset);
void threads_print_self();
#ifdef __cplusplus
}
#ifndef THREADS_
#define THREADS_
class thread
{
public:
bool start(int prio = -1) {
return threads_new_rt_prio(&_thread, thread_function_entry, this, prio);
}
bool start_cpu(int prio, int cpu) {
return threads_new_rt_cpu(&_thread, thread_function_entry, this, cpu, prio);
}
bool start_cpu_mask(int prio, int mask){
return threads_new_rt_mask(&_thread, thread_function_entry, this, mask, prio);
}
void print_priority() {
threads_print_self();
}
void wait_thread_finish() {
pthread_join(_thread, NULL);
}
void thread_cancel() {
pthread_cancel(_thread);
}
protected:
virtual void run_thread() = 0;
private:
static void *thread_function_entry(void *_this) { ((thread*) _this)->run_thread(); return NULL; }
pthread_t _thread;
};
class periodic_thread : public thread
{
public:
void start_periodic(int period_us_, int priority = -1) {
period_us = period_us_;
start(priority);
}
protected:
virtual void run_period() = 0;
private:
int wakeups_missed;
int timer_fd;
int period_us;
void run_thread() {
if (make_periodic()) {
return;
}
while(1) {
run_period();
wait_period();
}
}
int make_periodic() {
int ret = -1;
unsigned int ns;
unsigned int sec;
struct itimerspec itval;
/* Create the timer */
ret = timerfd_create (CLOCK_MONOTONIC, 0);
wakeups_missed = 0;
timer_fd = ret;
if (ret > 0) {
/* Make the timer periodic */
sec = period_us/1e6;
ns = (period_us - (sec * 1000000)) * 1000;
itval.it_interval.tv_sec = sec;
itval.it_interval.tv_nsec = ns;
itval.it_value.tv_sec = sec;
itval.it_value.tv_nsec = ns;
ret = timerfd_settime (timer_fd, 0, &itval, NULL);
if (ret < 0) {
perror("timerfd_settime");
}
} else {
perror("timerfd_create");
}
return ret;
}
void wait_period() {
unsigned long long missed;
int ret;
/* Wait for the next timer event. If we have missed any the
number is written to "missed" */
ret = read (timer_fd, &missed, sizeof (missed));
if (ret == -1)
{
perror ("read timer");
return;
}
/* "missed" should always be >= 1, but just to be sure, check it is not 0 anyway */
if (missed > 0) {
wakeups_missed += (missed - 1);
}
}
};
#endif // THREADS_
#endif // __cplusplus

@ -0,0 +1,124 @@
/**
*
* \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: timeout.h
* Description: Millisecond resolution timeouts. Uses a dedicated thread to
* call an optional callback function upon timeout expiry.
* Reference:
*****************************************************************************/
#ifndef TIMEOUT_H
#define TIMEOUT_H
#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include "srslte/srslte.h"
namespace srslte {
class timeout_callback
{
public:
virtual void timeout_expired(uint32_t timeout_id) = 0;
};
class timeout
{
public:
timeout():running(false),callback(NULL), thread(0), timeout_id(0) {}
~timeout()
{
if(running && callback)
pthread_join(thread, NULL);
}
void start(int duration_msec_, uint32_t timeout_id_=0,timeout_callback *callback_=NULL)
{
if(duration_msec_ < 0)
return;
reset();
gettimeofday(&start_time[1], NULL);
duration_msec = duration_msec_;
running = true;
timeout_id = timeout_id_;
callback = callback_;
if(callback)
pthread_create(&thread, NULL, &thread_start, this);
}
void reset()
{
if(callback)
pthread_cancel(thread);
running = false;
}
static void* thread_start(void *t_)
{
timeout *t = (timeout*)t_;
t->thread_func();
return NULL;
}
void thread_func()
{
// substract time elapsed until now from timer duration
gettimeofday(&start_time[2], NULL);
get_time_interval(start_time);
int32_t usec = duration_msec*1000-start_time[0].tv_usec;
if(usec > 0)
usleep(usec);
if(callback && running)
callback->timeout_expired(timeout_id);
}
bool expired()
{
if(running) {
gettimeofday(&start_time[2], NULL);
get_time_interval(start_time);
return start_time[0].tv_usec > duration_msec*1000;
} else {
return false;
}
}
bool is_running()
{
return running;
}
private:
struct timeval start_time[3];
pthread_t thread;
uint32_t timeout_id;
timeout_callback *callback;
bool running;
int duration_msec;
};
} // namespace srsue
#endif // TIMEOUT_H

@ -0,0 +1,151 @@
/**
*
* \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: timers.h
* Description: Manually incremented timers. Call a callback function upon
* expiry.
* Reference:
*****************************************************************************/
#ifndef TIMERS_H
#define TIMERS_H
#include <stdio.h>
#include <stdint.h>
#include <vector>
#include <time.h>
namespace srslte {
class timer_callback
{
public:
virtual void timer_expired(uint32_t timer_id) = 0;
};
class timers
{
public:
class timer
{
public:
timer(uint32_t id_=0) {id = id_; counter = 0; timeout = 0; running = false; callback = NULL; }
void set(timer_callback *callback_, uint32_t timeout_) {
callback = callback_;
timeout = timeout_;
reset();
}
bool is_running() {
return (counter < timeout) && running;
}
bool is_expired() {
return callback && (counter >= timeout || !running);
}
uint32_t get_timeout() {
return timeout;
}
void reset() {
counter = 0;
}
void step() {
if (running) {
counter++;
if (is_expired()) {
running = false;
if (callback) {
callback->timer_expired(id);
}
}
}
}
void stop() {
running = false;
}
void run() {
running = true;
}
uint32_t id;
private:
timer_callback *callback;
uint32_t timeout;
uint32_t counter;
bool running;
};
timers(uint32_t nof_timers_) : timer_list(nof_timers_) {
nof_timers = nof_timers_;
next_timer = 0;
for (uint32_t i=0;i<nof_timers;i++) {
timer_list[i].id = i;
}
}
void step_all() {
for (uint32_t i=0;i<nof_timers;i++) {
get(i)->step();
}
}
void stop_all() {
for (uint32_t i=0;i<nof_timers;i++) {
get(i)->stop();
}
}
void run_all() {
for (uint32_t i=0;i<nof_timers;i++) {
get(i)->run();
}
}
void reset_all() {
for (uint32_t i=0;i<nof_timers;i++) {
get(i)->reset();
}
}
timer *get(uint32_t i) {
if (i < nof_timers) {
return &timer_list[i];
} else {
printf("Error accessing invalid timer %d (Only %d timers available)\n", i, nof_timers);
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;
}
return next_timer++;
}
private:
uint32_t nof_timers;
uint32_t next_timer;
std::vector<timer> timer_list;
};
} // namespace srslte
#endif // TIMERS_H

@ -0,0 +1,101 @@
/**
*
* \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: trace.h
* Description:
* Reference:
*****************************************************************************/
#ifndef TRACE_H
#define TRACE_H
#include <stdio.h>
#include <string>
#include <vector>
namespace srslte {
template<class elemType>
class trace
{
public:
trace(uint32_t nof_elems_) : tti(nof_elems_), data(nof_elems_) {
rpm=0;
nof_elems=nof_elems_;
wrapped = false;
};
void push_cur_time_us(uint32_t cur_tti) {
struct timeval t;
gettimeofday(&t, NULL);
elemType us = t.tv_sec*1e6+t.tv_usec;
push(cur_tti, us);
}
void push(uint32_t value_tti, elemType value) {
tti[rpm] = value_tti;
data[rpm] = value;
rpm++;
if (rpm >= nof_elems) {
rpm = 0;
wrapped = true;
}
}
bool writeToBinary(std::string filename) {
FILE *f = fopen(filename.c_str(), "w");
if (f != NULL) {
uint32_t st=wrapped?(rpm+1):0;
do {
writeToBinaryValue(f, st++);
if (st >= nof_elems) {
st=0;
}
} while(st!=rpm);
fclose(f);
return true;
} else {
perror("fopen");
return false;
}
}
private:
std::vector<uint32_t> tti;
std::vector<elemType> data;
uint32_t rpm;
uint32_t nof_elems;
bool wrapped;
void writeToBinaryValue(FILE *f, uint32_t idx) {
fwrite(&tti[idx], 1, sizeof(uint32_t), f);
fwrite(&data[idx], 1, sizeof(elemType), f);
}
};
} // namespace srslte
#endif // TRACE_H

@ -0,0 +1,78 @@
/**
*
* \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: tti_synch.h
* Description: Interface used for PHY-MAC synchronization
* (producer-consumer model). The consumer waits while its
* counter is lower than the producer counter.
* The PHY is the consumer. The MAC is the producer.
* Reference:
*****************************************************************************/
#ifndef TTISYNC_H
#define TTISYNC_H
#include <stdint.h>
namespace srslte {
class tti_sync
{
public:
tti_sync(uint32_t modulus_)
{
modulus = modulus_;
increment = 1;
init_counters(0);
}
virtual void increase() = 0;
virtual void resync() = 0;
virtual uint32_t wait() = 0;
virtual void set_producer_cntr(uint32_t) = 0;
uint32_t get_producer_cntr() { return producer_cntr; }
uint32_t get_consumer_cntr() { return consumer_cntr; }
void set_increment(uint32_t increment_) {
increment = increment_;
}
protected:
void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; }
void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; }
bool wait_condition() { return producer_cntr == consumer_cntr; }
void init_counters(uint32_t val)
{
consumer_cntr = val;
producer_cntr = val;
}
uint32_t increment;
uint32_t modulus;
uint32_t producer_cntr;
uint32_t consumer_cntr;
};
} // namespace srsue
#endif // TTISYNC_H

@ -0,0 +1,58 @@
/**
*
* \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: tti_synch_cv.h
* Description: Implements tti_sync interface with condition variables.
* Reference:
*****************************************************************************/
#ifndef TTISYNC_CV_H
#define TTISYNC_CV_H
#include <pthread.h>
#include "srslte/common/tti_sync.h"
namespace srslte {
class tti_sync_cv : public tti_sync
{
public:
tti_sync_cv(uint32_t modulus = 10240);
~tti_sync_cv();
void increase();
uint32_t wait();
void resync();
void set_producer_cntr(uint32_t producer_cntr);
private:
pthread_cond_t cond;
pthread_mutex_t mutex;
};
} // namespace srsue
#endif // TTISYNC_CV_H

@ -0,0 +1,268 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2017 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of srsLTE.
*
* 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 "srslte/srslte.h"
#include "srslte/common/common.h"
#include "srslte/common/security.h"
#include "srslte/interfaces/sched_interface.h"
#include "srslte/asn1/liblte_rrc.h"
#include "srslte/asn1/liblte_s1ap.h"
#include <vector>
#ifndef ENBINTERFACES_H
#define ENBINTERFACES_H
namespace srsenb {
/* Interface PHY -> MAC */
class mac_interface_phy
{
public:
const static int MAX_GRANTS = 64;
typedef struct {
srslte_enb_dl_pdsch_t sched_grants[MAX_GRANTS];
uint32_t nof_grants;
uint32_t cfi;
} dl_sched_t;
typedef struct {
srslte_enb_ul_pusch_t sched_grants[MAX_GRANTS];
srslte_enb_dl_phich_t phich[MAX_GRANTS];
uint32_t nof_grants;
uint32_t nof_phich;
} ul_sched_t;
virtual int sr_detected(uint32_t tti, uint16_t rnti) = 0;
virtual int rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv) = 0;
virtual int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) = 0;
virtual int snr_info(uint32_t tti, uint16_t rnti, float snr_db) = 0;
virtual int ack_info(uint32_t tti, uint16_t rnti, bool ack) = 0;
virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc_res) = 0;
virtual int get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res) = 0;
virtual int get_ul_sched(uint32_t tti, ul_sched_t *ul_sched_res) = 0;
// Radio-Link status
virtual void rl_failure(uint16_t rnti) = 0;
virtual void rl_ok(uint16_t rnti) = 0;
virtual void tti_clock() = 0;
};
/* Interface MAC -> PHY */
class phy_interface_mac
{
public:
/* MAC adds/removes an RNTI to the list of active RNTIs */
virtual int add_rnti(uint16_t rnti) = 0;
virtual void rem_rnti(uint16_t rnti) = 0;
};
/* Interface RRC -> PHY */
class phy_interface_rrc
{
public:
virtual void set_config_dedicated(uint16_t rnti, LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT* dedicated) = 0;
};
class mac_interface_rrc
{
public:
/* Provides cell configuration including SIB periodicity, etc. */
virtual int cell_cfg(sched_interface::cell_cfg_t *cell_cfg) = 0;
virtual void reset() = 0;
/* Manages UE configuration context */
virtual int ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *cfg) = 0;
virtual int ue_rem(uint16_t rnti) = 0;
/* Manages UE bearers and associated configuration */
virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t *cfg) = 0;
virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0;
virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0;
};
class mac_interface_rlc
{
public:
virtual int rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0;
};
//RLC interface for MAC
class rlc_interface_mac
{
public:
/* MAC calls RLC to get RLC segment of nof_bytes length.
* Segmentation happens in this function. RLC PDU is stored in payload. */
virtual int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
virtual void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t *payload) = 0;
virtual void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) = 0;
/* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread.
* PDU gets placed into the buffer and higher layer thread gets notified. */
virtual void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
};
// RLC interface for PDCP
class rlc_interface_pdcp
{
public:
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
* RLC PDUs according to TB size. */
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
};
// RLC interface for RRC
class rlc_interface_rrc
{
public:
virtual void reset(uint16_t rnti) = 0;
virtual void clear_buffer(uint16_t rnti) = 0;
virtual void add_user(uint16_t rnti) = 0;
virtual void rem_user(uint16_t rnti) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
};
// PDCP interface for GTPU
class pdcp_interface_gtpu
{
public:
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
};
// PDCP interface for RRC
class pdcp_interface_rrc
{
public:
virtual void reset(uint16_t rnti) = 0;
virtual void add_user(uint16_t rnti) = 0;
virtual void rem_user(uint16_t rnti) = 0;
virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::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 config_security(uint16_t rnti,
uint32_t lcid,
uint8_t *k_rrc_enc_,
uint8_t *k_rrc_int_,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0;
};
// PDCP interface for RLC
class pdcp_interface_rlc
{
public:
/* RLC calls PDCP to push a PDCP PDU. */
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
};
// RRC interface for RLC
class rrc_interface_rlc
{
public:
virtual void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t *payload) = 0;
virtual void read_pdu_pcch(uint8_t *payload, uint32_t payload_size) = 0;
virtual void max_retx_attempted(uint16_t rnti) = 0;
};
// RRC interface for MAC
class rrc_interface_mac
{
public:
/* Radio Link failure */
virtual void rl_failure(uint16_t rnti) = 0;
virtual void add_user(uint16_t rnti) = 0;
virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0;
virtual void set_activity_user(uint16_t rnti) = 0;
virtual bool is_paging_opportunity(uint32_t tti, uint32_t *payload_len) = 0;
};
// RRC interface for PDCP
class rrc_interface_pdcp
{
public:
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
};
// RRC interface for S1AP
class rrc_interface_s1ap
{
public:
virtual void write_dl_info(uint16_t rnti, srslte::byte_buffer_t *sdu) = 0;
virtual void release_complete(uint16_t rnti) = 0;
virtual bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) = 0;
virtual bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg) = 0;
virtual bool release_erabs(uint32_t rnti) = 0;
virtual void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID) = 0;
};
// GTPU interface for PDCP
class gtpu_interface_pdcp
{
public:
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
};
// GTPU interface for RRC
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 rem_bearer(uint16_t rnti, uint32_t lcid) = 0;
virtual void rem_user(uint16_t rnti) = 0;
};
// S1AP interface for RRC
class s1ap_interface_rrc
{
public:
virtual void initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu) = 0;
virtual void initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec) = 0;
virtual void write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu) = 0;
virtual bool user_exists(uint16_t rnti) = 0;
virtual void user_inactivity(uint16_t rnti) = 0;
virtual void release_eutran(uint16_t rnti) = 0;
virtual bool user_link_lost(uint16_t rnti) = 0;
virtual void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res) = 0;
virtual void ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *res) = 0;
// virtual void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) = 0;
};
}
#endif

@ -0,0 +1,67 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2017 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of srsLTE.
*
* 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 ENB_METRICS_INTERFACE_H
#define ENB_METRICS_INTERFACE_H
#include <stdint.h>
#include "upper/common_enb.h"
#include "upper/s1ap_metrics.h"
#include "upper/rrc_metrics.h"
#include "srslte/upper/gw_metrics.h"
#include "srslte/upper/rlc_metrics.h"
#include "mac/mac_metrics.h"
#include "phy/phy_metrics.h"
namespace srsenb {
typedef struct {
uint32_t rf_o;
uint32_t rf_u;
uint32_t rf_l;
bool rf_error;
}rf_metrics_t;
typedef struct {
rf_metrics_t rf;
phy_metrics_t phy[ENB_METRICS_MAX_USERS];
mac_metrics_t mac[ENB_METRICS_MAX_USERS];
rrc_metrics_t rrc;
s1ap_metrics_t s1ap;
bool running;
}enb_metrics_t;
// ENB interface
class enb_metrics_interface
{
public:
virtual bool get_metrics(enb_metrics_t &m) = 0;
};
} // namespace srsenb
#endif // ENB_METRICS_INTERFACE_H

@ -0,0 +1,247 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2017 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of srsLTE.
*
* 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 "srslte/srslte.h"
#ifndef SCHED_INTERFACE_H
#define SCHED_INTERFACE_H
namespace srsenb {
class sched_interface
{
public:
const static int MAX_SIB_PAYLOAD_LEN = 2048;
const static int MAX_SIBS = 16;
const static int MAX_LC = 6;
const static int MAX_DATA_LIST = 32;
const static int MAX_RAR_LIST = 8;
const static int MAX_BC_LIST = 8;
const static int MAX_RLC_PDU_LIST = 8;
const static int MAX_PHICH_LIST = 8;
typedef struct {
uint32_t len;
uint32_t period_rf;
} cell_cfg_sib_t;
typedef struct {
int pdsch_mcs;
int pdsch_max_mcs;
int pusch_mcs;
int pusch_max_mcs;
int nof_ctrl_symbols;
} sched_args_t;
typedef struct {
// Main cell configuration (used to calculate DCI locations in scheduler)
srslte_cell_t cell;
/* SIB configuration */
cell_cfg_sib_t sibs[MAX_SIBS];
uint32_t si_window_ms;
/* pusch configuration */
srslte_pusch_hopping_cfg_t pusch_hopping_cfg;
/* prach configuration */
uint32_t prach_config;
uint32_t prach_freq_offset;
uint32_t prach_rar_window;
uint32_t prach_contention_resolution_timer;
uint32_t maxharq_msg3tx;
uint32_t n1pucch_an;
uint32_t delta_pucch_shift;
uint32_t nrb_cqi;
uint32_t ncs_an;
uint32_t srs_subframe_config;
uint32_t srs_subframe_offset;
uint32_t srs_bw_config;
} cell_cfg_t;
typedef struct {
int priority;
int bsd;
int pbr;
enum {IDLE = 0, UL, DL, BOTH} direction;
} ue_bearer_cfg_t;
typedef struct {
bool continuous_pusch;
/* ue capabilities, etc */
uint32_t maxharq_tx;
uint32_t aperiodic_cqi_period; // if 0 is periodic CQI
uint32_t beta_ack_index;
uint32_t beta_ri_index;
uint32_t beta_cqi_index;
srslte_pucch_cfg_t pucch_cfg;
uint32_t n_pucch_cqi;
uint32_t sr_I;
uint32_t sr_N_pucch;
bool sr_enabled;
uint32_t cqi_pucch;
uint32_t cqi_idx;
bool cqi_enabled;
ue_bearer_cfg_t ue_bearers[MAX_LC];
} ue_cfg_t;
typedef struct {
uint32_t lcid;
uint32_t nbytes;
} dl_sched_pdu_t;
typedef struct {
uint32_t rnti;
srslte_ra_dl_dci_t dci;
srslte_dci_location_t dci_location;
uint32_t tbs;
bool mac_ce_ta;
bool mac_ce_rnti;
uint32_t nof_pdu_elems;
dl_sched_pdu_t pdu[MAX_RLC_PDU_LIST];
} dl_sched_data_t;
typedef struct {
uint32_t rnti;
bool needs_pdcch;
uint32_t current_tx_nb;
uint32_t tbs;
srslte_ra_ul_dci_t dci;
srslte_dci_location_t dci_location;
} ul_sched_data_t;
typedef struct {
uint32_t ra_id;
srslte_dci_rar_grant_t grant;
} dl_sched_rar_grant_t;
typedef struct {
uint32_t rarnti;
uint32_t tbs;
srslte_ra_dl_dci_t dci;
srslte_dci_location_t dci_location;
uint32_t nof_grants;
dl_sched_rar_grant_t grants[MAX_RAR_LIST];
} dl_sched_rar_t;
typedef struct {
srslte_ra_dl_dci_t dci;
srslte_dci_location_t dci_location;
enum bc_type {
BCCH, PCCH
} type;
uint32_t index;
uint32_t tbs;
} dl_sched_bc_t;
typedef struct {
uint32_t cfi;
uint32_t nof_data_elems;
uint32_t nof_rar_elems;
uint32_t nof_bc_elems;
dl_sched_data_t data[MAX_DATA_LIST];
dl_sched_rar_t rar[MAX_RAR_LIST];
dl_sched_bc_t bc[MAX_BC_LIST];
} dl_sched_res_t;
typedef struct {
uint16_t rnti;
enum phich_elem {
ACK, NACK
} phich;
} ul_sched_phich_t;
typedef struct {
uint32_t nof_dci_elems;
uint32_t nof_phich_elems;
ul_sched_data_t pusch[MAX_DATA_LIST];
ul_sched_phich_t phich[MAX_PHICH_LIST];
} ul_sched_res_t;
/******************* Scheduler Control ****************************/
/* Provides cell configuration including SIB periodicity, etc. */
virtual int cell_cfg(cell_cfg_t *cell_cfg) = 0;
virtual int reset() = 0;
/* Manages UE scheduling context */
virtual int ue_cfg(uint16_t rnti, ue_cfg_t *cfg) = 0;
virtual int ue_rem(uint16_t rnti) = 0;
virtual bool ue_exists(uint16_t rnti) = 0;
/* Manages UE bearers and associated configuration */
virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, ue_bearer_cfg_t *cfg) = 0;
virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0;
virtual uint32_t get_ul_buffer(uint16_t rnti) = 0;
virtual uint32_t get_dl_buffer(uint16_t rnti) = 0;
/******************* Scheduling Interface ***********************/
/* DL buffer status report */
virtual int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0;
virtual int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) = 0;
/* DL information */
virtual int dl_ack_info(uint32_t tti, uint16_t rnti, bool ack) = 0;
virtual int dl_rach_info(uint32_t tti, uint32_t ra_id, uint16_t rnti, uint32_t estimated_size) = 0;
virtual int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) = 0;
/* 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_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;
/* Run Scheduler for this tti */
virtual int dl_sched(uint32_t tti, dl_sched_res_t *sched_result) = 0;
virtual int ul_sched(uint32_t tti, ul_sched_res_t *sched_result) = 0;
};
}
#endif

@ -0,0 +1,481 @@
/**
*
* \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: interfaces.h
* Description: Abstract base class interfaces provided by layers
* to other layers.
*****************************************************************************/
#ifndef INTERFACES_H
#define INTERFACES_H
#include <string>
#include "srslte/asn1/liblte_rrc.h"
#include "srslte/common/interfaces_common.h"
#include "srslte/common/common.h"
#include "srslte/common/security.h"
namespace srsue {
// UE interface
class ue_interface
{
};
// USIM interface for NAS
class usim_interface_nas
{
public:
virtual void get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0;
virtual void get_imei_vec(uint8_t* imei_, uint32_t n) = 0;
virtual void generate_authentication_response(uint8_t *rand,
uint8_t *autn_enb,
uint16_t mcc,
uint16_t mnc,
bool *net_valid,
uint8_t *res) = 0;
virtual void generate_nas_keys(uint8_t *k_nas_enc,
uint8_t *k_nas_int,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
};
// USIM interface for RRC
class usim_interface_rrc
{
public:
virtual void generate_as_keys(uint32_t count_ul,
uint8_t *k_rrc_enc,
uint8_t *k_rrc_int,
uint8_t *k_up_enc,
uint8_t *k_up_int,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
};
// GW interface for NAS
class gw_interface_nas
{
public:
virtual srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str) = 0;
};
// GW interface for PDCP
class gw_interface_pdcp
{
public:
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
};
// NAS interface for RRC
class nas_interface_rrc
{
public:
virtual bool is_attached() = 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;
};
// RRC interface for MAC
class rrc_interface_mac
{
public:
virtual void release_pucch_srs() = 0;
virtual void ra_problem() = 0;
};
// RRC interface for PHY
class rrc_interface_phy
{
public:
virtual void in_sync() = 0;
virtual void out_of_sync() = 0;
};
// RRC interface for NAS
class rrc_interface_nas
{
public:
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
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;
};
// RRC interface for PDCP
class rrc_interface_pdcp
{
public:
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
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;
};
// RRC interface for RLC
class rrc_interface_rlc
{
public:
virtual void max_retx_attempted() = 0;
};
// PDCP interface for GW
class pdcp_interface_gw
{
public:
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
};
// PDCP interface for RRC
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 config_security(uint32_t lcid,
uint8_t *k_rrc_enc_,
uint8_t *k_rrc_int_,
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0;
};
// PDCP interface for RLC
class pdcp_interface_rlc
{
public:
/* RLC calls PDCP to push a PDCP PDU. */
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu) = 0;
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu) = 0;
virtual void write_pdu_pcch(srslte::byte_buffer_t *sdu) = 0;
};
// RLC interface for RRC
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;
};
// RLC interface for PDCP
class rlc_interface_pdcp
{
public:
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
* RLC PDUs according to TB size. */
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
};
//RLC interface for MAC
class rlc_interface_mac : public srslte::read_pdu_interface
{
public:
/* MAC calls RLC to get buffer state for a logical channel.
* This function should return quickly. */
virtual uint32_t get_buffer_state(uint32_t lcid) = 0;
virtual uint32_t get_total_buffer_state(uint32_t lcid) = 0;
const static int MAX_PDU_SEGMENTS = 20;
/* MAC calls RLC to get RLC segment of nof_bytes length.
* Segmentation happens in this function. RLC PDU is stored in payload. */
virtual int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
/* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread.
* PDU gets placed into the buffer and higher layer thread gets notified. */
virtual void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
virtual void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) = 0;
virtual void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) = 0;
virtual void write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) = 0;
};
/** MAC interface
*
*/
/* Interface PHY -> MAC */
class mac_interface_phy
{
public:
typedef struct {
uint32_t pid;
uint32_t tti;
uint32_t last_tti;
bool ndi;
bool last_ndi;
uint32_t n_bytes;
int rv;
uint16_t rnti;
bool is_from_rar;
bool is_sps_release;
bool has_cqi_request;
srslte_rnti_type_t rnti_type;
srslte_phy_grant_t phy_grant;
} mac_grant_t;
typedef struct {
bool decode_enabled;
int rv;
uint16_t rnti;
bool generate_ack;
bool default_ack;
// 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;
srslte_phy_grant_t phy_grant;
} tb_action_dl_t;
typedef struct {
bool tx_enabled;
bool expect_ack;
uint32_t rv;
uint16_t rnti;
uint32_t current_tx_nb;
srslte_softbuffer_tx_t *softbuffer;
srslte_phy_grant_t phy_grant;
uint8_t *payload_ptr;
} tb_action_ul_t;
/* Indicate reception of UL grant.
* payload_ptr points to memory where MAC PDU must be written by MAC layer */
virtual void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) = 0;
/* Indicate reception of UL grant + HARQ information throught PHICH in the same TTI. */
virtual void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) = 0;
/* Indicate reception of HARQ information only through PHICH. */
virtual void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) = 0;
/* Indicate reception of DL grant. */
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;
/* Indicate successfull decoding of BCH TB through PBCH */
virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0;
/* Indicate successfull decoding of PCH TB through PDSCH */
virtual void pch_decoded_ok(uint32_t len) = 0;
/* Function called every start of a subframe (TTI). Warning, this function is called
* from a high priority thread and should terminate asap
*/
virtual void tti_clock(uint32_t tti) = 0;
};
/* Interface RRC -> MAC */
class mac_interface_rrc
{
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;
uint16_t temp_rnti;
uint16_t tpc_rnti;
uint16_t sps_rnti;
uint64_t contention_id;
} ue_rnti_t;
/* Instructs the MAC to start receiving BCCH */
virtual void bcch_start_rx() = 0;
virtual void bcch_stop_rx() = 0;
virtual void bcch_start_rx(int si_window_start, int si_window_length) = 0;
/* Instructs the MAC to start receiving PCCH */
virtual void pcch_start_rx() = 0;
virtual void pcch_stop_rx() = 0;
/* RRC configures a logical channel */
virtual void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) = 0;
virtual uint32_t get_current_tti() = 0;
virtual void set_config(mac_cfg_t *mac_cfg) = 0;
virtual void set_config_main(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *main_cfg) = 0;
virtual void set_config_rach(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT *rach_cfg, uint32_t prach_config_index) = 0;
virtual void set_config_sr(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT *sr_cfg) = 0;
virtual void get_config(mac_cfg_t *mac_cfg) = 0;
virtual void get_rntis(ue_rnti_t *rntis) = 0;
virtual void set_contention_id(uint64_t uecri) = 0;
virtual void reconfiguration() = 0;
virtual void reset() = 0;
};
/** PHY interface
*
*/
typedef struct {
bool ul_pwr_ctrl_en;
float prach_gain;
int pdsch_max_its;
bool attach_enable_64qam;
int nof_phy_threads;
int worker_cpu_mask;
int sync_cpu_affinity;
uint32_t nof_rx_ant;
std::string equalizer_mode;
int cqi_max;
int cqi_fixed;
float snr_ema_coeff;
std::string snr_estim_alg;
bool cfo_integer_enabled;
float cfo_correct_tol_hz;
int time_correct_period;
bool sfo_correct_disable;
std::string sss_algorithm;
float estimator_fil_w;
bool rssi_sensor_enabled;
} phy_args_t;
/* Interface MAC -> PHY */
class phy_interface_mac
{
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;
/* 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;
/* Sets RAR grant payload */
virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 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
{
public:
typedef struct {
LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT prach_cnfg;
LIBLTE_RRC_PDSCH_CONFIG_COMMON_STRUCT pdsch_cnfg;
LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT pusch_cnfg;
LIBLTE_RRC_PHICH_CONFIG_STRUCT phich_cnfg;
LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT pucch_cnfg;
LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT srs_ul_cnfg;
LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT ul_pwr_ctrl;
LIBLTE_RRC_TDD_CONFIG_STRUCT tdd_cnfg;
LIBLTE_RRC_ANTENNA_PORTS_COUNT_ENUM ant_info;
} phy_cfg_common_t;
typedef struct {
LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT dedicated;
phy_cfg_common_t common;
bool enable_64qam;
} phy_cfg_t;
virtual void get_current_cell(srslte_cell_t *cell) = 0;
virtual void get_config(phy_cfg_t *phy_cfg) = 0;
virtual void set_config(phy_cfg_t *phy_cfg) = 0;
virtual void set_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated) = 0;
virtual void set_config_common(phy_cfg_common_t *common) = 0;
virtual void set_config_tdd(LIBLTE_RRC_TDD_CONFIG_STRUCT *tdd) = 0;
virtual void set_config_64qam_en(bool enable) = 0;
/* Is the PHY downlink synchronized? */
virtual bool status_is_sync() = 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;
};
} // namespace srslte
#endif // INTERFACES_H

@ -45,11 +45,11 @@
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/ch_estimation/chest_common.h" #include "srslte/phy/ch_estimation/chest_common.h"
#include "srslte/resampling/interp.h" #include "srslte/phy/resampling/interp.h"
#include "srslte/ch_estimation/refsignal_dl.h" #include "srslte/phy/ch_estimation/refsignal_dl.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
#include "srslte/sync/pss.h" #include "srslte/phy/sync/pss.h"
typedef enum { typedef enum {
@ -76,9 +76,9 @@ typedef struct {
srslte_interp_linsrslte_vec_t srslte_interp_linvec; srslte_interp_linsrslte_vec_t srslte_interp_linvec;
srslte_interp_lin_t srslte_interp_lin; srslte_interp_lin_t srslte_interp_lin;
float rssi[SRSLTE_MAX_PORTS]; float rssi[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float rsrp[SRSLTE_MAX_PORTS]; float rsrp[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
float noise_estimate[SRSLTE_MAX_PORTS]; float noise_estimate[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS];
/* Use PSS for noise estimation in LS linear interpolation mode */ /* Use PSS for noise estimation in LS linear interpolation mode */
cf_t pss_signal[SRSLTE_PSS_LEN]; cf_t pss_signal[SRSLTE_PSS_LEN];
@ -86,6 +86,7 @@ typedef struct {
cf_t tmp_pss_noisy[SRSLTE_PSS_LEN]; cf_t tmp_pss_noisy[SRSLTE_PSS_LEN];
srslte_chest_dl_noise_alg_t noise_alg; srslte_chest_dl_noise_alg_t noise_alg;
int last_nof_antennas;
} srslte_chest_dl_t; } srslte_chest_dl_t;
@ -105,6 +106,12 @@ 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_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q,
srslte_chest_dl_noise_alg_t noise_estimation_alg); 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],
uint32_t sf_idx,
uint32_t nof_rx_antennas);
SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q, SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q,
cf_t *input, cf_t *input,
cf_t *ce[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS],
@ -114,7 +121,8 @@ SRSLTE_API int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q,
cf_t *input, cf_t *input,
cf_t *ce, cf_t *ce,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t port_id); uint32_t port_id,
uint32_t rxant_id);
SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q); SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q);

@ -43,10 +43,10 @@
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/ch_estimation/chest_common.h" #include "srslte/phy/ch_estimation/chest_common.h"
#include "srslte/resampling/interp.h" #include "srslte/phy/resampling/interp.h"
#include "srslte/ch_estimation/refsignal_ul.h" #include "srslte/phy/ch_estimation/refsignal_ul.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
typedef struct { typedef struct {
srslte_cell_t cell; srslte_cell_t cell;
@ -56,6 +56,7 @@ typedef struct {
bool dmrs_signal_configured; bool dmrs_signal_configured;
cf_t *pilot_estimates; cf_t *pilot_estimates;
cf_t *pilot_estimates_tmp[4];
cf_t *pilot_recv_signal; cf_t *pilot_recv_signal;
cf_t *pilot_known_signal; cf_t *pilot_known_signal;
cf_t *tmp_noise; cf_t *tmp_noise;
@ -105,7 +106,8 @@ SRSLTE_API int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q,
cf_t *ce, cf_t *ce,
srslte_pucch_format_t format, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t n_pucch,
uint32_t sf_idx); uint32_t sf_idx,
uint8_t *pucch2_ack_bits);
SRSLTE_API float srslte_chest_ul_get_noise_estimate(srslte_chest_ul_t *q); SRSLTE_API float srslte_chest_ul_get_noise_estimate(srslte_chest_ul_t *q);

@ -36,7 +36,7 @@
#define SRSLTE_REFSIGNAL_DL_ #define SRSLTE_REFSIGNAL_DL_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
// Number of references in a subframe: there are 2 symbols for port_id=0,1 x 2 slots x 2 refs per prb // 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(nof_prb, port_id) (((port_id)<2?8:4)*(nof_prb))

@ -36,8 +36,8 @@
#define SRSLTE_REFSIGNAL_UL_ #define SRSLTE_REFSIGNAL_UL_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/phch/pucch.h" #include "srslte/phy/phch/pucch.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
#define SRSLTE_NOF_GROUPS_U 30 #define SRSLTE_NOF_GROUPS_U 30
#define SRSLTE_NOF_SEQUENCES_U 2 #define SRSLTE_NOF_SEQUENCES_U 2

@ -50,7 +50,7 @@
#define SRSLTE_PC_MAX 23 // Maximum TX power for Category 1 UE (in dBm) #define SRSLTE_PC_MAX 23 // Maximum TX power for Category 1 UE (in dBm)
#define SRSLTE_MAX_PORTS 4 #define SRSLTE_MAX_PORTS 4
#define SRSLTE_MAX_LAYERS 8 #define SRSLTE_MAX_LAYERS 4
#define SRSLTE_MAX_CODEWORDS 2 #define SRSLTE_MAX_CODEWORDS 2
#define SRSLTE_LTE_CRC24A 0x1864CFB #define SRSLTE_LTE_CRC24A 0x1864CFB
@ -125,7 +125,7 @@ typedef enum {SRSLTE_CP_NORM, SRSLTE_CP_EXT} srslte_cp_t;
|| l == SRSLTE_CP_NSYMB(cp) - 3) || l == SRSLTE_CP_NSYMB(cp) - 3)
#define SRSLTE_NOF_LTE_BANDS 29 #define SRSLTE_NOF_LTE_BANDS 38
#define SRSLTE_DEFAULT_MAX_FRAMES_PBCH 500 #define SRSLTE_DEFAULT_MAX_FRAMES_PBCH 500
#define SRSLTE_DEFAULT_MAX_FRAMES_PSS 10 #define SRSLTE_DEFAULT_MAX_FRAMES_PSS 10
@ -158,7 +158,6 @@ typedef enum {
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t nof_prb; uint32_t nof_prb;
uint32_t nof_ports; uint32_t nof_ports;
uint32_t bw_idx;
uint32_t id; uint32_t id;
srslte_cp_t cp; srslte_cp_t cp;
srslte_phich_length_t phich_length; srslte_phich_length_t phich_length;
@ -168,7 +167,8 @@ typedef struct SRSLTE_API {
typedef enum SRSLTE_API { typedef enum SRSLTE_API {
SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA,
SRSLTE_MIMO_TYPE_TX_DIVERSITY, SRSLTE_MIMO_TYPE_TX_DIVERSITY,
SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX,
SRSLTE_MIMO_TYPE_CDD
} srslte_mimo_type_t; } srslte_mimo_type_t;
typedef enum SRSLTE_API { typedef enum SRSLTE_API {
@ -246,7 +246,13 @@ SRSLTE_API char *srslte_mod_string(srslte_mod_t mod);
SRSLTE_API uint32_t srslte_mod_bits_x_symbol(srslte_mod_t mod); SRSLTE_API uint32_t srslte_mod_bits_x_symbol(srslte_mod_t mod);
SRSLTE_API float srslte_band_fd(uint32_t earfcn); SRSLTE_API int srslte_band_get_band(uint32_t dl_earfcn);
SRSLTE_API float srslte_band_fd(uint32_t dl_earfcn);
SRSLTE_API float srslte_band_fu(uint32_t ul_earfcn);
SRSLTE_API uint32_t srslte_band_ul_earfcn(uint32_t dl_earfcn);
SRSLTE_API int srslte_band_get_fd_band(uint32_t band, SRSLTE_API int srslte_band_get_fd_band(uint32_t band,
srslte_earfcn_t *earfcn, srslte_earfcn_t *earfcn,

@ -37,7 +37,7 @@
#define LTESEQ_ #define LTESEQ_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint8_t *c; uint8_t *c;

@ -37,8 +37,8 @@
#define DFTPREC_ #define DFTPREC_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
#include "srslte/dft/dft.h" #include "srslte/phy/dft/dft.h"
/* DFT-based Transform Precoding object */ /* DFT-based Transform Precoding object */
typedef struct SRSLTE_API { typedef struct SRSLTE_API {

@ -41,8 +41,8 @@
#include <stdlib.h> #include <stdlib.h>
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
#include "srslte/dft/dft.h" #include "srslte/phy/dft/dft.h"
/* This is common for both directions */ /* This is common for both directions */
typedef struct SRSLTE_API{ typedef struct SRSLTE_API{

@ -40,25 +40,25 @@
#include <stdbool.h> #include <stdbool.h>
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
#include "srslte/dft/ofdm.h" #include "srslte/phy/dft/ofdm.h"
#include "srslte/sync/pss.h" #include "srslte/phy/sync/pss.h"
#include "srslte/sync/sss.h" #include "srslte/phy/sync/sss.h"
#include "srslte/ch_estimation/refsignal_dl.h" #include "srslte/phy/ch_estimation/refsignal_dl.h"
#include "srslte/phch/dci.h" #include "srslte/phy/phch/dci.h"
#include "srslte/phch/pbch.h" #include "srslte/phy/phch/pbch.h"
#include "srslte/phch/pcfich.h" #include "srslte/phy/phch/pcfich.h"
#include "srslte/phch/pdcch.h" #include "srslte/phy/phch/pdcch.h"
#include "srslte/phch/pdsch.h" #include "srslte/phy/phch/pdsch.h"
#include "srslte/phch/pdsch_cfg.h" #include "srslte/phy/phch/pdsch_cfg.h"
#include "srslte/phch/phich.h" #include "srslte/phy/phch/phich.h"
#include "srslte/phch/ra.h" #include "srslte/phy/phch/ra.h"
#include "srslte/phch/regs.h" #include "srslte/phy/phch/regs.h"
#include "srslte/enb/enb_ul.h" #include "srslte/phy/enb/enb_ul.h"
#include "srslte/utils/vector.h" #include "srslte/phy/utils/vector.h"
#include "srslte/utils/debug.h" #include "srslte/phy/utils/debug.h"
#include "srslte/config.h" #include "srslte/config.h"
@ -87,12 +87,12 @@ typedef struct SRSLTE_API {
float sss_signal0[SRSLTE_SSS_LEN]; float sss_signal0[SRSLTE_SSS_LEN];
float sss_signal5[SRSLTE_SSS_LEN]; float sss_signal5[SRSLTE_SSS_LEN];
uint32_t nof_rnti; float tx_amp;
} srslte_enb_dl_t; } srslte_enb_dl_t;
typedef struct { typedef struct {
int rnti_idx; uint16_t rnti;
srslte_ra_dl_dci_t grant; srslte_ra_dl_dci_t grant;
srslte_dci_location_t location; srslte_dci_location_t location;
srslte_softbuffer_tx_t *softbuffer; srslte_softbuffer_tx_t *softbuffer;
@ -100,20 +100,24 @@ typedef struct {
} srslte_enb_dl_pdsch_t; } srslte_enb_dl_pdsch_t;
typedef struct { typedef struct {
uint16_t rnti;
uint8_t ack; uint8_t ack;
int rnti_idx; uint32_t n_prb_lowest;
uint32_t n_dmrs;
} srslte_enb_dl_phich_t; } srslte_enb_dl_phich_t;
/* This function shall be called just after the initial synchronization */ /* This function shall be called just after the initial synchronization */
SRSLTE_API int srslte_enb_dl_init(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_init(srslte_enb_dl_t *q,
srslte_cell_t cell, srslte_cell_t cell);
uint32_t nof_rntis);
SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_free(srslte_enb_dl_t *q);
SRSLTE_API void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q,
uint32_t cfi); uint32_t cfi);
SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q,
float amp);
SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q); SRSLTE_API void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q);
SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_put_sync(srslte_enb_dl_t *q,
@ -140,17 +144,16 @@ SRSLTE_API void srslte_enb_dl_put_base(srslte_enb_dl_t *q,
SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_gen_signal(srslte_enb_dl_t *q,
cf_t *signal_buffer); cf_t *signal_buffer);
SRSLTE_API int srslte_enb_dl_cfg_rnti(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_add_rnti(srslte_enb_dl_t *q,
uint32_t idx,
uint16_t rnti); uint16_t rnti);
SRSLTE_API int srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q, SRSLTE_API void srslte_enb_dl_rem_rnti(srslte_enb_dl_t *q,
uint32_t idx); uint16_t rnti);
SRSLTE_API int srslte_enb_dl_put_pdsch(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_ra_dl_grant_t *grant,
srslte_softbuffer_tx_t *softbuffer, srslte_softbuffer_tx_t *softbuffer,
uint32_t rnti_idx, uint16_t rnti,
uint32_t rv_idx, uint32_t rv_idx,
uint32_t sf_idx, uint32_t sf_idx,
uint8_t *data); uint8_t *data);
@ -159,13 +162,13 @@ SRSLTE_API int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q,
srslte_ra_dl_dci_t *grant, srslte_ra_dl_dci_t *grant,
srslte_dci_format_t format, srslte_dci_format_t format,
srslte_dci_location_t location, srslte_dci_location_t location,
uint32_t rnti_idx, uint16_t rnti,
uint32_t sf_idx); uint32_t sf_idx);
SRSLTE_API int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q, SRSLTE_API int srslte_enb_dl_put_pdcch_ul(srslte_enb_dl_t *q,
srslte_ra_ul_dci_t *grant, srslte_ra_ul_dci_t *grant,
srslte_dci_location_t location, srslte_dci_location_t location,
uint32_t rnti_idx, uint16_t rnti,
uint32_t sf_idx); uint32_t sf_idx);

@ -40,16 +40,16 @@
#include <stdbool.h> #include <stdbool.h>
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
#include "srslte/dft/ofdm.h" #include "srslte/phy/dft/ofdm.h"
#include "srslte/ch_estimation/chest_ul.h" #include "srslte/phy/ch_estimation/chest_ul.h"
#include "srslte/phch/prach.h" #include "srslte/phy/phch/prach.h"
#include "srslte/phch/pusch.h" #include "srslte/phy/phch/pusch.h"
#include "srslte/phch/pusch_cfg.h" #include "srslte/phy/phch/pusch_cfg.h"
#include "srslte/phch/ra.h" #include "srslte/phy/phch/ra.h"
#include "srslte/utils/vector.h" #include "srslte/phy/utils/vector.h"
#include "srslte/utils/debug.h" #include "srslte/phy/utils/debug.h"
#include "srslte/config.h" #include "srslte/config.h"
@ -58,9 +58,16 @@ typedef struct {
uint32_t n_dmrs; uint32_t n_dmrs;
} srslte_enb_ul_phich_info_t; } srslte_enb_ul_phich_info_t;
typedef struct {
bool uci_cfg_en;
bool srs_cfg_en;
srslte_uci_cfg_t uci_cfg;
srslte_refsignal_srs_cfg_t srs_cfg;
srslte_pucch_sched_t pucch_sched;
} srslte_enb_ul_user_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_cell_t cell; srslte_cell_t cell;
uint32_t nof_rnti;
cf_t *sf_symbols; cf_t *sf_symbols;
cf_t *ce; cf_t *ce;
@ -77,24 +84,19 @@ typedef struct SRSLTE_API {
srslte_pusch_hopping_cfg_t hopping_cfg; srslte_pusch_hopping_cfg_t hopping_cfg;
// Configuration for each user // Configuration for each user
bool *uci_cfg_en; srslte_enb_ul_user_t **users;
bool *srs_cfg_en;
srslte_uci_cfg_t *uci_cfg;
srslte_refsignal_srs_cfg_t *srs_cfg;
srslte_pucch_sched_t *pucch_sched;
} srslte_enb_ul_t; } srslte_enb_ul_t;
typedef struct { typedef struct {
int rnti_idx; uint16_t rnti;
srslte_ra_ul_dci_t grant; srslte_ra_ul_dci_t grant;
srslte_dci_location_t location; srslte_dci_location_t location;
uint32_t rv_idx; uint32_t rv_idx;
uint32_t current_tx_nb; uint32_t current_tx_nb;
bool needs_pdcch;
uint8_t *data; uint8_t *data;
srslte_softbuffer_rx_t *softbuffer; srslte_softbuffer_rx_t *softbuffer;
bool needs_pdcch;
} srslte_enb_ul_pusch_t; } srslte_enb_ul_pusch_t;
/* This function shall be called just after the initial synchronization */ /* This function shall be called just after the initial synchronization */
@ -103,29 +105,27 @@ SRSLTE_API int srslte_enb_ul_init(srslte_enb_ul_t *q,
srslte_prach_cfg_t* prach_cfg, srslte_prach_cfg_t* prach_cfg,
srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg,
srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_pusch_hopping_cfg_t *hopping_cfg,
srslte_pucch_cfg_t *pucch_cfg, srslte_pucch_cfg_t *pucch_cfg);
uint32_t nof_rntis);
SRSLTE_API void srslte_enb_ul_free(srslte_enb_ul_t *q); SRSLTE_API void srslte_enb_ul_free(srslte_enb_ul_t *q);
SRSLTE_API int srslte_enb_ul_cfg_rnti(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_add_rnti(srslte_enb_ul_t *q,
uint32_t idx, uint16_t rnti);
SRSLTE_API void srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q,
uint16_t rnti); uint16_t rnti);
SRSLTE_API int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint32_t idx, SRSLTE_API int srslte_enb_ul_cfg_ue(srslte_enb_ul_t *q, uint16_t rnti,
srslte_uci_cfg_t *uci_cfg, srslte_uci_cfg_t *uci_cfg,
srslte_pucch_sched_t *pucch_sched, srslte_pucch_sched_t *pucch_sched,
srslte_refsignal_srs_cfg_t *srs_cfg); srslte_refsignal_srs_cfg_t *srs_cfg);
SRSLTE_API int srslte_enb_ul_rem_rnti(srslte_enb_ul_t *q,
uint32_t idx);
SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q, SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q,
cf_t *signal_buffer); cf_t *signal_buffer);
SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q,
uint32_t rnti_idx, uint16_t rnti,
uint32_t pdcch_n_cce, uint32_t pdcch_n_cce,
uint32_t sf_rx, uint32_t sf_rx,
srslte_uci_data_t *uci_data); srslte_uci_data_t *uci_data);
@ -133,7 +133,7 @@ SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q,
SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q,
srslte_ra_ul_grant_t *grant, srslte_ra_ul_grant_t *grant,
srslte_softbuffer_rx_t *softbuffer, srslte_softbuffer_rx_t *softbuffer,
uint32_t rnti_idx, uint16_t rnti,
uint32_t rv_idx, uint32_t rv_idx,
uint32_t current_tx_nb, uint32_t current_tx_nb,
uint8_t *data, uint8_t *data,

@ -37,7 +37,7 @@
#define SOFTBUFFER_ #define SOFTBUFFER_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t max_cb; uint32_t max_cb;

@ -39,7 +39,7 @@
#define TURBOCODER_ #define TURBOCODER_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/fec/tc_interl.h" #include "srslte/phy/fec/tc_interl.h"
#define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144/8) #define SRSLTE_TCOD_MAX_LEN_CB_BYTES (6144/8)

@ -40,8 +40,8 @@
#define TURBODECODER_ #define TURBODECODER_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/fec/tc_interl.h" #include "srslte/phy/fec/tc_interl.h"
#include "srslte/fec/cbsegm.h" #include "srslte/phy/fec/cbsegm.h"
#define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_RATE 3
#define SRSLTE_TCOD_TOTALTAIL 12 #define SRSLTE_TCOD_TOTALTAIL 12
@ -49,10 +49,10 @@
#define SRSLTE_TCOD_MAX_LEN_CB 6144 #define SRSLTE_TCOD_MAX_LEN_CB 6144
#define SRSLTE_TCOD_MAX_LEN_CODED (SRSLTE_TCOD_RATE*SRSLTE_TCOD_MAX_LEN_CB+SRSLTE_TCOD_TOTALTAIL) #define SRSLTE_TCOD_MAX_LEN_CODED (SRSLTE_TCOD_RATE*SRSLTE_TCOD_MAX_LEN_CB+SRSLTE_TCOD_TOTALTAIL)
#include "srslte/fec/turbodecoder_gen.h" #include "srslte/phy/fec/turbodecoder_gen.h"
#ifdef LV_HAVE_SSE #ifdef LV_HAVE_SSE
#include "srslte/fec/turbodecoder_sse.h" #include "srslte/phy/fec/turbodecoder_sse.h"
#endif #endif
typedef struct SRSLTE_API { typedef struct SRSLTE_API {

@ -40,8 +40,8 @@
#define TURBODECODER_GEN_ #define TURBODECODER_GEN_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/fec/tc_interl.h" #include "srslte/phy/fec/tc_interl.h"
#include "srslte/fec/cbsegm.h" #include "srslte/phy/fec/cbsegm.h"
#define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_RATE 3
#define SRSLTE_TCOD_TOTALTAIL 12 #define SRSLTE_TCOD_TOTALTAIL 12

@ -40,8 +40,8 @@
#define TURBODECODER_SSE_ #define TURBODECODER_SSE_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/fec/tc_interl.h" #include "srslte/phy/fec/tc_interl.h"
#include "srslte/fec/cbsegm.h" #include "srslte/phy/fec/cbsegm.h"
#define SRSLTE_TCOD_RATE 3 #define SRSLTE_TCOD_RATE 3
#define SRSLTE_TCOD_TOTALTAIL 12 #define SRSLTE_TCOD_TOTALTAIL 12

@ -100,6 +100,18 @@ SRSLTE_API int srslte_viterbi_init_sse(srslte_viterbi_t *q,
uint32_t max_frame_length, uint32_t max_frame_length,
bool tail_bitting); bool tail_bitting);
SRSLTE_API int srslte_viterbi_init_neon(srslte_viterbi_t *q,
srslte_viterbi_type_t type,
int poly[3],
uint32_t max_frame_length,
bool tail_bitting);
SRSLTE_API int srslte_viterbi_init_avx2(srslte_viterbi_t *q,
srslte_viterbi_type_t type,
int poly[3],
uint32_t max_frame_length,
bool tail_bitting);
#endif #endif

@ -41,7 +41,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/io/format.h" #include "srslte/phy/io/format.h"
/* Low-level API */ /* Low-level API */
typedef struct SRSLTE_API { typedef struct SRSLTE_API {

@ -41,7 +41,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/io/format.h" #include "srslte/phy/io/format.h"
/* Low-level API */ /* Low-level API */
typedef struct SRSLTE_API { typedef struct SRSLTE_API {

@ -59,8 +59,8 @@ typedef struct SRSLTE_API {
}srslte_netsink_t; }srslte_netsink_t;
SRSLTE_API int srslte_netsink_init(srslte_netsink_t *q, SRSLTE_API int srslte_netsink_init(srslte_netsink_t *q,
char *address, const char *address,
int port, uint16_t port,
srslte_netsink_type_t type); srslte_netsink_type_t type);
SRSLTE_API void srslte_netsink_free(srslte_netsink_t *q); SRSLTE_API void srslte_netsink_free(srslte_netsink_t *q);

@ -60,8 +60,8 @@ typedef struct SRSLTE_API {
}srslte_netsource_t; }srslte_netsource_t;
SRSLTE_API int srslte_netsource_init(srslte_netsource_t *q, SRSLTE_API int srslte_netsource_init(srslte_netsource_t *q,
char *address, const char *address,
int port, uint16_t port,
srslte_netsource_type_t type); srslte_netsource_type_t type);
SRSLTE_API void srslte_netsource_free(srslte_netsource_t *q); SRSLTE_API void srslte_netsource_free(srslte_netsource_t *q);

@ -38,7 +38,7 @@
#define LAYERMAP_H_ #define LAYERMAP_H_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
/* Generates the vector of layer-mapped symbols "x" based on the vector of data symbols "d" /* Generates the vector of layer-mapped symbols "x" based on the vector of data symbols "d"
*/ */

@ -37,7 +37,7 @@
#define PRECODING_H_ #define PRECODING_H_
#include "srslte/config.h" #include "srslte/config.h"
#include "srslte/common/phy_common.h" #include "srslte/phy/common/phy_common.h"
/** The precoder takes as input nlayers vectors "x" from the /** The precoder takes as input nlayers vectors "x" from the
* layer mapping and generates nports vectors "y" to be mapped onto * layer mapping and generates nports vectors "y" to be mapped onto
@ -53,7 +53,14 @@ SRSLTE_API int srslte_precoding_single(cf_t *x,
SRSLTE_API int srslte_precoding_diversity(cf_t *x[SRSLTE_MAX_LAYERS], SRSLTE_API int srslte_precoding_diversity(cf_t *x[SRSLTE_MAX_LAYERS],
cf_t *y[SRSLTE_MAX_PORTS], cf_t *y[SRSLTE_MAX_PORTS],
int nof_ports, int nof_symbols); int nof_ports,
int nof_symbols);
SRSLTE_API int srslte_precoding_cdd(cf_t *x[SRSLTE_MAX_LAYERS],
cf_t *y[SRSLTE_MAX_PORTS],
int nof_layers,
int nof_ports,
int nof_symbols);
SRSLTE_API int srslte_precoding_type(cf_t *x[SRSLTE_MAX_LAYERS], SRSLTE_API int srslte_precoding_type(cf_t *x[SRSLTE_MAX_LAYERS],
cf_t *y[SRSLTE_MAX_PORTS], cf_t *y[SRSLTE_MAX_PORTS],
@ -70,12 +77,26 @@ SRSLTE_API int srslte_predecoding_single(cf_t *y,
int nof_symbols, int nof_symbols,
float noise_estimate); float noise_estimate);
SRSLTE_API int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_PORTS],
cf_t *h[SRSLTE_MAX_PORTS],
cf_t *x,
int nof_rxant,
int nof_symbols,
float noise_estimate);
SRSLTE_API int srslte_predecoding_diversity(cf_t *y, SRSLTE_API int srslte_predecoding_diversity(cf_t *y,
cf_t *h[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS],
cf_t *x[SRSLTE_MAX_LAYERS], cf_t *x[SRSLTE_MAX_LAYERS],
int nof_ports, int nof_ports,
int nof_symbols); int nof_symbols);
SRSLTE_API int srslte_predecoding_diversity_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_symbols);
SRSLTE_API int srslte_predecoding_type(cf_t *y, SRSLTE_API int srslte_predecoding_type(cf_t *y,
cf_t *h[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS],
cf_t *x[SRSLTE_MAX_LAYERS], cf_t *x[SRSLTE_MAX_LAYERS],
@ -85,4 +106,14 @@ SRSLTE_API int srslte_predecoding_type(cf_t *y,
srslte_mimo_type_t type, srslte_mimo_type_t type,
float noise_estimate); float noise_estimate);
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 nof_symbols,
srslte_mimo_type_t type,
float noise_estimate);
#endif /* PRECODING_H_ */ #endif /* PRECODING_H_ */

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save