Merge branch 'next' of github.com:softwareradiosystems/srsLTE into next

This commit is contained in:
Ismael Gomez 2018-03-05 13:07:34 +01:00
commit 73602a8558
21 changed files with 176 additions and 53 deletions

View File

@ -30,6 +30,8 @@
#include <pthread.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <algorithm>
/*******************************************************************************
@ -76,8 +78,13 @@ public:
{
printf("%d buffers in queue\n", (int) used.size());
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
std::map<std::string, uint32_t> buffer_cnt;
for (uint32_t i=0;i<used.size();i++) {
printf("%s\n", strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined");
buffer_cnt[strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined"]++;
}
std::map<std::string, uint32_t>::iterator it;
for (it = buffer_cnt.begin(); it != buffer_cnt.end(); it++) {
printf(" - %dx %s\n", it->second, it->first.c_str());
}
#endif
}

View File

@ -63,7 +63,7 @@
#define SRSLTE_MAX_BUFFER_SIZE_BYTES 12756
#define SRSLTE_BUFFER_HEADER_OFFSET 1024
//#define SRSLTE_BUFFER_POOL_LOG_ENABLED
#define SRSLTE_BUFFER_POOL_LOG_ENABLED
#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED
#define pool_allocate (pool->allocate(__FUNCTION__))

View File

@ -60,6 +60,7 @@ typedef struct {
SRSLTE_RF_ERROR_LATE,
SRSLTE_RF_ERROR_UNDERFLOW,
SRSLTE_RF_ERROR_OVERFLOW,
SRSLTE_RF_ERROR_RX,
SRSLTE_RF_ERROR_OTHER
} type;
int opt;

View File

@ -40,6 +40,7 @@ log_filter::log_filter()
do_tti = false;
time_src = NULL;
time_format = TIME;
logger_h = NULL;
}
log_filter::log_filter(std::string layer)

View File

@ -35,6 +35,7 @@ namespace srslte{
logger_file::logger_file()
:inited(false)
,logfile(NULL)
,not_done(true)
,cur_length(0)
,max_length(0)
@ -46,7 +47,9 @@ logger_file::~logger_file() {
if(inited) {
wait_thread_finish();
flush();
fclose(logfile);
if (logfile) {
fclose(logfile);
}
}
}

View File

@ -58,10 +58,12 @@ void srslte_dft_exit() {
#ifdef FFTW_WISDOM_FILE
fftwf_export_wisdom_to_filename(FFTW_WISDOM_FILE);
#endif
fftwf_cleanup();
}
int srslte_dft_plan(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir,
srslte_dft_mode_t mode) {
bzero(plan, sizeof(srslte_dft_plan_t));
if(mode == SRSLTE_DFT_COMPLEX){
return srslte_dft_plan_c(plan,dft_points,dir);
} else {

View File

@ -171,5 +171,8 @@ int main(int argc, char **argv) {
n_prb++;
}
srslte_dft_exit();
exit(0);
}

View File

@ -198,6 +198,8 @@ int main(int argc, char **argv) {
}
srslte_rm_turbo_free_tables();
free(rm_bits_s);
free(rm_bits_f);
free(rm_bits);
free(rm_bits2);
free(rm_bits2_bytes);

View File

@ -96,6 +96,19 @@ static void log_underflow(rf_uhd_handler_t *h) {
}
}
static void log_rx_error(rf_uhd_handler_t *h) {
if (h->uhd_error_handler) {
char error_string[512];
uhd_usrp_last_error(h->usrp, error_string, 512);
fprintf(stderr, "USRP reported the following error: %s\n", error_string);
srslte_rf_error_t error;
bzero(&error, sizeof(srslte_rf_error_t));
error.type = SRSLTE_RF_ERROR_RX;
h->uhd_error_handler(error);
}
}
static void* async_thread(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_async_metadata_handle md;
@ -334,11 +347,12 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
perror("malloc");
return -1;
}
bzero(handler, sizeof(rf_uhd_handler_t));
*h = handler;
/* Set priority to UHD threads */
uhd_set_thread_priority(uhd_default_thread_priority, true);
/* Find available devices */
uhd_string_vector_handle devices_str;
uhd_string_vector_make(&devices_str);
@ -739,6 +753,7 @@ int rf_uhd_recv_with_time_multi(void *h,
num_rx_samples, md, 1.0, false, &rxd_samples);
if (error) {
fprintf(stderr, "Error receiving from UHD: %d\n", error);
log_rx_error(handler);
return -1;
}
@ -761,8 +776,12 @@ int rf_uhd_recv_with_time_multi(void *h,
}
}
} else {
return uhd_rx_streamer_recv(handler->rx_stream, data,
nsamples, md, 0.0, false, &rxd_samples);
uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, data, nsamples, md, 0.0, false, &rxd_samples);
if (error) {
fprintf(stderr, "Error receiving from UHD: %d\n", error);
log_rx_error(handler);
return -1;
}
}
if (secs && frac_secs) {
uhd_rx_metadata_time_spec(handler->rx_md_first, secs, frac_secs);

View File

@ -74,7 +74,7 @@ void usage(char *prog) {
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "adgetvsfil")) != -1) {
while ((opt = getopt(argc, argv, "adgetvnsfil")) != -1) {
switch (opt) {
case 'a':
rf_args = argv[optind];

View File

@ -157,6 +157,8 @@ int main(int argc, char **argv) {
if(test_dft(in) != 0)
return -1;
srslte_dft_exit();
free(in);
printf("Done\n");
exit(0);

View File

@ -72,6 +72,14 @@ rlc_am::~rlc_am()
{
// reset RLC and dealloc SDUs
stop();
if(rx_sdu) {
pool->deallocate(rx_sdu);
}
if(tx_sdu) {
pool->deallocate(tx_sdu);
}
}
void rlc_am::init(srslte::log *log_,

View File

@ -136,11 +136,11 @@ void rlc_um::reset()
vr_uh = 0;
pdu_lost = false;
if(rx_sdu) {
rx_sdu->reset();
pool->deallocate(rx_sdu);
}
if(tx_sdu) {
tx_sdu->reset();
pool->deallocate(tx_sdu);
}
if(mac_timers) {

View File

@ -31,7 +31,8 @@ target_link_libraries(rlc_am_test srslte_upper srslte_phy srslte_common)
add_test(rlc_am_test rlc_am_test)
add_executable(rlc_am_stress_test rlc_am_stress_test.cc)
target_link_libraries(rlc_am_stress_test srslte_upper srslte_phy srslte_common)
target_link_libraries(rlc_am_stress_test srslte_upper srslte_phy srslte_common ${Boost_LIBRARIES})
add_test(rlc_am_stress_test rlc_am_stress_test --duration 10)
add_executable(rlc_um_data_test rlc_um_data_test.cc)
target_link_libraries(rlc_um_data_test srslte_upper srslte_phy srslte_common)

View File

@ -31,23 +31,70 @@
#include "srslte/common/logger_stdout.h"
#include "srslte/common/threads.h"
#include "srslte/upper/rlc.h"
#include <boost/program_options.hpp>
#include <boost/program_options/parsers.hpp>
#include <assert.h>
#define NBUFS 5
using namespace std;
using namespace srsue;
using namespace srslte;
namespace bpo = boost::program_options;
typedef struct {
uint32_t test_duration_sec;
float error_rate;
uint32_t sdu_gen_delay_usec;
uint32_t pdu_tx_delay_usec;
bool reestablish;
} stress_test_args_t;
void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
// Command line only options
bpo::options_description general("General options");
general.add_options()
("help,h", "Produce help message")
("version,v", "Print version information and exit");
// Command line or config file options
bpo::options_description common("Configuration options");
common.add_options()
("duration", bpo::value<uint32_t>(&args->test_duration_sec)->default_value(10), "Duration (sec)")
("sdu_gen_delay", bpo::value<uint32_t>(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)")
("pdu_tx_delay", bpo::value<uint32_t>(&args->pdu_tx_delay_usec)->default_value(10), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)")
("error_rate", bpo::value<float>(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped")
("reestablish", bpo::value<bool>(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution");
// 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
if (vm.count("help")) {
cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << endl << endl;
cout << common << endl << general << endl;
exit(0);
}
}
class mac_reader
:public thread
{
public:
mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_)
mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t pdu_tx_delay_usec_)
{
rlc1 = rlc1_;
rlc2 = rlc2_;
fail_rate = fail_rate_;
run_enable = true;
running = false;
pdu_tx_delay_usec = pdu_tx_delay_usec_;
}
void stop()
@ -82,7 +129,7 @@ private:
if(((float)rand()/RAND_MAX > fail_rate) && read>0) {
rlc2->write_pdu(1, pdu->msg, opp_size);
}
usleep(100);
usleep(pdu_tx_delay_usec);
}
running = false;
byte_buffer_pool::get_instance()->deallocate(pdu);
@ -91,6 +138,7 @@ private:
rlc_interface_mac *rlc1;
rlc_interface_mac *rlc2;
float fail_rate;
uint32_t pdu_tx_delay_usec;
bool run_enable;
bool running;
@ -100,9 +148,9 @@ class mac_dummy
:public srslte::mac_interface_timers
{
public:
mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_)
:r1(rlc1_, rlc2_, fail_rate_)
,r2(rlc2_, rlc1_, fail_rate_)
mac_dummy(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t pdu_tx_delay)
:r1(rlc1_, rlc2_, fail_rate_, pdu_tx_delay)
,r2(rlc2_, rlc1_, fail_rate_, pdu_tx_delay)
{
}
@ -140,12 +188,13 @@ class rlc_am_tester
,public thread
{
public:
rlc_am_tester(rlc_interface_pdcp *rlc_, std::string name_=""){
rlc_am_tester(rlc_interface_pdcp *rlc_, std::string name_, uint32_t sdu_gen_delay_usec_){
rlc = rlc_;
run_enable = true;
running = false;
rx_pdus = 0;
name = name_;
sdu_gen_delay_usec = sdu_gen_delay_usec_;
}
void stop()
@ -191,7 +240,7 @@ private:
pdu->N_bytes = 1500;
pdu->msg[0] = sn++;
rlc->write_sdu(1, pdu);
usleep(100);
usleep(sdu_gen_delay_usec);
}
running = false;
}
@ -202,10 +251,12 @@ private:
std::string name;
uint32_t sdu_gen_delay_usec;
rlc_interface_pdcp *rlc;
};
void stress_test()
void stress_test(stress_test_args_t args)
{
srslte::log_filter log1("RLC_AM_1");
srslte::log_filter log2("RLC_AM_2");
@ -214,14 +265,12 @@ void stress_test()
log1.set_hex_limit(-1);
log2.set_hex_limit(-1);
float fail_rate = 0.1;
rlc rlc1;
rlc rlc2;
rlc_am_tester tester1(&rlc1, "tester1");
rlc_am_tester tester2(&rlc2, "tester2");
mac_dummy mac(&rlc1, &rlc2, fail_rate);
rlc_am_tester tester1(&rlc1, "tester1", args.sdu_gen_delay_usec);
rlc_am_tester tester2(&rlc2, "tester2", args.sdu_gen_delay_usec);
mac_dummy mac(&rlc1, &rlc2, args.error_rate, args.pdu_tx_delay_usec);
ue_interface ue;
rlc1.init(&tester1, &tester1, &ue, &log1, &mac, 0);
@ -245,7 +294,14 @@ void stress_test()
tester2.start(7);
mac.start();
usleep(100e6);
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);
}
tester1.stop();
tester2.stop();
@ -254,6 +310,9 @@ void stress_test()
int main(int argc, char **argv) {
stress_test();
stress_test_args_t args;
parse_args(&args, argc, argv);
stress_test(args);
byte_buffer_pool::get_instance()->cleanup();
}

View File

@ -110,8 +110,6 @@ private:
srslte::log_filter gw_log;
srslte::log_filter usim_log;
srslte::byte_buffer_pool *pool;
all_args_t *args;
bool started;

View File

@ -146,7 +146,7 @@ class ue_base
{
public:
ue_base();
virtual ~ue_base() {}
virtual ~ue_base();
static ue_base* get_instance(srsue_instance_type_t type);
@ -173,6 +173,9 @@ public:
std::string get_build_mode();
std::string get_build_info();
std::string get_build_string();
private:
srslte::byte_buffer_pool *pool;
};
} // namespace srsue

View File

@ -933,7 +933,7 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c
srslte_ue_sync_decode_sss_on_track(ue_sync, true);
int ret = srslte_ue_sync_zerocopy_multi(ue_sync, buffer);
if (ret < 0) {
Error("SYNC: Error calling ue_sync_get_buffer");
Error("SYNC: Error calling ue_sync_get_buffer.\n");
return ERROR;
}

View File

@ -40,12 +40,10 @@ namespace srsue{
ue::ue()
:started(false)
{
pool = byte_buffer_pool::get_instance();
}
ue::~ue()
{
byte_buffer_pool::cleanup();
}
bool ue::init(all_args_t *args_)
@ -306,8 +304,13 @@ void ue::rf_msg(srslte_rf_error_t error)
{
ue_base *ue = ue_base::get_instance(LTE);
ue->handle_rf_msg(error);
if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) {
if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) {
ue->radio_overflow();
} else
if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_RX) {
ue->stop();
ue->cleanup();
exit(-1);
}
}

View File

@ -64,6 +64,12 @@ ue_base::ue_base() {
// load FFTW wisdom
srslte_dft_load();
pool = byte_buffer_pool::get_instance();
}
ue_base::~ue_base() {
byte_buffer_pool::cleanup();
}
void ue_base::cleanup(void)

View File

@ -1538,10 +1538,13 @@ byte_buffer_t* rrc::byte_align_and_pack(byte_buffer_t *pdu)
pdcp_buf = pool_allocate;
}
srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits);
pdcp_buf->N_bytes = bit_buf.N_bits / 8;
pdcp_buf->set_timestamp();
if (pdcp_buf != NULL) {
srslte_bit_pack_vector(bit_buf.msg, pdcp_buf->msg, bit_buf.N_bits);
pdcp_buf->N_bytes = bit_buf.N_bits / 8;
pdcp_buf->set_timestamp();
} else {
rrc_log->error("Fatal Error: Couldn't allocate PDU in byte_align_and_pack().\n");
}
return pdcp_buf;
}
@ -1549,20 +1552,21 @@ void rrc::send_ul_ccch_msg(byte_buffer_t *pdu)
{
liblte_rrc_pack_ul_ccch_msg(&ul_ccch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf);
pdu = byte_align_and_pack(pdu);
if (pdu) {
// Set UE contention resolution ID in MAC
uint64_t uecri = 0;
uint8_t *ue_cri_ptr = (uint8_t *) &uecri;
uint32_t nbytes = 6;
for (uint32_t i = 0; i < nbytes; i++) {
ue_cri_ptr[nbytes - i - 1] = pdu->msg[i];
}
// Set UE contention resolution ID in MAC
uint64_t uecri = 0;
uint8_t *ue_cri_ptr = (uint8_t *) &uecri;
uint32_t nbytes = 6;
for (uint32_t i = 0; i < nbytes; i++) {
ue_cri_ptr[nbytes - i - 1] = pdu->msg[i];
rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri);
mac->set_contention_id(uecri);
rrc_log->info("Sending %s\n", liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]);
pdcp->write_sdu(RB_ID_SRB0, pdu);
}
rrc_log->debug("Setting UE contention resolution ID: %d\n", uecri);
mac->set_contention_id(uecri);
rrc_log->info("Sending %s\n", liblte_rrc_ul_ccch_msg_type_text[ul_ccch_msg.msg_type]);
pdcp->write_sdu(RB_ID_SRB0, pdu);
}
void rrc::send_ul_dcch_msg(byte_buffer_t *pdu)
@ -1570,9 +1574,10 @@ void rrc::send_ul_dcch_msg(byte_buffer_t *pdu)
liblte_rrc_pack_ul_dcch_msg(&ul_dcch_msg, (LIBLTE_BIT_MSG_STRUCT *) &bit_buf);
pdu = byte_align_and_pack(pdu);
rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]);
pdcp->write_sdu(RB_ID_SRB1, pdu);
if (pdu) {
rrc_log->info("Sending %s\n", liblte_rrc_ul_dcch_msg_type_text[ul_dcch_msg.msg_type]);
pdcp->write_sdu(RB_ID_SRB1, pdu);
}
}
void rrc::write_sdu(uint32_t lcid, byte_buffer_t *sdu) {