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

This commit is contained in:
Ismael Gomez 2018-03-06 22:20:46 +01:00
commit be7dc37e7c
19 changed files with 214 additions and 50 deletions

View File

@ -74,6 +74,7 @@ option(ENABLE_BLADERF "Enable BladeRF" ON)
option(BUILD_STATIC "Attempt to statically link external deps" OFF)
option(RPATH "Enable RPATH" OFF)
option(ENABLE_ASAN "Enable gcc address sanitizer" OFF)
option(USE_LTE_RATES "Use standard LTE sampling rates" OFF)
@ -303,6 +304,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
if(NOT WIN32)
ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN)
endif(NOT WIN32)
if (ENABLE_ASAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
endif (ENABLE_ASAN)
endif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")

View File

@ -84,7 +84,6 @@ public:
}
void thread_func()
{
// substract time elapsed until now from timer duration
gettimeofday(&start_time[2], NULL);
get_time_interval(start_time);
@ -105,6 +104,14 @@ public:
return false;
}
}
int32_t get_msec_to_expire() {
if (running) {
gettimeofday(&start_time[2], NULL);
get_time_interval(start_time);
return (duration_msec*1000 - start_time[0].tv_usec)/1000;
}
return 0;
}
bool is_running()
{
return running;

View File

@ -54,12 +54,5 @@ void byte_buffer_pool::cleanup(void)
}
pthread_mutex_unlock(&instance_mutex);
}
} // namespace srsue

View File

