@ -651,19 +651,6 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_)
p . add_section ( & phy_cfg_ ) ;
p . add_section ( & phy_cfg_ ) ;
p . add_section ( & rrc_cnfg ) ;
p . add_section ( & rrc_cnfg ) ;
// If the cell list is empty, use default values from enb.conf to keep backwards compatibility
if ( rrc_cfg_ - > cell_list . empty ( ) ) {
rrc_cfg_ - > cell_list . resize ( 1 ) ;
cell_cfg_t & cell_cfg = rrc_cfg_ - > cell_list [ 0 ] ;
cell_cfg . rf_port = 0 ;
cell_cfg . cell_id = 0 ;
cell_cfg . tac = args_ - > stack . s1ap . tac ;
cell_cfg . pci = args_ - > enb . pci ;
cell_cfg . root_seq_idx = rrc_cfg_ - > sibs [ 1 ] . sib2 ( ) . rr_cfg_common . prach_cfg . root_seq_idx ;
cell_cfg . dl_earfcn = args_ - > enb . dl_earfcn ;
cell_cfg . ul_earfcn = args_ - > enb . ul_earfcn ;
}
return p . parse ( ) ;
return p . parse ( ) ;
}
}
@ -672,7 +659,7 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root)
meas_cfg - > meas_cells . resize ( root . getLength ( ) ) ;
meas_cfg - > meas_cells . resize ( root . getLength ( ) ) ;
for ( uint32_t i = 0 ; i < meas_cfg - > meas_cells . size ( ) ; + + i ) {
for ( uint32_t i = 0 ; i < meas_cfg - > meas_cells . size ( ) ; + + i ) {
meas_cfg - > meas_cells [ i ] . earfcn = root [ i ] [ " dl_earfcn " ] ;
meas_cfg - > meas_cells [ i ] . earfcn = root [ i ] [ " dl_earfcn " ] ;
meas_cfg - > meas_cells [ i ] . pci = ( unsigned int ) root [ i ] [ " pci " ] % 504 ;
meas_cfg - > meas_cells [ i ] . pci = ( unsigned int ) root [ i ] [ " pci " ] % SRSLTE_NUM_PCI ;
meas_cfg - > meas_cells [ i ] . eci = ( unsigned int ) root [ i ] [ " eci " ] ;
meas_cfg - > meas_cells [ i ] . eci = ( unsigned int ) root [ i ] [ " eci " ] ;
meas_cfg - > meas_cells [ i ] . q_offset = 0 ; // LIBLTE_RRC_Q_OFFSET_RANGE_DB_0; // TODO
meas_cfg - > meas_cells [ i ] . q_offset = 0 ; // LIBLTE_RRC_Q_OFFSET_RANGE_DB_0; // TODO
// // TODO: TEMP
// // TODO: TEMP
@ -715,7 +702,6 @@ static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& root)
static int parse_cell_list ( all_args_t * args , rrc_cfg_t * rrc_cfg , Setting & root )
static int parse_cell_list ( all_args_t * args , rrc_cfg_t * rrc_cfg , Setting & root )
{
{
auto cell_id_parser = [ ] ( uint32_t & cell_id , Setting & root ) { return parse_bounded_number ( cell_id , root , 0u , 255u ) ; } ;
auto cell_id_parser = [ ] ( uint32_t & cell_id , Setting & root ) { return parse_bounded_number ( cell_id , root , 0u , 255u ) ; } ;
uint32_t self_cellid = args - > stack . s1ap . cell_id & 0xFFu ;
rrc_cfg - > cell_list . resize ( root . getLength ( ) ) ;
rrc_cfg - > cell_list . resize ( root . getLength ( ) ) ;
for ( uint32_t n = 0 ; n < rrc_cfg - > cell_list . size ( ) ; + + n ) {
for ( uint32_t n = 0 ; n < rrc_cfg - > cell_list . size ( ) ; + + n ) {
@ -723,13 +709,14 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root)
auto & cellroot = root [ n ] ;
auto & cellroot = root [ n ] ;
parse_opt_field ( cell_cfg . rf_port , cellroot , " rf_port " ) ;
parse_opt_field ( cell_cfg . rf_port , cellroot , " rf_port " ) ;
parse_default_field ( cell_cfg . cell_id , cellroot , " cell_id " , self_cellid , cell_id_parser ) ;
HANDLEPARSERCODE ( parse_required_field ( cell_cfg . cell_id , cellroot , " cell_id " ) ) ;
parse_default_field ( cell_cfg . tac , cellroot , " tac " , args - > stack . s1ap . tac ) ;
HANDLEPARSERCODE ( parse_required_field ( cell_cfg . tac , cellroot , " tac " ) ) ;
parse_default_field ( cell_cfg . pci , cellroot , " pci " , args - > enb . pci ) ;
HANDLEPARSERCODE ( parse_required_field ( cell_cfg . pci , cellroot , " pci " ) ) ;
cell_cfg . pci = cell_cfg . pci % SRSLTE_NUM_PCI ;
HANDLEPARSERCODE ( parse_required_field ( cell_cfg . dl_earfcn , cellroot , " dl_earfcn " ) ) ;
HANDLEPARSERCODE ( parse_required_field ( cell_cfg . ul_earfcn , cellroot , " ul_earfcn " ) ) ;
parse_default_field (
parse_default_field (
cell_cfg . root_seq_idx , cellroot , " root_seq_idx " , rrc_cfg - > sibs [ 1 ] . sib2 ( ) . rr_cfg_common . prach_cfg . root_seq_idx ) ;
cell_cfg . root_seq_idx , cellroot , " root_seq_idx " , rrc_cfg - > sibs [ 1 ] . sib2 ( ) . rr_cfg_common . prach_cfg . root_seq_idx ) ;
cell_cfg . dl_earfcn = cellroot [ " dl_earfcn " ] ;
cell_cfg . ul_earfcn = cellroot [ " ul_earfcn " ] ;
if ( cellroot [ " ho_active " ] ) {
if ( cellroot [ " ho_active " ] ) {
HANDLEPARSERCODE ( parse_meas_cell_list ( & rrc_cfg - > meas_cfg , cellroot [ " meas_cell_list " ] ) ) ;
HANDLEPARSERCODE ( parse_meas_cell_list ( & rrc_cfg - > meas_cfg , cellroot [ " meas_cell_list " ] ) ) ;
@ -778,13 +765,12 @@ namespace enb_conf_sections {
int parse_cell_cfg ( all_args_t * args_ , srslte_cell_t * cell )
int parse_cell_cfg ( all_args_t * args_ , srslte_cell_t * cell )
{
{
cell - > frame_type = SRSLTE_FDD ;
cell - > frame_type = SRSLTE_FDD ;
cell - > id = args_ - > enb . pci ;
cell - > cp = SRSLTE_CP_NORM ;
cell - > cp = SRSLTE_CP_NORM ;
cell - > nof_ports = args_ - > enb . nof_ports ;
cell - > nof_ports = args_ - > enb . nof_ports ;
cell - > nof_prb = args_ - > enb . n_prb ;
cell - > nof_prb = args_ - > enb . n_prb ;
// PCI not configured yet
phich_cfg_s phichcfg ;
phich_cfg_s phichcfg ;
parser : : section phy_cnfg ( " phy_cnfg " ) ;
parser : : section phy_cnfg ( " phy_cnfg " ) ;
parser : : section phich_cnfg ( " phich_cnfg " ) ;
parser : : section phich_cnfg ( " phich_cnfg " ) ;
phy_cnfg . add_subsection ( & phich_cnfg ) ;
phy_cnfg . add_subsection ( & phich_cnfg ) ;
@ -853,7 +839,7 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_)
return SRSLTE_ERROR ;
return SRSLTE_ERROR ;
}
}
} catch ( const SettingTypeException & stex ) {
} catch ( const SettingTypeException & stex ) {
fprintf ( stderr , " \" Error parsing DRB configuration: %s \n " , stex . getPath ( ) ) ;
fprintf ( stderr , " Error parsing DRB configuration: %s \n " , stex . getPath ( ) ) ;
return SRSLTE_ERROR ;
return SRSLTE_ERROR ;
} catch ( const ConfigException & cex ) {
} catch ( const ConfigException & cex ) {
fprintf ( stderr , " Error parsing DRB configuration \n " ) ;
fprintf ( stderr , " Error parsing DRB configuration \n " ) ;
@ -861,18 +847,61 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_)
}
}
// Set fields derived from others, and check for correctness of the parsed configuration
// Set fields derived from others, and check for correctness of the parsed configuration
return enb_conf_sections : : set_derived_args ( args_ , rrc_cfg_ , phy_cfg_ , & cell_common_cfg ) ;
return enb_conf_sections : : set_derived_args ( args_ , rrc_cfg_ , phy_cfg_ , cell_common_cfg ) ;
}
}
int set_derived_args ( all_args_t * args_ , rrc_cfg_t * rrc_cfg_ , phy_cfg_t * phy_cfg_ , srslte_cell_t * cell_cfg_ )
int set_derived_args ( all_args_t * args_ , rrc_cfg_t * rrc_cfg_ , phy_cfg_t * phy_cfg_ , const srslte_cell_t & cell_cfg_ )
{
{
// Copy cell struct to rrc and phy
// Sanity check
rrc_cfg_ - > cell = * cell_cfg_ ;
if ( rrc_cfg_ - > cell_list . empty ( ) ) {
ERROR ( " No cell specified in RR config. " ) ;
return SRSLTE_ERROR ;
}
// Check for a forced DL EARFCN or frequency (only valid for a single cell config (Xico's favorite feature))
if ( rrc_cfg_ - > cell_list . size ( ) = = 1 ) {
auto & cfg = rrc_cfg_ - > cell_list . at ( 0 ) ;
if ( args_ - > enb . dl_earfcn > 0 ) {
cfg . dl_earfcn = args_ - > enb . dl_earfcn ;
ERROR ( " Force DL EARFCN for cell PCI=%d to %d \n " , cfg . pci , cfg . dl_earfcn ) ;
}
if ( args_ - > rf . dl_freq > 0 ) {
cfg . dl_freq_hz = args_ - > rf . dl_freq ;
ERROR ( " Force DL freq for cell PCI=%d to %f MHz \n " , cfg . pci , cfg . dl_freq_hz / 1e6 f ) ;
}
} else {
// If more than one cell is defined, single EARFCN or DL freq will be ignored
if ( args_ - > enb . dl_earfcn > 0 | | args_ - > rf . dl_freq > 0 ) {
INFO ( " Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config. \n " ) ;
}
}
// set config for RRC's base cell
rrc_cfg_ - > cell = cell_cfg_ ;
// Set S1AP related params from cell list (Convert hex strings)
{
std : : stringstream sstr ;
sstr < < std : : hex < < args_ - > enb . enb_id ;
sstr > > args_ - > stack . s1ap . enb_id ;
}
{
std : : stringstream sstr ;
sstr < < std : : hex < < rrc_cfg_ - > cell_list . at ( 0 ) . cell_id ;
uint16_t tmp ; // Need intermediate uint16_t as uint8_t is treated as char
sstr > > tmp ;
args_ - > stack . s1ap . cell_id = tmp ;
}
{
std : : stringstream sstr ;
sstr < < std : : hex < < rrc_cfg_ - > cell_list . at ( 0 ) . tac ;
sstr > > args_ - > stack . s1ap . tac ;
}
// Create dedicated cell configuration from RRC configuration
// Create dedicated cell configuration from RRC configuration
for ( auto & cfg : rrc_cfg_ - > cell_list ) {
for ( auto & cfg : rrc_cfg_ - > cell_list ) {
phy_cell_cfg_t phy_cell_cfg = { } ;
phy_cell_cfg_t phy_cell_cfg = { } ;
phy_cell_cfg . cell = * cell_cfg_ ;
phy_cell_cfg . cell = cell_cfg_ ;
phy_cell_cfg . cell . id = cfg . pci ;
phy_cell_cfg . cell . id = cfg . pci ;
phy_cell_cfg . cell_id = cfg . cell_id ;
phy_cell_cfg . cell_id = cfg . cell_id ;
phy_cell_cfg . root_seq_idx = cfg . root_seq_idx ;
phy_cell_cfg . root_seq_idx = cfg . root_seq_idx ;
@ -906,16 +935,12 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
rrc_cfg_ - > inactivity_timeout_ms = args_ - > general . rrc_inactivity_timer ;
rrc_cfg_ - > inactivity_timeout_ms = args_ - > general . rrc_inactivity_timer ;
rrc_cfg_ - > enable_mbsfn = args_ - > stack . embms . enable ;
rrc_cfg_ - > enable_mbsfn = args_ - > stack . embms . enable ;
rrc_cfg_ - > dl_earfcn = args_ - > enb . dl_earfcn ;
rrc_cfg_ - > pci = args_ - > enb . pci ;
// Check number of control symbols
// Check number of control symbols
if ( cell_cfg_ - > nof_prb < 50 & & args_ - > stack . mac . sched . nof_ctrl_symbols ! = 3 ) {
if ( cell_cfg_ . nof_prb < 50 & & args_ - > stack . mac . sched . nof_ctrl_symbols ! = 3 ) {
args_ - > stack . mac . sched . nof_ctrl_symbols = 3 ;
args_ - > stack . mac . sched . nof_ctrl_symbols = 3 ;
fprintf ( stdout ,
INFO ( " Setting number of control symbols to %d for %d PRB cell. \n " ,
" Setting number of control symbols to %d for %d PRB cell. \n " ,
args_ - > stack . mac . sched . nof_ctrl_symbols ,
args_ - > stack . mac . sched . nof_ctrl_symbols ,
cell_cfg_ . nof_prb ) ;
cell_cfg_ - > nof_prb ) ;
}
}
// Parse EEA preference list
// Parse EEA preference list
@ -968,9 +993,9 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
// Check PRACH configuration
// Check PRACH configuration
uint32_t prach_freq_offset = rrc_cfg_ - > sibs [ 1 ] . sib2 ( ) . rr_cfg_common . prach_cfg . prach_cfg_info . prach_freq_offset ;
uint32_t prach_freq_offset = rrc_cfg_ - > sibs [ 1 ] . sib2 ( ) . rr_cfg_common . prach_cfg . prach_cfg_info . prach_freq_offset ;
if ( rrc_cfg_- > cell . nof _prb > 10 ) {
if ( args_- > enb . n _prb > 10 ) {
uint32_t lower_bound = SRSLTE_MAX ( rrc_cfg_ - > sr_cfg . nof_prb , rrc_cfg_ - > cqi_cfg . nof_prb ) ;
uint32_t lower_bound = SRSLTE_MAX ( rrc_cfg_ - > sr_cfg . nof_prb , rrc_cfg_ - > cqi_cfg . nof_prb ) ;
uint32_t upper_bound = rrc_cfg_- > cell . nof _prb - lower_bound ;
uint32_t upper_bound = args_- > enb . n _prb - lower_bound ;
if ( prach_freq_offset + 6 > upper_bound or prach_freq_offset < lower_bound ) {
if ( prach_freq_offset + 6 > upper_bound or prach_freq_offset < lower_bound ) {
fprintf ( stderr ,
fprintf ( stderr ,
" ERROR: Invalid PRACH configuration - prach_freq_offset=%d collides with PUCCH. \n " ,
" ERROR: Invalid PRACH configuration - prach_freq_offset=%d collides with PUCCH. \n " ,
@ -982,12 +1007,12 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
return SRSLTE_ERROR ;
return SRSLTE_ERROR ;
}
}
} else { // 6 PRB case
} else { // 6 PRB case
if ( prach_freq_offset + 6 > rrc_cfg_- > cell . nof _prb) {
if ( prach_freq_offset + 6 > args_- > enb . n _prb) {
fprintf ( stderr ,
fprintf ( stderr ,
" WARNING: Invalid PRACH configuration - prach=(%d, %d) does not fit into the eNB PRBs=(0, %d). \n " ,
" WARNING: Invalid PRACH configuration - prach=(%d, %d) does not fit into the eNB PRBs=(0, %d). \n " ,
prach_freq_offset ,
prach_freq_offset ,
prach_freq_offset + 6 ,
prach_freq_offset + 6 ,
rrc_cfg_- > cell . nof _prb) ;
args_- > enb . n _prb) ;
fprintf (
fprintf (
stderr ,
stderr ,
" Consider changing the \" prach_freq_offset \" value to 0 in the sib.conf file when using 6 PRBs. \n " ) ;
" Consider changing the \" prach_freq_offset \" value to 0 in the sib.conf file when using 6 PRBs. \n " ) ;
@ -1001,6 +1026,12 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
args_ - > rf . nof_carriers = rrc_cfg_ - > cell_list . size ( ) ;
args_ - > rf . nof_carriers = rrc_cfg_ - > cell_list . size ( ) ;
args_ - > rf . nof_antennas = args_ - > enb . nof_ports ;
args_ - > rf . nof_antennas = args_ - > enb . nof_ports ;
// MAC needs to know the cell bandwidth to dimension softbuffers
args_ - > stack . mac . nof_prb = args_ - > enb . n_prb ;
// RRC needs eNB id for SIB1 packing
rrc_cfg_ - > enb_id = args_ - > stack . s1ap . enb_id ;
return SRSLTE_SUCCESS ;
return SRSLTE_SUCCESS ;
}
}
@ -1390,10 +1421,6 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co
}
}
// Fill rest of data from enb config
// Fill rest of data from enb config
sib_type1_s : : cell_access_related_info_s_ * cell_access = & sib1 - > cell_access_related_info ;
cell_access - > cell_id . from_number ( ( args_ - > stack . s1ap . enb_id < < 8u ) + args_ - > stack . s1ap . cell_id ) ;
cell_access - > tac . from_number ( args_ - > stack . s1ap . tac ) ;
sib1 - > freq_band_ind = ( uint8_t ) srslte_band_get_band ( args_ - > enb . dl_earfcn ) ;
std : : string mnc_str ;
std : : string mnc_str ;
if ( not srslte : : mnc_to_string ( args_ - > stack . s1ap . mnc , & mnc_str ) ) {
if ( not srslte : : mnc_to_string ( args_ - > stack . s1ap . mnc , & mnc_str ) ) {
ERROR ( " The provided mnc=%d is not valid " , args_ - > stack . s1ap . mnc ) ;
ERROR ( " The provided mnc=%d is not valid " , args_ - > stack . s1ap . mnc ) ;
@ -1404,6 +1431,7 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co
ERROR ( " The provided mnc=%d is not valid " , args_ - > stack . s1ap . mcc ) ;
ERROR ( " The provided mnc=%d is not valid " , args_ - > stack . s1ap . mcc ) ;
return - 1 ;
return - 1 ;
}
}
sib_type1_s : : cell_access_related_info_s_ * cell_access = & sib1 - > cell_access_related_info ;
cell_access - > plmn_id_list . resize ( 1 ) ;
cell_access - > plmn_id_list . resize ( 1 ) ;
srslte : : plmn_id_t plmn ;
srslte : : plmn_id_t plmn ;
if ( plmn . from_string ( mcc_str + mnc_str ) = = SRSLTE_ERROR ) {
if ( plmn . from_string ( mcc_str + mnc_str ) = = SRSLTE_ERROR ) {
@ -1424,9 +1452,7 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co
if ( sib2 - > freq_info . ul_bw_present ) {
if ( sib2 - > freq_info . ul_bw_present ) {
asn1 : : number_to_enum ( sib2 - > freq_info . ul_bw , args_ - > enb . n_prb ) ;
asn1 : : number_to_enum ( sib2 - > freq_info . ul_bw , args_ - > enb . n_prb ) ;
}
}
if ( sib2 - > freq_info . ul_carrier_freq_present ) {
// UL carrier freq is patched before packing the SIB for each CC
sib2 - > freq_info . ul_carrier_freq = ( uint16_t ) args_ - > enb . ul_earfcn ;
}
// Update MBSFN list counter. Only 1 supported
// Update MBSFN list counter. Only 1 supported
if ( not args_ - > stack . embms . enable ) {
if ( not args_ - > stack . embms . enable ) {