From 240f95530af7c301a6927e90df8a9cd04e1cae17 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 7 May 2018 17:22:37 +0200 Subject: [PATCH 01/24] Select cell in cell_selection() if serving->in_sync but not camping --- srsue/src/upper/rrc.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 4e09ba3f9..f0bc40a8e 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -823,6 +823,15 @@ rrc::cs_ret_t rrc::cell_selection() } } if (serving_cell->in_sync) { + if (!phy->cell_is_camping()) { + rrc_log->info("Serving cell is in-sync but not camping. Selecting it...\n"); + if (phy->cell_select(&serving_cell->phy_cell)) { + rrc_log->info("Selected serving cell OK.\n"); + } else { + serving_cell->in_sync = false; + rrc_log->error("Could not camp on serving cell.\n"); + } + } return SAME_CELL; } // If can not find any suitable cell, search again @@ -1251,7 +1260,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause) rrc_log->warning("Could not re-synchronize with cell.\n"); } } else { - rrc_log->info("Selected cell no longer suitable for camping. Going to IDLE\n"); + rrc_log->info("Selected cell no longer suitable for camping (in_sync=%s). Going to IDLE\n", serving_cell->in_sync?"yes":"no"); go_idle = true; } } From 595ed70cae0c4fd55b7e051335321f8be46e9fe3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 8 May 2018 21:41:33 +0200 Subject: [PATCH 02/24] Revert "Deallocate SCH pdu on demux instead of pdu_queue" This reverts commit e9fcb10c9e888dd56a7cf662092f7f1e374a61d9. --- lib/include/srslte/common/buffer_pool.h | 4 ---- lib/src/common/pdu_queue.cc | 5 +++++ srsue/src/mac/demux.cc | 2 -- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index eee04caa8..1895c8330 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -93,10 +93,6 @@ public: #endif } - uint32_t nof_available_pdus() { - return available.size(); - } - bool is_almost_empty() { return available.size() < capacity/20; } diff --git a/lib/src/common/pdu_queue.cc b/lib/src/common/pdu_queue.cc index 8e9656116..9b5e83c7b 100644 --- a/lib/src/common/pdu_queue.cc +++ b/lib/src/common/pdu_queue.cc @@ -96,6 +96,11 @@ bool pdu_queue::process_pdus() if (callback) { callback->process_pdu(pdu->ptr, pdu->len, pdu->channel, pdu->tstamp); } + if (pdu->channel == DCH) { + if (!pool.deallocate(pdu)) { + log_h->warning("Error deallocating from buffer pool in process_pdus(): buffer not created in this pool.\n"); + } + } cnt++; have_data = true; } diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index dd481c76c..640b78bd5 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -148,8 +148,6 @@ void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes, srslte::pdu_queue: process_sch_pdu(&mac_msg); //srslte_vec_fprint_byte(stdout, mac_pdu, nof_bytes); - - pdus.deallocate(mac_pdu); break; case srslte::pdu_queue::BCH: rlc->write_pdu_bcch_dlsch(mac_pdu, nof_bytes); From 5c7cf5594aafc1edc4db497c47800cf0b9ffee26 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 9 May 2018 13:53:59 +0200 Subject: [PATCH 03/24] fix log msgs in usim --- srsue/src/upper/usim.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/srsue/src/upper/usim.cc b/srsue/src/upper/usim.cc index ca9075edb..3e0e086e5 100644 --- a/srsue/src/upper/usim.cc +++ b/srsue/src/upper/usim.cc @@ -49,8 +49,8 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) if(32 == args->op.length()) { str_to_hex(args->op, op); } else { - usim_log->error("Invalid length for OP: %zu should be %d", args->op.length(), 32); - usim_log->console("Invalid length for OP: %zu should be %d", args->op.length(), 32); + usim_log->error("Invalid length for OP: %zu should be %d\n", args->op.length(), 32); + usim_log->console("Invalid length for OP: %zu should be %d\n", args->op.length(), 32); } if(15 == args->imsi.length()) { @@ -61,8 +61,8 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) imsi += imsi_c[i] - '0'; } } else { - usim_log->error("Invalid length for ISMI: %zu should be %d", args->imsi.length(), 15); - usim_log->console("Invalid length for IMSI: %zu should be %d", args->imsi.length(), 15); + usim_log->error("Invalid length for ISMI: %zu should be %d\n", args->imsi.length(), 15); + usim_log->console("Invalid length for IMSI: %zu should be %d\n", args->imsi.length(), 15); } if(15 == args->imei.length()) { @@ -73,15 +73,15 @@ void usim::init(usim_args_t *args, srslte::log *usim_log_) imei += imei_c[i] - '0'; } } else { - usim_log->error("Invalid length for IMEI: %zu should be %d", args->imei.length(), 15); - usim_log->console("Invalid length for IMEI: %zu should be %d", args->imei.length(), 15); + usim_log->error("Invalid length for IMEI: %zu should be %d\n", args->imei.length(), 15); + usim_log->console("Invalid length for IMEI: %zu should be %d\n", args->imei.length(), 15); } if(32 == args->k.length()) { str_to_hex(args->k, k); } else { - usim_log->error("Invalid length for K: %zu should be %d", args->k.length(), 32); - usim_log->console("Invalid length for K: %zu should be %d", args->k.length(), 32); + usim_log->error("Invalid length for K: %zu should be %d\n", args->k.length(), 32); + usim_log->console("Invalid length for K: %zu should be %d\n", args->k.length(), 32); } auth_algo = auth_algo_milenage; @@ -115,7 +115,7 @@ bool usim::get_imsi_vec(uint8_t* imsi_, uint32_t n) } if(NULL == imsi_ || n < 15) { - usim_log->error("Invalid parameters to get_imsi_vec"); + usim_log->error("Invalid parameters to get_imsi_vec\n"); return false; } @@ -135,7 +135,7 @@ bool usim::get_imei_vec(uint8_t* imei_, uint32_t n) } if(NULL == imei_ || n < 15) { - usim_log->error("Invalid parameters to get_imei_vec"); + usim_log->error("Invalid parameters to get_imei_vec\n"); return false; } From f7fee7602220bd663f0d43de386d770217bbfcb5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 9 May 2018 13:52:19 +0200 Subject: [PATCH 04/24] fix bug in logger_file where logger was used but not initialized --- lib/src/common/logger_file.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/common/logger_file.cc b/lib/src/common/logger_file.cc index a911ae20e..abbea8f93 100644 --- a/lib/src/common/logger_file.cc +++ b/lib/src/common/logger_file.cc @@ -43,8 +43,8 @@ logger_file::logger_file() logger_file::~logger_file() { not_done = false; - log(new std::string("Closing log\n")); if(inited) { + log(new std::string("Closing log\n")); wait_thread_finish(); flush(); if (logfile) { From 9230d111cea28287c78e9be6748554992d987566 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 9 May 2018 12:22:23 +0200 Subject: [PATCH 05/24] use pool_allocate wrapper in srsENB's UE subclass in RRC --- srsenb/hdr/upper/rrc.h | 3 ++- srsenb/src/upper/rrc.cc | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/srsenb/hdr/upper/rrc.h b/srsenb/hdr/upper/rrc.h index cadb4af43..871c9ebb3 100644 --- a/srsenb/hdr/upper/rrc.h +++ b/srsenb/hdr/upper/rrc.h @@ -243,7 +243,8 @@ public: bool connect_notified; private: - + srslte::byte_buffer_pool *pool; + struct timeval t_last_activity; // S-TMSI for this UE diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 031322c5d..8abb1ed08 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -731,6 +731,7 @@ rrc::ue::ue() cqi_sched_sf_idx = 0; cqi_sched_prb_idx = 0; state = RRC_STATE_IDLE; + pool = srslte::byte_buffer_pool::get_instance(); } rrc_state_t rrc::ue::get_state() @@ -1505,7 +1506,7 @@ void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu) void rrc::ue::send_connection_reconf_new_bearer(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *e) { - srslte::byte_buffer_t *pdu = parent->pool->allocate(__FUNCTION__); + srslte::byte_buffer_t *pdu = pool_allocate; LIBLTE_RRC_DL_DCCH_MSG_STRUCT dl_dcch_msg; dl_dcch_msg.msg_type = LIBLTE_RRC_DL_DCCH_MSG_TYPE_RRC_CON_RECONFIG; @@ -1592,7 +1593,7 @@ void rrc::ue::send_ue_cap_enquiry() void rrc::ue::send_dl_ccch(LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ccch_msg) { // Allocate a new PDU buffer, pack the message and send to PDCP - byte_buffer_t *pdu = parent->pool->allocate(__FUNCTION__); + byte_buffer_t *pdu = pool_allocate; if (pdu) { liblte_rrc_pack_dl_ccch_msg(dl_ccch_msg, (LIBLTE_BIT_MSG_STRUCT*) &parent->bit_buf); srslte_bit_pack_vector(parent->bit_buf.msg, pdu->msg, parent->bit_buf.N_bits); @@ -1612,7 +1613,7 @@ void rrc::ue::send_dl_ccch(LIBLTE_RRC_DL_CCCH_MSG_STRUCT *dl_ccch_msg) void rrc::ue::send_dl_dcch(LIBLTE_RRC_DL_DCCH_MSG_STRUCT *dl_dcch_msg, byte_buffer_t *pdu) { if (!pdu) { - pdu = parent->pool->allocate(__FUNCTION__); + pdu = pool_allocate; } if (pdu) { liblte_rrc_pack_dl_dcch_msg(dl_dcch_msg, (LIBLTE_BIT_MSG_STRUCT*) &parent->bit_buf); From 718a15608ca5dff07300be09d5a0921d5b9e1be8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 10 May 2018 16:36:55 +0200 Subject: [PATCH 06/24] dealloc SCH pdu in MAC instead of pdu_queue - this is basically e9fcb10c9e888dd56a7cf662092f7f1e374a61d9 but with the counterpart in the eNB's MAC --- lib/include/srslte/common/buffer_pool.h | 4 ++++ lib/src/common/pdu_queue.cc | 7 +------ srsenb/src/mac/ue.cc | 2 ++ srsue/src/mac/demux.cc | 2 ++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 1895c8330..eee04caa8 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -93,6 +93,10 @@ public: #endif } + uint32_t nof_available_pdus() { + return available.size(); + } + bool is_almost_empty() { return available.size() < capacity/20; } diff --git a/lib/src/common/pdu_queue.cc b/lib/src/common/pdu_queue.cc index 9b5e83c7b..4a45f0721 100644 --- a/lib/src/common/pdu_queue.cc +++ b/lib/src/common/pdu_queue.cc @@ -48,7 +48,7 @@ uint8_t* pdu_queue::request(uint32_t len) fprintf(stderr, "Error request buffer of invalid size %d. Max bytes %d\n", len, MAX_PDU_LEN); return NULL; } - pdu_t *pdu = pool.allocate(); + pdu_t *pdu = pool.allocate("pdu_queue::request"); if (!pdu) { if (log_h) { log_h->error("Not enough buffers for MAC PDU\n"); @@ -96,11 +96,6 @@ bool pdu_queue::process_pdus() if (callback) { callback->process_pdu(pdu->ptr, pdu->len, pdu->channel, pdu->tstamp); } - if (pdu->channel == DCH) { - if (!pool.deallocate(pdu)) { - log_h->warning("Error deallocating from buffer pool in process_pdus(): buffer not created in this pool.\n"); - } - } cnt++; have_data = true; } diff --git a/srsenb/src/mac/ue.cc b/srsenb/src/mac/ue.cc index 975d6e9b1..0ddd5afea 100644 --- a/srsenb/src/mac/ue.cc +++ b/srsenb/src/mac/ue.cc @@ -152,6 +152,8 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti); } + pdus.deallocate(pdu); + uint32_t lcid_most_data = 0; int most_data = -99; diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 640b78bd5..dd481c76c 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -148,6 +148,8 @@ void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes, srslte::pdu_queue: process_sch_pdu(&mac_msg); //srslte_vec_fprint_byte(stdout, mac_pdu, nof_bytes); + + pdus.deallocate(mac_pdu); break; case srslte::pdu_queue::BCH: rlc->write_pdu_bcch_dlsch(mac_pdu, nof_bytes); From 9a10f5f6d468015302fc2aaf684752b9262f7082 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 10 May 2018 16:40:37 +0200 Subject: [PATCH 07/24] add buffer_pool printing option to eNB --- srsenb/hdr/enb.h | 3 +++ srsenb/src/enb.cc | 4 ++++ srsenb/src/main.cc | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 745096daa..3ab6e9a4c 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -126,6 +126,7 @@ typedef struct { mac_args_t mac; uint32_t rrc_inactivity_timer; float metrics_period_secs; + bool print_buffer_state; }expert_args_t; typedef struct { @@ -156,6 +157,8 @@ public: void start_plot(); + void print_pool(); + static void rf_msg(srslte_rf_error_t error); void handle_rf_msg(srslte_rf_error_t error); diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index e91aea7bf..fdf959a95 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -256,6 +256,10 @@ void enb::start_plot() { phy.start_plot(); } +void enb::print_pool() { + srslte::byte_buffer_pool::get_instance()->print_all_buffers(); +} + bool enb::get_metrics(enb_metrics_t &m) { m.rf = rf_metrics; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 45dd028b0..a4d7532f0 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -184,6 +184,9 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { bpo::value(&args->expert.rrc_inactivity_timer)->default_value(10000), "Inactivity timer in ms") + ("expert.print_buffer_state", + bpo::value(&args->expert.print_buffer_state)->default_value(false), + "Prints on the console the buffer state every 10 seconds") ("rf_calibration.tx_corr_dc_gain", bpo::value(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0), "TX DC offset gain correction") ("rf_calibration.tx_corr_dc_phase", bpo::value(&args->rf_cal.tx_corr_dc_phase)->default_value(0.0), "TX DC offset phase correction") @@ -385,11 +388,21 @@ int main(int argc, char *argv[]) bool plot_started = false; bool signals_pregenerated = false; - while(running) { + if(running) { if (!plot_started && args.gui.enable) { enb->start_plot(); plot_started = true; } + } + int cnt=0; + while (running) { + if (args.expert.print_buffer_state) { + cnt++; + if (cnt==10) { + cnt=0; + enb->print_pool(); + } + } sleep(1); } pthread_cancel(input); From 85028d2aedfb237ca5c1013d57dc682ff9e8f92c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 10 May 2018 16:41:37 +0200 Subject: [PATCH 08/24] use pretty function name in buffer_pool debug - this avoids ambiguity between names, for example in reassemble_rx_sdus() for rlc_am an rlc_um --- lib/include/srslte/common/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index 5668454e0..749765f17 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -66,7 +66,7 @@ #define SRSLTE_BUFFER_POOL_LOG_ENABLED #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED -#define pool_allocate (pool->allocate(__FUNCTION__)) +#define pool_allocate (pool->allocate(__PRETTY_FUNCTION__)) #define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128 #else #define pool_allocate (pool->allocate()) From b4a23d325a1904b3cd3adb9d8aa600b2ff4cbf88 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 10 May 2018 16:43:08 +0200 Subject: [PATCH 09/24] cosmetic changes --- srsenb/src/mac/mac.cc | 4 ++-- srsenb/src/upper/s1ap.cc | 2 +- srsepc/src/mme/mme.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/srsenb/src/mac/mac.cc b/srsenb/src/mac/mac.cc index 463da2e25..204e7f74e 100644 --- a/srsenb/src/mac/mac.cc +++ b/srsenb/src/mac/mac.cc @@ -301,7 +301,7 @@ int mac::crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc) // push the pdu through the queue if received correctly if (crc) { - ue_db[rnti]->push_pdu(tti, nof_bytes); + ue_db[rnti]->push_pdu(tti, nof_bytes); pdu_process_thread.notify(); if (nof_bytes > 64) { // do not count RLC status messages only rrc_h->set_activity_user(rnti); @@ -732,7 +732,7 @@ void mac::timer_thread::tti_clock() /******************************************************** * * Class that runs a thread to process DL MAC PDUs from - * DEMU unit + * DEMUX unit * *******************************************************/ mac::pdu_process::pdu_process(pdu_process_handler *h) : running(false) { diff --git a/srsenb/src/upper/s1ap.cc b/srsenb/src/upper/s1ap.cc index b48e8a248..6eafe5030 100644 --- a/srsenb/src/upper/s1ap.cc +++ b/srsenb/src/upper/s1ap.cc @@ -87,7 +87,7 @@ void s1ap::get_metrics(s1ap_metrics_t &m) void s1ap::run_thread() { - srslte::byte_buffer_t *pdu = pool_allocate; + srslte::byte_buffer_t *pdu = pool->allocate("s1ap::run_thread"); if (!pdu) { s1ap_log->error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread().\n"); return; diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index 1a385d8dc..21554bcdc 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -115,7 +115,7 @@ mme::stop() void mme::run_thread() { - srslte::byte_buffer_t *pdu = m_pool->allocate(); + srslte::byte_buffer_t *pdu = m_pool->allocate("mme::run_thread"); uint32_t sz = SRSLTE_MAX_BUFFER_SIZE_BYTES - SRSLTE_BUFFER_HEADER_OFFSET; struct sockaddr_in enb_addr; From 7e77329aa3c0a8c08e1bc8ac3e54fc54e8db3243 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 7 May 2018 18:41:42 +0200 Subject: [PATCH 10/24] Reestablishment uses serving cell PCI instead of current cell PCI --- srsue/src/upper/rrc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f0bc40a8e..0b76bb6c6 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1194,7 +1194,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause) srslte_bit_pack_vector(varShortMAC, varShortMAC_packed, (4+2+4)*8); rrc_log->info("Generated varShortMAC: cellId=0x%x, PCI=%d, rnti=%d\n", - serving_cell->get_cell_id(), phy->get_current_pci(), crnti); + serving_cell->get_cell_id(), serving_cell->get_pci(), crnti); // Compute MAC-I uint8_t mac_key[4]; @@ -1258,6 +1258,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause) } } else { rrc_log->warning("Could not re-synchronize with cell.\n"); + go_idle = true; } } else { rrc_log->info("Selected cell no longer suitable for camping (in_sync=%s). Going to IDLE\n", serving_cell->in_sync?"yes":"no"); From f3f4528a2f10f5dea672864b768c54fdef9f0e2f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 7 May 2018 15:40:11 -0500 Subject: [PATCH 11/24] Testing commit to force a Reestablishment 1s after CONNECT --- lib/include/srslte/common/security.h | 4 +- lib/src/common/security.cc | 4 +- srsue/src/upper/rrc.cc | 55 +++++++++++++++++----------- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/common/security.h b/lib/include/srslte/common/security.h index 80b4c0c0e..f88d48a17 100644 --- a/lib/include/srslte/common/security.h +++ b/lib/include/srslte/common/security.h @@ -109,7 +109,7 @@ uint8_t security_generate_k_up( uint8_t *k_enb, uint8_t security_128_eia1( uint8_t *key, uint32_t count, - uint8_t bearer, + uint32_t bearer, uint8_t direction, uint8_t *msg, uint32_t msg_len, @@ -117,7 +117,7 @@ uint8_t security_128_eia1( uint8_t *key, uint8_t security_128_eia2( uint8_t *key, uint32_t count, - uint8_t bearer, + uint32_t bearer, uint8_t direction, uint8_t *msg, uint32_t msg_len, diff --git a/lib/src/common/security.cc b/lib/src/common/security.cc index fba1b37d9..b10b5beab 100644 --- a/lib/src/common/security.cc +++ b/lib/src/common/security.cc @@ -126,7 +126,7 @@ uint8_t security_generate_k_up( uint8_t *k_enb, uint8_t security_128_eia1( uint8_t *key, uint32_t count, - uint8_t bearer, + uint32_t bearer, uint8_t direction, uint8_t *msg, uint32_t msg_len, @@ -151,7 +151,7 @@ uint8_t security_128_eia1( uint8_t *key, uint8_t security_128_eia2( uint8_t *key, uint32_t count, - uint8_t bearer, + uint32_t bearer, uint8_t direction, uint8_t *msg, uint32_t msg_len, diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 0b76bb6c6..9406c01ca 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -184,6 +184,7 @@ void rrc::run_thread() { } } } +uint32_t rest_cnt=0; /* @@ -238,6 +239,10 @@ void rrc::run_tti(uint32_t tti) { } break; case RRC_STATE_CONNECTED: + rest_cnt++; + if (rest_cnt == 1000) { + send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE); + } if (ho_start) { ho_start = false; if (!ho_prepare()) { @@ -1171,12 +1176,18 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause) bzero(&ul_ccch_msg, sizeof(LIBLTE_RRC_UL_CCCH_MSG_STRUCT)); uint16_t crnti; + uint16_t pci; + uint32_t cellid; if (cause == LIBLTE_RRC_CON_REEST_REQ_CAUSE_HANDOVER_FAILURE) { - crnti = ho_src_rnti; + crnti = ho_src_rnti; + pci = ho_src_cell.get_pci(); + cellid = ho_src_cell.get_cell_id(); } else { mac_interface_rrc::ue_rnti_t uernti; mac->get_rntis(&uernti); - crnti = uernti.crnti; + crnti = uernti.crnti; + pci = serving_cell->get_pci(); + cellid = serving_cell->get_cell_id(); } // Compute shortMAC-I @@ -1185,36 +1196,38 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause) bzero(varShortMAC_packed, 16); uint8_t *msg_ptr = varShortMAC; - // ASN.1 encode byte-aligned VarShortMAC-Input - liblte_rrc_pack_cell_identity_ie(serving_cell->get_cell_id(), &msg_ptr); - msg_ptr = &varShortMAC[4]; - liblte_rrc_pack_phys_cell_id_ie(phy->get_current_pci(), &msg_ptr); - msg_ptr = &varShortMAC[4+2]; + // ASN.1 encode VarShortMAC-Input + liblte_rrc_pack_cell_identity_ie(cellid, &msg_ptr); + liblte_rrc_pack_phys_cell_id_ie(pci, &msg_ptr); liblte_rrc_pack_c_rnti_ie(crnti, &msg_ptr); - srslte_bit_pack_vector(varShortMAC, varShortMAC_packed, (4+2+4)*8); - rrc_log->info("Generated varShortMAC: cellId=0x%x, PCI=%d, rnti=%d\n", - serving_cell->get_cell_id(), serving_cell->get_pci(), crnti); + // byte align (already zero-padded) + uint32_t N_bits = (uint32_t) (msg_ptr-varShortMAC); + uint32_t N_bytes = ((N_bits-1)/8+1); + srslte_bit_pack_vector(varShortMAC, varShortMAC_packed, N_bytes*8); + + rrc_log->info("Encoded varShortMAC: cellId=0x%x, PCI=%d, rnti=0x%x (%d bytes, %d bits)\n", + cellid, pci, crnti, N_bytes, N_bits); // Compute MAC-I uint8_t mac_key[4]; switch(integ_algo) { case INTEGRITY_ALGORITHM_ID_128_EIA1: security_128_eia1(&k_rrc_int[16], - 1, - 1, - 1, + 0xffffffff, // 32-bit all to ones + 0x1f, // 5-bit all to ones + 1, // 1-bit to one varShortMAC_packed, - 10, + N_bytes, mac_key); break; case INTEGRITY_ALGORITHM_ID_128_EIA2: security_128_eia2(&k_rrc_int[16], - 1, - 1, - 1, + 0xffffffff, // 32-bit all to ones + 0x1f, // 5-bit all to ones + 1, // 1-bit to one varShortMAC_packed, - 10, + N_bytes, mac_key); break; default: @@ -1224,8 +1237,8 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause) // Prepare ConnectionRestalishmentRequest packet ul_ccch_msg.msg_type = LIBLTE_RRC_UL_CCCH_MSG_TYPE_RRC_CON_REEST_REQ; ul_ccch_msg.msg.rrc_con_reest_req.ue_id.c_rnti = crnti; - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.phys_cell_id = phy->get_current_pci(); - ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i = mac_key[1] << 8 | mac_key[0]; + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.phys_cell_id = pci; + ul_ccch_msg.msg.rrc_con_reest_req.ue_id.short_mac_i = mac_key[2] << 8 | mac_key[3]; ul_ccch_msg.msg.rrc_con_reest_req.cause = cause; rrc_log->info("Initiating RRC Connection Reestablishment Procedure\n"); @@ -1510,7 +1523,7 @@ void rrc::con_reconfig_failed() if (security_is_activated) { // Start the Reestablishment Procedure - send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE); + send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_RECONFIG_FAILURE); } else { go_idle = true; } From cac027d69548f3baa7cac0c75d7cadffa4d40efc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 8 May 2018 09:48:10 -0500 Subject: [PATCH 12/24] Merge branch 'issue_incorrect_dci' into raa_new --- srsue/hdr/mac/dl_harq.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index c56031ef3..47ebb209f 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -280,7 +280,10 @@ private: memcpy(&cur_grant, &grant, sizeof(Tgrant)); if (payload_buffer_ptr) { - Warning("DL PID %d: Allocating buffer already allocated\n", pid); + Warning("DL PID %d: Allocating buffer already allocated. Deallocating.\n", pid); + if (pid != HARQ_BCCH_PID) { + harq_entity->demux_unit->deallocate(payload_buffer_ptr); + } } // Instruct the PHY To combine the received data and attempt to decode it @@ -296,7 +299,7 @@ private: pthread_mutex_unlock(&mutex); return; } - action->decode_enabled[tid]= true; + action->decode_enabled[tid] = true; action->rv[tid] = cur_grant.rv[tid]; action->softbuffers[tid] = &softbuffer; memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(Tphygrant)); @@ -327,11 +330,13 @@ private: } } - pthread_mutex_unlock(&mutex); + if (!action->decode_enabled[tid]) { + pthread_mutex_unlock(&mutex); + } + } void tb_decoded(bool ack_) { - pthread_mutex_lock(&mutex); ack = ack_; if (ack) { if (pid == HARQ_BCCH_PID) { From b2f2ce69f230df030d7d167df8a54f5684d75536 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 8 May 2018 11:42:03 -0500 Subject: [PATCH 13/24] Check existence of SIB3 in cell selection criteria --- srsue/src/upper/rrc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9406c01ca..c88617838 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -850,7 +850,7 @@ rrc::cs_ret_t rrc::cell_selection() // Cell selection criteria Section 5.2.3.2 of 36.304 bool rrc::cell_selection_criteria(float rsrp, float rsrq) { - if (get_srxlev(rsrp) > 0) { + if (get_srxlev(rsrp) > 0 || !serving_cell->has_sib3()) { return true; } else { return false; @@ -1462,6 +1462,7 @@ void rrc::ho_ra_completed(bool ra_successful) { bool rrc::con_reconfig_ho(LIBLTE_RRC_CONNECTION_RECONFIGURATION_STRUCT *reconfig) { if (reconfig->mob_ctrl_info.target_pci == phy->get_current_pci()) { + rrc_log->console("Warning: Received HO command to own cell\n"); rrc_log->warning("Received HO command to own cell\n"); return false; } From 352ce4ce04f0185e8a5b4814393ef0070e4edfb8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 8 May 2018 11:46:12 -0500 Subject: [PATCH 14/24] Disable Reest testing --- srsue/src/upper/rrc.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index c88617838..c8cb881f9 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -184,7 +184,6 @@ void rrc::run_thread() { } } } -uint32_t rest_cnt=0; /* @@ -239,10 +238,6 @@ void rrc::run_tti(uint32_t tti) { } break; case RRC_STATE_CONNECTED: - rest_cnt++; - if (rest_cnt == 1000) { - send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE); - } if (ho_start) { ho_start = false; if (!ho_prepare()) { From af7a7d4ceb8959f2c968c25d40f1fc41b0b98129 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 8 May 2018 13:47:41 -0500 Subject: [PATCH 15/24] Enable TA commands --- srsue/src/phy/phy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index eb1b87aa7..bf8ccffaa 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -222,7 +222,7 @@ void phy::set_timeadv_rar(uint32_t ta_cmd) { void phy::set_timeadv(uint32_t ta_cmd) { uint32_t new_nta = srslte_N_ta_new(n_ta, ta_cmd); - //sf_recv.set_time_adv_sec(((float) new_nta)*SRSLTE_LTE_TS); + sf_recv.set_time_adv_sec(((float) new_nta)*SRSLTE_LTE_TS); Info("PHY: Set TA: ta_cmd: %d, n_ta: %d, old_n_ta: %d, ta_usec: %.1f\n", ta_cmd, new_nta, n_ta, ((float) new_nta)*SRSLTE_LTE_TS*1e6); n_ta = new_nta; } From abea37118060838e4821479df6b8fadd159b3626 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 9 May 2018 22:14:21 -0500 Subject: [PATCH 16/24] RLF on separate thread to avoid blocking in RLC AM RLF --- srsue/hdr/upper/rrc.h | 1 + srsue/src/upper/rrc.cc | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index fb89fbbe9..e59537e2f 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -440,6 +440,7 @@ private: bool initiated; bool ho_start; bool go_idle; + bool go_rlf; // Measurements sub-class class rrc_meas { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index c8cb881f9..5dfa1b48c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -57,6 +57,8 @@ rrc::rrc() neighbour_cells.reserve(NOF_NEIGHBOUR_CELLS); initiated = false; running = false; + go_idle = false; + go_rlf = false; } rrc::~rrc() @@ -249,6 +251,11 @@ void rrc::run_tti(uint32_t tti) { go_idle = false; leave_connected(); } + if (go_rlf) { + go_rlf = false; + // Initiate connection re-establishment procedure after RLF + send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE); + } break; default:break; } @@ -1066,12 +1073,10 @@ int rrc::find_neighbour_cell(uint32_t earfcn, uint32_t pci) { */ void rrc::radio_link_failure() { // TODO: Generate and store failure report - rrc_log->warning("Detected Radio-Link Failure\n"); rrc_log->console("Warning: Detected Radio-Link Failure\n"); if (state == RRC_STATE_CONNECTED) { - // Initiate connection re-establishment procedure - send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_OTHER_FAILURE); + go_rlf = true; } } From ba40a4de8419398dd9f0f2c4ace69c0286632602 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 9 May 2018 22:14:47 -0500 Subject: [PATCH 17/24] Add checks for when RLC TM queue is corrupted and reset it --- lib/include/srslte/common/msg_queue.h | 10 ++++++++++ lib/src/upper/rlc_tm.cc | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/include/srslte/common/msg_queue.h b/lib/include/srslte/common/msg_queue.h index 0dcdc2a55..8e73caa00 100644 --- a/lib/include/srslte/common/msg_queue.h +++ b/lib/include/srslte/common/msg_queue.h @@ -86,6 +86,8 @@ public: *msg = buf[tail]; tail = (tail+1)%capacity; unread--; + /* FIXME: When byte_buffer_t is reset() but is in the queue, it gets corrupted + * because N_bytes becomes 0 and queue is empty but unread_bytes > 0 */ unread_bytes -= (*msg)->N_bytes; pthread_cond_signal(¬_full); @@ -134,6 +136,14 @@ public: return r; } + // This is a hack to reset N_bytes counter when queue is corrupted (see line 89) + void reset() { + pthread_mutex_lock(&mutex); + unread_bytes = 0; + unread = 0; + pthread_mutex_unlock(&mutex); + } + private: bool is_empty() const { return unread == 0; } bool is_full() const { return unread == capacity; } diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index 2ae7515a7..423f88785 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -59,10 +59,8 @@ void rlc_tm::empty_queue() { // Drop all messages in TX queue byte_buffer_t *buf; - while(ul_queue.size() > 0) { - if (ul_queue.try_read(&buf)) { - pool->deallocate(buf); - } + while(ul_queue.try_read(&buf)) { + pool->deallocate(buf); } } @@ -89,8 +87,11 @@ uint32_t rlc_tm::get_bearer() // PDCP interface void rlc_tm::write_sdu(byte_buffer_t *sdu) { - log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU", rrc->get_rb_name(lcid).c_str()); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, before: queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); ul_queue.write(sdu); + log->info_hex(sdu->msg, sdu->N_bytes, "%s Tx SDU, after: queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), ul_queue.size(), ul_queue.size_bytes()); } // MAC interface @@ -119,10 +120,15 @@ int rlc_tm::read_pdu(uint8_t *payload, uint32_t nof_bytes) log->debug("%s Complete SDU scheduled for tx. Stack latency: %ld us\n", rrc->get_rb_name(lcid).c_str(), buf->get_latency_us()); pool->deallocate(buf); - log->info_hex(payload, pdu_size, "TX %s, %s PDU", rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM]); + log->info_hex(payload, pdu_size, "TX %s, %s PDU, queue size=%d, bytes=%d", + rrc->get_rb_name(lcid).c_str(), rlc_mode_text[RLC_MODE_TM], ul_queue.size(), ul_queue.size_bytes()); return pdu_size; } else { log->warning("Queue empty while trying to read\n"); + if (ul_queue.size_bytes() > 0) { + log->warning("Corrupted queue: empty but size_bytes > 0. Resetting queue\n"); + ul_queue.reset(); + } return 0; } } From 3065941638b463bd223a0cdacf3f945838818e25 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 10 May 2018 10:00:16 -0500 Subject: [PATCH 18/24] Check for non-zero nof_re/nof_bits in pdsch_codeword_decode --- lib/src/phy/phch/pdsch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 6e7a3b33c..59f5bf58b 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -620,7 +620,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c uint32_t rv = cfg->rv[tb_idx]; int ret = SRSLTE_ERROR_INVALID_INPUTS; - if (softbuffer && data && ack) { + if (softbuffer && data && ack && nbits->nof_bits && nbits->nof_re) { INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", cfg->sf_idx, codeword_idx, tb_idx, srslte_mod_string(mcs->mod), mcs->tbs, nbits->nof_re, nbits->nof_bits, rv); @@ -687,7 +687,8 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c ret = SRSLTE_ERROR; } } else { - ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p", codeword_idx, softbuffer, (void*)data, ack); + ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p, nbits=%d, nof_re=%d", + codeword_idx, softbuffer, (void*)data, ack, nbits->nof_bits, nbits->nof_re); } return ret; From 62ae4e309427aa76b0eb5fb7e41b2b8b1b164b62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 10 May 2018 11:02:17 -0500 Subject: [PATCH 19/24] Check prach generation parameters --- srsue/src/phy/prach.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index 278f19eb5..05aa56a7f 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -175,7 +175,8 @@ int prach::tx_tti() { cf_t *prach::generate(float cfo, uint32_t *nof_sf, float *target_power) { - if (cell_initiated && preamble_idx >= 0 && nof_sf) { + if (cell_initiated && preamble_idx >= 0 && nof_sf && preamble_idx <= 64 && + srslte_cell_isvalid(&cell) && len < MAX_LEN_SF * 30720 && len > 0) { // Correct CFO before transmission FIXME: UL SISO Only srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb)); @@ -196,6 +197,8 @@ cf_t *prach::generate(float cfo, uint32_t *nof_sf, float *target_power) { return signal_buffer; } else { + Error("PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d\n", + cell_initiated, preamble_idx, cell.nof_prb, len); return NULL; } } From 04609cd07dbb6be3993392a1e34885fd5c6656f6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 10 May 2018 11:02:41 -0500 Subject: [PATCH 20/24] Check msg_queue size_tail_bytes existence of buffer --- lib/include/srslte/common/msg_queue.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/msg_queue.h b/lib/include/srslte/common/msg_queue.h index 8e73caa00..e3a86941d 100644 --- a/lib/include/srslte/common/msg_queue.h +++ b/lib/include/srslte/common/msg_queue.h @@ -131,7 +131,10 @@ public: uint32_t size_tail_bytes() { pthread_mutex_lock(&mutex); - uint32_t r = buf[tail]->N_bytes; + uint32_t r = 0; + if (buf[tail]) { + r = buf[tail]->N_bytes; + } pthread_mutex_unlock(&mutex); return r; } From 4515dd94eaf94ec752a007c2b8d11ac70f6527ec Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 10 May 2018 13:21:01 -0500 Subject: [PATCH 21/24] Use blocking queue for RRC measurement fixes #193 --- lib/include/srslte/common/block_queue.h | 4 ++++ srsue/hdr/upper/rrc.h | 2 +- srsue/src/upper/rrc.cc | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/include/srslte/common/block_queue.h b/lib/include/srslte/common/block_queue.h index b04a91985..b481022a8 100644 --- a/lib/include/srslte/common/block_queue.h +++ b/lib/include/srslte/common/block_queue.h @@ -86,6 +86,10 @@ public: while (try_pop(item)); } + size_t size() { + return q.size(); + } + private: std::queue q; pthread_mutex_t mutex; diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index e59537e2f..a381940ec 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -547,7 +547,7 @@ private: void process_phy_meas(); void process_new_phy_meas(phy_meas_t meas); - std::queue phy_meas_q; + srslte::block_queue phy_meas_q; // Cell selection/reselection functions/variables typedef struct { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 5dfa1b48c..eebbd38b8 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -534,10 +534,10 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p /* Processes all pending PHY measurements in queue. Must be called from a mutexed function */ void rrc::process_phy_meas() { - while(!phy_meas_q.empty()) { + phy_meas_t m; + while(phy_meas_q.try_pop(&m)) { rrc_log->debug("MEAS: Processing measurement. %lu measurements in queue\n", phy_meas_q.size()); - process_new_phy_meas(phy_meas_q.front()); - phy_meas_q.pop(); + process_new_phy_meas(m); } } From cd367617ecb63d5d603f47801846206d19b0b728 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 10 May 2018 15:09:42 -0500 Subject: [PATCH 22/24] Do not correct freq_offset when cfo is doppler --- srsue/src/phy/phch_recv.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index b74139bf7..ca00a07ff 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -642,12 +642,12 @@ float phch_recv::get_tx_cfo() if (worker_com->args->cfo_is_doppler) { ret *= -1; - } - - if (radio_h->get_freq_offset() != 0.0f) { - /* Compensates the radio frequency offset applied equally to DL and UL */ - const float offset_hz = (float) radio_h->get_freq_offset() * (1.0f - ul_dl_factor); - ret = cfo - offset_hz; + } else { + /* Compensates the radio frequency offset applied equally to DL and UL. Does not work in doppler mode */ + if (radio_h->get_freq_offset() != 0.0f) { + const float offset_hz = (float) radio_h->get_freq_offset() * (1.0f - ul_dl_factor); + ret = cfo - offset_hz; + } } return ret/15000; From 040c33497d005d5565b3a28139dea633be2d0abb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 10 May 2018 21:32:32 -0500 Subject: [PATCH 23/24] merged PR#189 and added check for non-empty queue in get size tail --- lib/include/srslte/common/block_queue.h | 57 +++++++- lib/include/srslte/common/msg_queue.h | 168 ------------------------ lib/include/srslte/upper/rlc_am.h | 4 +- lib/include/srslte/upper/rlc_tm.h | 4 +- lib/include/srslte/upper/rlc_tx_queue.h | 117 +++++++++++++++++ lib/include/srslte/upper/rlc_um.h | 4 +- lib/test/common/msg_queue_test.cc | 11 +- 7 files changed, 178 insertions(+), 187 deletions(-) delete mode 100644 lib/include/srslte/common/msg_queue.h create mode 100644 lib/include/srslte/upper/rlc_tx_queue.h diff --git a/lib/include/srslte/common/block_queue.h b/lib/include/srslte/common/block_queue.h index b481022a8..1d17e9339 100644 --- a/lib/include/srslte/common/block_queue.h +++ b/lib/include/srslte/common/block_queue.h @@ -24,6 +24,15 @@ * */ + +/****************************************************************************** + * File: block_queue.h + * Description: General-purpose blocking queue. It can behave as a bounded or + * unbounded blocking queue and allows blocking and non-blocking + * operations in both push and pop + *****************************************************************************/ + + #ifndef SRSLTE_BLOCK_QUEUE_H #define SRSLTE_BLOCK_QUEUE_H @@ -32,21 +41,47 @@ #include #include #include +#include + namespace srslte { template class block_queue { public: - block_queue() { + block_queue(int capacity = -1) { pthread_mutex_init(&mutex, NULL); - pthread_cond_init(&cvar, NULL); + pthread_cond_init(&cv_empty, NULL); + pthread_cond_init(&cv_full, NULL); + this->capacity = capacity; } - void push(const myobj& value) { + void resize(int new_capacity) { + capacity = new_capacity; + } + bool push_(const myobj& value, bool block) { pthread_mutex_lock(&mutex); + if (capacity > 0) { + if (block) { + while(q.size() > (uint32_t) capacity) { + pthread_cond_wait(&cv_full, &mutex); + } + } else { + pthread_mutex_unlock(&mutex); + return false; + } + } q.push(value); - pthread_cond_signal(&cvar); + pthread_cond_signal(&cv_empty); pthread_mutex_unlock(&mutex); + return true; + } + + void push(const myobj& value) { + push_(value, true); + } + + bool try_push(const myobj& value) { + return push_(value, false); } bool try_pop(myobj *value) { @@ -59,6 +94,7 @@ public: *value = q.front(); q.pop(); } + pthread_cond_signal(&cv_full); pthread_mutex_unlock(&mutex); return true; } @@ -66,15 +102,16 @@ public: myobj wait_pop() { // blocking pop pthread_mutex_lock(&mutex); while(q.empty()) { - pthread_cond_wait(&cvar, &mutex); + pthread_cond_wait(&cv_empty, &mutex); } myobj value = q.front(); q.pop(); + pthread_cond_signal(&cv_full); pthread_mutex_unlock(&mutex); return value; } - bool empty() const { // queue is empty? + bool empty() { // queue is empty? pthread_mutex_lock(&mutex); bool ret = q.empty(); pthread_mutex_unlock(&mutex); @@ -86,6 +123,10 @@ public: while (try_pop(item)); } + myobj front() { + return q.front(); + } + size_t size() { return q.size(); } @@ -93,7 +134,9 @@ public: private: std::queue q; pthread_mutex_t mutex; - pthread_cond_t cvar; + pthread_cond_t cv_empty; + pthread_cond_t cv_full; + int capacity; }; } diff --git a/lib/include/srslte/common/msg_queue.h b/lib/include/srslte/common/msg_queue.h deleted file mode 100644 index e3a86941d..000000000 --- a/lib/include/srslte/common/msg_queue.h +++ /dev/null @@ -1,168 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * 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. - * - * srsUE is distributed in the hope that it will be useful, - * 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/. - * - */ - -/****************************************************************************** - * File: msg_queue.h - * Description: Thread-safe bounded circular buffer of srsue_byte_buffer pointers. - * Reference: - *****************************************************************************/ - -#ifndef SRSLTE_MSG_QUEUE_H -#define SRSLTE_MSG_QUEUE_H - -#include "srslte/common/common.h" -#include - -namespace srslte { - -class msg_queue -{ -public: - msg_queue(uint32_t capacity_ = 128) - :head(0) - ,tail(0) - ,unread(0) - ,unread_bytes(0) - ,capacity(capacity_) - { - buf = new byte_buffer_t*[capacity]; - pthread_mutex_init(&mutex, NULL); - pthread_cond_init(¬_empty, NULL); - pthread_cond_init(¬_full, NULL); - } - - ~msg_queue() - { - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(¬_empty); - pthread_cond_destroy(¬_full); - delete [] buf; - } - - void write(byte_buffer_t *msg) - { - pthread_mutex_lock(&mutex); - while(is_full()) { - pthread_cond_wait(¬_full, &mutex); - } - buf[head] = msg; - head = (head+1)%capacity; - unread++; - unread_bytes += msg->N_bytes; - - pthread_cond_signal(¬_empty); - pthread_mutex_unlock(&mutex); - } - - void read(byte_buffer_t **msg) - { - pthread_mutex_lock(&mutex); - while(is_empty()) { - pthread_cond_wait(¬_empty, &mutex); - } - *msg = buf[tail]; - tail = (tail+1)%capacity; - unread--; - /* FIXME: When byte_buffer_t is reset() but is in the queue, it gets corrupted - * because N_bytes becomes 0 and queue is empty but unread_bytes > 0 */ - unread_bytes -= (*msg)->N_bytes; - - pthread_cond_signal(¬_full); - pthread_mutex_unlock(&mutex); - } - - bool try_read(byte_buffer_t **msg) - { - pthread_mutex_lock(&mutex); - if(is_empty()) - { - pthread_mutex_unlock(&mutex); - return false; - }else{ - *msg = buf[tail]; - tail = (tail+1)%capacity; - unread--; - unread_bytes -= (*msg)->N_bytes; - pthread_cond_signal(¬_full); - pthread_mutex_unlock(&mutex); - return true; - } - } - - uint32_t size() - { - pthread_mutex_lock(&mutex); - uint32_t r = unread; - pthread_mutex_unlock(&mutex); - return r; - } - - uint32_t size_bytes() - { - pthread_mutex_lock(&mutex); - uint32_t r = unread_bytes; - pthread_mutex_unlock(&mutex); - return r; - } - - uint32_t size_tail_bytes() - { - pthread_mutex_lock(&mutex); - uint32_t r = 0; - if (buf[tail]) { - r = buf[tail]->N_bytes; - } - pthread_mutex_unlock(&mutex); - return r; - } - - // This is a hack to reset N_bytes counter when queue is corrupted (see line 89) - void reset() { - pthread_mutex_lock(&mutex); - unread_bytes = 0; - unread = 0; - pthread_mutex_unlock(&mutex); - } - -private: - bool is_empty() const { return unread == 0; } - bool is_full() const { return unread == capacity; } - - pthread_cond_t not_empty; - pthread_cond_t not_full; - pthread_mutex_t mutex; - byte_buffer_t **buf; - uint32_t capacity; - uint32_t unread; - uint32_t unread_bytes; - uint32_t head; - uint32_t tail; -}; - -} // namespace srslte - - -#endif // SRSLTE_MSG_QUEUE_H diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index 894f96ac5..be6c1f669 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -31,7 +31,7 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" #include "srslte/interfaces/ue_interfaces.h" -#include "srslte/common/msg_queue.h" +#include "srslte/upper/rlc_tx_queue.h" #include "srslte/common/timeout.h" #include "srslte/upper/rlc_common.h" #include @@ -104,7 +104,7 @@ private: srsue::rrc_interface_rlc *rrc; // TX SDU buffers - msg_queue tx_sdu_queue; + rlc_tx_queue tx_sdu_queue; byte_buffer_t *tx_sdu; // PDU being resegmented diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index 5408cb835..d3a8aa1ae 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -31,7 +31,7 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" #include "srslte/interfaces/ue_interfaces.h" -#include "srslte/common/msg_queue.h" +#include "srslte/upper/rlc_tx_queue.h" #include "srslte/upper/rlc_common.h" namespace srslte { @@ -72,7 +72,7 @@ private: srsue::rrc_interface_rlc *rrc; // Thread-safe queues for MAC messages - msg_queue ul_queue; + rlc_tx_queue ul_queue; }; } // namespace srsue diff --git a/lib/include/srslte/upper/rlc_tx_queue.h b/lib/include/srslte/upper/rlc_tx_queue.h new file mode 100644 index 000000000..dee326ab6 --- /dev/null +++ b/lib/include/srslte/upper/rlc_tx_queue.h @@ -0,0 +1,117 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * 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. + * + * srsUE is distributed in the hope that it will be useful, + * 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/. + * + */ + +/****************************************************************************** + * File: rlc_tx_queue.h + * Description: Queue used in RLC TM/UM/AM TX queues. + * Uses a blocking queue with bounded capacity to block higher layers + * when pushing Uplink traffic + * Reference: + *****************************************************************************/ + +#ifndef SRSLTE_MSG_QUEUE_H +#define SRSLTE_MSG_QUEUE_H + +#include "srslte/common/block_queue.h" +#include "srslte/common/common.h" +#include + +namespace srslte { + +class rlc_tx_queue +{ +public: + rlc_tx_queue(uint32_t capacity = 128) : queue((int) capacity) { + unread_bytes = 0; + } + void write(byte_buffer_t *msg) + { + queue.push(msg); + unread_bytes += msg->N_bytes; + } + + void read(byte_buffer_t **msg) + { + byte_buffer_t *m = queue.wait_pop(); + *msg = m; + if (unread_bytes > (*msg)->N_bytes) { + unread_bytes -= (*msg)->N_bytes; + } else { + unread_bytes = 0; + } + } + + bool try_read(byte_buffer_t **msg) + { + if (queue.try_pop(msg)) { + if (unread_bytes > (*msg)->N_bytes) { + unread_bytes -= (*msg)->N_bytes; + } else { + unread_bytes = 0; + } + return true; + } else { + return false; + } + } + + uint32_t size() + { + return (uint32_t) queue.size(); + } + + uint32_t size_bytes() + { + return unread_bytes; + } + + uint32_t size_tail_bytes() + { + if (!queue.empty()) { + byte_buffer_t *m = queue.front(); + if (m) { + return m->N_bytes; + } + } + return 0; + } + + // This is a hack to reset N_bytes counter when queue is corrupted (see line 89) + void reset() { + unread_bytes = 0; + } + +private: + bool is_empty() { return queue.empty(); } + + block_queue queue; + uint32_t unread_bytes; +}; + +} // namespace srslte + + +#endif // SRSLTE_MSG_QUEUE_H diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index 8e6f527e2..d41192d6d 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -31,7 +31,7 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" #include "srslte/interfaces/ue_interfaces.h" -#include "srslte/common/msg_queue.h" +#include "srslte/upper/rlc_tx_queue.h" #include "srslte/upper/rlc_common.h" #include #include @@ -89,7 +89,7 @@ private: mac_interface_timers *mac_timers; // TX SDU buffers - msg_queue tx_sdu_queue; + rlc_tx_queue tx_sdu_queue; byte_buffer_t *tx_sdu; // Rx window diff --git a/lib/test/common/msg_queue_test.cc b/lib/test/common/msg_queue_test.cc index 393931ab5..5a4e2cc23 100644 --- a/lib/test/common/msg_queue_test.cc +++ b/lib/test/common/msg_queue_test.cc @@ -27,12 +27,12 @@ #define NMSGS 1000000 #include -#include "srslte/common/msg_queue.h" +#include "srslte/upper/rlc_tx_queue.h" using namespace srslte; typedef struct { - msg_queue *q; + rlc_tx_queue *q; }args_t; void* write_thread(void *a) { @@ -49,27 +49,26 @@ void* write_thread(void *a) { int main(int argc, char **argv) { bool result; - msg_queue *q = new msg_queue; + rlc_tx_queue q; byte_buffer_t *b; pthread_t thread; args_t args; u_int32_t r; result = true; - args.q = q; + args.q = &q; pthread_create(&thread, NULL, &write_thread, &args); for(uint32_t i=0;iread(&b); + q.read(&b); memcpy(&r, b->msg, 4); delete b; if(r != i) result = false; } - delete q; pthread_join(thread, NULL); if(result) { From 563bf6cde59556f65cd0365c25c041be4c6b262b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 11 May 2018 15:00:43 +0200 Subject: [PATCH 24/24] extend log in GW --- srsue/src/upper/gw.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/upper/gw.cc b/srsue/src/upper/gw.cc index 4c3cf6301..4fd439f77 100644 --- a/srsue/src/upper/gw.cc +++ b/srsue/src/upper/gw.cc @@ -126,7 +126,7 @@ void gw::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) int n = write(tun_fd, pdu->msg, pdu->N_bytes); if(n > 0 && (pdu->N_bytes != (uint32_t)n)) { - gw_log->warning("DL TUN/TAP write failure\n"); + gw_log->warning("DL TUN/TAP write failure. Wanted to write %d B but only wrote %d B.\n", pdu->N_bytes, n); } } pool->deallocate(pdu);