@ -88,7 +88,7 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, uint32_t max_prb)
goto clean_exit;
}
q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t*));
q->mbsfn_refs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_refsignal_t));
if (!q->mbsfn_refs) {
fprintf(stderr, "Calloc error initializing mbsfn_refs (%d)\n", ret);
goto clean_exit;
@ -169,14 +169,14 @@ clean_exit:
void srslte_chest_dl_free(srslte_chest_dl_t *q)
{
int i;
if(&q->csr_refs)
srslte_refsignal_free(&q->csr_refs);
if (q->mbsfn_refs) {
for (i=0; i<SRSLTE_MAX_MBSFN_AREA_IDS; i++) {
for (int i=0; i<SRSLTE_MAX_MBSFN_AREA_IDS; i++) {
if (q->mbsfn_refs[i]) {
srslte_refsignal_free(q->mbsfn_refs[i]);
free(q->mbsfn_refs[i]);
}
}
free(q->mbsfn_refs);
@ -206,15 +206,18 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q)
int srslte_chest_dl_set_mbsfn_area_id(srslte_chest_dl_t *q, uint16_t mbsfn_area_id){
if(!q->mbsfn_refs[mbsfn_area_id]){
q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t));
}
if(q->mbsfn_refs[mbsfn_area_id]) {
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
return SRSLTE_ERROR;
if (mbsfn_area_id < SRSLTE_MAX_MBSFN_AREA_IDS) {
if(!q->mbsfn_refs[mbsfn_area_id]) {
q->mbsfn_refs[mbsfn_area_id] = calloc(1, sizeof(srslte_refsignal_t));
}
}
return SRSLTE_SUCCESS;
if(q->mbsfn_refs[mbsfn_area_id]) {
if(srslte_refsignal_mbsfn_init(q->mbsfn_refs[mbsfn_area_id], q->cell, mbsfn_area_id)) {
return SRSLTE_ERROR;
}
}
return SRSLTE_SUCCESS;
}
return SRSLTE_ERROR;
}
int srslte_chest_dl_set_cell(srslte_chest_dl_t *q, srslte_cell_t cell)

View File

@ -71,8 +71,6 @@ int main(int argc, char **argv) {
parse_args(argc, argv);
srslte_tcod_gentable();
srslte_tcod_t tcod;
srslte_tcod_init(&tcod, 6144);

View File

@ -152,9 +152,8 @@ int srslte_pmch_init(srslte_pmch_t *q, uint32_t max_prb)
int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_antennas)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
int i;
if (q != NULL &&
if (q != NULL &&
nof_rx_antennas <= SRSLTE_MAX_PORTS)
{
@ -169,7 +168,7 @@ int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_a
INFO("Init PMCH: %d PRBs, max_symbols: %d\n",
max_prb, q->max_re);
for (i = 0; i < 4; i++) {
for (int i = 0; i < 4; i++) {
if (srslte_modem_table_lte(&q->mod[i], modulations[i])) {
goto clean;
}
@ -189,7 +188,7 @@ int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_a
goto clean;
}
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
if (!q->x[i]) {
goto clean;
@ -232,7 +231,7 @@ void srslte_pmch_free(srslte_pmch_t *q) {
if (q->d) {
free(q->d);
}
for (i = 0; i < q->cell.nof_ports; i++) {
for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
if (q->x[i]) {
free(q->x[i]);
}

View File

@ -80,8 +80,8 @@ static void log_overflow(rf_uhd_handler_t *h) {
static void log_late(rf_uhd_handler_t *h, bool is_rx) {
if (h->uhd_error_handler) {
srslte_rf_error_t error;
error.opt = is_rx?1:0;
bzero(&error, sizeof(srslte_rf_error_t));
error.opt = is_rx?1:0;
error.type = SRSLTE_RF_ERROR_LATE;
h->uhd_error_handler(error);
}

View File

@ -265,6 +265,7 @@ TEST(srslte_vec_sum_fff,
free(x);
free(y);
free(z);
)
TEST(srslte_vec_sub_fff,
@ -287,6 +288,7 @@ TEST(srslte_vec_sub_fff,
free(x);
free(y);
free(z);
)
TEST(srslte_vec_dot_prod_ccc,
@ -354,6 +356,7 @@ TEST(srslte_vec_prod_ccc,
}
free(x);
free(y);
free(z);
)
@ -407,6 +410,7 @@ TEST(srslte_vec_prod_conj_ccc,
}
free(x);
free(y);
free(z);
)

View File

@ -198,7 +198,7 @@ uint32_t rlc_am::get_bearer()
void rlc_am::write_sdu(byte_buffer_t *sdu)
{
tx_sdu_queue.write(sdu);
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size());
log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, tx_sdu_queue_len=%d", rrc->get_rb_name(lcid).c_str(), tx_sdu_queue.size());
}
/****************************************************************************
@ -273,6 +273,27 @@ uint32_t rlc_am::get_buffer_state()
goto unlock_and_return;
}
// check if pollRetx timer expired (Section 5.2.2.3 in TS 36.322)
if (poll_retx()) {
// if both tx and retx buffer are empty, retransmit next PDU to be ack'ed
log->info("Poll reTx timer expired (lcid=%d)\n", lcid);
if ((tx_window.size() > 0 && retx_queue.size() == 0 && tx_sdu_queue.size() == 0)) {
std::map<uint32_t, rlc_amd_tx_pdu_t>::iterator it = tx_window.find(vt_s - 1);
if (it != tx_window.end()) {
log->info("Schedule last PDU (SN=%d) for reTx.\n", vt_s - 1);
rlc_amd_retx_t retx;
retx.is_segment = false;
retx.so_start = 0;
retx.so_end = tx_window[vt_s - 1].buf->N_bytes;
retx.sn = vt_s - 1;
retx_queue.push_back(retx);
} else {
log->error("Found invalid PDU in tx_window.\n");
}
poll_retx_timeout.start(cfg.t_poll_retx);
}
}
// Bytes needed for retx
if(retx_queue.size() > 0) {
rlc_amd_retx_t retx = retx_queue.front();

View File

@ -125,10 +125,14 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes)
void rlc_tm::write_pdu(uint8_t *payload, uint32_t nof_bytes)
{
byte_buffer_t *buf = pool_allocate;
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
pdcp->write_pdu(lcid, buf);
if (buf) {
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
pdcp->write_pdu(lcid, buf);
} else {
log->error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu().\n");
}
}
} // namespace srsue

View File

@ -448,8 +448,13 @@ void rlc_um::handle_data_pdu(uint8_t *payload, uint32_t nof_bytes)
void rlc_um::reassemble_rx_sdus()
{
if(!rx_sdu)
if(!rx_sdu) {
rx_sdu = pool_allocate;
if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
}
}
// First catch up with lower edge of reordering window
while(!inside_reordering_window(vr_ur))
@ -474,6 +479,10 @@ void rlc_um::reassemble_rx_sdus()
rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate;
if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
}
}
pdu_lost = false;
}
@ -494,6 +503,10 @@ void rlc_um::reassemble_rx_sdus()
rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate;
if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
}
}
pdu_lost = false;
}
@ -528,6 +541,10 @@ void rlc_um::reassemble_rx_sdus()
rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate;
if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
}
}
pdu_lost = false;
}
@ -557,6 +574,10 @@ void rlc_um::reassemble_rx_sdus()
rx_sdu->set_timestamp();
pdcp->write_pdu(lcid, rx_sdu);
rx_sdu = pool_allocate;
if (!rx_sdu) {
log->error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus().\n");
return;
}
}
pdu_lost = false;
}

View File

@ -64,7 +64,43 @@ private:
pthread_mutex_t mutex;
};
int main(int argc, char **argv) {
int timer_thread_test()
{
bool result;
uint32_t id = 0;
uint32_t duration_msec = 5;
uint32_t result_tolerance = 1;
callback c;
timeout t;
gettimeofday(&c.start_time[1], NULL);
t.start(duration_msec);
while (t.is_running() && !t.expired()) {
printf("time to expire=%dms\n", t.get_msec_to_expire());
usleep(1000);
}
gettimeofday(&c.start_time[2], NULL);
get_time_interval(c.start_time);
uint32_t diff_ms = c.start_time[0].tv_usec*1e-3;
printf("Target duration: %dms, started: %ld:%ld, ended: %ld:%ld, actual duration %dms\n",
duration_msec, c.start_time[1].tv_sec, c.start_time[1].tv_usec, c.start_time[2].tv_sec, c.start_time[2].tv_usec, diff_ms);
result = (duration_msec - result_tolerance <= diff_ms < duration_msec + result_tolerance);
if(result) {
printf("Timer thread test passed\n");
return 0;
}else{
return -1;
}
}
int single_thread_test()
{
bool result;
uint32_t id = 0;
uint32_t duration_msec = 5;
@ -84,10 +120,25 @@ int main(int argc, char **argv) {
result = (diff_ms == duration_msec);
if(result) {
printf("Passed\n");
exit(0);
printf("Single thread test passed\n");
return 0;
}else{
printf("Failed\n;");
exit(1);
return -1;
}
}
int main(int argc, char **argv)
{
if (single_thread_test()) {
printf("Single thread test failed.\n");
return -1;
}
if (timer_thread_test()) {
printf("Timer thread test failed.\n");
return -1;
}
return 0;
}

View File

@ -46,6 +46,7 @@ typedef struct {
uint32_t sdu_gen_delay_usec;
uint32_t pdu_tx_delay_usec;
bool reestablish;
uint32_t log_level;
} stress_test_args_t;
void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
@ -64,7 +65,8 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
("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");
("reestablish", bpo::value<bool>(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution")
("loglevel", bpo::value<uint32_t>(&args->log_level)->default_value(srslte::LOG_LEVEL_DEBUG), "Log level (1=Error,2=Warning,3=Info,4=Debug");
// these options are allowed on the command line
bpo::options_description cmdline_options;
@ -81,6 +83,11 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) {
cout << common << endl << general << endl;
exit(0);
}
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]);
}
}
class mac_reader
@ -260,8 +267,8 @@ void stress_test(stress_test_args_t args)
{
srslte::log_filter log1("RLC_AM_1");
srslte::log_filter log2("RLC_AM_2");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log2.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_level((LOG_LEVEL_ENUM)args.log_level);
log2.set_level((LOG_LEVEL_ENUM)args.log_level);
log1.set_hex_limit(-1);
log2.set_hex_limit(-1);

View File

@ -195,6 +195,10 @@ void gtpu::rem_user(uint16_t rnti)
void gtpu::run_thread()
{
byte_buffer_t *pdu = pool_allocate;
if (!pdu) {
gtpu_log->error("Fatal Error: Couldn't allocate buffer in gtpu::run_thread().\n");
return;
}
run_enable = true;
running=true;

View File

@ -88,6 +88,10 @@ void s1ap::get_metrics(s1ap_metrics_t &m)
void s1ap::run_thread()
{
srslte::byte_buffer_t *pdu = pool_allocate;
if (!pdu) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n");
return;
}
uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET;
running = true;
@ -514,10 +518,15 @@ bool s1ap::handle_dlnastransport(LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT
}
srslte::byte_buffer_t *pdu = pool_allocate;
memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets);
pdu->N_bytes = msg->NAS_PDU.n_octets;
rrc->write_dl_info(rnti, pdu);
return true;
if (pdu) {
memcpy(pdu->msg, msg->NAS_PDU.buffer, msg->NAS_PDU.n_octets);
pdu->N_bytes = msg->NAS_PDU.n_octets;
rrc->write_dl_info(rnti, pdu);
return true;
} else {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n");
return false;
}
}
bool s1ap::handle_initialctxtsetuprequest(LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg)
@ -850,6 +859,11 @@ bool s1ap::send_initial_ctxt_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_I
return false;
}
srslte::byte_buffer_t *buf = pool_allocate;
if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_response().\n");
return false;
}
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
tx_pdu.ext = false;
@ -896,6 +910,11 @@ bool s1ap::send_erab_setup_response(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETU
return false;
}
srslte::byte_buffer_t *buf = pool_allocate;
if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_erab_setup_response().\n");
return false;
}
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
tx_pdu.ext = false;
@ -942,6 +961,11 @@ bool s1ap::send_initial_ctxt_setup_failure(uint16_t rnti)
return false;
}
srslte::byte_buffer_t *buf = pool_allocate;
if (!buf) {
s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::send_initial_ctxt_setup_failure().\n");
return false;
}
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
tx_pdu.ext = false;
tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME;

View File

@ -242,7 +242,11 @@ void gw::run_thread()
struct iphdr *ip_pkt;
uint32 idx = 0;
int32 N_bytes;
srslte::byte_buffer_t *pdu = pool_allocate;
srslte::byte_buffer_t *pdu = pool_allocate;
if (!pdu) {
gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n");
return;
}
const static uint32_t ATTACH_TIMEOUT_MS = 10000;
const static uint32_t ATTACH_MAX_ATTEMPTS = 3;
@ -307,7 +311,7 @@ void gw::run_thread()
do {
pdu = pool_allocate;
if (!pdu) {
printf("Not enough buffers in pool\n");
gw_log->error("Fatal Error: Couldn't allocate PDU in run_thread().\n");
usleep(100000);
}
} while(!pdu);

View File

@ -810,6 +810,11 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) {
void nas::send_attach_request() {
LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req;
byte_buffer_t *msg = pool_allocate;
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_attach_request().\n");
return;
}
u_int32_t i;
attach_req.eps_attach_type = LIBLTE_MME_EPS_ATTACH_TYPE_EPS_ATTACH;
@ -911,6 +916,10 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) {
void nas::send_security_mode_reject(uint8_t cause) {
byte_buffer_t *msg = pool_allocate;
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_security_mode_reject().\n");
return;
}
LIBLTE_MME_SECURITY_MODE_REJECT_MSG_STRUCT sec_mode_rej;
sec_mode_rej.emm_cause = cause;
@ -926,6 +935,10 @@ void nas::send_identity_response() {}
void nas::send_service_request() {
byte_buffer_t *msg = pool_allocate;
if (!msg) {
nas_log->error("Fatal Error: Couldn't allocate PDU in send_service_request().\n");
return;
}
// Pack the service request message directly
msg->msg[0] = (LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT);

View File

@ -1283,9 +1283,14 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, LIBLTE_RRC_CONNECTION_RECONFIGU
byte_buffer_t *nas_sdu;
for (i = 0; i < reconfig->N_ded_info_nas; i++) {
nas_sdu = pool_allocate;
memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes);
nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes;
nas->write_pdu(lcid, nas_sdu);
if (nas_sdu) {
memcpy(nas_sdu->msg, &reconfig->ded_info_nas_list[i].msg, reconfig->ded_info_nas_list[i].N_bytes);
nas_sdu->N_bytes = reconfig->ded_info_nas_list[i].N_bytes;
nas->write_pdu(lcid, nas_sdu);
} else {
rrc_log->error("Fatal Error: Couldn't allocate PDU in handle_rrc_con_reconfig().\n");
return;
}
}
}
}

View File

@ -76,6 +76,7 @@ public:
printf("NAS generated SDU (len=%d):\n", sdu->N_bytes);
last_sdu_len = sdu->N_bytes;
srslte_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes);
byte_buffer_pool::get_instance()->deallocate(sdu);
}
std::string get_rb_name(uint32_t lcid) { return std::string("lcid"); }
uint32_t get_last_sdu_len() { return last_sdu_len; }