Commit 4a10f2c7 authored by Ben Wojtowicz's avatar Ben Wojtowicz

Version 0.9.1: Implemented liblte_phy routines for determining TBS, MCS,...

Version 0.9.1: Implemented liblte_phy routines for determining TBS, MCS, N_prb, and N_cce, fixed a bug in the RIV calculation of dci_1a_unpack, added error checking on sizes passed to memcpy in liblte_rrc, added support for changing the sample rate in the LTE_fdd_dl_file_gen app, and added finding FFTW to cmake
parent 9d8cd129
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
######################################################################## ########################################################################
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
project(openLTE CXX C) project(openLTE CXX C)
set(openLTE_version 0.9.0) set(openLTE_version 0.9.1)
enable_testing() enable_testing()
#select the release build type by default to get optimization flags #select the release build type by default to get optimization flags
...@@ -93,6 +93,7 @@ find_package(Gnuradio "3.7.0") ...@@ -93,6 +93,7 @@ find_package(Gnuradio "3.7.0")
find_package(GnuradioOsmosdr) find_package(GnuradioOsmosdr)
find_package(Rtlsdr) find_package(Rtlsdr)
find_package(HackRf) find_package(HackRf)
find_package(FFTW3F)
if(NOT GNURADIO_RUNTIME_FOUND) if(NOT GNURADIO_RUNTIME_FOUND)
message(FATAL_ERROR "GNURadio required to compile openLTE") message(FATAL_ERROR "GNURadio required to compile openLTE")
...@@ -110,11 +111,16 @@ if(NOT HACKRF_FOUND) ...@@ -110,11 +111,16 @@ if(NOT HACKRF_FOUND)
message(FATAL_ERROR "HackRF required to compile openLTE (http://github.com/mossmann/hackrf/wiki)") message(FATAL_ERROR "HackRF required to compile openLTE (http://github.com/mossmann/hackrf/wiki)")
endif() endif()
if(NOT FFTW3F_FOUND)
message(FATAL_ERROR "FFTW3 required to compile openLTE")
endif()
######################################################################## ########################################################################
# Setup the include and linker paths # Setup the include and linker paths
######################################################################## ########################################################################
include_directories( include_directories(
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${FFTW3F_INCLUDE_DIRS}
${GNURADIO_RUNTIME_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS}
${GNURADIO_PMT_INCLUDE_DIRS} ${GNURADIO_PMT_INCLUDE_DIRS}
${GNURADIO_OSMOSDR_INCLUDE_DIRS} ${GNURADIO_OSMOSDR_INCLUDE_DIRS}
...@@ -122,6 +128,7 @@ include_directories( ...@@ -122,6 +128,7 @@ include_directories(
link_directories( link_directories(
${Boost_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS}
${FFTW3F_LIBRARY_DIRS}
${GNURADIO_RUNTIME_LIBRARY_DIRS} ${GNURADIO_RUNTIME_LIBRARY_DIRS}
${GNURADIO_PMT_LIBRARY_DIRS} ${GNURADIO_PMT_LIBRARY_DIRS}
${GNURADIO_OSMOSDR_LIBRARY_DIRS} ${GNURADIO_OSMOSDR_LIBRARY_DIRS}
......
...@@ -60,6 +60,11 @@ v00.08.03 Added MAC functionality to the LTE library, fixed bugs in RRC port ...@@ -60,6 +60,11 @@ v00.08.03 Added MAC functionality to the LTE library, fixed bugs in RRC port
of the LTE library, and added hackrf and SIB decode and print support of the LTE library, and added hackrf and SIB decode and print support
to the scanner app. to the scanner app.
v00.09.00 Updated to support GnuRadio 3.7, added PRACH support to liblte_phy, v00.09.00 Updated to support GnuRadio 3.7, added PRACH support to liblte_phy,
cleaned up PRACH support in octave, moved to using a socket select with cleaned up PRACH support in octave, moved to using socket select with
a timeout in libtools, added a new hardware discovery mechanism in a timeout in libtools, added a new hardware discovery mechanism in
LTE_fdd_dl_scan, and added a file recording application. LTE_fdd_dl_scan, and added a file recording application.
v00.09.01 Implemented liblte_phy routines for determining TBS, MCS, N_prb, and
N_cce, fixed a bug in the RIV calculation of dci_1a_unpack, added error
checking on sizes passed to memcpy in liblte_rrc, added support for
changing the sample rate in the LTE_fdd_dl_file_gen app, and added
finding FFTW to cmake.
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
03/03/2013 Ben Wojtowicz Added support for a test load. 03/03/2013 Ben Wojtowicz Added support for a test load.
07/21/2013 Ben Wojtowicz Using the latest LTE library. 07/21/2013 Ben Wojtowicz Using the latest LTE library.
08/26/2013 Ben Wojtowicz Updates to support GnuRadio 3.7. 08/26/2013 Ben Wojtowicz Updates to support GnuRadio 3.7.
09/16/2013 Ben Wojtowicz Added support for changing the sample rate.
*******************************************************************************/ *******************************************************************************/
...@@ -53,7 +54,7 @@ ...@@ -53,7 +54,7 @@
DEFINES DEFINES
*******************************************************************************/ *******************************************************************************/
#define LTE_FDD_DL_FG_SAMP_BUF_SIZE (307200) #define LTE_FDD_DL_FG_SAMP_BUF_SIZE (LIBLTE_PHY_N_SAMPS_PER_FRAME_30_72MHZ)
// Configurable Parameters // Configurable Parameters
#define BANDWIDTH_PARAM "bandwidth" #define BANDWIDTH_PARAM "bandwidth"
...@@ -129,6 +130,7 @@ private: ...@@ -129,6 +130,7 @@ private:
LIBLTE_PHY_PHICH_STRUCT phich; LIBLTE_PHY_PHICH_STRUCT phich;
LIBLTE_PHY_PDCCH_STRUCT pdcch; LIBLTE_PHY_PDCCH_STRUCT pdcch;
LIBLTE_PHY_SUBFRAME_STRUCT subframe; LIBLTE_PHY_SUBFRAME_STRUCT subframe;
LIBLTE_PHY_FS_ENUM fs;
float phich_res; float phich_res;
float bandwidth; float bandwidth;
uint32 sfn; uint32 sfn;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
07/21/2013 Ben Wojtowicz Using the latest LTE library. 07/21/2013 Ben Wojtowicz Using the latest LTE library.
08/26/2013 Ben Wojtowicz Updates to support GnuRadio 3.7 and the 08/26/2013 Ben Wojtowicz Updates to support GnuRadio 3.7 and the
latest LTE library. latest LTE library.
09/16/2013 Ben Wojtowicz Added support for changing the sample rate.
*******************************************************************************/ *******************************************************************************/
...@@ -87,8 +88,9 @@ LTE_fdd_dl_fg_samp_buf::LTE_fdd_dl_fg_samp_buf() ...@@ -87,8 +88,9 @@ LTE_fdd_dl_fg_samp_buf::LTE_fdd_dl_fg_samp_buf()
{ {
// Initialize the LTE parameters // Initialize the LTE parameters
// General // General
bandwidth = 10; bandwidth = 20;
N_rb_dl = LIBLTE_PHY_N_RB_DL_10MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_20MHZ;
fs = LIBLTE_PHY_FS_30_72MHZ;
sfn = 0; sfn = 0;
N_frames = 30; N_frames = 30;
N_ant = 1; N_ant = 1;
...@@ -98,7 +100,7 @@ LTE_fdd_dl_fg_samp_buf::LTE_fdd_dl_fg_samp_buf() ...@@ -98,7 +100,7 @@ LTE_fdd_dl_fg_samp_buf::LTE_fdd_dl_fg_samp_buf()
sib_tx_mode = 1; sib_tx_mode = 1;
percent_load = 0; percent_load = 0;
// MIB // MIB
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_50; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_100;
mib.phich_config.dur = LIBLTE_RRC_PHICH_DURATION_NORMAL; mib.phich_config.dur = LIBLTE_RRC_PHICH_DURATION_NORMAL;
mib.phich_config.res = LIBLTE_RRC_PHICH_RESOURCE_1; mib.phich_config.res = LIBLTE_RRC_PHICH_RESOURCE_1;
phich_res = 1; phich_res = 1;
...@@ -270,7 +272,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -270,7 +272,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
{ {
// Initialize the LTE library // Initialize the LTE library
liblte_phy_init(&phy_struct, liblte_phy_init(&phy_struct,
LIBLTE_PHY_FS_30_72MHZ, fs,
N_id_cell, N_id_cell,
N_ant, N_ant,
N_rb_dl, N_rb_dl,
...@@ -534,8 +536,8 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -534,8 +536,8 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
liblte_phy_create_dl_subframe(phy_struct, liblte_phy_create_dl_subframe(phy_struct,
&subframe, &subframe,
p, p,
&i_buf[(p*LTE_FDD_DL_FG_SAMP_BUF_SIZE) + (subframe.num*30720)], &i_buf[(p*phy_struct->N_samps_per_frame) + (subframe.num*phy_struct->N_samps_per_subfr)],
&q_buf[(p*LTE_FDD_DL_FG_SAMP_BUF_SIZE) + (subframe.num*30720)]); &q_buf[(p*phy_struct->N_samps_per_frame) + (subframe.num*phy_struct->N_samps_per_subfr)]);
} }
} }
}else{ }else{
...@@ -558,7 +560,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -558,7 +560,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
q_samp = 0; q_samp = 0;
for(p=0; p<N_ant; p++) for(p=0; p<N_ant; p++)
{ {
q_samp += q_buf[(p*LTE_FDD_DL_FG_SAMP_BUF_SIZE) + samp_buf_idx]; q_samp += q_buf[(p*phy_struct->N_samps_per_frame) + samp_buf_idx];
} }
out[out_idx++] = (int8)(q_samp); out[out_idx++] = (int8)(q_samp);
samp_buf_idx++; samp_buf_idx++;
...@@ -566,9 +568,9 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -566,9 +568,9 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
} }
// Determine how many full samples to write // Determine how many full samples to write
if((LTE_FDD_DL_FG_SAMP_BUF_SIZE - samp_buf_idx) < ((noutput_items - act_noutput_items) / 2)) if((phy_struct->N_samps_per_frame - samp_buf_idx) < ((noutput_items - act_noutput_items) / 2))
{ {
loop_cnt = (LTE_FDD_DL_FG_SAMP_BUF_SIZE - samp_buf_idx)*2; loop_cnt = (phy_struct->N_samps_per_frame - samp_buf_idx)*2;
}else{ }else{
loop_cnt = noutput_items - act_noutput_items; loop_cnt = noutput_items - act_noutput_items;
} }
...@@ -580,8 +582,8 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -580,8 +582,8 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
q_samp = 0; q_samp = 0;
for(p=0; p<N_ant; p++) for(p=0; p<N_ant; p++)
{ {
i_samp += i_buf[(p*LTE_FDD_DL_FG_SAMP_BUF_SIZE) + samp_buf_idx]; i_samp += i_buf[(p*phy_struct->N_samps_per_frame) + samp_buf_idx];
q_samp += q_buf[(p*LTE_FDD_DL_FG_SAMP_BUF_SIZE) + samp_buf_idx]; q_samp += q_buf[(p*phy_struct->N_samps_per_frame) + samp_buf_idx];
} }
out[out_idx++] = (int8)(i_samp); out[out_idx++] = (int8)(i_samp);
...@@ -596,7 +598,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -596,7 +598,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
i_samp = 0; i_samp = 0;
for(p=0; p<N_ant; p++) for(p=0; p<N_ant; p++)
{ {
i_samp += i_buf[(p*LTE_FDD_DL_FG_SAMP_BUF_SIZE) + samp_buf_idx]; i_samp += i_buf[(p*phy_struct->N_samps_per_frame) + samp_buf_idx];
} }
out[out_idx++] = (int8)(i_samp); out[out_idx++] = (int8)(i_samp);
act_noutput_items++; act_noutput_items++;
...@@ -607,7 +609,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items, ...@@ -607,7 +609,7 @@ int32 LTE_fdd_dl_fg_samp_buf::work(int32 noutput_items,
} }
// Check to see if we need more samples // Check to see if we need more samples
if(samp_buf_idx >= LTE_FDD_DL_FG_SAMP_BUF_SIZE) if(samp_buf_idx >= phy_struct->N_samps_per_frame)
{ {
samples_ready = false; samples_ready = false;
samp_buf_idx = 0; samp_buf_idx = 0;
...@@ -926,26 +928,32 @@ bool LTE_fdd_dl_fg_samp_buf::set_bandwidth(char *char_value) ...@@ -926,26 +928,32 @@ bool LTE_fdd_dl_fg_samp_buf::set_bandwidth(char *char_value)
bandwidth = 1.4; bandwidth = 1.4;
N_rb_dl = LIBLTE_PHY_N_RB_DL_1_4MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_1_4MHZ;
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_6; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_6;
fs = LIBLTE_PHY_FS_1_92MHZ;
}else if(!strcasecmp(char_value, "3")){ }else if(!strcasecmp(char_value, "3")){
bandwidth = 3; bandwidth = 3;
N_rb_dl = LIBLTE_PHY_N_RB_DL_3MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_3MHZ;
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_15; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_15;
fs = LIBLTE_PHY_FS_3_84MHZ;
}else if(!strcasecmp(char_value, "5")){ }else if(!strcasecmp(char_value, "5")){
bandwidth = 5; bandwidth = 5;
N_rb_dl = LIBLTE_PHY_N_RB_DL_5MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_5MHZ;
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_25; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_25;
fs = LIBLTE_PHY_FS_7_68MHZ;
}else if(!strcasecmp(char_value, "10")){ }else if(!strcasecmp(char_value, "10")){
bandwidth = 10; bandwidth = 10;
N_rb_dl = LIBLTE_PHY_N_RB_DL_10MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_10MHZ;
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_50; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_50;
fs = LIBLTE_PHY_FS_15_36MHZ;
}else if(!strcasecmp(char_value, "15")){ }else if(!strcasecmp(char_value, "15")){
bandwidth = 15; bandwidth = 15;
N_rb_dl = LIBLTE_PHY_N_RB_DL_15MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_15MHZ;
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_75; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_75;
fs = LIBLTE_PHY_FS_30_72MHZ;
}else if(!strcasecmp(char_value, "20")){ }else if(!strcasecmp(char_value, "20")){
bandwidth = 20; bandwidth = 20;
N_rb_dl = LIBLTE_PHY_N_RB_DL_20MHZ; N_rb_dl = LIBLTE_PHY_N_RB_DL_20MHZ;
mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_100; mib.dl_bw = LIBLTE_RRC_DL_BANDWIDTH_100;
fs = LIBLTE_PHY_FS_30_72MHZ;
}else{ }else{
err = true; err = true;
} }
......
...@@ -7,7 +7,6 @@ octave Octave test code ...@@ -7,7 +7,6 @@ octave Octave test code
cmn_hdr Common header files cmn_hdr Common header files
liblte C++ library of commonly used LTE functions liblte C++ library of commonly used LTE functions
cmake Files needed for cmake cmake Files needed for cmake
build Cmake generated build files
LTE_fdd_dl_file_scan A gnu-radio LTE FDD DL file scanner application LTE_fdd_dl_file_scan A gnu-radio LTE FDD DL file scanner application
LTE_fdd_dl_file_gen A gnu-radio LTE FDD DL file generator application LTE_fdd_dl_file_gen A gnu-radio LTE FDD DL file generator application
LTE_fdd_dl_scan A gnu-radio LTE FDD DL scanner application that LTE_fdd_dl_scan A gnu-radio LTE FDD DL scanner application that
...@@ -17,12 +16,14 @@ LTE_file_recorder A gnu-radio LTE file recording application that ...@@ -17,12 +16,14 @@ LTE_file_recorder A gnu-radio LTE file recording application that
To build the C++ and python code use the following: To build the C++ and python code use the following:
$ mkdir build
$ cd build $ cd build
$ cmake ../ $ cmake ../
$ make $ make
To install the C++ and python code use the following: To install the C++ and python code use the following:
$ mkdir build
$ cd build $ cd build
$ cmake ../ $ cmake ../
$ make $ make
...@@ -43,7 +44,9 @@ and specify a recorded LTE file as the input. For example: ...@@ -43,7 +44,9 @@ and specify a recorded LTE file as the input. For example:
$ LTE_fdd_dl_file_scan.py lte_file.bin $ LTE_fdd_dl_file_scan.py lte_file.bin
The recorded LTE file currently must be interleaved 8-bit I and The recorded LTE file currently must be interleaved 8-bit I and
Q samples recorded at 30.72MHz. Q samples recorded at 30.72MHz. NOTE: Files generated by the
file generator app can be used with the file scanner app only if
generated with 20MHz or 15MHz of bandwidth.
#################### ####################
# FILE GENERATOR # # FILE GENERATOR #
...@@ -60,8 +63,11 @@ For example: ...@@ -60,8 +63,11 @@ For example:
$ LTE_fdd_dl_file_gen.py lte_file.bin $ LTE_fdd_dl_file_gen.py lte_file.bin
The generated LTE file contains interleaved 8-bit I and Q samples The generated LTE file contains interleaved 8-bit I and Q samples
at a sample rate of 30.72MHz. The output file can be used as the at a sample rate specified by the bandwidth (i.e. 30.72Msps for
input for the LTE_fdd_dl_file_scan application. 20MHz or 15MHz, 15.36Msps for 10MHz, 7.68MHz for 5MHz, 3.84Msps
for 3MHz, or 1.92Msps for 1.4MHz). The output file can be used as
the input for the LTE_fdd_dl_file_scan application when the
bandwidth is set to 20MHz or 15MHz.
############# #############
# SCANNER # # SCANNER #
......
# http://tim.klingt.org/code/projects/supernova/repository/revisions/d336dd6f400e381bcfd720e96139656de0c53b6a/entry/cmake_modules/FindFFTW3f.cmake
# Modified to use pkg config and use standard var names
# Find single-precision (float) version of FFTW3
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_FFTW3F "fftw3f >= 3.0")
FIND_PATH(
FFTW3F_INCLUDE_DIRS
NAMES fftw3.h
HINTS $ENV{FFTW3_DIR}/include
${PC_FFTW3F_INCLUDE_DIR}
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
FFTW3F_LIBRARIES
NAMES fftw3f libfftw3f
HINTS $ENV{FFTW3_DIR}/lib
${PC_FFTW3F_LIBDIR}
PATHS /usr/local/lib
/usr/lib
/usr/lib64
)
FIND_LIBRARY(
FFTW3F_THREADS_LIBRARIES
NAMES fftw3f_threads libfftw3f_threads
HINTS $ENV{FFTW3_DIR}/lib
${PC_FFTW3F_LIBDIR}
PATHS /usr/local/lib
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFTW3F DEFAULT_MSG FFTW3F_LIBRARIES FFTW3F_INCLUDE_DIRS)
MARK_AS_ADVANCED(FFTW3F_LIBRARIES FFTW3F_INCLUDE_DIRS FFTW3F_THREADS_LIBRARIES)
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
08/26/2013 Ben Wojtowicz Added PRACH generation and detection support 08/26/2013 Ben Wojtowicz Added PRACH generation and detection support
and changed ambiguous routines/variables to and changed ambiguous routines/variables to
be non-ambiguous. be non-ambiguous.
09/16/2013 Ben Wojtowicz Implemented routines for determine TBS, MCS,
N_prb, and N_cce.
*******************************************************************************/ *******************************************************************************/
...@@ -860,6 +862,8 @@ LIBLTE_ERROR_ENUM liblte_phy_get_dl_subframe_and_ce(LIBLTE_PHY_STRUCT * ...@@ -860,6 +862,8 @@ LIBLTE_ERROR_ENUM liblte_phy_get_dl_subframe_and_ce(LIBLTE_PHY_STRUCT *
the specified number of DL bits the specified number of DL bits
Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7 Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7
NOTES: Currently only supports DCI format 1A
*********************************************************************/ *********************************************************************/
// Defines // Defines
// Enums // Enums
...@@ -882,15 +886,15 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits, ...@@ -882,15 +886,15 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits,
scheme scheme
Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7 Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7
NOTES: Currently only supports single layer transport blocks
*********************************************************************/ *********************************************************************/
// Defines // Defines
// Enums // Enums
// Structs // Structs
// Functions // Functions
LIBLTE_ERROR_ENUM liblte_phy_get_tbs_and_n_prb_for_dl(uint32 N_bits, LIBLTE_ERROR_ENUM liblte_phy_get_tbs_and_n_prb_for_dl(uint32 N_bits,
uint32 N_subframe,
uint32 N_rb_dl, uint32 N_rb_dl,
uint16 rnti,
uint8 mcs, uint8 mcs,
uint32 *tbs, uint32 *tbs,
uint32 *N_prb); uint32 *N_prb);
...@@ -927,7 +931,9 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_ul(uint32 N_bits, ...@@ -927,7 +931,9 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_ul(uint32 N_bits,
// Structs // Structs
// Functions // Functions
LIBLTE_ERROR_ENUM liblte_phy_get_n_cce(LIBLTE_PHY_STRUCT *phy_struct, LIBLTE_ERROR_ENUM liblte_phy_get_n_cce(LIBLTE_PHY_STRUCT *phy_struct,
uint32 N_subframe, float phich_res,
uint32 N_pdcch_symbs,
uint8 N_ant,
uint32 *N_cce); uint32 *N_cce);
#endif /* __LIBLTE_PHY_H__ */ #endif /* __LIBLTE_PHY_H__ */
...@@ -71,6 +71,9 @@ ...@@ -71,6 +71,9 @@
08/26/2013 Ben Wojtowicz Added PRACH generation and detection support 08/26/2013 Ben Wojtowicz Added PRACH generation and detection support
and changed ambiguous routines/variables to and changed ambiguous routines/variables to
be non-ambiguous. be non-ambiguous.
09/16/2013 Ben Wojtowicz Implemented routines for determining TBS,
MCS, N_prb, and N_cce. Fixed a bug in the
RIV calculation of dci_1a_unpack.
*******************************************************************************/ *******************************************************************************/
...@@ -4890,6 +4893,8 @@ LIBLTE_ERROR_ENUM liblte_phy_get_dl_subframe_and_ce(LIBLTE_PHY_STRUCT * ...@@ -4890,6 +4893,8 @@ LIBLTE_ERROR_ENUM liblte_phy_get_dl_subframe_and_ce(LIBLTE_PHY_STRUCT *
the specified number of DL bits the specified number of DL bits
Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7 Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7
NOTES: Currently only supports DCI format 1A
*********************************************************************/ *********************************************************************/
LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits, LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits,
uint32 N_subframe, uint32 N_subframe,
...@@ -4908,7 +4913,10 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits, ...@@ -4908,7 +4913,10 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits,
mcs != NULL && mcs != NULL &&
N_prb != NULL) N_prb != NULL)
{ {
if(LIBLTE_MAC_SI_RNTI == rnti) if(LIBLTE_MAC_SI_RNTI == rnti ||
LIBLTE_MAC_P_RNTI == rnti ||
(LIBLTE_MAC_RA_RNTI_START <= rnti &&
LIBLTE_MAC_RA_RNTI_END >= rnti))
{ {
// Choose N_prb == 2 to give the largest possible tbs // Choose N_prb == 2 to give the largest possible tbs
N_prb_tmp = 2; N_prb_tmp = 2;
...@@ -4956,16 +4964,48 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits, ...@@ -4956,16 +4964,48 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_dl(uint32 N_bits,
scheme scheme
Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7 Document Reference: 3GPP TS 36.213 v10.3.0 section 7.1.7
NOTES: Currently only supports single layer transport blocks
*********************************************************************/ *********************************************************************/
LIBLTE_ERROR_ENUM liblte_phy_get_tbs_and_n_prb_for_dl(uint32 N_bits, LIBLTE_ERROR_ENUM liblte_phy_get_tbs_and_n_prb_for_dl(uint32 N_bits,
uint32 N_subframe,
uint32 N_rb_dl, uint32 N_rb_dl,
uint16 rnti,
uint8 mcs, uint8 mcs,
uint32 *tbs, uint32 *tbs,
uint32 *N_prb) uint32 *N_prb)
{ {
// FIXME LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint32 I_tbs;
uint32 i;
if(tbs != NULL &&
N_prb != NULL &&
mcs <= 28)
{
// Determine I_tbs
if(9 >= mcs)
{
I_tbs = mcs;
}else if(16 >= mcs){
I_tbs = mcs - 1;
}else{
I_tbs = mcs - 2;
}
// Determine N_prb
for(i=0; i<N_rb_dl; i++)
{
if(N_bits < TBS_71721[I_tbs][i])
{
*tbs = TBS_71721[I_tbs][i];
*N_prb = i + 1;
break;
}
}
err = LIBLTE_SUCCESS;
}
return(err);
} }
/********************************************************************* /*********************************************************************
...@@ -4983,7 +5023,44 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_ul(uint32 N_bits, ...@@ -4983,7 +5023,44 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_ul(uint32 N_bits,
uint8 *mcs, uint8 *mcs,
uint32 *N_prb) uint32 *N_prb)
{ {
// FIXME LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS;
uint32 I_tbs;
uint32 i;
uint32 j;
if(tbs != NULL &&
mcs != NULL &&
N_prb != NULL)
{
// Determine I_tbs and N_prb
for(i=0; i<27; i++)
{
for(j=0; j<N_rb_ul; j++)
{
if(N_bits < TBS_71721[i][j])
{
I_tbs = i;
*tbs = TBS_71721[i][j];
*N_prb = j + 1;
break;
}
}
}
// Determine mcs
if(10 >= I_tbs)
{
*mcs = I_tbs;
}else if(19 >= I_tbs){
*mcs = I_tbs + 1;
}else{
*mcs = I_tbs + 2;
}
err = LIBLTE_SUCCESS;
}
return(err);
} }
/********************************************************************* /*********************************************************************
...@@ -4995,10 +5072,33 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_ul(uint32 N_bits, ...@@ -4995,10 +5072,33 @@ LIBLTE_ERROR_ENUM liblte_phy_get_tbs_mcs_and_n_prb_for_ul(uint32 N_bits,
Document Reference: 3GPP TS 36.211 v10.1.0 section 6.8.1 Document Reference: 3GPP TS 36.211 v10.1.0 section 6.8.1
*********************************************************************/ *********************************************************************/
LIBLTE_ERROR_ENUM liblte_phy_get_n_cce(LIBLTE_PHY_STRUCT *phy_struct, LIBLTE_ERROR_ENUM liblte_phy_get_n_cce(LIBLTE_PHY_STRUCT *phy_struct,
uint32 N_subframe, float phich_res,
uint32 N_pdcch_symbs,
uint8 N_ant,
uint32 *N_cce) uint32 *N_cce)
{ {
// FIXME uint32 N_group_phich;
uint32 N_reg_phich;
uint32 N_reg_pcfich = 4;
uint32 N_reg_rb = 3;
uint32 N_reg_pdcch;
uint32 N_reg_cce = 9;
// From liblte_phy_pdcch_channel_encode
if(LIBLTE_PHY_N_SC_RB_NORMAL_CP == phy_struct->N_sc_rb)
{
N_group_phich = (uint32)ceilf((float)phich_res*((float)phy_struct->N_rb_dl/(float)8));
}else{
N_group_phich = 2*(uint32)ceilf((float)phich_res*((float)phy_struct->N_rb_dl/(float)8));
}
N_reg_phich = N_group_phich*3;
N_reg_pdcch = N_pdcch_symbs*(phy_struct->N_rb_dl*N_reg_rb) - phy_struct->N_rb_dl - N_reg_pcfich - N_reg_phich;
if(N_ant == 4)
{
N_reg_pdcch -= phy_struct->N_rb_dl;
}
*N_cce = N_reg_pdcch/N_reg_cce;
} }
/******************************************************************************* /*******************************************************************************
...@@ -9877,9 +9977,9 @@ void dci_1a_unpack(uint8 *in_bits, ...@@ -9877,9 +9977,9 @@ void dci_1a_unpack(uint8 *in_bits,
// Find the RIV that was sent 3GPP TS 36.213 v10.3.0 section 7.1.6.3 // Find the RIV that was sent 3GPP TS 36.213 v10.3.0 section 7.1.6.3
RIV_length = (uint32)ceilf(logf(N_rb_dl*(N_rb_dl+1)/2)/logf(2)); RIV_length = (uint32)ceilf(logf(N_rb_dl*(N_rb_dl+1)/2)/logf(2));
RIV = phy_bits_2_value(&dci, RIV_length); RIV = phy_bits_2_value(&dci, RIV_length);
for(i=0; i<N_rb_dl; i++) for(i=1; i<=N_rb_dl; i++) // L_crb running variable (1 to N_rb_dl)
{ {
for(j=0; j<(N_rb_dl-i); j++) for(j=0; j<=(N_rb_dl-i); j++) // RB_start running variable (0 to N_rb_dl-L_crb)
{ {
if((i-1) <= (N_rb_dl/2)) if((i-1) <= (N_rb_dl/2))
{ {
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
and paging packing and unpacking. and paging packing and unpacking.
07/21/2013 Ben Wojtowicz Fixed several bugs and moved to the common 07/21/2013 Ben Wojtowicz Fixed several bugs and moved to the common
message struct. message struct.
09/16/2013 Ben Wojtowicz Added error checking on sizes passed to
memcpy.
*******************************************************************************/ *******************************************************************************/
...@@ -6457,21 +6459,31 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_bcch_dlsch_msg(LIBLTE_RRC_BCCH_DLSCH_MSG_STRUC ...@@ -6457,21 +6459,31 @@ LIBLTE_ERROR_ENUM liblte_rrc_pack_bcch_dlsch_msg(LIBLTE_RRC_BCCH_DLSCH_MSG_STRUC
// SIB1 Choice // SIB1 Choice
rrc_value_2_bits(1, &msg_ptr, 1); rrc_value_2_bits(1, &msg_ptr, 1);
liblte_rrc_pack_sys_info_block_type_1_msg((LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *)&bcch_dlsch_msg->sibs[0].sib, err = liblte_rrc_pack_sys_info_block_type_1_msg((LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *)&bcch_dlsch_msg->sibs[0].sib,
&global_msg); &global_msg);
memcpy(msg_ptr, global_msg.msg, global_msg.N_bits); if(global_msg.N_bits <= (LIBLTE_MAX_MSG_SIZE - 2))
msg->N_bits = global_msg.N_bits + 2; {
memcpy(msg_ptr, global_msg.msg, global_msg.N_bits);
msg->N_bits = global_msg.N_bits + 2;
}else{
msg->N_bits = 0;
err = LIBLTE_ERROR_INVALID_INPUTS;
}