2019-04-26 12:27:38 -07:00
/*
* Copyright 2013 - 2019 Software Radio Systems Limited
2018-02-07 13:59:50 -08:00
*
2019-04-26 12:27:38 -07:00
* This file is part of srsLTE .
2018-02-07 13:59:50 -08:00
*
2019-04-26 12:27:38 -07:00
* srsLTE is free software : you can redistribute it and / or modify
2018-02-07 13:59:50 -08:00
* 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 .
*
2019-04-26 12:27:38 -07:00
* srsLTE is distributed in the hope that it will be useful ,
2018-02-07 13:59:50 -08:00
* 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/.
*
*/
2019-07-02 07:23:43 -07:00
# include "srslte/common/crash_handler.h"
2018-02-07 13:59:50 -08:00
# include "srslte/common/log_filter.h"
# include "srslte/common/logger_stdout.h"
2018-03-23 09:20:12 -07:00
# include "srslte/common/rlc_pcap.h"
2019-07-02 07:23:43 -07:00
# include "srslte/common/threads.h"
2018-02-07 13:59:50 -08:00
# include "srslte/upper/rlc.h"
2018-02-22 05:07:27 -08:00
# include <boost/program_options.hpp>
# include <boost/program_options/parsers.hpp>
2018-09-12 01:57:49 -07:00
# include <cassert>
2019-07-02 07:23:43 -07:00
# include <cstdlib>
# include <iostream>
# include <pthread.h>
# include <random>
2018-03-23 09:20:12 -07:00
2018-09-20 12:28:40 -07:00
# define LOG_HEX_LIMIT (-1)
2018-02-07 13:59:50 -08:00
2019-12-10 07:38:34 -08:00
# define PCAP 0
2019-10-23 02:53:00 -07:00
# define PCAP_CRNTI (0x1001)
# define PCAP_TTI (666)
# if PCAP
# include "srslte/common/mac_nr_pcap.h"
# include "srslte/common/mac_nr_pdu.h"
static std : : unique_ptr < srslte : : mac_nr_pcap > pcap_handle = nullptr ;
# endif
int write_pdu_to_pcap ( const bool is_dl , const uint32_t lcid , const uint8_t * payload , const uint32_t len )
{
# if PCAP
if ( pcap_handle ) {
srslte : : byte_buffer_t tx_buffer ;
srslte : : mac_nr_sch_pdu tx_pdu ;
tx_pdu . init_tx ( & tx_buffer , len + 10 ) ;
tx_pdu . add_sdu ( lcid , payload , len ) ;
tx_pdu . pack ( ) ;
if ( is_dl ) {
pcap_handle - > write_dl_crnti ( tx_buffer . msg , tx_buffer . N_bytes , PCAP_CRNTI , true , PCAP_TTI ) ;
} else {
pcap_handle - > write_ul_crnti ( tx_buffer . msg , tx_buffer . N_bytes , PCAP_CRNTI , true , PCAP_TTI ) ;
}
return SRSLTE_SUCCESS ;
}
# endif
return SRSLTE_ERROR ;
}
2018-02-22 05:07:27 -08:00
using namespace std ;
2018-02-07 13:59:50 -08:00
using namespace srsue ;
using namespace srslte ;
2018-02-22 05:07:27 -08:00
namespace bpo = boost : : program_options ;
typedef struct {
2019-10-23 02:53:00 -07:00
std : : string rat ;
2018-04-27 06:40:05 -07:00
std : : string mode ;
2018-09-24 08:51:32 -07:00
uint32_t sdu_size ;
2018-04-27 06:40:05 -07:00
uint32_t test_duration_sec ;
2019-07-02 07:23:43 -07:00
float pdu_drop_rate ;
float pdu_cut_rate ;
2018-04-27 06:40:05 -07:00
uint32_t sdu_gen_delay_usec ;
uint32_t pdu_tx_delay_usec ;
bool reestablish ;
uint32_t log_level ;
bool single_tx ;
bool write_pcap ;
2018-09-27 02:23:06 -07:00
uint32_t avg_opp_size ;
bool random_opp ;
2018-09-20 12:28:40 -07:00
bool zero_seed ;
2019-07-02 07:23:43 -07:00
bool pedantic_sdu_check ;
2018-02-22 05:07:27 -08:00
} stress_test_args_t ;
2019-12-16 07:04:22 -08:00
void parse_args ( stress_test_args_t * args , int argc , char * argv [ ] )
{
2018-02-22 05:07:27 -08:00
// Command line only options
bpo : : options_description general ( " General options " ) ;
2019-12-16 07:04:22 -08:00
general . add_options ( ) ( " help,h " , " Produce help message " ) ( " version,v " , " Print version information and exit " ) ;
2018-02-22 05:07:27 -08:00
2019-07-02 07:23:43 -07:00
// clang-format off
2018-02-22 05:07:27 -08:00
// Command line or config file options
bpo : : options_description common ( " Configuration options " ) ;
common . add_options ( )
2019-10-23 02:53:00 -07:00
( " rat " , bpo : : value < std : : string > ( & args - > rat ) - > default_value ( " LTE " ) , " The RLC version to use (LTE/NR) " )
2018-04-27 06:40:05 -07:00
( " mode " , bpo : : value < std : : string > ( & args - > mode ) - > default_value ( " AM " ) , " Whether to test RLC acknowledged or unacknowledged mode (AM/UM) " )
2018-05-04 03:40:20 -07:00
( " duration " , bpo : : value < uint32_t > ( & args - > test_duration_sec ) - > default_value ( 5 ) , " Duration (sec) " )
2018-09-24 08:51:32 -07:00
( " sdu_size " , bpo : : value < uint32_t > ( & args - > sdu_size ) - > default_value ( 1500 ) , " Size of SDUs " )
2018-09-27 02:23:06 -07:00
( " avg_opp_size " , bpo : : value < uint32_t > ( & args - > avg_opp_size ) - > default_value ( 1505 ) , " Size of the MAC opportunity (if not random) " )
( " random_opp " , bpo : : value < bool > ( & args - > random_opp ) - > default_value ( true ) , " Whether to generate random MAC opportunities " )
2018-05-04 03:40:20 -07:00
( " sdu_gen_delay " , bpo : : value < uint32_t > ( & args - > sdu_gen_delay_usec ) - > default_value ( 0 ) , " SDU generation delay (usec) " )
( " pdu_tx_delay " , bpo : : value < uint32_t > ( & args - > pdu_tx_delay_usec ) - > default_value ( 0 ) , " Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec) " )
2019-07-02 07:23:43 -07:00
( " pdu_drop_rate " , bpo : : value < float > ( & args - > pdu_drop_rate ) - > default_value ( 0.1 ) , " Rate at which RLC PDUs are dropped " )
( " pdu_cut_rate " , bpo : : value < float > ( & args - > pdu_cut_rate ) - > default_value ( 0.0 ) , " Rate at which RLC PDUs are chopped in length " )
2018-03-06 04:59:57 -08:00
( " reestablish " , bpo : : value < bool > ( & args - > reestablish ) - > default_value ( false ) , " Mimic RLC reestablish during execution " )
2018-03-23 09:20:12 -07:00
( " loglevel " , bpo : : value < uint32_t > ( & args - > log_level ) - > default_value ( srslte : : LOG_LEVEL_DEBUG ) , " Log level (1=Error,2=Warning,3=Info,4=Debug) " )
( " singletx " , bpo : : value < bool > ( & args - > single_tx ) - > default_value ( false ) , " If set to true, only one node is generating data " )
2018-09-20 12:28:40 -07:00
( " pcap " , bpo : : value < bool > ( & args - > write_pcap ) - > default_value ( false ) , " Whether to write all RLC PDU to PCAP file " )
2019-07-02 07:23:43 -07:00
( " zeroseed " , bpo : : value < bool > ( & args - > zero_seed ) - > default_value ( false ) , " Whether to initialize random seed to zero " )
( " pedantic " , bpo : : value < bool > ( & args - > pedantic_sdu_check ) - > default_value ( false ) , " Whether to check SDU length and exit on error " ) ;
// clang-format on
2018-02-22 05:07:27 -08:00
// these options are allowed on the command line
bpo : : options_description cmdline_options ;
cmdline_options . add ( common ) . add ( general ) ;
// parse the command line and store result in vm
bpo : : variables_map vm ;
bpo : : store ( bpo : : command_line_parser ( argc , argv ) . options ( cmdline_options ) . run ( ) , vm ) ;
bpo : : notify ( vm ) ;
// help option was given - print usage and exit
2018-09-24 08:51:32 -07:00
if ( vm . count ( " help " ) > 0 ) {
2018-02-22 05:07:27 -08:00
cout < < " Usage: " < < argv [ 0 ] < < " [OPTIONS] config_file " < < endl < < endl ;
cout < < common < < endl < < general < < endl ;
exit ( 0 ) ;
}
2018-03-06 04:59:57 -08:00
if ( args - > log_level > 4 ) {
args - > log_level = 4 ;
printf ( " Set log level to %d (%s) \n " , args - > log_level , srslte : : log_level_text [ args - > log_level ] ) ;
}
2018-02-22 05:07:27 -08:00
}
2018-02-07 13:59:50 -08:00
2019-06-06 03:00:48 -07:00
class mac_dummy : public thread
2018-02-07 13:59:50 -08:00
{
public :
2019-05-27 03:09:56 -07:00
mac_dummy ( rlc_interface_mac * rlc1_ ,
rlc_interface_mac * rlc2_ ,
stress_test_args_t args_ ,
uint32_t lcid_ ,
2019-10-21 10:00:49 -07:00
timer_handler * timers_ ,
2019-05-27 03:09:56 -07:00
rlc_pcap * pcap_ = NULL ) :
run_enable ( true ) ,
rlc1 ( rlc1_ ) ,
rlc2 ( rlc2_ ) ,
args ( args_ ) ,
pcap ( pcap_ ) ,
lcid ( lcid_ ) ,
2019-09-04 06:28:09 -07:00
timers ( timers_ ) ,
2019-05-27 03:09:56 -07:00
log ( " MAC " ) ,
2019-07-02 07:23:43 -07:00
thread ( " MAC_DUMMY " ) ,
real_dist ( 0.0 , 1.0 )
2018-02-07 13:59:50 -08:00
{
2018-09-24 08:51:32 -07:00
log . set_level ( static_cast < LOG_LEVEL_ENUM > ( args . log_level ) ) ;
2018-09-20 12:28:40 -07:00
log . set_hex_limit ( LOG_HEX_LIMIT ) ;
2018-02-07 13:59:50 -08:00
}
void stop ( )
{
run_enable = false ;
wait_thread_finish ( ) ;
}
private :
2019-12-16 07:04:22 -08:00
void run_tti ( rlc_interface_mac * tx_rlc , rlc_interface_mac * rx_rlc , bool is_dl )
2018-02-07 13:59:50 -08:00
{
2019-12-16 07:04:22 -08:00
byte_buffer_pool * pool = byte_buffer_pool : : get_instance ( ) ;
2019-05-13 07:34:15 -07:00
unique_byte_buffer_t pdu = srslte : : allocate_unique_buffer ( * pool , __PRETTY_FUNCTION__ , true ) ;
2018-02-07 15:13:59 -08:00
if ( ! pdu ) {
printf ( " Fatal Error: Could not allocate PDU in mac_reader::run_thread \n " ) ;
exit ( - 1 ) ;
}
2018-02-07 13:59:50 -08:00
2018-09-27 02:23:06 -07:00
float factor = 1.0 ;
if ( args . random_opp ) {
2019-07-02 07:23:43 -07:00
factor = 0.5 + real_dist ( mt19937 ) ;
2018-09-27 02:23:06 -07:00
}
2019-12-16 07:04:22 -08:00
int opp_size = args . avg_opp_size * factor ;
2018-09-20 12:28:40 -07:00
uint32_t buf_state = tx_rlc - > get_buffer_state ( lcid ) ;
2018-09-24 08:51:32 -07:00
if ( buf_state > 0 ) {
2019-12-16 07:04:22 -08:00
int read = tx_rlc - > read_pdu ( lcid , pdu - > msg , opp_size ) ;
2018-09-20 12:28:40 -07:00
pdu - > N_bytes = read ;
2018-09-24 08:51:32 -07:00
if ( args . pdu_tx_delay_usec > 0 ) {
usleep ( args . pdu_tx_delay_usec ) ;
}
2019-07-02 07:23:43 -07:00
if ( ( real_dist ( mt19937 ) > args . pdu_drop_rate ) & & read > 0 ) {
uint32_t pdu_len = pdu - > N_bytes ;
if ( ( real_dist ( mt19937 ) > 0.1 ) & & args . pdu_cut_rate ) {
int cut_pdu_len = pdu_len * real_dist ( mt19937 ) ;
log . info ( " Cutting MAC PDU len (%d B > %d B) \n " , pdu_len , cut_pdu_len ) ;
pdu_len = cut_pdu_len ;
}
rx_rlc - > write_pdu ( lcid , pdu - > msg , pdu_len ) ;
2019-10-23 02:53:00 -07:00
write_pdu_to_pcap ( is_dl , 4 , pdu - > msg , pdu_len ) ;
2018-09-20 12:28:40 -07:00
if ( is_dl ) {
2019-07-02 07:23:43 -07:00
pcap - > write_dl_am_ccch ( pdu - > msg , pdu_len ) ;
2018-09-20 12:28:40 -07:00
} else {
2019-07-02 07:23:43 -07:00
pcap - > write_ul_am_ccch ( pdu - > msg , pdu_len ) ;
2018-03-23 09:20:12 -07:00
}
2018-09-20 12:28:40 -07:00
} else {
2018-08-10 06:50:08 -07:00
log . warning_hex ( pdu - > msg , pdu - > N_bytes , " Dropping RLC PDU (%d B) \n " , pdu - > N_bytes ) ;
2018-02-07 13:59:50 -08:00
}
}
}
2018-09-20 12:28:40 -07:00
void run_thread ( )
{
while ( run_enable ) {
// Downlink direction first (RLC1->RLC2)
run_tti ( rlc1 , rlc2 , true ) ;
// UL direction (RLC2->RLC1)
run_tti ( rlc2 , rlc1 , false ) ;
// step timer
2019-09-04 06:28:09 -07:00
timers - > step_all ( ) ;
2018-09-20 12:28:40 -07:00
}
}
2019-10-21 10:00:49 -07:00
rlc_interface_mac * rlc1 ;
rlc_interface_mac * rlc2 ;
2019-06-06 03:00:48 -07:00
2019-10-21 10:00:49 -07:00
bool run_enable ;
stress_test_args_t args ;
rlc_pcap * pcap ;
uint32_t lcid ;
srslte : : log_filter log ;
srslte : : timer_handler * timers = nullptr ;
2019-07-02 07:23:43 -07:00
std : : mt19937 mt19937 ;
std : : uniform_real_distribution < float > real_dist ;
2018-02-07 13:59:50 -08:00
} ;
2019-10-21 10:00:49 -07:00
class rlc_tester : public pdcp_interface_rlc , public rrc_interface_rlc , public thread
2018-02-07 13:59:50 -08:00
{
public :
2019-05-27 03:09:56 -07:00
rlc_tester ( rlc_interface_pdcp * rlc_ , std : : string name_ , stress_test_args_t args_ , uint32_t lcid_ ) :
log ( " Testr " ) ,
rlc ( rlc_ ) ,
run_enable ( true ) ,
rx_pdus ( ) ,
name ( name_ ) ,
args ( args_ ) ,
lcid ( lcid_ ) ,
thread ( " RLC_TESTER " )
2018-09-24 08:51:32 -07:00
{
log . set_level ( srslte : : LOG_LEVEL_ERROR ) ;
log . set_hex_limit ( LOG_HEX_LIMIT ) ;
2018-02-07 13:59:50 -08:00
}
void stop ( )
{
run_enable = false ;
wait_thread_finish ( ) ;
}
// PDCP interface
2019-05-13 07:34:15 -07:00
void write_pdu ( uint32_t rx_lcid , unique_byte_buffer_t sdu )
2018-02-07 13:59:50 -08:00
{
2018-04-27 07:25:37 -07:00
assert ( rx_lcid = = lcid ) ;
2018-09-25 07:23:00 -07:00
if ( sdu - > N_bytes ! = args . sdu_size ) {
log . error_hex ( sdu - > msg , sdu - > N_bytes , " Received SDU with size %d, expected %d. \n " , sdu - > N_bytes , args . sdu_size ) ;
2019-07-02 07:23:43 -07:00
if ( args . pedantic_sdu_check ) {
exit ( - 1 ) ;
}
2018-05-03 09:36:29 -07:00
}
2018-09-24 08:51:32 -07:00
2018-05-03 09:36:29 -07:00
rx_pdus + + ;
2018-02-07 13:59:50 -08:00
}
2019-05-13 07:34:15 -07:00
void write_pdu_bcch_bch ( unique_byte_buffer_t sdu ) { }
void write_pdu_bcch_dlsch ( unique_byte_buffer_t sdu ) { }
void write_pdu_pcch ( unique_byte_buffer_t sdu ) { }
void write_pdu_mch ( uint32_t lcid , srslte : : unique_byte_buffer_t sdu ) { }
2019-05-01 09:41:04 -07:00
2018-02-07 13:59:50 -08:00
// RRC interface
2019-12-16 07:04:22 -08:00
void max_retx_attempted ( ) { }
2018-09-20 12:28:40 -07:00
std : : string get_rb_name ( uint32_t rx_lcid ) { return std : : string ( " DRB1 " ) ; }
2018-02-07 13:59:50 -08:00
2018-05-03 09:36:29 -07:00
int get_nof_rx_pdus ( ) { return rx_pdus ; }
2018-02-07 13:59:50 -08:00
private :
2019-12-16 07:04:22 -08:00
void run_thread ( )
{
uint8_t sn = 0 ;
2019-05-01 09:41:04 -07:00
byte_buffer_pool * pool = byte_buffer_pool : : get_instance ( ) ;
2019-12-16 07:04:22 -08:00
while ( run_enable ) {
2019-05-13 07:34:15 -07:00
unique_byte_buffer_t pdu = srslte : : allocate_unique_buffer ( * pool , " rlc_tester::run_thread " , true ) ;
2018-09-24 08:51:32 -07:00
if ( pdu = = NULL ) {
2018-05-15 07:29:49 -07:00
printf ( " Error: Could not allocate PDU in rlc_tester::run_thread \n \n \n " ) ;
// backoff for a bit
usleep ( 1000 ) ;
continue ;
2018-02-07 15:13:59 -08:00
}
2018-09-24 08:51:32 -07:00
for ( uint32_t i = 0 ; i < args . sdu_size ; i + + ) {
2018-03-23 09:20:12 -07:00
pdu - > msg [ i ] = sn ;
}
sn + + ;
2018-09-24 08:51:32 -07:00
pdu - > N_bytes = args . sdu_size ;
2019-05-01 09:41:04 -07:00
rlc - > write_sdu ( lcid , std : : move ( pdu ) ) ;
2018-09-24 08:51:32 -07:00
if ( args . sdu_gen_delay_usec > 0 ) {
usleep ( args . sdu_gen_delay_usec ) ;
}
2018-02-07 13:59:50 -08:00
}
}
2019-12-16 07:04:22 -08:00
bool run_enable ;
uint64_t rx_pdus ;
uint32_t lcid ;
2018-09-24 08:51:32 -07:00
srslte : : log_filter log ;
2018-02-12 05:42:59 -08:00
std : : string name ;
2018-02-07 13:59:50 -08:00
2018-09-24 08:51:32 -07:00
stress_test_args_t args ;
2018-02-22 06:43:40 -08:00
2019-12-16 07:04:22 -08:00
rlc_interface_pdcp * rlc ;
2018-02-07 13:59:50 -08:00
} ;
2018-02-22 05:07:27 -08:00
void stress_test ( stress_test_args_t args )
2018-02-07 13:59:50 -08:00
{
2018-04-27 06:40:05 -07:00
srslte : : log_filter log1 ( " RLC_1 " ) ;
srslte : : log_filter log2 ( " RLC_2 " ) ;
2018-09-24 08:51:32 -07:00
log1 . set_level ( static_cast < LOG_LEVEL_ENUM > ( args . log_level ) ) ;
log2 . set_level ( static_cast < LOG_LEVEL_ENUM > ( args . log_level ) ) ;
2018-09-20 12:28:40 -07:00
log1 . set_hex_limit ( LOG_HEX_LIMIT ) ;
log2 . set_hex_limit ( LOG_HEX_LIMIT ) ;
2018-03-23 09:20:12 -07:00
rlc_pcap pcap ;
2018-04-27 07:25:37 -07:00
uint32_t lcid = 1 ;
2018-03-23 09:20:12 -07:00
2019-10-23 02:53:00 -07:00
rlc_config_t cnfg_ = { } ;
if ( args . rat = = " LTE " ) {
if ( args . mode = = " AM " ) {
// config RLC AM bearer
cnfg_ . rlc_mode = rlc_mode_t : : am ;
cnfg_ . am . max_retx_thresh = 4 ;
cnfg_ . am . poll_byte = 25 * 1000 ;
cnfg_ . am . poll_pdu = 4 ;
cnfg_ . am . t_poll_retx = 5 ;
cnfg_ . am . t_reordering = 5 ;
cnfg_ . am . t_status_prohibit = 5 ;
} else if ( args . mode = = " UM " ) {
// config UM bearer
cnfg_ . rlc_mode = rlc_mode_t : : um ;
cnfg_ . um . t_reordering = 5 ;
cnfg_ . um . rx_mod = 32 ;
cnfg_ . um . rx_sn_field_length = rlc_umd_sn_size_t : : size5bits ;
cnfg_ . um . rx_window_size = 16 ;
cnfg_ . um . tx_sn_field_length = rlc_umd_sn_size_t : : size5bits ;
cnfg_ . um . tx_mod = 32 ;
} else if ( args . mode = = " TM " ) {
// use default LCID in TM
lcid = 0 ;
} else {
cout < < " Unsupported RLC mode " < < args . mode < < " , exiting. " < < endl ;
exit ( - 1 ) ;
}
# if PCAP
if ( args . write_pcap ) {
pcap . open ( " rlc_stress_test.pcap " , 0 ) ;
}
# endif
2018-02-07 13:59:50 -08:00
2019-10-23 02:53:00 -07:00
} else if ( args . rat = = " NR " ) {
if ( args . mode = = " UM " ) {
cnfg_ = rlc_config_t : : default_rlc_um_nr_config ( 6 ) ;
} else {
cout < < " Unsupported RLC mode " < < args . mode < < " , exiting. " < < endl ;
exit ( - 1 ) ;
}
# if PCAP
if ( args . write_pcap ) {
pcap_handle = std : : unique_ptr < srslte : : mac_nr_pcap > ( new srslte : : mac_nr_pcap ( ) ) ;
pcap_handle - > open ( " rlc_stress_test_nr.pcap " ) ;
}
# endif
2018-04-27 06:40:05 -07:00
} else {
2019-10-23 02:53:00 -07:00
cout < < " Unsupported RAT mode " < < args . rat < < " , exiting. " < < endl ;
2018-05-04 03:40:20 -07:00
exit ( - 1 ) ;
2018-04-27 06:40:05 -07:00
}
2018-02-07 13:59:50 -08:00
2019-10-21 10:00:49 -07:00
srslte : : timer_handler timers ( 8 ) ;
2019-06-06 03:00:48 -07:00
2019-06-27 01:50:47 -07:00
rlc rlc1 ( & log1 ) ;
rlc rlc2 ( & log2 ) ;
2018-04-27 07:25:37 -07:00
2018-09-24 08:51:32 -07:00
rlc_tester tester1 ( & rlc1 , " tester1 " , args , lcid ) ;
rlc_tester tester2 ( & rlc2 , " tester2 " , args , lcid ) ;
2019-09-04 06:28:09 -07:00
mac_dummy mac ( & rlc1 , & rlc2 , args , lcid , & timers , & pcap ) ;
2018-04-27 07:25:37 -07:00
2019-09-04 06:28:09 -07:00
rlc1 . init ( & tester1 , & tester1 , & timers , 0 ) ;
rlc2 . init ( & tester2 , & tester2 , & timers , 0 ) ;
2018-04-27 07:25:37 -07:00
// only add AM and UM bearers
if ( args . mode ! = " TM " ) {
rlc1 . add_bearer ( lcid , cnfg_ ) ;
rlc2 . add_bearer ( lcid , cnfg_ ) ;
}
2018-02-07 13:59:50 -08:00
tester1 . start ( 7 ) ;
2018-03-23 09:20:12 -07:00
if ( ! args . single_tx ) {
tester2 . start ( 7 ) ;
}
2018-02-07 13:59:50 -08:00
mac . start ( ) ;
2018-09-24 08:51:32 -07:00
if ( args . test_duration_sec < 1 ) {
args . test_duration_sec = 1 ;
}
2018-02-22 06:43:40 -08:00
for ( uint32_t i = 0 ; i < args . test_duration_sec ; i + + ) {
// if enabled, mimic reestablishment every second
if ( args . reestablish ) {
rlc1 . reestablish ( ) ;
rlc2 . reestablish ( ) ;
}
usleep ( 1e6 ) ;
}
2018-02-07 13:59:50 -08:00
2018-08-10 06:50:08 -07:00
printf ( " Test finished, tearing down .. \n " ) ;
2018-07-30 05:57:17 -07:00
// Stop RLC instances first to release blocking writers
rlc1 . stop ( ) ;
rlc2 . stop ( ) ;
2018-08-10 06:50:08 -07:00
printf ( " RLC entities stopped. \n " ) ;
// Stop upper layer writers
2018-02-07 13:59:50 -08:00
tester1 . stop ( ) ;
tester2 . stop ( ) ;
2018-08-10 06:50:08 -07:00
printf ( " Writers stopped. \n " ) ;
2018-02-07 13:59:50 -08:00
mac . stop ( ) ;
2018-03-23 09:20:12 -07:00
if ( args . write_pcap ) {
pcap . close ( ) ;
}
2018-05-03 09:36:29 -07:00
2018-09-24 08:51:32 -07:00
rlc_metrics_t metrics = { } ;
2018-07-23 06:44:50 -07:00
rlc1 . get_metrics ( metrics ) ;
2019-10-23 02:53:00 -07:00
printf ( " RLC1 received %d SDUs in %ds (%.2f/s), Tx=% " PRIu64 " B, Rx=% " PRIu64 " B \n " ,
2018-05-03 09:36:29 -07:00
tester1 . get_nof_rx_pdus ( ) ,
args . test_duration_sec ,
2019-10-23 02:53:00 -07:00
static_cast < double > ( tester1 . get_nof_rx_pdus ( ) / args . test_duration_sec ) ,
metrics . bearer [ lcid ] . num_tx_bytes ,
metrics . bearer [ lcid ] . num_rx_bytes ) ;
2018-05-03 09:36:29 -07:00
2018-07-23 06:44:50 -07:00
rlc2 . get_metrics ( metrics ) ;
2019-10-23 02:53:00 -07:00
printf ( " RLC2 received %d SDUs in %ds (%.2f/s), Tx=% " PRIu64 " B, Rx=% " PRIu64 " B \n " ,
2018-05-03 09:36:29 -07:00
tester2 . get_nof_rx_pdus ( ) ,
args . test_duration_sec ,
2019-10-23 02:53:00 -07:00
static_cast < double > ( tester2 . get_nof_rx_pdus ( ) / args . test_duration_sec ) ,
metrics . bearer [ lcid ] . num_tx_bytes ,
metrics . bearer [ lcid ] . num_rx_bytes ) ;
2018-02-07 13:59:50 -08:00
}
2019-12-16 07:04:22 -08:00
int main ( int argc , char * * argv )
2018-10-09 01:42:35 -07:00
{
srslte_debug_handle_crash ( argc , argv ) ;
2018-08-10 06:50:08 -07:00
stress_test_args_t args = { } ;
2018-02-22 05:07:27 -08:00
parse_args ( & args , argc , argv ) ;
2018-09-20 12:28:40 -07:00
if ( args . zero_seed ) {
srand ( 0 ) ;
} else {
srand ( time ( NULL ) ) ;
}
2018-02-22 05:07:27 -08:00
stress_test ( args ) ;
2018-02-07 13:59:50 -08:00
byte_buffer_pool : : get_instance ( ) - > cleanup ( ) ;
2018-05-04 03:40:20 -07:00
exit ( 0 ) ;
2018-02-07 13:59:50 -08:00
}