@ -19,15 +19,10 @@
*
*/
# include <pthread.h>
# include <string.h>
# include <strings.h>
# include "srsue/hdr/phy/prach.h"
# include "srslte/common/log.h"
# include "srslte/interfaces/ue_interfaces.h"
# include "srslte/srslte.h"
# include "srsue/hdr/phy/phy.h"
# include "srsue/hdr/phy/prach.h"
# define Error(fmt, ...) \
if ( SRSLTE_DEBUG_ENABLED ) \
@ -42,76 +37,80 @@
if ( SRSLTE_DEBUG_ENABLED ) \
log_h - > debug ( fmt , # # __VA_ARGS__ )
namespace srsue {
prach : : ~ prach ( )
{
stop ( ) ;
}
using namespace srsue ;
void prach : : init ( uint32_t max_prb , srslte : : log * log_h_ )
{
log_h = log_h_ ;
for ( int i = 0 ; i < 64 ; i + + ) {
for ( int f = 0 ; f < 12 ; f + + ) {
buffer[ f ] [ i ] = srslte_vec_cf_malloc ( SRSLTE_PRACH_MAX_LEN ) ;
if ( ! buffer[ f ] [ i ] ) {
for ( auto & i : buffer ) {
for ( auto & j : i ) {
j = srslte_vec_cf_malloc ( SRSLTE_PRACH_MAX_LEN ) ;
if ( ! j ) {
perror ( " malloc " ) ;
return ;
}
}
}
if ( srslte_cfo_init ( & cfo_h , SRSLTE_PRACH_MAX_LEN ) ) {
ERROR ( " PRACH: Error initiating CFO \n " ) ;
return ;
}
srslte_cfo_set_tol ( & cfo_h , 0 ) ;
signal_buffer = srslte_vec_cf_malloc ( MAX_LEN_SF * 30720U ) ;
if ( ! signal_buffer ) {
perror ( " malloc " ) ;
return ;
}
if ( srslte_prach_init ( & prach_obj , srslte_symbol_sz ( max_prb ) ) ) {
Error ( " Initiating PRACH library \n " ) ;
return ;
}
mem_initiated = true ;
}
void prach : : stop ( )
{
if ( mem_initiated ) {
for ( int i = 0 ; i < 64 ; i + + ) {
for ( int f = 0 ; f < 12 ; f + + ) {
if ( buffer [ f ] [ i ] ) {
free ( buffer [ f ] [ i ] ) ;
if ( ! mem_initiated ) {
return ;
}
for ( auto & i : buffer ) {
for ( auto & j : i ) {
free ( j ) ;
}
}
if ( signal_buffer ) {
free ( signal_buffer ) ;
}
srslte_cfo_free ( & cfo_h ) ;
srslte_prach_free ( & prach_obj ) ;
mem_initiated = false ;
}
}
bool prach : : set_cell ( srslte_cell_t cell_ , srslte_prach_cfg_t prach_cfg )
{
if ( mem_initiated ) {
if ( ! mem_initiated ) {
ERROR ( " PRACH: Error must call init() first \n " ) ;
return false ;
}
// TODO: Check if other PRACH parameters changed
if ( cell . id ! = cell_ . id | | ! cell_initiated ) {
if ( cell . id = = cell_ . id & & cell_initiated ) {
return true ;
}
cell = cell_ ;
cfg = prach_cfg ;
preamble_idx = - 1 ;
if ( 6 + prach_cfg . freq_offset > cell . nof_prb ) {
log_h - > console (
" Error no space for PRACH: frequency offset=%d, N_rb_ul=%d \n " , prach_cfg . freq_offset , cell . nof_prb ) ;
log_h - > error (
" Error no space for PRACH: frequency offset=%d, N_rb_ul=%d \n " , prach_cfg . freq_offset , cell . nof_prb ) ;
log_h - > console ( " Error no space for PRACH: frequency offset=%d, N_rb_ul=%d \n " , prach_cfg . freq_offset , cell . nof_prb ) ;
log_h - > error ( " Error no space for PRACH: frequency offset=%d, N_rb_ul=%d \n " , prach_cfg . freq_offset , cell . nof_prb ) ;
return false ;
}
@ -130,12 +129,8 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg)
len = prach_obj . N_seq + prach_obj . N_cp ;
transmitted_tti = - 1 ;
cell_initiated = true ;
}
return true ;
} else {
ERROR ( " PRACH: Error must call init() first \n " ) ;
return false ;
}
}
bool prach : : generate_buffer ( uint32_t f_idx )
@ -161,14 +156,15 @@ bool prach::generate_buffer(uint32_t f_idx)
bool prach : : prepare_to_send ( uint32_t preamble_idx_ , int allowed_subframe_ , float target_power_dbm_ )
{
if ( cell_initiated & & preamble_idx_ < 64 ) {
if ( cell_initiated & & preamble_idx_ < max_preambles ) {
preamble_idx = preamble_idx_ ;
target_power_dbm = target_power_dbm_ ;
allowed_subframe = allowed_subframe_ ;
transmitted_tti = - 1 ;
Debug ( " PRACH: prepare to send preamble %d \n " , preamble_idx ) ;
return true ;
} else {
}
if ( ! cell_initiated ) {
Error ( " PRACH: Cell not configured \n " ) ;
} else {
@ -176,11 +172,10 @@ bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float
}
return false ;
}
}
bool prach : : is_pending ( )
bool prach : : is_pending ( ) const
{
return cell_initiated & & preamble_idx > = 0 & & preamble_idx < 64 ;
return cell_initiated & & preamble_idx > = 0 & & unsigned ( preamble_idx ) < max_preambles ;
}
bool prach : : is_ready_to_send ( uint32_t current_tti_ )
@ -197,7 +192,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_)
return false ;
}
phy_interface_mac_lte : : prach_info_t prach : : get_info ( )
phy_interface_mac_lte : : prach_info_t prach : : get_info ( ) const
{
phy_interface_mac_lte : : prach_info_t info = { } ;
@ -217,8 +212,15 @@ phy_interface_mac_lte::prach_info_t prach::get_info()
cf_t * prach : : generate ( float cfo , uint32_t * nof_sf , float * target_power )
{
if ( cell_initiated & & preamble_idx > = 0 & & nof_sf & & preamble_idx < 64 & & srslte_cell_isvalid ( & cell ) & &
len < MAX_LEN_SF * 30720 & & len > 0 ) {
if ( ! cell_initiated | | preamble_idx < 0 | | ! nof_sf | | unsigned ( preamble_idx ) > = max_preambles | |
! srslte_cell_isvalid ( & cell ) | | len > = MAX_LEN_SF * 30720 | | len = = 0 ) {
Error ( " PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d \n " ,
cell_initiated ,
preamble_idx ,
cell . nof_prb ,
len ) ;
return nullptr ;
}
uint32_t f_idx = 0 ;
if ( cell . frame_type = = SRSLTE_TDD ) {
@ -227,19 +229,19 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power)
if ( prach_obj . config_idx > = 48 ) {
f_idx + = 6 ;
}
if ( f_idx > = 12 ) {
if ( f_idx > = max_fs ) {
Error ( " PRACH Buffer: Invalid f_idx=%d \n " , f_idx ) ;
f_idx = 0 ;
}
}
if ( ! generate_buffer ( f_idx ) ) {
return NULL ;
return nullptr ;
}
if ( ! is_buffer_generated ( f_idx , preamble_idx ) ) {
Error ( " PRACH Buffer not generated: f_idx=%d preamble_idx=%d \n " , f_idx , preamble_idx ) ;
return NULL ;
return nullptr ;
}
// Correct CFO before transmission
@ -264,14 +266,4 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power)
preamble_idx = - 1 ;
return signal_buffer ;
} else {
Error ( " PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d \n " ,
cell_initiated ,
preamble_idx ,
cell . nof_prb ,
len ) ;
return NULL ;
}
}
} // namespace srsue