@ -67,14 +67,14 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
common . add_options ( )
( " enb.enb_id " , bpo : : value < string > ( & enb_id ) - > default_value ( " 0x0 " ) , " eNodeB ID " )
( " enb.name " , bpo : : value < string > ( & args - > enb . s1ap . enb_name ) - > default_value ( " srsenb01 " ) , " eNodeB Name " )
( " enb.name " , bpo : : value < string > ( & args - > stack . s1ap . enb_name ) - > default_value ( " srsenb01 " ) , " eNodeB Name " )
( " enb.cell_id " , bpo : : value < string > ( & cell_id ) - > default_value ( " 0x0 " ) , " Cell ID " )
( " enb.tac " , bpo : : value < string > ( & tac ) - > default_value ( " 0x0 " ) , " Tracking Area Code " )
( " enb.mcc " , bpo : : value < string > ( & mcc ) - > default_value ( " 001 " ) , " Mobile Country Code " )
( " enb.mnc " , bpo : : value < string > ( & mnc ) - > default_value ( " 01 " ) , " Mobile Network Code " )
( " enb.mme_addr " , bpo : : value < string > ( & args - > enb . s1ap . mme_addr ) - > default_value ( " 127.0.0.1 " ) , " IP address of MME for S1 connection " )
( " enb.gtp_bind_addr " , bpo : : value < string > ( & args - > enb . s1ap . gtp_bind_addr ) - > default_value ( " 192.168.3.1 " ) , " Local IP address to bind for GTP connection " )
( " enb.s1c_bind_addr " , bpo : : value < string > ( & args - > enb . s1ap . s1c_bind_addr ) - > default_value ( " 192.168.3.1 " ) , " Local IP address to bind for S1AP connection " )
( " enb.mme_addr " , bpo : : value < string > ( & args - > stack . s1ap . mme_addr ) - > default_value ( " 127.0.0.1 " ) , " IP address of MME for S1 connection " )
( " enb.gtp_bind_addr " , bpo : : value < string > ( & args - > stack . s1ap . gtp_bind_addr ) - > default_value ( " 192.168.3.1 " ) , " Local IP address to bind for GTP connection " )
( " enb.s1c_bind_addr " , bpo : : value < string > ( & args - > stack . s1ap . s1c_bind_addr ) - > default_value ( " 192.168.3.1 " ) , " Local IP address to bind for S1AP connection " )
( " enb.phy_cell_id " , bpo : : value < uint32_t > ( & args - > enb . pci ) - > default_value ( 0 ) , " Physical Cell Identity (PCI) " )
( " enb.n_prb " , bpo : : value < uint32_t > ( & args - > enb . n_prb ) - > default_value ( 25 ) , " Number of PRB " )
( " enb.nof_ports " , bpo : : value < uint32_t > ( & args - > enb . nof_ports ) - > default_value ( 1 ) , " Number of ports " )
@ -85,15 +85,15 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
( " enb_files.rr_config " , bpo : : value < string > ( & args - > enb_files . rr_config ) - > default_value ( " rr.conf " ) , " RR configuration files " )
( " enb_files.drb_config " , bpo : : value < string > ( & args - > enb_files . drb_config ) - > default_value ( " drb.conf " ) , " DRB configuration files " )
( " rf.dl_earfcn " , bpo : : value < uint32_t > ( & args - > rf . dl_earfcn ) - > default_value ( 3400 ) , " Downlink EARFCN " )
( " rf.ul_earfcn " , bpo : : value < uint32_t > ( & args - > rf . ul_earfcn ) - > default_value ( 0 ) , " Uplink EARFCN (Default based on Downlink EARFCN) " )
( " rf.dl_earfcn " , bpo : : value < uint32_t > ( & args - > enb . dl_earfcn ) - > default_value ( 3400 ) , " Downlink EARFCN " )
( " rf.ul_earfcn " , bpo : : value < uint32_t > ( & args - > enb . ul_earfcn ) - > default_value ( 0 ) , " Uplink EARFCN (Default based on Downlink EARFCN) " )
( " rf.rx_gain " , bpo : : value < float > ( & args - > rf . rx_gain ) - > default_value ( 50 ) , " Front-end receiver gain " )
( " rf.tx_gain " , bpo : : value < float > ( & args - > rf . tx_gain ) - > default_value ( 70 ) , " Front-end transmitter gain " )
( " rf.dl_freq " , bpo : : value < float > ( & args - > rf . dl_freq ) - > default_value ( - 1 ) , " Downlink Frequency (if positive overrides EARFCN) " )
( " rf.ul_freq " , bpo : : value < float > ( & args - > rf . ul_freq ) - > default_value ( - 1 ) , " Uplink Frequency (if positive overrides EARFCN) " )
( " rf.device_name " , bpo : : value < string > ( & args - > rf . device_name ) - > default_value ( " auto " ) , " Front-end device name " )
( " rf.device_args " , bpo : : value < string > ( & args - > rf . device_args )- > default_value ( " auto " ) , " Front-end device arguments " )
( " rf.device_args " , bpo : : value < string > ( & args - > rf . device_args [0 ] )- > default_value ( " auto " ) , " Front-end device arguments " )
( " rf.time_adv_nsamples " , bpo : : value < string > ( & args - > rf . time_adv_nsamples ) - > default_value ( " auto " ) , " Transmission time advance " )
( " rf.burst_preamble_us " , bpo : : value < string > ( & args - > rf . burst_preamble ) - > default_value ( " auto " ) , " Transmission time advance " )
@ -105,18 +105,18 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
( " log.phy_level " , bpo : : value < string > ( & args - > log . phy_level ) , " PHY log level " )
( " log.phy_hex_limit " , bpo : : value < int > ( & args - > log . phy_hex_limit ) , " PHY log hex dump limit " )
( " log.phy_lib_level " , bpo : : value < string > ( & args - > log . phy_lib_level ) - > default_value ( " none " ) , " PHY lib log level " )
( " log.mac_level " , bpo : : value < string > ( & args - > log. mac_level ) , " MAC log level " )
( " log.mac_hex_limit " , bpo : : value < int > ( & args - > log. mac_hex_limit ) , " MAC log hex dump limit " )
( " log.rlc_level " , bpo : : value < string > ( & args - > log. rlc_level ) , " RLC log level " )
( " log.rlc_hex_limit " , bpo : : value < int > ( & args - > log. rlc_hex_limit ) , " RLC log hex dump limit " )
( " log.pdcp_level " , bpo : : value < string > ( & args - > log. pdcp_level ) , " PDCP log level " )
( " log.pdcp_hex_limit " , bpo : : value < int > ( & args - > log. pdcp_hex_limit ) , " PDCP log hex dump limit " )
( " log.rrc_level " , bpo : : value < string > ( & args - > log. rrc_level ) , " RRC log level " )
( " log.rrc_hex_limit " , bpo : : value < int > ( & args - > log. rrc_hex_limit ) , " RRC log hex dump limit " )
( " log.gtpu_level " , bpo : : value < string > ( & args - > log. gtpu_level ) , " GTPU log level " )
( " log.gtpu_hex_limit " , bpo : : value < int > ( & args - > log. gtpu_hex_limit ) , " GTPU log hex dump limit " )
( " log.s1ap_level " , bpo : : value < string > ( & args - > log. s1ap_level ) , " S1AP log level " )
( " log.s1ap_hex_limit " , bpo : : value < int > ( & args - > log. s1ap_hex_limit ) , " S1AP log hex dump limit " )
( " log.mac_level " , bpo : : value < string > ( & args - > stack. log. mac_level ) , " MAC log level " )
( " log.mac_hex_limit " , bpo : : value < int > ( & args - > stack. log. mac_hex_limit ) , " MAC log hex dump limit " )
( " log.rlc_level " , bpo : : value < string > ( & args - > stack. log. rlc_level ) , " RLC log level " )
( " log.rlc_hex_limit " , bpo : : value < int > ( & args - > stack. log. rlc_hex_limit ) , " RLC log hex dump limit " )
( " log.pdcp_level " , bpo : : value < string > ( & args - > stack. log. pdcp_level ) , " PDCP log level " )
( " log.pdcp_hex_limit " , bpo : : value < int > ( & args - > stack. log. pdcp_hex_limit ) , " PDCP log hex dump limit " )
( " log.rrc_level " , bpo : : value < string > ( & args - > stack. log. rrc_level ) , " RRC log level " )
( " log.rrc_hex_limit " , bpo : : value < int > ( & args - > stack. log. rrc_hex_limit ) , " RRC log hex dump limit " )
( " log.gtpu_level " , bpo : : value < string > ( & args - > stack. log. gtpu_level ) , " GTPU log level " )
( " log.gtpu_hex_limit " , bpo : : value < int > ( & args - > stack. log. gtpu_hex_limit ) , " GTPU log hex dump limit " )
( " log.s1ap_level " , bpo : : value < string > ( & args - > stack. log. s1ap_level ) , " S1AP log level " )
( " log.s1ap_hex_limit " , bpo : : value < int > ( & args - > stack. log. s1ap_hex_limit ) , " S1AP log hex dump limit " )
( " log.all_level " , bpo : : value < string > ( & args - > log . all_level ) - > default_value ( " info " ) , " ALL log level " )
( " log.all_hex_limit " , bpo : : value < int > ( & args - > log . all_hex_limit ) - > default_value ( 32 ) , " ALL log hex dump limit " )
@ -125,11 +125,11 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
( " log.file_max_size " , bpo : : value < int > ( & args - > log . file_max_size ) - > default_value ( - 1 ) , " Maximum file size (in kilobytes). When passed, multiple files are created. Default -1 (single file) " )
/* MCS section */
( " scheduler.pdsch_mcs " , bpo : : value < int > ( & args - > expert . mac . sched . pdsch_mcs ) - > default_value ( - 1 ) , " Optional fixed PDSCH MCS (ignores reported CQIs if specified) " )
( " scheduler.pdsch_max_mcs " , bpo : : value < int > ( & args - > expert . mac . sched . pdsch_max_mcs ) - > default_value ( - 1 ) , " Optional PDSCH MCS limit " )
( " scheduler.pusch_mcs " , bpo : : value < int > ( & args - > expert . mac . sched . pusch_mcs ) - > default_value ( - 1 ) , " Optional fixed PUSCH MCS (ignores reported CQIs if specified) " )
( " scheduler.pusch_max_mcs " , bpo : : value < int > ( & args - > expert . mac . sched . pusch_max_mcs ) - > default_value ( - 1 ) , " Optional PUSCH MCS limit " )
( " scheduler.nof_ctrl_symbols " , bpo : : value < int > ( & args - > expert . mac . sched . nof_ctrl_symbols ) - > default_value ( 3 ) , " Number of control symbols " )
( " scheduler.pdsch_mcs " , bpo : : value < int > ( & args - > stack . mac . sched . pdsch_mcs ) - > default_value ( - 1 ) , " Optional fixed PDSCH MCS (ignores reported CQIs if specified) " )
( " scheduler.pdsch_max_mcs " , bpo : : value < int > ( & args - > stack . mac . sched . pdsch_max_mcs ) - > default_value ( - 1 ) , " Optional PDSCH MCS limit " )
( " scheduler.pusch_mcs " , bpo : : value < int > ( & args - > stack . mac . sched . pusch_mcs ) - > default_value ( - 1 ) , " Optional fixed PUSCH MCS (ignores reported CQIs if specified) " )
( " scheduler.pusch_max_mcs " , bpo : : value < int > ( & args - > stack . mac . sched . pusch_max_mcs ) - > default_value ( - 1 ) , " Optional PUSCH MCS limit " )
( " scheduler.nof_ctrl_symbols " , bpo : : value < int > ( & args - > stack . mac . sched . nof_ctrl_symbols ) - > default_value ( 3 ) , " Number of control symbols " )
/* Expert section */
( " expert.metrics_period_secs " , bpo : : value < float > ( & args - > expert . metrics_period_secs ) - > default_value ( 1.0 ) , " Periodicity for metrics in seconds " )
@ -140,7 +140,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
( " expert.pusch_8bit_decoder " , bpo : : value < bool > ( & args - > expert . phy . pusch_8bit_decoder ) - > default_value ( false ) , " Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental) " )
( " expert.tx_amplitude " , bpo : : value < float > ( & args - > expert . phy . tx_amplitude ) - > default_value ( 0.6 ) , " Transmit amplitude factor " )
( " expert.nof_phy_threads " , bpo : : value < int > ( & args - > expert . phy . nof_phy_threads ) - > default_value ( 3 ) , " Number of PHY threads " )
( " expert.link_failure_nof_err " , bpo : : value < int > ( & args - > expert . mac . link_failure_nof_err ) - > default_value ( 100 ) , " Number of PUSCH failures after which a radio-link failure is triggered " )
( " expert.link_failure_nof_err " , bpo : : value < int > ( & args - > stack . mac . link_failure_nof_err ) - > default_value ( 100 ) , " Number of PUSCH failures after which a radio-link failure is triggered " )
( " expert.max_prach_offset_us " , bpo : : value < float > ( & args - > expert . phy . max_prach_offset_us ) - > default_value ( 30 ) , " Maximum allowed RACH offset (in us) " )
( " expert.equalizer_mode " , bpo : : value < string > ( & args - > expert . phy . equalizer_mode ) - > default_value ( " mmse " ) , " Equalizer mode " )
( " expert.estimator_fil_w " , bpo : : value < float > ( & args - > expert . phy . estimator_fil_w ) - > default_value ( 0.1 ) , " Chooses the coefficients for the 3-tap channel estimator centered filter. " )
@ -220,53 +220,53 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
{
std : : stringstream sstr ;
sstr < < std : : hex < < vm [ " enb.enb_id " ] . as < std : : string > ( ) ;
sstr > > args - > enb . s1ap . enb_id ;
sstr > > args - > stack . s1ap . enb_id ;
}
{
std : : stringstream sstr ;
sstr < < std : : hex < < vm [ " enb.cell_id " ] . as < std : : string > ( ) ;
uint16_t tmp ; // Need intermediate uint16_t as uint8_t is treated as char
sstr > > tmp ;
args - > enb . s1ap . cell_id = tmp ;
args - > stack . s1ap . cell_id = tmp ;
}
{
std : : stringstream sstr ;
sstr < < std : : hex < < vm [ " enb.tac " ] . as < std : : string > ( ) ;
sstr > > args - > enb . s1ap . tac ;
sstr > > args - > stack . s1ap . tac ;
}
// Convert MCC/MNC strings
if ( ! srslte : : string_to_mcc ( mcc , & args - > enb . s1ap . mcc ) ) {
if ( ! srslte : : string_to_mcc ( mcc , & args - > stack . s1ap . mcc ) ) {
cout < < " Error parsing enb.mcc: " < < mcc < < " - must be a 3-digit string. " < < endl ;
}
if ( ! srslte : : string_to_mnc ( mnc , & args - > enb . s1ap . mnc ) ) {
if ( ! srslte : : string_to_mnc ( mnc , & args - > stack . s1ap . mnc ) ) {
cout < < " Error parsing enb.mnc: " < < mnc < < " - must be a 2 or 3-digit string. " < < endl ;
}
// Convert UL/DL EARFCN to frequency if needed
if ( args - > rf . dl_freq < 0 ) {
args - > rf . dl_freq = 1e6 * srslte_band_fd ( args - > rf . dl_earfcn ) ;
args - > rf . dl_freq = 1e6 * srslte_band_fd ( args - > enb . dl_earfcn ) ;
if ( args - > rf . dl_freq < 0 ) {
fprintf ( stderr , " Error getting DL frequency for EARFCN=%d \n " , args - > rf . dl_earfcn ) ;
fprintf ( stderr , " Error getting DL frequency for EARFCN=%d \n " , args - > enb . dl_earfcn ) ;
exit ( 1 ) ;
}
}
if ( args - > rf . ul_freq < 0 ) {
if ( args - > rf . ul_earfcn = = 0 ) {
args - > rf . ul_earfcn = srslte_band_ul_earfcn ( args - > rf . dl_earfcn ) ;
if ( args - > enb . ul_earfcn = = 0 ) {
args - > enb . ul_earfcn = srslte_band_ul_earfcn ( args - > enb . dl_earfcn ) ;
}
args - > rf . ul_freq = 1e6 * srslte_band_fu ( args - > rf . ul_earfcn ) ;
args - > rf . ul_freq = 1e6 * srslte_band_fu ( args - > enb . ul_earfcn ) ;
if ( args - > rf . ul_freq < 0 ) {
fprintf ( stderr , " Error getting UL frequency for EARFCN=%d \n " , args - > rf . dl_earfcn ) ;
fprintf ( stderr , " Error getting UL frequency for EARFCN=%d \n " , args - > enb . dl_earfcn ) ;
exit ( 1 ) ;
}
}
if ( args - > expert . enable_mbsfn ) {
if ( args - > expert . mac . sched . nof_ctrl_symbols = = 3 ) {
if ( args - > stack . mac . sched . nof_ctrl_symbols = = 3 ) {
fprintf ( stderr ,
" nof_ctrl_symbols = %d, While using MBMS, please set number of control symbols to either 1 or 2, "
" depending on the length of the non-mbsfn region \n " ,
args - > expert . mac . sched . nof_ctrl_symbols ) ;
args - > stack . mac . sched . nof_ctrl_symbols ) ;
exit ( 1 ) ;
}
}
@ -280,22 +280,22 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
args - > log . phy_lib_level = args - > log . all_level ;
}
if ( ! vm . count ( " log.mac_level " ) ) {
args - > log. mac_level = args - > log . all_level ;
args - > stack. log. mac_level = args - > log . all_level ;
}
if ( ! vm . count ( " log.rlc_level " ) ) {
args - > log. rlc_level = args - > log . all_level ;
args - > stack. log. rlc_level = args - > log . all_level ;
}
if ( ! vm . count ( " log.pdcp_level " ) ) {
args - > log. pdcp_level = args - > log . all_level ;
args - > stack. log. pdcp_level = args - > log . all_level ;
}
if ( ! vm . count ( " log.rrc_level " ) ) {
args - > log. rrc_level = args - > log . all_level ;
args - > stack. log. rrc_level = args - > log . all_level ;
}
if ( ! vm . count ( " log.gtpu_level " ) ) {
args - > log. gtpu_level = args - > log . all_level ;
args - > stack. log. gtpu_level = args - > log . all_level ;
}
if ( ! vm . count ( " log.s1ap_level " ) ) {
args - > log. s1ap_level = args - > log . all_level ;
args - > stack. log. s1ap_level = args - > log . all_level ;
}
}
@ -305,22 +305,22 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
args - > log . phy_hex_limit = args - > log . all_hex_limit ;
}
if ( ! vm . count ( " log.mac_hex_limit " ) ) {
args - > log. mac_hex_limit = args - > log . all_hex_limit ;
args - > stack. log. mac_hex_limit = args - > log . all_hex_limit ;
}
if ( ! vm . count ( " log.rlc_hex_limit " ) ) {
args - > log. rlc_hex_limit = args - > log . all_hex_limit ;
args - > stack. log. rlc_hex_limit = args - > log . all_hex_limit ;
}
if ( ! vm . count ( " log.pdcp_hex_limit " ) ) {
args - > log. pdcp_hex_limit = args - > log . all_hex_limit ;
args - > stack. log. pdcp_hex_limit = args - > log . all_hex_limit ;
}
if ( ! vm . count ( " log.rrc_hex_limit " ) ) {
args - > log. rrc_hex_limit = args - > log . all_hex_limit ;
args - > stack. log. rrc_hex_limit = args - > log . all_hex_limit ;
}
if ( ! vm . count ( " log.gtpu_hex_limit " ) ) {
args - > log. gtpu_hex_limit = args - > log . all_hex_limit ;
args - > stack. log. gtpu_hex_limit = args - > log . all_hex_limit ;
}
if ( ! vm . count ( " log.s1ap_hex_limit " ) ) {
args - > log. s1ap_hex_limit = args - > log . all_hex_limit ;
args - > stack. log. s1ap_hex_limit = args - > log . all_hex_limit ;
}
}
@ -383,7 +383,7 @@ int main(int argc, char *argv[])
{
signal ( SIGINT , sig_int_handler ) ;
signal ( SIGTERM , sig_int_handler ) ;
all_args_t args ;
all_args_t args = { } ;
srslte : : metrics_hub < enb_metrics_t > metricshub ;
metrics_stdout metrics_screen ;
@ -394,8 +394,9 @@ int main(int argc, char *argv[])
cout < < " --- Software Radio Systems LTE eNodeB --- " < < endl < < endl ;
parse_args ( & args , argc , argv ) ;
if ( ! enb - > init ( & args ) ) {
exit ( 1 ) ;
if ( enb - > init ( args ) ) {
enb - > stop ( ) ;
return SRSLTE_ERROR ;
}
metricshub . init ( enb , args . expert . metrics_period_secs ) ;
@ -412,12 +413,10 @@ int main(int argc, char *argv[])
pthread_t input ;
pthread_create ( & input , NULL , & input_loop , & metrics_screen ) ;
bool plot_started = false ;
bool signals_pregenerated = false ;
if ( running ) {
if ( ! plot_started & & args . gui . enable ) {
bool signals_pregenerated = false ;
if ( running ) {
if ( args . gui . enable ) {
enb - > start_plot ( ) ;
plot_started = true ;
}
}
int cnt = 0 ;
@ -436,5 +435,6 @@ int main(int argc, char *argv[])
enb - > stop ( ) ;
enb - > cleanup ( ) ;
cout < < " --- exiting --- " < < endl ;
exit ( 0 ) ;
return SRSLTE_SUCCESS ;
}