From 7e091b8e6057f583ef6337777b1fbdc90d9325db Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 23 Feb 2018 10:12:44 +0100 Subject: [PATCH 01/52] Fix Underflow when PHY Reset --- srsue/src/phy/phy.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 4417beb86..cf8ae33f8 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -366,7 +366,6 @@ void phy::reset() workers[i].reset(); } workers_common.reset(); - usleep(4000); workers_common.reset_ul(); } From 8474c6e3aac854bd7320158741fd9110b192d0ec Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 23 Feb 2018 13:05:02 +0100 Subject: [PATCH 02/52] Fixed HO to unkown cell issue --- srsue/hdr/upper/rrc.h | 112 +++++++++++++++++- srsue/src/upper/rrc.cc | 259 ++++++++++++++++++++++++----------------- 2 files changed, 258 insertions(+), 113 deletions(-) diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 1aaf6f29b..5f269ec86 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -65,12 +65,14 @@ class cell_t return earfcn == this->earfcn && pci == phy_cell.id; } bool greater(cell_t *x) { - return x->rsrp > rsrp; + return rsrp > x->rsrp; } bool plmn_equals(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { - for (uint32_t i = 0; i < sib1.N_plmn_ids; i++) { - if (plmn_id.mcc == sib1.plmn_id[i].id.mcc && plmn_id.mnc == sib1.plmn_id[i].id.mnc) { - return true; + if (has_valid_sib1) { + for (uint32_t i = 0; i < sib1.N_plmn_ids; i++) { + if (plmn_id.mcc == sib1.plmn_id[i].id.mcc && plmn_id.mnc == sib1.plmn_id[i].id.mnc) { + return true; + } } } return false; @@ -80,6 +82,7 @@ class cell_t cell_t(tmp, 0, 0); } cell_t(srslte_cell_t phy_cell, uint32_t earfcn, float rsrp) { + gettimeofday(&last_update, NULL); this->has_valid_sib1 = false; this->has_valid_sib2 = false; this->has_valid_sib3 = false; @@ -94,14 +97,106 @@ class cell_t bzero(&sib13, sizeof(sib13)); } - uint32_t earfcn; + uint32_t get_earfcn() { + return earfcn; + } + + uint32_t get_pci() { + return phy_cell.id; + } + + void set_rsrp(float rsrp) { + this->rsrp = rsrp; + in_sync = true; + gettimeofday(&last_update, NULL); + } + + float get_rsrp() { + return rsrp; + } + + void set_sib1(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *sib1) { + memcpy(&this->sib1, sib1, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT)); + has_valid_sib1 = true; + } + void set_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2) { + memcpy(&this->sib2, sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); + has_valid_sib2 = true; + } + void set_sib3(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3) { + memcpy(&this->sib3, sib3, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT)); + has_valid_sib3 = true; + } + void set_sib13(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT *sib13) { + memcpy(&this->sib13, sib13, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT)); + has_valid_sib13 = true; + } + + uint32_t timeout_secs(struct timeval now) { + struct timeval t[3]; + memcpy(&t[2], &now, sizeof(struct timeval)); + memcpy(&t[1], &last_update, sizeof(struct timeval)); + get_time_interval(t); + return t[0].tv_sec; + } + + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *sib1ptr() { + return &sib1; + } + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2ptr() { + return &sib2; + } + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3ptr() { + return &sib3; + } + + uint32_t get_cell_id() { + return sib1.cell_id; + } + + bool has_sib1() { + return has_valid_sib1; + } + bool has_sib2() { + return has_valid_sib2; + } + bool has_sib3() { + return has_valid_sib3; + } + bool has_sib13() { + return has_valid_sib13; + } + + uint16_t get_mcc() { + if (has_valid_sib1) { + if (sib1.N_plmn_ids > 0) { + return sib1.plmn_id[0].id.mcc; + } + } + return 0; + } + + uint16_t get_mnc() { + if (has_valid_sib1) { + if (sib1.N_plmn_ids > 0) { + return sib1.plmn_id[0].id.mnc; + } + } + return 0; + } + srslte_cell_t phy_cell; + bool in_sync; + + private: float rsrp; + uint32_t earfcn; + struct timeval last_update; + bool has_valid_sib1; bool has_valid_sib2; bool has_valid_sib3; bool has_valid_sib13; - bool in_sync; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT sib2; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT sib3; @@ -274,6 +369,7 @@ private: } // List of strongest neighbour cell + const static int NEIGHBOUR_TIMEOUT = 5; const static int NOF_NEIGHBOUR_CELLS = 8; std::vector neighbour_cells; cell_t *serving_cell; @@ -285,6 +381,9 @@ private: bool add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); bool add_neighbour_cell(cell_t *cell); void sort_neighbour_cells(); + void clean_neighbours(); + std::vector::iterator delete_neighbour(std::vector::iterator it); + void delete_neighbour(uint32_t cell_idx); typedef enum { SI_ACQUIRE_IDLE = 0, @@ -315,6 +414,7 @@ private: void run_tti(uint32_t tti); bool timer_expired(uint32_t timer_id); void ho_finish(); + void delete_report(uint32_t earfcn, uint32_t pci); private: const static int NOF_MEASUREMENTS = 3; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 4d93c9452..9e26436ae 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -54,6 +54,7 @@ rrc::rrc() n310_cnt = 0; n311_cnt = 0; serving_cell = new cell_t(); + neighbour_cells.reserve(NOF_NEIGHBOUR_CELLS); } rrc::~rrc() @@ -168,6 +169,7 @@ void rrc::set_args(rrc_args_t *args) { void rrc::run_thread() { uint32_t failure_test = 0; + uint32_t cell_clean_cnt = 0; while (thread_running) { @@ -217,13 +219,13 @@ void rrc::run_thread() { * Cell is selected when all SIBs downloaded or applied. */ if (phy->sync_status()) { - if (!serving_cell->has_valid_sib1) { + if (!serving_cell->has_sib1()) { si_acquire_state = SI_ACQUIRE_SIB1; sysinfo_index = 0; - } else if (!serving_cell->has_valid_sib2) { + } else if (!serving_cell->has_sib2()) { si_acquire_state = SI_ACQUIRE_SIB2; } else { - apply_sib2_configs(&serving_cell->sib2); + apply_sib2_configs(serving_cell->sib2ptr()); si_acquire_state = SI_ACQUIRE_IDLE; state = RRC_STATE_CELL_SELECTED; } @@ -302,6 +304,13 @@ void rrc::run_thread() { default: break; } + if (state == RRC_STATE_CONNECTED || RRC_STATE_IDLE) { + cell_clean_cnt++; + if (cell_clean_cnt==1000) { + clean_neighbours(); + cell_clean_cnt = 0; + } + } usleep(1000); } } @@ -363,16 +372,16 @@ void rrc::run_si_acquisition_procedure() break; case SI_ACQUIRE_SIB2: // Instruct MAC to look for next SIB - if(sysinfo_index < serving_cell->sib1.N_sched_info) { - si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length]; + if(sysinfo_index < serving_cell->sib1ptr()->N_sched_info) { + si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; x = sysinfo_index*si_win_len; sf = x%10; offset = x/10; tti = mac->get_current_tti(); - period = liblte_rrc_si_periodicity_num[serving_cell->sib1.sched_info[sysinfo_index].si_periodicity]; + period = liblte_rrc_si_periodicity_num[serving_cell->sib1ptr()->sched_info[sysinfo_index].si_periodicity]; si_win_start = sib_start_tti(tti, period, offset, sf); - si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length]; + si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; if (last_win_start == 0 || (srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000)) @@ -416,17 +425,11 @@ void rrc::run_si_acquisition_procedure() *******************************************************************************/ uint16_t rrc::get_mcc() { - if (serving_cell->sib1.N_plmn_ids > 0) { - return serving_cell->sib1.plmn_id[0].id.mcc; - } - return 0; + return serving_cell->get_mcc(); } uint16_t rrc::get_mnc() { - if (serving_cell->sib1.N_plmn_ids > 0) { - return serving_cell->sib1.plmn_id[0].id.mnc; - } - return 0; + return serving_cell->get_mnc(); } void rrc::plmn_search() { @@ -491,7 +494,7 @@ void rrc::set_serving_cell(uint32_t cell_idx) { // Move serving cell to neighbours list if (serving_cell->is_valid()) { // Make sure it does not exist already - int serving_idx = find_neighbour_cell(serving_cell->earfcn, serving_cell->phy_cell.id); + int serving_idx = find_neighbour_cell(serving_cell->get_earfcn(), serving_cell->phy_cell.id); if (serving_idx >= 0 && (uint32_t) serving_idx < neighbour_cells.size()) { printf("Error serving cell is already in the neighbour list. Removing it\n"); neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[serving_idx]), neighbour_cells.end()); @@ -506,7 +509,7 @@ void rrc::set_serving_cell(uint32_t cell_idx) { serving_cell = new_serving_cell; rrc_log->info("Setting serving cell idx=%d, earfcn=%d, PCI=%d, nof_neighbours=%d\n", - cell_idx, serving_cell->earfcn, serving_cell->phy_cell.id, neighbour_cells.size()); + cell_idx, serving_cell->get_earfcn(), serving_cell->phy_cell.id, neighbour_cells.size()); } else { rrc_log->error("Setting invalid serving cell idx %d\n", cell_idx); @@ -520,19 +523,19 @@ void rrc::select_next_cell_in_plmn() { neighbour_cells[i]->in_sync) // matches S criteria { // Try to select Cell - if (phy->cell_select(neighbour_cells[i]->earfcn, neighbour_cells[i]->phy_cell)) { + if (phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell)) { set_serving_cell(i); rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->earfcn, - serving_cell->sib1.cell_id); + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->earfcn, - serving_cell->sib1.cell_id); + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); } else { // Set to out-of-sync if can't synchronize neighbour_cells[i]->in_sync = false; rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", - neighbour_cells[i]->earfcn, neighbour_cells[i]->sib1.cell_id); + neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->get_cell_id()); } return; } @@ -543,7 +546,7 @@ void rrc::select_next_cell_in_plmn() { void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int pci_i) { if (earfcn_i < 0 || pci_i < 0) { - earfcn_i = serving_cell->earfcn; + earfcn_i = serving_cell->get_earfcn(); pci_i = serving_cell->phy_cell.id; } @@ -560,7 +563,7 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p // Update serving cell if (serving_cell->equals(earfcn, pci)) { cell_reselection_eval(rsrp, rsrq); - serving_cell->rsrp = rsrp; + serving_cell->set_rsrp(rsrp); rrc_log->info("MEAS: New measurement serving cell in IDLE, rsrp=%f, rsrq=%f, tti=%d\n", rsrp, rsrq, tti); // Or update/add neighbour cell @@ -573,13 +576,13 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } // Verify cell selection criteria with strongest neighbour cell (always first) - if (cell_selection_eval(neighbour_cells[0]->rsrp) && - neighbour_cells[0]->rsrp > serving_cell->rsrp + 5) + if (cell_selection_eval(neighbour_cells[0]->get_rsrp()) && + neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) { set_serving_cell(0); - rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->rsrp); + rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->get_rsrp()); state = RRC_STATE_CELL_SELECTING; - phy->cell_select(serving_cell->earfcn, serving_cell->phy_cell); + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); } } } @@ -590,7 +593,7 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { int cell_idx = -1; if (serving_cell->equals(earfcn, phy_cell.id)) { - serving_cell->rsrp = rsrp; + serving_cell->set_rsrp(rsrp); serving_cell->in_sync = true; found = true; } else { @@ -598,18 +601,18 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { cell_idx = find_neighbour_cell(earfcn, phy_cell.id); if (cell_idx >= 0) { set_serving_cell(cell_idx); - serving_cell->rsrp = rsrp; + serving_cell->set_rsrp(rsrp); serving_cell->in_sync = true; found = true; } } if (found) { - if (!serving_cell->has_valid_sib1) { + if (!serving_cell->has_sib1()) { si_acquire_state = SI_ACQUIRE_SIB1; } else if (state == RRC_STATE_PLMN_SELECTION) { - for (uint32_t j = 0; j < serving_cell->sib1.N_plmn_ids; j++) { - nas->plmn_found(serving_cell->sib1.plmn_id[j].id, serving_cell->sib1.tracking_area_code); + for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { + nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); } usleep(5000); phy->cell_search_next(); @@ -631,22 +634,54 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", found?"Updating":"Adding", cell_idx>=0?"neighbour":"serving", - serving_cell->earfcn, + serving_cell->get_earfcn(), serving_cell->phy_cell.id, - serving_cell->rsrp); + serving_cell->get_rsrp()); } bool sort_rsrp(cell_t *u1, cell_t *u2) { - return !u1->greater(u2); + return u1->greater(u2); } -// Sort neighbour cells by decreasing order of RSRP -void rrc::sort_neighbour_cells() { +void rrc::delete_neighbour(uint32_t cell_idx) { + measurements.delete_report(neighbour_cells[cell_idx]->get_earfcn(), neighbour_cells[cell_idx]->get_pci()); + delete neighbour_cells[cell_idx]; + neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[cell_idx]), neighbour_cells.end()); +} - for (uint32_t i=1;iin_sync == false) { - rrc_log->info("Removing neighbour cell PCI=%d, out_of_sync\n", neighbour_cells[i]->phy_cell.id); - neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[i]), neighbour_cells.end()); +std::vector::iterator rrc::delete_neighbour(std::vector::iterator it) { + measurements.delete_report((*it)->get_earfcn(), (*it)->get_pci()); + delete (*it); + return neighbour_cells.erase(it); +} + +void rrc::clean_neighbours() +{ + struct timeval now; + gettimeofday(&now, NULL); + + std::vector::iterator it = neighbour_cells.begin(); + while(it != neighbour_cells.end()) { + if ((*it)->timeout_secs(now) > NEIGHBOUR_TIMEOUT) { + rrc_log->info("Neighbour PCI=%d timed out. Deleting\n", (*it)->get_pci()); + it = delete_neighbour(it); + } else { + ++it; + } + } +} + +// Sort neighbour cells by decreasing order of RSRP +void rrc::sort_neighbour_cells() +{ + // Remove out-of-sync cells + std::vector::iterator it = neighbour_cells.begin(); + while(it != neighbour_cells.end()) { + if ((*it)->in_sync == false) { + rrc_log->info("Neighbour PCI=%d is out-of-sync. Deleting\n", (*it)->get_pci()); + it = delete_neighbour(it); + } else { + ++it; } } @@ -654,28 +689,27 @@ void rrc::sort_neighbour_cells() { char ordered[512]; int n=0; - n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->rsrp); + n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); for (uint32_t i=1;iphy_cell.id, neighbour_cells[i]->rsrp); + n += snprintf(&ordered[n], 512-n, " | pci=%d, rsrp=%.2f", neighbour_cells[i]->get_pci(), neighbour_cells[i]->get_rsrp()); } - rrc_log->info("Sorted neighbour cells: %s]\n", ordered); + rrc_log->info("Neighbours: %s]\n", ordered); } bool rrc::add_neighbour_cell(cell_t *new_cell) { bool ret = false; - if (neighbour_cells.size() < NOF_NEIGHBOUR_CELLS - 1) { + if (neighbour_cells.size() < NOF_NEIGHBOUR_CELLS) { ret = true; - } else if (!neighbour_cells[neighbour_cells.size()-1]->greater(new_cell)) { - // Delete old one - delete neighbour_cells[neighbour_cells.size()-1]; - neighbour_cells.erase(std::remove(neighbour_cells.begin(), neighbour_cells.end(), neighbour_cells[neighbour_cells.size()-1]), neighbour_cells.end()); + } else if (new_cell->greater(neighbour_cells[neighbour_cells.size()-1])) { + // Replace old one by new one + delete_neighbour(neighbour_cells.size()-1); ret = true; } if (ret) { neighbour_cells.push_back(new_cell); } rrc_log->info("Added neighbour cell EARFCN=%d, PCI=%d, nof_neighbours=%d\n", - new_cell->earfcn, new_cell->phy_cell.id, neighbour_cells.size()); + new_cell->get_earfcn(), new_cell->get_pci(), neighbour_cells.size()); sort_neighbour_cells(); return ret; } @@ -690,7 +724,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, uint32_t pci, float rsrp) { bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (earfcn == 0) { - earfcn = serving_cell->earfcn; + earfcn = serving_cell->get_earfcn(); } // First check if already exists @@ -700,7 +734,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp // If exists, update RSRP, sort again and return if (cell_idx >= 0) { - neighbour_cells[cell_idx]->rsrp = rsrp; + neighbour_cells[cell_idx]->set_rsrp(rsrp); sort_neighbour_cells(); return true; } @@ -929,7 +963,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, uint8_t *msg_ptr = varShortMAC; // ASN.1 encode byte-aligned VarShortMAC-Input - liblte_rrc_pack_cell_identity_ie(serving_cell->sib1.cell_id, &msg_ptr); + 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]; @@ -937,7 +971,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->sib1.cell_id, phy->get_current_pci(), crnti); + serving_cell->get_cell_id(), phy->get_current_pci(), crnti); // Compute MAC-I uint8_t mac_key[4]; @@ -1065,10 +1099,10 @@ bool rrc::ho_prepare() { if (pending_mob_reconf) { rrc_log->info("Processing HO command to target PCell=%d\n", mob_reconf.mob_ctrl_info.target_pci); - int target_cell_idx = find_neighbour_cell(serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); + int target_cell_idx = find_neighbour_cell(serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); if (target_cell_idx < 0) { rrc_log->console("Received HO command to unknown PCI=%d\n", mob_reconf.mob_ctrl_info.target_pci); - rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->earfcn, mob_reconf.mob_ctrl_info.target_pci); + rrc_log->error("Could not find target cell earfcn=%d, pci=%d\n", serving_cell->get_earfcn(), mob_reconf.mob_ctrl_info.target_pci); return false; } @@ -1076,7 +1110,7 @@ bool rrc::ho_prepare() { mac_timers->timer_get(t310)->stop(); mac_timers->timer_get(t304)->set(this, liblte_rrc_t304_num[mob_reconf.mob_ctrl_info.t304]); if (mob_reconf.mob_ctrl_info.carrier_freq_eutra_present && - mob_reconf.mob_ctrl_info.carrier_freq_eutra.dl_carrier_freq != serving_cell->earfcn) { + mob_reconf.mob_ctrl_info.carrier_freq_eutra.dl_carrier_freq != serving_cell->get_earfcn()) { rrc_log->warning("Received mobilityControlInfo for inter-frequency handover\n"); } @@ -1099,9 +1133,9 @@ bool rrc::ho_prepare() { mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); - rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->phy_cell.id); + rrc_log->info("Selecting new cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); if (!phy->cell_handover(neighbour_cells[target_cell_idx]->phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->phy_cell.id); + rrc_log->error("Could not synchronize with target cell pci=%d\n", neighbour_cells[target_cell_idx]->get_pci()); return false; } @@ -1177,7 +1211,7 @@ void rrc::ho_failed() { // Instruct PHY to resync with source PCI if (!phy->cell_handover(ho_src_cell.phy_cell)) { - rrc_log->error("Could not synchronize with target cell pci=%d\n", ho_src_cell.phy_cell.id); + rrc_log->error("Could not synchronize with target cell pci=%d\n", ho_src_cell.get_pci()); return; } @@ -1302,27 +1336,23 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { rrc_log->info("Processing SIB: %d\n", liblte_rrc_sys_info_block_type_num[dlsch_msg.sibs[i].sib_type]); if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1 == dlsch_msg.sibs[i].sib_type && SI_ACQUIRE_SIB1 == si_acquire_state) { - memcpy(&serving_cell->sib1, &dlsch_msg.sibs[i].sib.sib1, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT)); - serving_cell->has_valid_sib1 = true; + serving_cell->set_sib1(&dlsch_msg.sibs[i].sib.sib1); handle_sib1(); - } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_valid_sib2) { - memcpy(&serving_cell->sib2, &dlsch_msg.sibs[i].sib.sib2, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT)); - serving_cell->has_valid_sib2 = true; + } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_sib2()) { + serving_cell->set_sib2(&dlsch_msg.sibs[i].sib.sib2); handle_sib2(); - } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_valid_sib3) { - memcpy(&serving_cell->sib3, &dlsch_msg.sibs[i].sib.sib3, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT)); - serving_cell->has_valid_sib3 = true; + } else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_sib3()) { + serving_cell->set_sib3(&dlsch_msg.sibs[i].sib.sib3); handle_sib3(); - }else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_valid_sib13) { - memcpy(&serving_cell->sib13, &dlsch_msg.sibs[0].sib.sib13, sizeof(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13_STRUCT)); - serving_cell->has_valid_sib13 = true; + }else if (LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_13 == dlsch_msg.sibs[i].sib_type && !serving_cell->has_sib13()) { + serving_cell->set_sib13(&dlsch_msg.sibs[i].sib.sib13); handle_sib13(); } } last_win_start = 0; - if(serving_cell->has_valid_sib2) { + if(serving_cell->has_sib2()) { sysinfo_index++; } } @@ -1330,16 +1360,16 @@ void rrc::write_pdu_bcch_dlsch(byte_buffer_t *pdu) { void rrc::handle_sib1() { rrc_log->info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d\n", - serving_cell->sib1.cell_id&0xfff, - liblte_rrc_si_window_length_num[serving_cell->sib1.si_window_length], - liblte_rrc_si_periodicity_num[serving_cell->sib1.sched_info[0].si_periodicity]); + serving_cell->get_cell_id()&0xfff, + liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length], + liblte_rrc_si_periodicity_num[serving_cell->sib1ptr()->sched_info[0].si_periodicity]); // Print SIB scheduling info uint32_t i,j; - for(i=0;isib1.N_sched_info;i++){ - for(j=0;jsib1.sched_info[i].N_sib_mapping_info;j++){ - LIBLTE_RRC_SIB_TYPE_ENUM t = serving_cell->sib1.sched_info[i].sib_mapping_info[j].sib_type; - LIBLTE_RRC_SI_PERIODICITY_ENUM p = serving_cell->sib1.sched_info[i].si_periodicity; + for(i=0;isib1ptr()->N_sched_info;i++){ + for(j=0;jsib1ptr()->sched_info[i].N_sib_mapping_info;j++){ + LIBLTE_RRC_SIB_TYPE_ENUM t = serving_cell->sib1ptr()->sched_info[i].sib_mapping_info[j].sib_type; + LIBLTE_RRC_SI_PERIODICITY_ENUM p = serving_cell->sib1ptr()->sched_info[i].si_periodicity; rrc_log->debug("SIB scheduling info, sib_type=%d, si_periodicity=%d\n", liblte_rrc_sib_type_num[t], liblte_rrc_si_periodicity_num[p]); @@ -1347,16 +1377,14 @@ void rrc::handle_sib1() } // Set TDD Config - if(serving_cell->sib1.tdd) { - phy->set_config_tdd(&serving_cell->sib1.tdd_cnfg); + if(serving_cell->sib1ptr()->tdd) { + phy->set_config_tdd(&serving_cell->sib1ptr()->tdd_cnfg); } - serving_cell->has_valid_sib1 = true; - // Send PLMN and TAC to NAS std::stringstream ss; - for (uint32_t i = 0; i < serving_cell->sib1.N_plmn_ids; i++) { - nas->plmn_found(serving_cell->sib1.plmn_id[i].id, serving_cell->sib1.tracking_area_code); + for (uint32_t i = 0; i < serving_cell->sib1ptr()->N_plmn_ids; i++) { + nas->plmn_found(serving_cell->sib1ptr()->plmn_id[i].id, serving_cell->sib1ptr()->tracking_area_code); } // Jump to next state @@ -1379,7 +1407,7 @@ void rrc::handle_sib2() { rrc_log->info("SIB2 received\n"); - apply_sib2_configs(&serving_cell->sib2); + apply_sib2_configs(serving_cell->sib2ptr()); } @@ -1387,7 +1415,7 @@ void rrc::handle_sib3() { rrc_log->info("SIB3 received\n"); - LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3 = &serving_cell->sib3; + LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_3_STRUCT *sib3 = serving_cell->sib3ptr(); // cellReselectionInfoCommon cell_resel_cfg.q_hyst = liblte_rrc_q_hyst_num[sib3->q_hyst]; @@ -1699,7 +1727,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { * *******************************************************************************/ void rrc::enable_capabilities() { - bool enable_ul_64 = args.ue_category >= 5 && serving_cell->sib2.rr_config_common_sib.pusch_cnfg.enable_64_qam; + bool enable_ul_64 = args.ue_category >= 5 && serving_cell->sib2ptr()->rr_config_common_sib.pusch_cnfg.enable_64_qam; rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); phy->set_config_64qam_en(enable_ul_64); } @@ -2373,28 +2401,45 @@ void rrc::rrc_meas::new_phy_meas(uint32_t earfcn, uint32_t pci, float rsrp, floa L3_filter(&pcell_measurement, values); // Update serving cell measurement - parent->serving_cell->rsrp = rsrp; + parent->serving_cell->set_rsrp(rsrp); } else { // Add to list of neighbour cells - parent->add_neighbour_cell(earfcn, pci, rsrp); - - log_h->info("MEAS: New measurement earfcn=%d, pci=%d, rsrp=%f, rsrq=%f, tti=%d\n", earfcn, pci, rsrp, rsrq, tti); - - // Save PHY measurement for all active measurements whose earfcn/pci matches - for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { - meas_t *m = &iter->second; - if (objects[m->object_id].earfcn == earfcn) { - // If it's a newly discovered cell, add it to objects - if (!m->cell_values.count(pci)) { - uint32_t cell_idx = objects[m->object_id].cells.size(); - objects[m->object_id].cells[cell_idx].pci = pci; - objects[m->object_id].cells[cell_idx].q_offset = 0; + bool added = parent->add_neighbour_cell(earfcn, pci, rsrp); + + log_h->info("MEAS: New measurement %s earfcn=%d, pci=%d, rsrp=%f, rsrq=%f, tti=%d\n", + added?"added":"not added", earfcn, pci, rsrp, rsrq, tti); + + // Only report measurements of 8th strongest cells + if (added) { + // Save PHY measurement for all active measurements whose earfcn/pci matches + for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { + meas_t *m = &iter->second; + if (objects[m->object_id].earfcn == earfcn) { + // If it's a newly discovered cell, add it to objects + if (!m->cell_values.count(pci)) { + uint32_t cell_idx = objects[m->object_id].cells.size(); + objects[m->object_id].cells[cell_idx].pci = pci; + objects[m->object_id].cells[cell_idx].q_offset = 0; + } + // Update or add cell + L3_filter(&m->cell_values[pci], values); + return; } - // Update or add cell - L3_filter(&m->cell_values[pci], values); - return; + } + } + } +} + +// Remove all stored measurements for a given cell +void rrc::rrc_meas::delete_report(uint32_t earfcn, uint32_t pci) { + for(std::map::iterator iter=active.begin(); iter!=active.end(); ++iter) { + meas_t *m = &iter->second; + if (objects[m->object_id].earfcn == earfcn) { + if (m->cell_values.count(pci)) { + m->cell_values.erase(pci); + log_h->info("Deleting report PCI=%d from cell_values\n", pci); } } } From 9c416aa97e22130821d0a6562129f965ded905e4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 23 Feb 2018 13:15:01 +0100 Subject: [PATCH 03/52] Disable RSSI sensor by default and expose rx_gain for calibration --- srsue/src/main.cc | 4 ++-- srsue/src/upper/rrc.cc | 2 +- srsue/ue.conf.example | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index e76891796..1cac2092d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -159,11 +159,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "Pregenerate uplink signals after attach. Improves CPU performance.") ("expert.rssi_sensor_enabled", - bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(true), + bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(false), "Enable or disable RF frontend RSSI sensor. In some USRP devices can cause segmentation fault") ("expert.rx_gain_offset", - bpo::value(&args->expert.phy.rx_gain_offset)->default_value(10), + bpo::value(&args->expert.phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to correct RSRP value") ("expert.prach_gain", diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9e26436ae..6809eea4f 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -389,7 +389,7 @@ void rrc::run_si_acquisition_procedure() last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", + rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", si_win_start, si_win_len); } diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 2b8da9643..5e6f01027 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -118,6 +118,7 @@ enable = false # ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0 # rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but # can cause UHD instability for long-duration testing. Default true. +# rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings # prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only., # Default is to use tx_gain in [rf] section. # cqi_max: Upper bound on the maximum CQI to be reported. Default 15. @@ -176,6 +177,7 @@ enable = false [expert] #ip_netmask = 255.255.255.0 #rssi_sensor_enabled = false +#rx_gain_offset = 62 #prach_gain = 30 #cqi_max = 15 #cqi_fixed = 10 From aced809146ff2e1327829b288fd29cad059040f0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:28:05 +0100 Subject: [PATCH 04/52] Set rx_gain_offset for B210 --- srsue/src/main.cc | 4 ++-- srsue/ue.conf.example | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index e76891796..1cac2092d 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -159,11 +159,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "Pregenerate uplink signals after attach. Improves CPU performance.") ("expert.rssi_sensor_enabled", - bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(true), + bpo::value(&args->expert.phy.rssi_sensor_enabled)->default_value(false), "Enable or disable RF frontend RSSI sensor. In some USRP devices can cause segmentation fault") ("expert.rx_gain_offset", - bpo::value(&args->expert.phy.rx_gain_offset)->default_value(10), + bpo::value(&args->expert.phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to correct RSRP value") ("expert.prach_gain", diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 2b8da9643..b8cc43c2e 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -118,6 +118,7 @@ enable = false # ip_netmask: Netmask of the tun_srsue device. Default: 255.255.255.0 # rssi_sensor_enabled: Enable or disable RF frontend RSSI sensor. Required for RSRP metrics but # can cause UHD instability for long-duration testing. Default true. +# rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings # prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only., # Default is to use tx_gain in [rf] section. # cqi_max: Upper bound on the maximum CQI to be reported. Default 15. @@ -176,6 +177,7 @@ enable = false [expert] #ip_netmask = 255.255.255.0 #rssi_sensor_enabled = false +#rx_gain_offset = 72 #prach_gain = 30 #cqi_max = 15 #cqi_fixed = 10 From 56455b31ef212286501f9f25b205259daeb2d6a9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:29:57 +0100 Subject: [PATCH 05/52] Use dedicated thread for MAC timers --- srsue/hdr/mac/mac.h | 15 +++++++++++++-- srsue/hdr/mac/ul_harq.h | 1 - srsue/src/mac/mac.cc | 14 +++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index e59aa8f16..f4b0ffe3a 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -162,13 +162,24 @@ private: void timer_alignment_expire(); srslte::timers timers; - // pointer to MAC PCAP object srslte::mac_pcap* pcap; bool is_first_ul_grant; + mac_metrics_t metrics; + + /* Class to run Timers in a dedicated thread */ + class mac_timers : public periodic_thread { + public: + void init(srslte::timers *timers, srslte::log *log_h); + private: + void run_period(); + srslte::timers *timers; + bool running; + srslte::log *log_h; + }; - mac_metrics_t metrics; + mac_timers mactimers; /* Class to process MAC PDUs from DEMUX unit */ class pdu_process : public thread { diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 60deff36f..5c44a222e 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -246,7 +246,6 @@ private: } else { Warning("UL RAR grant available but no Msg3 on buffer\n"); } - printf("Transmitted Msg3\n"); // Normal UL grant } else { diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index daa82d1cb..2531faafc 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -82,6 +82,7 @@ bool mac::init(phy_interface_mac *phy, rlc_interface_mac *rlc, rrc_interface_mac started = true; start(MAC_MAIN_THREAD_PRIO); + mactimers.init(&timers, log_h); return started; } @@ -94,6 +95,7 @@ void mac::stop() ttisync.increase(); pdu_process_thread.stop(); wait_thread_finish(); + mactimers.stop(); } void mac::start_pcap(srslte::mac_pcap* pcap_) @@ -148,6 +150,17 @@ void mac::reset() bzero(&uernti, sizeof(ue_rnti_t)); } +void mac::mac_timers::init(srslte::timers *timers, srslte::log *log_h) { + this->timers = timers; + running = true; + this->log_h = log_h; + start_periodic(1000); +} + +void mac::mac_timers::run_period() { + timers->step_all(); +} + void mac::run_thread() { int cnt=0; @@ -165,7 +178,6 @@ void mac::run_thread() { tti = ttisync.wait(); log_h->step(tti); - timers.step_all(); // Step all procedures bsr_procedure.step(tti); From 42ece73453274f064b15ba450a59578397dbef35 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:33:13 +0100 Subject: [PATCH 06/52] Changed cell selection/reselection to avoid stopping/restarting radio. Fixed SIB message search --- srsue/hdr/phy/phch_recv.h | 3 +-- srsue/hdr/upper/rrc_common.h | 4 +++ srsue/src/phy/phch_recv.cc | 51 ++++++++++++++++++++---------------- srsue/src/upper/nas.cc | 5 +++- srsue/src/upper/rrc.cc | 35 ++++++++++++------------- 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index bc7255ac9..a14f8e9fa 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -104,7 +104,7 @@ private: bool set_cell(); void cell_search_inc(); - void resync_sfn(bool is_connected = false, bool rx_now = false); + void resync_sfn(bool restart_radio, bool restart_now = false); bool stop_sync(); void stop_rx(); @@ -307,7 +307,6 @@ private: IDLE = 0, CELL_SEARCH, CELL_SELECT, - CELL_RESELECT, CELL_MEASURE, CELL_CAMP, IDLE_RX diff --git a/srsue/hdr/upper/rrc_common.h b/srsue/hdr/upper/rrc_common.h index 6d1186812..259d08fd7 100644 --- a/srsue/hdr/upper/rrc_common.h +++ b/srsue/hdr/upper/rrc_common.h @@ -33,6 +33,7 @@ namespace srsue { // RRC states (3GPP 36.331 v10.0.0) typedef enum { RRC_STATE_IDLE = 0, + RRC_STATE_PLMN_START, RRC_STATE_PLMN_SELECTION, RRC_STATE_CELL_SELECTING, RRC_STATE_CELL_SELECTED, @@ -44,11 +45,14 @@ typedef enum { RRC_STATE_N_ITEMS, } rrc_state_t; static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", + "PLMN SELECTED", "PLMN SELECTION", "CELL SELECTING", "CELL SELECTED", "CONNECTING", "CONNECTED", + "HO PREPARE", + "HO PROCESS", "LEAVE CONNECTED"}; } // namespace srsue diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5e2ec4dee..4a8fef5bf 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -265,17 +265,22 @@ bool phch_recv::set_cell() { return cell_is_set; } -void phch_recv::resync_sfn(bool is_connected, bool now) { +void phch_recv::resync_sfn(bool restart_radio, bool restart_now) { - if (!now) { + if (restart_radio) { wait_radio_reset(); stop_rx(); + usleep(100000); } - start_rx(now); sfn_p.reset(); - Info("SYNC: Starting SFN synchronization\n"); + search_p.reset(); + srslte_ue_sync_reset(&ue_sync); - phy_state = is_connected?CELL_RESELECT:CELL_SELECT; + if (restart_radio) { + start_rx(restart_now); + } + + phy_state = CELL_SELECT; } void phch_recv::set_earfcn(std::vector earfcn) { @@ -294,7 +299,7 @@ bool phch_recv::stop_sync() { if (phy_state == IDLE && is_in_idle) { return true; } else { - Info("SYNC: Going to IDLE\n"); + Info("SYNC: Going to IDLE (state=%d)\n", phy_state); phy_state = IDLE; int cnt = 0; while (!is_in_idle && cnt < 100) { @@ -302,7 +307,7 @@ bool phch_recv::stop_sync() { cnt++; } if (!is_in_idle) { - Warning("SYNC: Could not go to IDLE\n"); + Warning("SYNC: Could not go to IDLE (state=%d)\n", phy_state); } return is_in_idle; } @@ -310,11 +315,12 @@ bool phch_recv::stop_sync() { void phch_recv::reset_sync() { - Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); - - search_p.reset(); - srslte_ue_sync_reset(&ue_sync); - resync_sfn(true, true); + if (phy_state != CELL_SELECT) { + Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); + resync_sfn(false); + } else { + Warning("SYNC: Trying to reset sync while in cell reselection\n"); + } } void phch_recv::cell_search_inc() @@ -323,6 +329,8 @@ void phch_recv::cell_search_inc() if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= (int) earfcn.size()) { cur_earfcn_index = 0; + cell_search_in_progress = false; + phy_state = IDLE; rrc->earfcn_end(); } else { Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); @@ -338,7 +346,7 @@ void phch_recv::cell_search_next(bool reset) { if (cell_search_in_progress || reset) { cell_search_in_progress = false; if (!stop_sync()) { - log_h->warning("SYNC: Couldn't stop PHY\n"); + log_h->warning("SYNC: Couldn't stop PHY (state=%d)\n", phy_state); } if (reset) { cur_earfcn_index = -1; @@ -393,9 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell) if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { - //resync_sfn(true, true); - sfn_p.reset(); - phy_state = CELL_RESELECT; + resync_sfn(false); Info("Cell HO: Synchronizing with new cell\n"); ret = true; } else { @@ -419,7 +425,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { set_sampling_rate(); } if (phy_state < CELL_SELECT) { - resync_sfn(); + resync_sfn(true, false); } return true; } else { @@ -444,9 +450,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - resync_sfn(); - - usleep(500000); // Time offset we set start_rx to start receiving samples + resync_sfn(true, false); return true; } return false; @@ -616,13 +620,14 @@ void phch_recv::run_thread() } if (set_cell()) { set_sampling_rate(); - resync_sfn(); + resync_sfn(true, false); } break; case search::CELL_NOT_FOUND: if (cell_search_in_progress) { cell_search_inc(); } + phy_state = IDLE; break; default: radio_error(); @@ -630,7 +635,6 @@ void phch_recv::run_thread() } } break; - case CELL_RESELECT: case CELL_SELECT: switch (sfn_p.run_subframe(&cell, &tti)) { @@ -650,7 +654,7 @@ void phch_recv::run_thread() phy_state = CELL_SEARCH; } else { log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - resync_sfn(true, true); + resync_sfn(false); } break; case sfn_sync::IDLE: @@ -666,6 +670,7 @@ void phch_recv::run_thread() case measure::MEASURE_OK: log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; + cell_search_in_progress = false; rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 04b5f4869..7f5683867 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -171,7 +171,10 @@ void nas::plmn_search_end() { rrc->plmn_select(known_plmns[0]); } else { - nas_log->debug("Finished searching PLMN in current EARFCN set but no networks were found.\n"); + nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); + if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { + rrc->plmn_search(); + } } } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9e26436ae..0760ccb7e 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -202,6 +202,12 @@ void rrc::run_thread() { // If not attached, PLMN selection will be triggered from higher layers } break; + case RRC_STATE_PLMN_START: + rrc_log->info("RRC PLMN Search: Starting cell search\n"); + plmn_select_timeout = 0; + phy->cell_search_start(); + state = RRC_STATE_PLMN_SELECTION; + break; case RRC_STATE_PLMN_SELECTION: plmn_select_timeout++; if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) { @@ -209,8 +215,7 @@ void rrc::run_thread() { phy->cell_search_stop(); sleep(1); rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n"); - plmn_select_timeout = 0; - phy->cell_search_start(); + } break; case RRC_STATE_CELL_SELECTING: @@ -230,7 +235,7 @@ void rrc::run_thread() { state = RRC_STATE_CELL_SELECTED; } } - // Don't time out during restablishment (T311 running) + // Don't time out during reestablishment (T311 running) if (!mac_timers->timer_get(t311)->is_running()) { select_cell_timeout++; if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { @@ -351,7 +356,7 @@ void rrc::run_si_acquisition_procedure() tti = mac->get_current_tti(); si_win_start = sib_start_tti(tti, 2, 0, 5); if (last_win_start == 0 || - (srslte_tti_interval(last_win_start, tti) > 20 && srslte_tti_interval(last_win_start, tti) < 1000)) + (srslte_tti_interval(tti, last_win_start) >= 20 && srslte_tti_interval(tti, last_win_start) < 1000)) { last_win_start = si_win_start; @@ -384,12 +389,12 @@ void rrc::run_si_acquisition_procedure() si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; if (last_win_start == 0 || - (srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000)) + (srslte_tti_interval(tti, last_win_start) > period*10 && srslte_tti_interval(tti, last_win_start) < 1000)) { last_win_start = si_win_start; mac->bcch_start_rx(si_win_start, si_win_len); - rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", + rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", si_win_start, si_win_len); } @@ -433,10 +438,7 @@ uint16_t rrc::get_mnc() { } void rrc::plmn_search() { - rrc_log->info("Starting PLMN search procedure\n"); - state = RRC_STATE_PLMN_SELECTION; - phy->cell_search_start(); - plmn_select_timeout = 0; + state = RRC_STATE_PLMN_START; } /* This is the NAS interface. When NAS requests to select a PLMN we have to @@ -576,7 +578,8 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } // Verify cell selection criteria with strongest neighbour cell (always first) - if (cell_selection_eval(neighbour_cells[0]->get_rsrp()) && + if (neighbour_cells.size() > 1 && + cell_selection_eval(neighbour_cells[0]->get_rsrp()) && neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) { set_serving_cell(0); @@ -761,10 +764,6 @@ void rrc::earfcn_end() { // If searching for PLMN, indicate NAS we scanned all frequencies if (state == RRC_STATE_PLMN_SELECTION) { nas->plmn_search_end(); - } else if (state == RRC_STATE_CELL_SELECTING) { - select_cell_timeout = 0; - rrc_log->info("Starting cell search again\n"); - phy->cell_search_start(); } } @@ -825,11 +824,11 @@ void rrc::out_of_sync() { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; if (n310_cnt == N310) { + rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n", + N310, mac_timers->timer_get(t310)->get_timeout()); mac_timers->timer_get(t310)->reset(); mac_timers->timer_get(t310)->run(); n310_cnt = 0; - phy->sync_reset(); - rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer\n", N310); } } } else { @@ -856,7 +855,6 @@ void rrc::in_sync() { void rrc::radio_link_failure() { // TODO: Generate and store failure report - phy->sync_reset(); rrc_log->warning("Detected Radio-Link Failure\n"); rrc_log->console("Warning: Detected Radio-Link Failure\n"); if (state != RRC_STATE_CONNECTED) { @@ -1016,6 +1014,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, set_phy_default(); mac->reset(); set_mac_default(); + phy->sync_reset(); state = RRC_STATE_CELL_SELECTING; } From df67735a99d256ff45df73bedfa12e8627fec57c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 13:08:36 +0100 Subject: [PATCH 07/52] Reset UL after IDLEling PHY --- srsue/src/phy/phch_recv.cc | 11 ++++++++++- srsue/src/upper/rrc.cc | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4a8fef5bf..d63d298ec 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -391,13 +391,22 @@ bool phch_recv::cell_handover(srslte_cell_t cell) bool ret = false; this->cell = cell; Info("Cell HO: Stopping sync with current cell\n"); - worker_com->reset_ul(); phy_state = IDLE_RX; cnt = 0; while(!is_in_idle_rx && cnt<20) { usleep(1000); cnt++; } + cnt = 0; + while(!is_in_idle_rx && cnt<20) { + usleep(1000); + cnt++; + } + for(uint32_t i=0;iget_nof_workers();i++) { + ((phch_worker*) workers_pool->get_worker(i))->reset(); + } + worker_com->reset(); + worker_com->reset_ul(); if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 0760ccb7e..9c5ad52c1 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1128,7 +1128,8 @@ bool rrc::ho_prepare() { pdcp->reestablish(); rlc->reestablish(); mac->reset(); - phy->reset(); + // PHY is reset inside cell_handover() function + mac->set_ho_rnti(mob_reconf.mob_ctrl_info.new_ue_id, mob_reconf.mob_ctrl_info.target_pci); apply_rr_config_common_dl(&mob_reconf.mob_ctrl_info.rr_cnfg_common); From cfaa5e9b281e4bb501446a3d35f26ccf9a7cd4fc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 19:13:12 +0100 Subject: [PATCH 08/52] Fix previous commit could not HO more than once due to not refreshing serving cell after 1st HO --- lib/include/srslte/interfaces/ue_interfaces.h | 2 +- srsue/hdr/upper/rrc.h | 7 +++++-- srsue/src/phy/phch_recv.cc | 3 ++- srsue/src/upper/rrc.cc | 8 ++++---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 00b61fa1c..f18a6737b 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -160,7 +160,7 @@ public: virtual void in_sync() = 0; virtual void out_of_sync() = 0; virtual void earfcn_end() = 0; - virtual void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) = 0; + virtual void cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp = NAN) = 0; virtual void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn = -1, int pci = -1) = 0; }; diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 5f269ec86..1bfae16b3 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -37,6 +37,7 @@ #include "srslte/common/security.h" #include "srslte/common/threads.h" +#include #include #include @@ -106,7 +107,9 @@ class cell_t } void set_rsrp(float rsrp) { - this->rsrp = rsrp; + if (~isnan(rsrp)) { + this->rsrp = rsrp; + } in_sync = true; gettimeofday(&last_update, NULL); } @@ -252,7 +255,7 @@ public: void in_sync(); void out_of_sync(); void earfcn_end(); - void cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); + void cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp); void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn, int pci); // MAC interface diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index d63d298ec..5701297c4 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -651,6 +651,7 @@ void phch_recv::run_thread() if (!cell_search_in_progress) { log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; + rrc->cell_camping(earfcn[cur_earfcn_index], cell); } else { log_h->info("Sync OK. Measuring PCI=%d...\n", cell.id); measure_p.reset(); @@ -680,7 +681,7 @@ void phch_recv::run_thread() log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; cell_search_in_progress = false; - rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); + rrc->cell_camping(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: break; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9c5ad52c1..dfb356b92 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -590,14 +590,16 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p } } -void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { +/* PHY begins camping in a cell. RRC updates RSRP measurement, + * proceeds with PLMN selection/cell search if applicable and sets + * new cell as current serving cell */ +void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { bool found = false; int cell_idx = -1; if (serving_cell->equals(earfcn, phy_cell.id)) { serving_cell->set_rsrp(rsrp); - serving_cell->in_sync = true; found = true; } else { // Check if cell is in our list of neighbour cells @@ -605,7 +607,6 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { if (cell_idx >= 0) { set_serving_cell(cell_idx); serving_cell->set_rsrp(rsrp); - serving_cell->in_sync = true; found = true; } } @@ -629,7 +630,6 @@ void rrc::cell_found(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { phy->cell_search_next(); } else { set_serving_cell(earfcn, phy_cell.id); - si_acquire_state = SI_ACQUIRE_SIB1; } } From 65aa5abb309e2739af0725c86211a0ae6b6f8402 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 20:51:16 +0100 Subject: [PATCH 09/52] Restored RSRP calculation changed in commit 3f002aca85f9a23226c3481b3619ae11ad798e94 --- lib/src/phy/ch_estimation/chest_dl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 5249696af..221bac319 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -540,22 +540,23 @@ void chest_interpolate_noise_est(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, ui } } } - - /* Compute RSRP for the channel estimates in this port */ - uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); - q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_estimates, npilots); - q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); } int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) { + uint32_t npilots = SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); + /* Get references from the input signal */ srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal); /* Use the known CSR signal to compute Least-squares estimates */ srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_refs.pilots[port_id/2][sf_idx], - q->pilot_estimates, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id)); + q->pilot_estimates, npilots); + /* Compute RSRP for the channel estimates in this port */ + double energy = cabs(srslte_vec_acc_cc(q->pilot_estimates, npilots)/npilots); + q->rsrp[rxant_id][port_id] = energy*energy; + q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); chest_interpolate_noise_est(q, input, ce, sf_idx, port_id, rxant_id, SRSLTE_SF_NORM); From beccfd29195194857417e278b157e3bdb9747000 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 25 Feb 2018 23:36:08 +0100 Subject: [PATCH 10/52] Average RSRP in linear domain to get better resolution --- srsue/hdr/phy/phch_recv.h | 6 ++--- srsue/src/phy/phch_recv.cc | 50 ++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index a14f8e9fa..1e15aea62 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -167,13 +167,14 @@ private: typedef enum {IDLE, MEASURE_OK, ERROR} ret_code; ~measure(); - void init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, srslte::radio *radio_h, + void init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, uint32_t nof_rx_antennas, uint32_t nof_subframes = RSRP_MEASURE_NOF_FRAMES); void reset(); void set_cell(srslte_cell_t cell); ret_code run_subframe(uint32_t sf_idx); ret_code run_subframe_sync(srslte_ue_sync_t *ue_sync, uint32_t sf_idx); ret_code run_multiple_subframes(cf_t *buffer, uint32_t offset, uint32_t sf_idx, uint32_t nof_sf); + float rssi(); float rsrp(); float rsrq(); float snr(); @@ -183,7 +184,6 @@ private: srslte::log *log_h; srslte_ue_dl_t ue_dl; cf_t *buffer[SRSLTE_MAX_PORTS]; - srslte::radio *radio_h; uint32_t cnt; uint32_t nof_subframes; uint32_t current_prb; @@ -235,7 +235,7 @@ private: void write(uint32_t tti, cf_t *data, uint32_t nsamples); private: void run_thread(); - const static int INTRA_FREQ_MEAS_LEN_MS = 20; + const static int INTRA_FREQ_MEAS_LEN_MS = 50; const static int INTRA_FREQ_MEAS_PERIOD_MS = 200; const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5701297c4..6737f52e0 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -91,7 +91,7 @@ void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_ma sfn_p.init(&ue_sync, sf_buffer, log_h); // Initialize measurement class for the primary cell - measure_p.init(sf_buffer, log_h, radio_h, nof_rx_antennas); + measure_p.init(sf_buffer, log_h, nof_rx_antennas); // Start intra-frequency measurement intra_freq_meas.init(worker_com, rrc, log_h); @@ -675,9 +675,18 @@ void phch_recv::run_thread() } break; case CELL_MEASURE: + switch(measure_p.run_subframe_sync(&ue_sync, sf_idx)) { case measure::MEASURE_OK: + + // Calibrate measure object since worker not yet calibrated + if (worker_com->args->rssi_sensor_enabled) { + measure_p.set_rx_gain_offset(measure_p.rssi() - radio_h->get_rssi() + 30); + } else { + measure_p.set_rx_gain_offset(worker_com->args->rx_gain_offset + radio_h->get_rx_gain()); + } + log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; cell_search_in_progress = false; @@ -1095,11 +1104,10 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c /********* * Measurement class */ -void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, srslte::radio *radio_h, uint32_t nof_rx_antennas, uint32_t nof_subframes) +void phch_recv::measure::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, uint32_t nof_rx_antennas, uint32_t nof_subframes) { - this->radio_h = radio_h; - this->log_h = log_h; + this->log_h = log_h; this->nof_subframes = nof_subframes; for (int i=0;ibuffer[i] = buffer[i]; @@ -1132,17 +1140,21 @@ void phch_recv::measure::set_cell(srslte_cell_t cell) } reset(); } - + +float phch_recv::measure::rssi() { + return 10*log10(mean_rssi); +} + float phch_recv::measure::rsrp() { - return mean_rsrp; + return 10*log10(mean_rsrp) + 30 - rx_gain_offset; } float phch_recv::measure::rsrq() { - return mean_rsrq; + return 10*log10(mean_rsrq); } float phch_recv::measure::snr() { - return mean_snr; + return 10*log10(mean_snr); } uint32_t phch_recv::measure::frame_st_idx() { @@ -1243,10 +1255,10 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) return ERROR; } - float rsrp = 10*log10(srslte_chest_dl_get_rsrp(&ue_dl.chest)) + 30 - rx_gain_offset; - float rsrq = 10*log10(srslte_chest_dl_get_rsrq(&ue_dl.chest)); - float snr = 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)); - float rssi = 10*log10(srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb))) + 30; + float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); + float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); + float snr = srslte_chest_dl_get_snr(&ue_dl.chest); + float rssi = srslte_vec_avg_power_cf(buffer[0], SRSLTE_SF_LEN_PRB(current_prb)); if (cnt == 0) { mean_rsrp = rsrp; @@ -1265,17 +1277,6 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) cnt, nof_subframes, sf_idx, rsrp, snr); if (cnt >= nof_subframes) { - - // Calibrate RSRP if no gain offset measurements - if (fabsf(rx_gain_offset) < 1.0 && radio_h) { - float temporal_offset = 0; - if (radio_h->has_rssi()) { - temporal_offset = mean_rssi - radio_h->get_rssi() + 30; - } else { - temporal_offset = radio_h->get_rx_gain(); - } - mean_rsrp -= temporal_offset; - } return MEASURE_OK; } else { return IDLE; @@ -1304,7 +1305,7 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled, uint3 sf_buffer[0] = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*max_sf_size); input_cfo_corrected = (cf_t*) srslte_vec_malloc(sizeof(cf_t)*15*max_sf_size); - measure_p.init(sf_buffer, log_h, NULL, 1, max_sf_window); + measure_p.init(sf_buffer, log_h, 1, max_sf_window); //do this different we don't need all this search window. if(srslte_sync_init(&sync_find, max_sf_window*max_sf_size, 5*max_sf_size, max_fft_sz)) { @@ -1609,6 +1610,7 @@ void phch_recv::intra_measure::run_thread() } if (running) { + // Read data from buffer and find cells in it srslte_ringbuffer_read(&ring_buffer, search_buffer, INTRA_FREQ_MEAS_LEN_MS*current_sflen*sizeof(cf_t)); int found_cells = scell.find_cells(search_buffer, common->rx_gain_offset, primary_cell, INTRA_FREQ_MEAS_LEN_MS, info); From bf80a0a21ba363eb207e27f0b25ad899d9e1b758 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 26 Feb 2018 16:42:52 +0100 Subject: [PATCH 11/52] Udated enb.config.example for TM1-4 --- srsenb/enb.conf.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 1fafbdc00..9b62d80ca 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -13,6 +13,8 @@ # mme_addr: IP address of MME for S1 connnection # gtp_bind_addr: Local IP address to bind for GTP connection # n_prb: Number of Physical Resource Blocks (6,15,25,50,75,100) +# tm: Transmission mode 1-4 (TM1 default) +# nof_ports: Number of Tx ports (1 port default, set to 2 for TM2/3/4) # ##################################################################### [enb] @@ -25,6 +27,9 @@ mnc = 01 mme_addr = 127.0.1.100 gtp_bind_addr = 127.0.0.1 n_prb = 50 +#tm = 4 +#nof_ports = 2 + ##################################################################### # eNB configuration files From fafed4a4a00f4ab5ac5162bb1f612fd7716f1065 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 28 Feb 2018 17:58:47 +0000 Subject: [PATCH 12/52] small fix in mbsfn ofdm --- lib/src/phy/dft/ofdm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/dft/ofdm.c b/lib/src/phy/dft/ofdm.c index e266023bb..977f37892 100644 --- a/lib/src/phy/dft/ofdm.c +++ b/lib/src/phy/dft/ofdm.c @@ -128,6 +128,8 @@ int srslte_ofdm_init_mbsfn_(srslte_ofdm_t *q, srslte_cp_t cp, cf_t *in_buffer, c if (sf_type == SRSLTE_SF_MBSFN) { q->mbsfn_subframe = true; q->non_mbsfn_region = 2; // default set to 2 + } else { + q->mbsfn_subframe = false; } return SRSLTE_SUCCESS; From a92a5d65f8ac38edd52fb1b2deafb2a86ea86c05 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 1 Mar 2018 12:30:47 +0100 Subject: [PATCH 13/52] Try to fix tx_end issue during HO --- srsue/src/phy/phch_recv.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 6737f52e0..46973b125 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -397,16 +397,11 @@ bool phch_recv::cell_handover(srslte_cell_t cell) usleep(1000); cnt++; } - cnt = 0; - while(!is_in_idle_rx && cnt<20) { - usleep(1000); - cnt++; - } for(uint32_t i=0;iget_nof_workers();i++) { ((phch_worker*) workers_pool->get_worker(i))->reset(); } worker_com->reset(); - worker_com->reset_ul(); + radio_h->tx_end(); if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { From fb53a515daac1f9d369e71a4ae8a9c0d393aa42a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 1 Mar 2018 12:48:14 +0100 Subject: [PATCH 14/52] Disable tx_end during HO --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 46973b125..68d7d6c3c 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -401,7 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell) ((phch_worker*) workers_pool->get_worker(i))->reset(); } worker_com->reset(); - radio_h->tx_end(); + //radio_h->tx_end(); if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { From 0fcb065ae8f50ae6ec23c823a4c2db8daa36d42a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 14:08:29 +0100 Subject: [PATCH 15/52] Disabled TX continuous and sleep on cell search --- srsue/hdr/mac/dl_harq.h | 13 +++++++------ srsue/hdr/phy/phch_common.h | 2 +- srsue/src/phy/phch_recv.cc | 1 + srsue/src/upper/nas.cc | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 9a7f66f47..261fb0d41 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -253,14 +253,14 @@ private: n_retx = 0; } - // Save grant - grant.last_ndi[tid] = cur_grant.ndi[tid]; - grant.last_tti = cur_grant.tti; - memcpy(&cur_grant, &grant, sizeof(Tgrant)); - // If data has not yet been successfully decoded if (!ack) { + // Save grant + grant.last_ndi[tid] = cur_grant.ndi[tid]; + grant.last_tti = cur_grant.tti; + memcpy(&cur_grant, &grant, sizeof(Tgrant)); + // Instruct the PHY To combine the received data and attempt to decode it if (pid == HARQ_BCCH_PID) { payload_buffer_ptr = harq_entity->demux_unit->request_buffer_bcch(cur_grant.n_bytes[tid]); @@ -281,7 +281,8 @@ private: } else { action->default_ack[tid] = true; - Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); + Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK (grant_tti=%d, ndi=%d, sz=%d)\n", + pid, cur_grant.tti, cur_grant.ndi[tid], cur_grant.n_bytes[tid]); } if (pid == HARQ_BCCH_PID || harq_entity->timer_aligment_timer->is_expired()) { diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index f21738b6b..e6ce10bc3 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -27,7 +27,7 @@ #ifndef UEPHYWORKERCOMMON_H #define UEPHYWORKERCOMMON_H -#define TX_MODE_CONTINUOUS 1 +#define TX_MODE_CONTINUOUS 0 #include diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 68d7d6c3c..7bb371db4 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -935,6 +935,7 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) if (ret < 0) { Error("SYNC: Error decoding MIB: Error searching PSS\n"); + p->stop_rx(); return ERROR; } else if (ret == 0) { p->stop_rx(); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 7f5683867..07d254cdc 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -173,6 +173,7 @@ void nas::plmn_search_end() { } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { + sleep(1); rrc->plmn_search(); } } From de747f4e1c7ed50bdde2a0dd57e9c6ba15bf21f5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 16:49:52 +0100 Subject: [PATCH 16/52] MUX retx Msg3 correctly --- srsue/hdr/mac/mux.h | 3 ++- srsue/src/mac/mux.cc | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/srsue/hdr/mac/mux.h b/srsue/hdr/mac/mux.h index 889dd68f3..17a854711 100644 --- a/srsue/hdr/mac/mux.h +++ b/srsue/hdr/mac/mux.h @@ -104,7 +104,8 @@ private: /* Msg3 Buffer */ static const uint32_t MSG3_BUFF_SZ = 1024; uint8_t msg3_buff[MSG3_BUFF_SZ]; - + uint8_t *msg3_buff_start_pdu; + /* PDU Buffer */ srslte::sch_pdu pdu_msg; bool msg3_has_been_transmitted; diff --git a/srsue/src/mac/mux.cc b/srsue/src/mac/mux.cc index 2f8ade2af..59b94f085 100644 --- a/srsue/src/mac/mux.cc +++ b/srsue/src/mac/mux.cc @@ -46,8 +46,9 @@ mux::mux(uint8_t nof_harq_proc_) : pdu_msg(MAX_NOF_SUBHEADERS), pid_has_bsr(nof_ log_h = NULL; rlc = NULL; bsr_procedure = NULL; - phr_procedure = NULL; - + phr_procedure = NULL; + msg3_buff_start_pdu = NULL; + msg3_flush(); } @@ -347,6 +348,7 @@ void mux::msg3_flush() msg3_has_been_transmitted = false; msg3_pending = false; bzero(msg3_buff, sizeof(MSG3_BUFF_SZ)); + msg3_buff_start_pdu = NULL; } bool mux::msg3_is_transmitted() @@ -366,19 +368,22 @@ bool mux::msg3_is_pending() { uint8_t* mux::msg3_get(uint8_t *payload, uint32_t pdu_sz) { if (pdu_sz < MSG3_BUFF_SZ - 32) { - uint8_t* msg3_buff_start_pdu = pdu_get(msg3_buff, pdu_sz, 0, 0); if (!msg3_buff_start_pdu) { - Error("Moving PDU from Mux unit to Msg3 buffer\n"); - return NULL; + msg3_buff_start_pdu = pdu_get(msg3_buff, pdu_sz, 0, 0); + if (!msg3_buff_start_pdu) { + Error("Moving PDU from Mux unit to Msg3 buffer\n"); + return NULL; + } + msg3_has_been_transmitted = true; + msg3_pending = false; } - memcpy(payload, msg3_buff_start_pdu, sizeof(uint8_t)*pdu_sz); - msg3_has_been_transmitted = true; - msg3_pending = false; - return payload; } else { Error("Msg3 size (%d) is longer than internal msg3_buff size=%d, (see mux.h)\n", pdu_sz, MSG3_BUFF_SZ-32); return NULL; } + memcpy(payload, msg3_buff_start_pdu, sizeof(uint8_t)*pdu_sz); + msg3_has_been_transmitted = true; + return payload; } From fd0c8168f0ea7bda062eab1ecfa3e27d740834eb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 20:59:17 +0100 Subject: [PATCH 17/52] Set to Continuous RX and TX --- lib/include/srslte/radio/radio.h | 11 ++- lib/src/phy/rf/rf_uhd_imp.c | 5 +- lib/src/radio/radio.cc | 21 ++--- lib/src/radio/radio_multi.cc | 7 +- srsenb/src/phy/txrx.cc | 4 +- srsue/hdr/phy/phch_common.h | 2 +- srsue/hdr/phy/phch_recv.h | 11 +-- srsue/hdr/upper/rrc.h | 2 +- srsue/src/phy/phch_recv.cc | 153 ++++++------------------------- srsue/src/phy/phch_worker.cc | 2 +- srsue/src/phy/phy.cc | 1 - srsue/src/upper/nas.cc | 1 - 12 files changed, 61 insertions(+), 159 deletions(-) diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 454f1578f..143927730 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -72,6 +72,8 @@ namespace srslte { trace_enabled = false; tti = 0; agc_enabled = false; + radio_is_streaming = false; + is_initialized = false; }; bool init(char *args = NULL, char *devname = NULL, uint32_t nof_channels = 1); @@ -119,13 +121,13 @@ namespace srslte { void start_trace(); void write_trace(std::string filename); - void start_rx(bool now = false); - void stop_rx(); - + void set_tti(uint32_t tti); bool is_first_of_burst(); + bool is_init(); + void register_error_handler(srslte_rf_error_handler_t h); protected: @@ -168,6 +170,9 @@ namespace srslte { uint32_t tti; bool agc_enabled; + bool is_initialized = true;; + bool radio_is_streaming; + uint32_t saved_nof_channels; char saved_args[128]; char saved_devname[128]; diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 0fc70c547..07eacbfb7 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -557,11 +557,12 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) uhd_meta_range_free(&gain_range); // Start low priority thread to receive async commands - handler->async_thread_running = true; + /* + handler->async_thread_running = true; if (pthread_create(&handler->async_thread, NULL, async_thread, handler)) { perror("pthread_create"); return -1; - } + }*/ /* Restore priorities */ uhd_set_thread_priority(0, false); diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index f3baad4a5..aa7fa0d2c 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -71,7 +71,12 @@ bool radio::init(char *args, char *devname, uint32_t nof_channels) } saved_nof_channels = nof_channels; - return true; + is_initialized = true; + return true; +} + +bool radio::is_init() { + return is_initialized; } void radio::stop() @@ -141,6 +146,10 @@ bool radio::rx_at(void* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time bool radio::rx_now(void* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t* rxd_time) { + if (!radio_is_streaming) { + srslte_rf_start_rx_stream(&rf_device, true); + radio_is_streaming = true; + } if (srslte_rf_recv_with_time_multi(&rf_device, buffer, nof_samples, true, rxd_time?&rxd_time->full_secs:NULL, rxd_time?&rxd_time->frac_secs:NULL) > 0) { return true; @@ -446,16 +455,6 @@ void radio::set_tx_srate(double srate) tx_adv_sec = nsamples/cur_tx_srate; } -void radio::start_rx(bool now) -{ - srslte_rf_start_rx_stream(&rf_device, now); -} - -void radio::stop_rx() -{ - srslte_rf_stop_rx_stream(&rf_device); -} - void radio::register_error_handler(srslte_rf_error_handler_t h) { srslte_rf_register_error_handler(&rf_device, h); diff --git a/lib/src/radio/radio_multi.cc b/lib/src/radio/radio_multi.cc index 664458c75..df2cb4dfc 100644 --- a/lib/src/radio/radio_multi.cc +++ b/lib/src/radio/radio_multi.cc @@ -37,6 +37,7 @@ bool radio_multi::init_multi(uint32_t nof_rx_antennas, char* args, char* devname strncpy(saved_devname, devname, 127); } + is_initialized = true; return true; } @@ -46,7 +47,11 @@ bool radio_multi::rx_now(cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, s for (int i=0;ifull_secs:NULL, rxd_time?&rxd_time->frac_secs:NULL) > 0) { return true; } else { diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index 7e97bd1af..fbc96ea72 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -104,9 +104,7 @@ void txrx::run_thread() log_h->info("Starting RX/TX thread nof_prb=%d, sf_len=%d\n",worker_com->cell.nof_prb, sf_len); - // Start streaming RX samples - radio_h->start_rx(); - + // Set TTI so that first TX is at tti=0 tti = 10235; diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index e6ce10bc3..f21738b6b 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -27,7 +27,7 @@ #ifndef UEPHYWORKERCOMMON_H #define UEPHYWORKERCOMMON_H -#define TX_MODE_CONTINUOUS 0 +#define TX_MODE_CONTINUOUS 1 #include diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 1e15aea62..cea3004f6 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -95,7 +95,6 @@ private: void reset(); void radio_error(); - bool wait_radio_reset(); void set_ue_sync_opts(srslte_ue_sync_t *q, float cfo); void run_thread(); @@ -104,14 +103,7 @@ private: bool set_cell(); void cell_search_inc(); - void resync_sfn(bool restart_radio, bool restart_now = false); - bool stop_sync(); - void stop_rx(); - void start_rx(bool now = false); - bool radio_is_rx; - - bool radio_is_resetting; bool running; // Class to run cell search @@ -309,10 +301,9 @@ private: CELL_SELECT, CELL_MEASURE, CELL_CAMP, - IDLE_RX } phy_state; - bool is_in_idle, is_in_idle_rx; + bool is_in_idle; // Sampling rate mode (find is 1.96 MHz, camp is the full cell BW) enum { diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 1bfae16b3..926e2bebe 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -325,7 +325,7 @@ private: static const uint32_t RRC_PLMN_SELECT_TIMEOUT = 10000; uint32_t select_cell_timeout; - static const uint32_t RRC_SELECT_CELL_TIMEOUT = 2000; + static const uint32_t RRC_SELECT_CELL_TIMEOUT = 1000; uint8_t k_rrc_enc[32]; uint8_t k_rrc_int[32]; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7bb371db4..36614a0d1 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -134,7 +134,6 @@ void phch_recv::reset() srate_mode = SRATE_NONE; cell_search_in_progress = false; current_earfcn = 0; - radio_is_resetting = false; sfn_p.reset(); measure_p.reset(); search_p.reset(); @@ -145,7 +144,6 @@ void phch_recv::radio_error() { log_h->error("SYNC: Receiving from radio.\n"); phy_state = IDLE; - radio_is_resetting=true; // Need to find a method to effectively reset radio, reloading the driver does not work //radio_h->reset(); @@ -155,22 +153,12 @@ void phch_recv::radio_error() exit(-1); reset(); - radio_is_resetting=false; } void phch_recv::set_cfo(float cfo) { srslte_ue_sync_set_cfo_ref(&ue_sync, cfo); } -bool phch_recv::wait_radio_reset() { - int cnt=0; - while(cnt < 20 && radio_is_resetting) { - sleep(1); - cnt++; - } - return radio_is_resetting; -} - void phch_recv::set_agc_enable(bool enable) { do_agc = enable; @@ -265,24 +253,6 @@ bool phch_recv::set_cell() { return cell_is_set; } -void phch_recv::resync_sfn(bool restart_radio, bool restart_now) { - - if (restart_radio) { - wait_radio_reset(); - stop_rx(); - usleep(100000); - } - sfn_p.reset(); - search_p.reset(); - srslte_ue_sync_reset(&ue_sync); - - if (restart_radio) { - start_rx(restart_now); - } - - phy_state = CELL_SELECT; -} - void phch_recv::set_earfcn(std::vector earfcn) { this->earfcn = earfcn; } @@ -292,35 +262,14 @@ void phch_recv::force_freq(float dl_freq, float ul_freq) { this->ul_freq = ul_freq; } -bool phch_recv::stop_sync() { - - wait_radio_reset(); - - if (phy_state == IDLE && is_in_idle) { - return true; - } else { - Info("SYNC: Going to IDLE (state=%d)\n", phy_state); - phy_state = IDLE; - int cnt = 0; - while (!is_in_idle && cnt < 100) { - usleep(10000); - cnt++; - } - if (!is_in_idle) { - Warning("SYNC: Could not go to IDLE (state=%d)\n", phy_state); - } - return is_in_idle; - } -} - void phch_recv::reset_sync() { - if (phy_state != CELL_SELECT) { - Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); - resync_sfn(false); - } else { - Warning("SYNC: Trying to reset sync while in cell reselection\n"); - } + sfn_p.reset(); + search_p.reset(); + measure_p.reset(); + srslte_ue_sync_reset(&ue_sync); + + phy_state = CELL_SELECT; } void phch_recv::cell_search_inc() @@ -345,9 +294,6 @@ void phch_recv::cell_search_inc() void phch_recv::cell_search_next(bool reset) { if (cell_search_in_progress || reset) { cell_search_in_progress = false; - if (!stop_sync()) { - log_h->warning("SYNC: Couldn't stop PHY (state=%d)\n", phy_state); - } if (reset) { cur_earfcn_index = -1; } @@ -373,9 +319,6 @@ void phch_recv::cell_search_start() { void phch_recv::cell_search_stop() { Info("SYNC: Stopping Cell Search procedure...\n"); - if (!stop_sync()) { - Error("SYNC: Stopping cell search\n"); - } cell_search_in_progress = false; } @@ -391,9 +334,9 @@ bool phch_recv::cell_handover(srslte_cell_t cell) bool ret = false; this->cell = cell; Info("Cell HO: Stopping sync with current cell\n"); - phy_state = IDLE_RX; + phy_state = IDLE; cnt = 0; - while(!is_in_idle_rx && cnt<20) { + while(!is_in_idle && cnt<20) { usleep(1000); cnt++; } @@ -401,12 +344,11 @@ bool phch_recv::cell_handover(srslte_cell_t cell) ((phch_worker*) workers_pool->get_worker(i))->reset(); } worker_com->reset(); - //radio_h->tx_end(); - if (is_in_idle_rx) { + if (is_in_idle) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { - resync_sfn(false); Info("Cell HO: Synchronizing with new cell\n"); + phy_state = CELL_SELECT; ret = true; } else { log_h->error("Cell HO: Configuring cell PCI=%d\n", cell.id); @@ -428,18 +370,12 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (srate_mode != SRATE_CAMP) { set_sampling_rate(); } - if (phy_state < CELL_SELECT) { - resync_sfn(true, false); - } + phy_state = CELL_SELECT; return true; } else { cell_search_in_progress = false; - if (!stop_sync()) { - log_h->warning("Still not in idle\n"); - } - if (earfcn != current_earfcn) { if (set_frequency()) { log_h->error("Cell Select: Configuring cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); @@ -453,8 +389,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - - resync_sfn(true, false); + phy_state = CELL_SELECT; return true; } return false; @@ -522,22 +457,6 @@ void phch_recv::set_sampling_rate() } } -void phch_recv::stop_rx() { - if (radio_is_rx) { - Info("SYNC: Stopping RX streaming\n"); - radio_h->stop_rx(); - } - radio_is_rx = false; -} - -void phch_recv::start_rx(bool now) { - if (!radio_is_rx) { - Info("SYNC: Starting RX streaming\n"); - radio_h->start_rx(now); - } - radio_is_rx = true; -} - uint32_t phch_recv::get_current_tti() { return tti; } @@ -592,18 +511,19 @@ void phch_recv::run_thread() uint32_t sf_idx = 0; phy_state = IDLE; is_in_idle = true; - is_in_idle_rx = false; + + cf_t *dummy_buffer[SRSLTE_MAX_PORTS]; + + for (int i=0;istep(tti); log_phy_lib_h->step(tti); @@ -624,7 +544,7 @@ void phch_recv::run_thread() } if (set_cell()) { set_sampling_rate(); - resync_sfn(true, false); + phy_state = CELL_SELECT; } break; case search::CELL_NOT_FOUND: @@ -659,7 +579,7 @@ void phch_recv::run_thread() phy_state = CELL_SEARCH; } else { log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - resync_sfn(false); + phy_state = CELL_SELECT; } break; case sfn_sync::IDLE: @@ -775,28 +695,18 @@ void phch_recv::run_thread() } break; case IDLE: - if (!is_in_idle) { - stop_rx(); - } - is_in_idle = true; - usleep(1000); - break; - case IDLE_RX: - if (!worker) { - worker = (phch_worker *) workers_pool->wait_worker(tti); - } - is_in_idle_rx = true; - if (worker) { - for (uint32_t i = 0; i < SRSLTE_MAX_PORTS; i++) { - buffer[i] = worker->get_buffer(i); + if (radio_h->is_init()) { + uint32_t nsamples = 1920; + if (current_srate > 0) { + nsamples = current_srate/1000; } - if (!radio_h->rx_now(buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), NULL)) { - Error("SYNC: Receiving from radio while in IDLE_RX\n"); + if (!radio_h->rx_now(dummy_buffer, nsamples, NULL)) { + printf("SYNC: Receiving from radio while in IDLE_RX\n"); } } else { - // wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here - running = false; + usleep(1000); } + is_in_idle = true; break; } @@ -917,7 +827,6 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) p->srate_mode = SRATE_FIND; p->radio_h->set_rx_srate(1.92e6); } - p->start_rx(); /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ uint32_t max_peak_cell = 0; @@ -935,10 +844,8 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) if (ret < 0) { Error("SYNC: Error decoding MIB: Error searching PSS\n"); - p->stop_rx(); return ERROR; } else if (ret == 0) { - p->stop_rx(); Info("SYNC: Could not find any cell in this frequency\n"); return CELL_NOT_FOUND; } @@ -966,8 +873,6 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) ret = srslte_ue_mib_sync_decode(&ue_mib_sync, 40, bch_payload, &cell->nof_ports, &sfn_offset); - p->stop_rx(); - if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, cell, NULL); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 6a533759b..cdfab95b9 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -1380,7 +1380,7 @@ void phch_worker::update_measurements() /* Only worker 0 reads the RSSI sensor every ~1-nof_cores s */ if (get_id() == 0) { - if (rssi_read_cnt) { + if (!rssi_read_cnt) { if (phy->get_radio()->has_rssi() && phy->args->rssi_sensor_enabled) { phy->last_radio_rssi = phy->get_radio()->get_rssi(); phy->rx_gain_offset = phy->avg_rssi_dbm - phy->last_radio_rssi + 30; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index cf8ae33f8..3dfb5889a 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -366,7 +366,6 @@ void phy::reset() workers[i].reset(); } workers_common.reset(); - workers_common.reset_ul(); } uint32_t phy::get_current_tti() diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 07d254cdc..7f5683867 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -173,7 +173,6 @@ void nas::plmn_search_end() { } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) { - sleep(1); rrc->plmn_search(); } } From e64f3240cb83a9eec768fe78dbaadcaf3bc13a29 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 21:33:28 +0100 Subject: [PATCH 18/52] Disable tx_end before PRACH (not needed now?) --- srsue/src/phy/phch_recv.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 36614a0d1..3c2e4fc1e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -657,10 +657,11 @@ void phch_recv::run_thread() tx_mutex_cnt = (tx_mutex_cnt+1) % nof_tx_mutex; // Reset Uplink TX buffer to avoid mixing packets in TX queue + /* if (prach_buffer->is_pending()) { Info("SYNC: PRACH pending: Reset UL\n"); - worker_com->reset_ul(); - } + radio_h->tx_end(); + }*/ // Check if we need to TX a PRACH if (prach_buffer->is_ready_to_send(tti)) { From df1a0c68e2ed2d37a6d82008545bccd5b8152e62 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 2 Mar 2018 22:46:24 +0100 Subject: [PATCH 19/52] Disable ul_reset --- srsue/src/phy/phch_common.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_common.cc b/srsue/src/phy/phch_common.cc index 65681c8c6..3c3cf1641 100644 --- a/srsue/src/phy/phch_common.cc +++ b/srsue/src/phy/phch_common.cc @@ -355,13 +355,16 @@ void phch_common::reset() { void phch_common::reset_ul() { + /* is_first_tx = true; - is_first_of_burst = true; + is_first_of_burst = true; + for (uint32_t i=0;itx_end(); + */ } } From fea5c3462c17008512227a846ed923c19a75155c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 11:15:51 +0100 Subject: [PATCH 20/52] Start RX with delay --- lib/src/radio/radio.cc | 2 +- lib/src/radio/radio_multi.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index aa7fa0d2c..ba2b1d1f0 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -147,7 +147,7 @@ bool radio::rx_at(void* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time bool radio::rx_now(void* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t* rxd_time) { if (!radio_is_streaming) { - srslte_rf_start_rx_stream(&rf_device, true); + srslte_rf_start_rx_stream(&rf_device, false); radio_is_streaming = true; } if (srslte_rf_recv_with_time_multi(&rf_device, buffer, nof_samples, true, diff --git a/lib/src/radio/radio_multi.cc b/lib/src/radio/radio_multi.cc index df2cb4dfc..ff0a036a2 100644 --- a/lib/src/radio/radio_multi.cc +++ b/lib/src/radio/radio_multi.cc @@ -48,7 +48,7 @@ bool radio_multi::rx_now(cf_t *buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, s ptr[i] = buffer[i]; } if (!radio_is_streaming) { - srslte_rf_start_rx_stream(&rf_device, true); + srslte_rf_start_rx_stream(&rf_device, false); radio_is_streaming = true; } if (srslte_rf_recv_with_time_multi(&rf_device, ptr, nof_samples, true, From 650f43353267982d3c7d9f4724b51e2c950c9443 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 11:55:31 +0100 Subject: [PATCH 21/52] Add mutex to worker_imp/set_cell worker --- srsue/hdr/phy/phch_worker.h | 3 ++- srsue/src/phy/phch_worker.cc | 27 +++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 78389ccf7..167334918 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -119,7 +119,8 @@ private: struct timeval tr_time[3]; srslte::trace tr_exec; bool trace_enabled; - + + pthread_mutex_t mutex; /* Common objects */ phch_common *phy; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index cdfab95b9..f8b9e8148 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -86,6 +86,7 @@ phch_worker::~phch_worker() void phch_worker::reset() { + pthread_mutex_lock(&mutex); bzero(&dl_metrics, sizeof(dl_metrics_t)); bzero(&ul_metrics, sizeof(ul_metrics_t)); bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); @@ -101,6 +102,7 @@ void phch_worker::reset() I_sr = 0; cfi = 0; rssi_read_cnt = 0; + pthread_mutex_unlock(&mutex); } void phch_worker::set_common(phch_common* phy_) @@ -140,29 +142,35 @@ bool phch_worker::init(uint32_t max_prb, srslte::log *log_h, srslte::log *log_ph mem_initiated = true; + pthread_mutex_init(&mutex, NULL); return true; } bool phch_worker::set_cell(srslte_cell_t cell_) { + bool ret = false; + pthread_mutex_lock(&mutex); if (cell.id != cell_.id || !cell_initiated) { memcpy(&cell, &cell_, sizeof(srslte_cell_t)); if (srslte_ue_dl_set_cell(&ue_dl, cell)) { Error("Initiating UE DL\n"); - return false; + goto unlock; } if (srslte_ue_ul_set_cell(&ue_ul, cell)) { Error("Initiating UE UL\n"); - return false; + goto unlock; } srslte_ue_ul_set_normalization(&ue_ul, true); srslte_ue_ul_set_cfo_enable(&ue_ul, true); cell_initiated = true; } - return true; + ret = true; +unlock: + pthread_mutex_unlock(&mutex); + return ret; } cf_t* phch_worker::get_buffer(uint32_t antenna_idx) @@ -193,9 +201,11 @@ void phch_worker::set_sample_offset(float sample_offset) void phch_worker::set_crnti(uint16_t rnti) { + pthread_mutex_lock(&mutex); srslte_ue_dl_set_rnti(&ue_dl, rnti); srslte_ue_ul_set_rnti(&ue_ul, rnti); - rnti_is_set = true; + rnti_is_set = true; + pthread_mutex_unlock(&mutex); } float phch_worker::get_ref_cfo() @@ -243,7 +253,9 @@ void phch_worker::work_imp() if (!cell_initiated) { return; } - + + pthread_mutex_lock(&mutex); + Debug("TTI %d running\n", tti); #ifdef LOG_EXECTIME @@ -412,7 +424,9 @@ void phch_worker::work_imp() chest_loop->out_of_sync(); } } - + + pthread_mutex_unlock(&mutex); + /* Tell the plotting thread to draw the plots */ #ifdef ENABLE_GUI if ((int) get_id() == plot_worker_id) { @@ -1211,6 +1225,7 @@ void phch_worker::enable_pregen_signals(bool enabled) void phch_worker::set_ul_params(bool pregen_disabled) { + phy_interface_rrc::phy_cfg_common_t *common = &phy->config->common; LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated = &phy->config->dedicated; From 91664ef2beef186ef2717b0003da3afe9de839b0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 11:55:58 +0100 Subject: [PATCH 22/52] Do sell reselection on IDLE by phch_recv thread instead of worker --- lib/include/srslte/interfaces/ue_interfaces.h | 2 +- srsue/hdr/phy/phch_recv.h | 7 +++++- srsue/hdr/phy/phy.h | 2 +- srsue/src/phy/phch_recv.cc | 24 ++++++++++++++----- srsue/src/phy/phy.cc | 4 ++-- srsue/src/upper/rrc.cc | 22 +++++++---------- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index f18a6737b..52d11416c 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -582,7 +582,7 @@ public: virtual void cell_search_start() = 0; virtual void cell_search_stop() = 0; virtual void cell_search_next() = 0; - virtual bool cell_select(uint32_t earfcn, srslte_cell_t cell) = 0; + virtual void cell_select(uint32_t earfcn, srslte_cell_t cell) = 0; virtual bool cell_handover(srslte_cell_t cell) = 0; /* Is the PHY downlink synchronized? */ diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index cea3004f6..b5848a6b3 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -63,7 +63,7 @@ public: void cell_search_start(); void cell_search_stop(); void cell_search_next(bool reset = false); - bool cell_select(uint32_t earfcn, srslte_cell_t cell); + void cell_select(uint32_t earfcn, srslte_cell_t cell); bool cell_handover(srslte_cell_t cell); void meas_reset(); @@ -103,6 +103,10 @@ private: bool set_cell(); void cell_search_inc(); + void cell_reselect(); + + uint32_t new_earfcn; + srslte_cell_t new_cell; bool running; @@ -299,6 +303,7 @@ private: IDLE = 0, CELL_SEARCH, CELL_SELECT, + CELL_RESELECT, CELL_MEASURE, CELL_CAMP, } phy_state; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index a29480ad4..9270973c0 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -87,7 +87,7 @@ public: void cell_search_start(); void cell_search_stop(); void cell_search_next(); - bool cell_select(uint32_t earfcn, srslte_cell_t phy_cell); + void cell_select(uint32_t earfcn, srslte_cell_t phy_cell); bool cell_handover(srslte_cell_t cell); void meas_reset(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 3c2e4fc1e..7a3efeab7 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -361,9 +361,21 @@ bool phch_recv::cell_handover(srslte_cell_t cell) return ret; } -bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { +/* interface from higher layers to select a new cell */ +void phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { - // Check if we are already camping in this cell + new_earfcn = earfcn; + new_cell = cell; + phy_state = CELL_RESELECT; +} + +/* Perform cell (re)-selection on IDLE or CAMP */ +void phch_recv::cell_reselect() +{ + uint32_t earfcn = new_earfcn; + srslte_cell_t cell = new_cell; + + // If we are already in the new cell, just resynchronize if (earfcn == current_earfcn && this->cell.id == cell.id) { log_h->info("Cell Select: Already in cell EARFCN=%d\n", earfcn); cell_search_in_progress = false; @@ -371,15 +383,14 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { set_sampling_rate(); } phy_state = CELL_SELECT; - return true; } else { + /* If we are going to a new cell, configure it */ cell_search_in_progress = false; if (earfcn != current_earfcn) { if (set_frequency()) { log_h->error("Cell Select: Configuring cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); - return false; } current_earfcn = earfcn; } @@ -390,9 +401,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); phy_state = CELL_SELECT; - return true; } - return false; } } @@ -559,6 +568,9 @@ void phch_recv::run_thread() } } break; + case CELL_RESELECT: + cell_reselect(); + break; case CELL_SELECT: switch (sfn_p.run_subframe(&cell, &tti)) { diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 3dfb5889a..a2d517a02 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -282,9 +282,9 @@ int phy::meas_stop(uint32_t earfcn, int pci) { return sf_recv.meas_stop(earfcn, pci); } -bool phy::cell_select(uint32_t earfcn, srslte_cell_t phy_cell) +void phy::cell_select(uint32_t earfcn, srslte_cell_t phy_cell) { - return sf_recv.cell_select(earfcn, phy_cell); + sf_recv.cell_select(earfcn, phy_cell); } bool phy::cell_handover(srslte_cell_t cell) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index dfb356b92..1aecb273b 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -525,20 +525,14 @@ void rrc::select_next_cell_in_plmn() { neighbour_cells[i]->in_sync) // matches S criteria { // Try to select Cell - if (phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell)) { - set_serving_cell(i); - rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - } else { - // Set to out-of-sync if can't synchronize - neighbour_cells[i]->in_sync = false; - rrc_log->warning("Selecting cell EARFCN=%d, Cell ID=0x%x.\n", - neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->get_cell_id()); - } + phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); + set_serving_cell(i); + rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); + rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn(), + serving_cell->get_cell_id()); return; } } From ed52604d3001e0237eb6f2a0b89cd990c2f988c9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 21:51:14 +0100 Subject: [PATCH 23/52] Restart rx_stream on radio error --- lib/src/radio/radio.cc | 7 ++----- srsue/src/phy/phch_recv.cc | 12 +++--------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index ba2b1d1f0..7008790a3 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -87,11 +87,8 @@ void radio::stop() void radio::reset() { printf("Resetting Radio...\n"); - srslte_rf_close(&rf_device); - sleep(3); - if (srslte_rf_open_devname(&rf_device, saved_devname, saved_args, saved_nof_channels)) { - fprintf(stderr, "Error opening RF device\n"); - } + srslte_rf_stop_rx_stream(&rf_device); + radio_is_streaming = false; } void radio::set_manual_calibration(rf_cal_t* calibration) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7a3efeab7..a6f1a5d84 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -143,16 +143,10 @@ void phch_recv::reset() void phch_recv::radio_error() { log_h->error("SYNC: Receiving from radio.\n"); - phy_state = IDLE; - - // Need to find a method to effectively reset radio, reloading the driver does not work - //radio_h->reset(); - radio_h->stop(); - - fprintf(stdout, "Error while receiving samples. Restart srsUE\n"); - exit(-1); - + phy_state = CELL_SEARCH; reset(); + // Need to find a method to effectively reset radio, reloading the driver does not work + radio_h->reset(); } void phch_recv::set_cfo(float cfo) { From b257ab96bf8ba407ae322e61dd2c8be1c1dee193 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 4 Mar 2018 21:51:32 +0100 Subject: [PATCH 24/52] Locking on worker::reset() causes dead-lock --- srsue/src/phy/phch_worker.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index f8b9e8148..3075b0b30 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -86,7 +86,6 @@ phch_worker::~phch_worker() void phch_worker::reset() { - pthread_mutex_lock(&mutex); bzero(&dl_metrics, sizeof(dl_metrics_t)); bzero(&ul_metrics, sizeof(ul_metrics_t)); bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); @@ -102,7 +101,6 @@ void phch_worker::reset() I_sr = 0; cfi = 0; rssi_read_cnt = 0; - pthread_mutex_unlock(&mutex); } void phch_worker::set_common(phch_common* phy_) From 3dddae0566a6e8eefda35c71421196aa520bb732 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 12:18:29 +0100 Subject: [PATCH 25/52] rrc: check pool buffer allocation and handle error --- srsue/src/upper/rrc.cc | 43 +++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1aecb273b..cade0e306 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1529,10 +1529,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; } @@ -1540,20 +1543,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->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->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) @@ -1561,9 +1565,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) { From a85288566bb7786856a058db44f0b4bf6c3d90e9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 13:51:20 +0100 Subject: [PATCH 26/52] print summary about allocated buffers when buffer pool is full --- lib/include/srslte/common/buffer_pool.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index e48144b6f..4edc50fc6 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include /******************************************************************************* @@ -76,8 +78,13 @@ public: { printf("%d buffers in queue\n", (int) used.size()); #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + std::map buffer_cnt; for (uint32_t i=0;idebug_name)?used[i]->debug_name:"Undefined"); + buffer_cnt[strlen(used[i]->debug_name)?used[i]->debug_name:"Undefined"]++; + } + std::map::iterator it; + for (it = buffer_cnt.begin(); it != buffer_cnt.end(); it++) { + printf(" - %dx %s\n", it->second, it->first.c_str()); } #endif } From 507ce037bfa756e4c9843757fa104c7ee949ed4e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 14:07:27 +0100 Subject: [PATCH 27/52] parameterize RLC AM stress tester and add to ctest suite --- lib/test/upper/CMakeLists.txt | 3 +- lib/test/upper/rlc_am_stress_test.cc | 71 +++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/lib/test/upper/CMakeLists.txt b/lib/test/upper/CMakeLists.txt index 8793118e7..79bbb8331 100644 --- a/lib/test/upper/CMakeLists.txt +++ b/lib/test/upper/CMakeLists.txt @@ -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) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index 137236b4a..c5cf4e877 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -31,23 +31,66 @@ #include "srslte/common/logger_stdout.h" #include "srslte/common/threads.h" #include "srslte/upper/rlc.h" +#include +#include #include -#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; +} 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(&args->test_duration_sec)->default_value(10), "Duration (sec)") + ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)") + ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped"); + + // 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 sdu_gen_delay_usec_) { rlc1 = rlc1_; rlc2 = rlc2_; fail_rate = fail_rate_; run_enable = true; running = false; + sdu_gen_delay_usec = sdu_gen_delay_usec_; } void stop() @@ -82,7 +125,7 @@ private: if(((float)rand()/RAND_MAX > fail_rate) && read>0) { rlc2->write_pdu(1, pdu->msg, opp_size); } - usleep(100); + usleep(sdu_gen_delay_usec); } running = false; byte_buffer_pool::get_instance()->deallocate(pdu); @@ -91,6 +134,7 @@ private: rlc_interface_mac *rlc1; rlc_interface_mac *rlc2; float fail_rate; + uint32_t sdu_gen_delay_usec; bool run_enable; bool running; @@ -100,9 +144,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 sdu_gen_delay_usec_) + :r1(rlc1_, rlc2_, fail_rate_, sdu_gen_delay_usec_) + ,r2(rlc2_, rlc1_, fail_rate_, sdu_gen_delay_usec_) { } @@ -191,7 +235,7 @@ private: pdu->N_bytes = 1500; pdu->msg[0] = sn++; rlc->write_sdu(1, pdu); - usleep(100); + usleep(10); } running = false; } @@ -205,7 +249,7 @@ private: 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 +258,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); + mac_dummy mac(&rlc1, &rlc2, args.error_rate, args.sdu_gen_delay_usec); ue_interface ue; rlc1.init(&tester1, &tester1, &ue, &log1, &mac, 0); @@ -245,7 +287,7 @@ void stress_test() tester2.start(7); mac.start(); - usleep(100e6); + usleep(args.test_duration_sec * 1e6); tester1.stop(); tester2.stop(); @@ -254,6 +296,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(); } From 2c85da3e4ba41ec5d4f82532de8faf9e227a23e5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:18:38 +0100 Subject: [PATCH 28/52] initilize variable in log_filter --- lib/src/common/log_filter.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/common/log_filter.cc b/lib/src/common/log_filter.cc index b498d466c..8b72a3c2b 100644 --- a/lib/src/common/log_filter.cc +++ b/lib/src/common/log_filter.cc @@ -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) From f60a9eab415ac08bb8c5e2e8591d3207d1abe058 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:20:34 +0100 Subject: [PATCH 29/52] initialize RF UHD handler in init --- lib/src/phy/rf/rf_uhd_imp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 07eacbfb7..a1bec2657 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -334,11 +334,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); From 4a279150224c54cc5f76cd426613aef11a25cae0 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:21:58 +0100 Subject: [PATCH 30/52] bzero dft object during init, add call to fftw_cleanup in dft_exit --- lib/src/phy/dft/dft_fftw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index e6eb70ecf..ede6ce69b 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -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 { From 1efcea7e47f88e5fde2b06eec1ee81c3c6e347c8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:29:10 +0100 Subject: [PATCH 31/52] call dft_exit in various tests --- lib/src/phy/dft/test/ofdm_test.c | 3 +++ lib/src/phy/utils/test/dft_test.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/lib/src/phy/dft/test/ofdm_test.c b/lib/src/phy/dft/test/ofdm_test.c index e77fcd39e..c40be4d0a 100644 --- a/lib/src/phy/dft/test/ofdm_test.c +++ b/lib/src/phy/dft/test/ofdm_test.c @@ -171,5 +171,8 @@ int main(int argc, char **argv) { n_prb++; } + + srslte_dft_exit(); + exit(0); } diff --git a/lib/src/phy/utils/test/dft_test.c b/lib/src/phy/utils/test/dft_test.c index fd5a308a7..b880f8027 100644 --- a/lib/src/phy/utils/test/dft_test.c +++ b/lib/src/phy/utils/test/dft_test.c @@ -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); From 57bb831f27c4eb005039b991ef9e80758e67d08d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:32:21 +0100 Subject: [PATCH 32/52] fix RM turbo test --- lib/src/phy/fec/test/rm_turbo_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/phy/fec/test/rm_turbo_test.c b/lib/src/phy/fec/test/rm_turbo_test.c index 1c5b2abf5..c8a0a95b5 100644 --- a/lib/src/phy/fec/test/rm_turbo_test.c +++ b/lib/src/phy/fec/test/rm_turbo_test.c @@ -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); From 281611b26aabb1bffc2407e5b80d20206bc0c065 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 13:45:49 +0100 Subject: [PATCH 33/52] allow n param in pss_usrp test --- lib/src/phy/sync/test/pss_usrp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index d82555c95..08afdd025 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -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]; From f6ee0e1c8a49f53c0c27eacd902288ae14045349 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:47:14 +0100 Subject: [PATCH 34/52] move byte_buffer to UE base class --- srsue/hdr/ue.h | 2 -- srsue/hdr/ue_base.h | 5 ++++- srsue/src/ue.cc | 2 -- srsue/src/ue_base.cc | 6 ++++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index e36277461..e6c66b540 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -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; diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h index 256813d5f..201f63843 100644 --- a/srsue/hdr/ue_base.h +++ b/srsue/hdr/ue_base.h @@ -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 diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 2f8fa5794..1de1ddbd0 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -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_) diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc index 4b2c372ae..a4264a099 100644 --- a/srsue/src/ue_base.cc +++ b/srsue/src/ue_base.cc @@ -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) From 8fcf25360eab03c6c70ceca2e091b92c020473c6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:48:38 +0100 Subject: [PATCH 35/52] fix missing newline --- srsue/src/phy/phch_recv.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index a6f1a5d84..81c964a7b 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -954,7 +954,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; } From 20e6ed102e03880dc702ba25d79845a431896d9b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:50:22 +0100 Subject: [PATCH 36/52] fix when accessing uninitialized file --- lib/src/common/logger_file.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/common/logger_file.cc b/lib/src/common/logger_file.cc index 25155da08..a911ae20e 100644 --- a/lib/src/common/logger_file.cc +++ b/lib/src/common/logger_file.cc @@ -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); + } } } From 5cfffd11e102ef504cfa213d07316d5fd58242d9 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 21 Feb 2018 15:51:13 +0100 Subject: [PATCH 37/52] Revert "only reset SDU buffer in RLC AM/UM" This reverts commit 8d852ddfe5e4f6eedb80e247d62b8628f9643c2f. This commit was needed because the order in which objects where destructed on UE exit was such that the byte_buffer was deleted before RLC_AM dtor was called. --- lib/src/upper/rlc_am.cc | 8 ++++++++ lib/src/upper/rlc_um.cc | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index bc24f20bd..f4dced1ec 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -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_, diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 3fbcbaadf..a365a4501 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -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) { From 07c704b0ddb7b04da4b34f4defafc4bddb62ec33 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 22 Feb 2018 15:43:40 +0100 Subject: [PATCH 38/52] extend RLC AM stress tester to mimic reestablishment --- lib/test/upper/rlc_am_stress_test.cc | 44 ++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/test/upper/rlc_am_stress_test.cc b/lib/test/upper/rlc_am_stress_test.cc index c5cf4e877..bdee2248b 100644 --- a/lib/test/upper/rlc_am_stress_test.cc +++ b/lib/test/upper/rlc_am_stress_test.cc @@ -44,6 +44,8 @@ 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[]) { @@ -58,9 +60,11 @@ void parse_args(stress_test_args_t *args, int argc, char *argv[]) { // Command line or config file options bpo::options_description common("Configuration options"); common.add_options() - ("duration", bpo::value(&args->test_duration_sec)->default_value(10), "Duration (sec)") + ("duration", bpo::value(&args->test_duration_sec)->default_value(10), "Duration (sec)") ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(10), "SDU generation delay (usec)") - ("error_rate", bpo::value(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped"); + ("pdu_tx_delay", bpo::value(&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(&args->error_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") + ("reestablish", bpo::value(&args->reestablish)->default_value(false), "Mimic RLC reestablish during execution"); // these options are allowed on the command line bpo::options_description cmdline_options; @@ -83,14 +87,14 @@ class mac_reader :public thread { public: - mac_reader(rlc_interface_mac *rlc1_, rlc_interface_mac *rlc2_, float fail_rate_, uint32_t sdu_gen_delay_usec_) + 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; - sdu_gen_delay_usec = sdu_gen_delay_usec_; + pdu_tx_delay_usec = pdu_tx_delay_usec_; } void stop() @@ -125,7 +129,7 @@ private: if(((float)rand()/RAND_MAX > fail_rate) && read>0) { rlc2->write_pdu(1, pdu->msg, opp_size); } - usleep(sdu_gen_delay_usec); + usleep(pdu_tx_delay_usec); } running = false; byte_buffer_pool::get_instance()->deallocate(pdu); @@ -134,7 +138,7 @@ private: rlc_interface_mac *rlc1; rlc_interface_mac *rlc2; float fail_rate; - uint32_t sdu_gen_delay_usec; + uint32_t pdu_tx_delay_usec; bool run_enable; bool running; @@ -144,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_, uint32_t sdu_gen_delay_usec_) - :r1(rlc1_, rlc2_, fail_rate_, sdu_gen_delay_usec_) - ,r2(rlc2_, rlc1_, fail_rate_, sdu_gen_delay_usec_) + 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) { } @@ -184,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() @@ -235,7 +240,7 @@ private: pdu->N_bytes = 1500; pdu->msg[0] = sn++; rlc->write_sdu(1, pdu); - usleep(10); + usleep(sdu_gen_delay_usec); } running = false; } @@ -246,6 +251,8 @@ private: std::string name; + uint32_t sdu_gen_delay_usec; + rlc_interface_pdcp *rlc; }; @@ -261,9 +268,9 @@ void stress_test(stress_test_args_t args) rlc rlc1; rlc rlc2; - rlc_am_tester tester1(&rlc1, "tester1"); - rlc_am_tester tester2(&rlc2, "tester2"); - mac_dummy mac(&rlc1, &rlc2, args.error_rate, args.sdu_gen_delay_usec); + 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); @@ -287,7 +294,14 @@ void stress_test(stress_test_args_t args) tester2.start(7); mac.start(); - usleep(args.test_duration_sec * 1e6); + 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(); From c198547728d95fc6b058b8d97e1e738cdfce850c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 23 Feb 2018 13:23:04 +0100 Subject: [PATCH 39/52] add new RF RX error type and make the UHD driver issue that if anything unexpected happens --- lib/include/srslte/phy/rf/rf.h | 1 + lib/src/phy/rf/rf_uhd_imp.c | 22 ++++++++++++++++++++-- srsue/src/ue.cc | 7 ++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/include/srslte/phy/rf/rf.h b/lib/include/srslte/phy/rf/rf.h index 44bde9943..da1600b66 100644 --- a/lib/include/srslte/phy/rf/rf.h +++ b/lib/include/srslte/phy/rf/rf.h @@ -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; diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index a1bec2657..0370fa700 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -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; @@ -740,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; } @@ -762,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); diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 1de1ddbd0..23175fa46 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -304,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); } } From 067d76a5c8cc5e4ef0619d28b96e28777c20f1b2 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 5 Mar 2018 11:22:02 +0100 Subject: [PATCH 40/52] enable buffer pool log --- 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 41a89fb36..ddd558016 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -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__)) From 90553e830d4211edbd2fdb997ecee718ec00ae6f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 13:07:24 +0100 Subject: [PATCH 41/52] Fixed cell search for non-home PLMN --- lib/include/srslte/interfaces/ue_interfaces.h | 1 - lib/src/phy/ue/ue_sync.c | 7 +- srsue/hdr/phy/phch_recv.h | 8 +- srsue/hdr/phy/phy.h | 1 - srsue/src/phy/phch_recv.cc | 87 +++++++------------ srsue/src/phy/phy.cc | 5 -- srsue/src/upper/nas.cc | 17 ++-- srsue/src/upper/rrc.cc | 39 +++++---- 8 files changed, 76 insertions(+), 89 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 52d11416c..923111371 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -580,7 +580,6 @@ public: /* Cell search and selection procedures */ virtual void cell_search_start() = 0; - virtual void cell_search_stop() = 0; virtual void cell_search_next() = 0; virtual void cell_select(uint32_t earfcn, srslte_cell_t cell) = 0; virtual bool cell_handover(srslte_cell_t cell) = 0; diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index d99bff89a..b66cf5b53 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -755,7 +755,9 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE if (q->do_agc) { srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } - + + INFO("SYNC FIND: sf_idx=%d, ret=%d, next_state=%d\n", q->sf_idx, ret, q->state); + break; case SF_TRACK: @@ -817,6 +819,9 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE q->frame_total_cnt++; } + + INFO("SYNC TRACK: sf_idx=%d, ret=%d, next_state=%d\n", q->sf_idx, ret, q->state); + break; } } diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index b5848a6b3..861d58229 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -61,7 +61,6 @@ public: void reset_sync(); void cell_search_start(); - void cell_search_stop(); void cell_search_next(bool reset = false); void cell_select(uint32_t earfcn, srslte_cell_t cell); bool cell_handover(srslte_cell_t cell); @@ -299,14 +298,16 @@ private: const static uint32_t NOF_IN_SYNC_SF = 100; // State for primary cell - enum { + typedef enum { IDLE = 0, CELL_SEARCH, CELL_SELECT, CELL_RESELECT, CELL_MEASURE, CELL_CAMP, - } phy_state; + } phy_state_t; + + phy_state_t phy_state, prev_state; bool is_in_idle; @@ -330,7 +331,6 @@ private: float ul_dl_factor; uint32_t current_earfcn; int cur_earfcn_index; - bool cell_search_in_progress; float dl_freq; float ul_freq; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 9270973c0..0894a98fb 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -85,7 +85,6 @@ public: void sync_reset(); void configure_ul_params(bool pregen_disabled = false); void cell_search_start(); - void cell_search_stop(); void cell_search_next(); void cell_select(uint32_t earfcn, srslte_cell_t phy_cell); bool cell_handover(srslte_cell_t cell); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index a6f1a5d84..ad76537e0 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -132,7 +132,6 @@ void phch_recv::reset() next_offset = 0; cell_is_set = false; srate_mode = SRATE_NONE; - cell_search_in_progress = false; current_earfcn = 0; sfn_p.reset(); measure_p.reset(); @@ -262,17 +261,17 @@ void phch_recv::reset_sync() { search_p.reset(); measure_p.reset(); srslte_ue_sync_reset(&ue_sync); - + Info("----- PHY RESET----\n"); phy_state = CELL_SELECT; } void phch_recv::cell_search_inc() { + Info("cell_search_inc, cur_idx=%d, size=%d\n", cur_earfcn_index, earfcn.size()); cur_earfcn_index++; if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= (int) earfcn.size()) { cur_earfcn_index = 0; - cell_search_in_progress = false; phy_state = IDLE; rrc->earfcn_end(); } else { @@ -281,20 +280,16 @@ void phch_recv::cell_search_inc() current_earfcn = earfcn[cur_earfcn_index]; set_frequency(); } + phy_state = CELL_SEARCH; } } } void phch_recv::cell_search_next(bool reset) { - if (cell_search_in_progress || reset) { - cell_search_in_progress = false; - if (reset) { - cur_earfcn_index = -1; - } - cell_search_inc(); - phy_state = CELL_SEARCH; - cell_search_in_progress = true; + if (reset) { + cur_earfcn_index = -1; } + cell_search_inc(); } void phch_recv::cell_search_start() { @@ -311,11 +306,6 @@ void phch_recv::cell_search_start() { } } -void phch_recv::cell_search_stop() { - Info("SYNC: Stopping Cell Search procedure...\n"); - cell_search_in_progress = false; -} - bool phch_recv::cell_handover(srslte_cell_t cell) { int cnt = 0; @@ -369,19 +359,18 @@ void phch_recv::cell_reselect() uint32_t earfcn = new_earfcn; srslte_cell_t cell = new_cell; + Info("Reset from cell_reselect\n"); + reset_sync(); + // If we are already in the new cell, just resynchronize if (earfcn == current_earfcn && this->cell.id == cell.id) { - log_h->info("Cell Select: Already in cell EARFCN=%d\n", earfcn); - cell_search_in_progress = false; + log_h->info("Cell Select: Already in cell EARFCN=%d, PCI=%d\n", earfcn, cell.id); if (srate_mode != SRATE_CAMP) { set_sampling_rate(); + log_h->info("Cell Select: Setting Camping sampling rate\n"); } - phy_state = CELL_SELECT; } else { - /* If we are going to a new cell, configure it */ - cell_search_in_progress = false; - if (earfcn != current_earfcn) { if (set_frequency()) { log_h->error("Cell Select: Configuring cell in EARFCN=%d, PCI=%d\n", earfcn, cell.id); @@ -394,7 +383,6 @@ void phch_recv::cell_reselect() if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - phy_state = CELL_SELECT; } } } @@ -533,33 +521,29 @@ void phch_recv::run_thread() sf_idx = tti%10; + prev_state = phy_state; + switch (phy_state) { case CELL_SEARCH: - if (cell_search_in_progress) + switch(search_p.run(&cell)) { - switch(search_p.run(&cell)) - { - case search::CELL_FOUND: - if (!srslte_cell_isvalid(&cell)) { - Error("SYNC: Detected invalid cell\n"); - phy_state = IDLE; - break; - } - if (set_cell()) { - set_sampling_rate(); - phy_state = CELL_SELECT; - } - break; - case search::CELL_NOT_FOUND: - if (cell_search_in_progress) { - cell_search_inc(); - } + case search::CELL_FOUND: + if (!srslte_cell_isvalid(&cell)) { + Error("SYNC: Detected invalid cell\n"); phy_state = IDLE; break; - default: - radio_error(); - break; } + if (set_cell()) { + set_sampling_rate(); + phy_state = CELL_SELECT; + } + break; + case search::CELL_NOT_FOUND: + cell_search_inc(); + break; + default: + radio_error(); + break; } break; case CELL_RESELECT: @@ -569,7 +553,7 @@ void phch_recv::run_thread() switch (sfn_p.run_subframe(&cell, &tti)) { case sfn_sync::SFN_FOUND: - if (!cell_search_in_progress) { + if (prev_state == CELL_SEARCH) { log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; rrc->cell_camping(earfcn[cur_earfcn_index], cell); @@ -580,13 +564,8 @@ void phch_recv::run_thread() } break; case sfn_sync::TIMEOUT: - if (cell_search_in_progress) { - log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); - phy_state = CELL_SEARCH; - } else { - log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - phy_state = CELL_SELECT; - } + log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); + phy_state = CELL_SEARCH; break; case sfn_sync::IDLE: break; @@ -610,7 +589,6 @@ void phch_recv::run_thread() log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; - cell_search_in_progress = false; rrc->cell_camping(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: @@ -833,6 +811,7 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) if (p->srate_mode != SRATE_FIND) { p->srate_mode = SRATE_FIND; p->radio_h->set_rx_srate(1.92e6); + Info("SYNC: Setting Cell Search sampling rate\n"); } /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ @@ -992,7 +971,7 @@ phch_recv::sfn_sync::ret_code phch_recv::sfn_sync::run_subframe(srslte_cell_t *c } } } else { - Debug("SYNC: PSS/SSS not found...\n"); + Info("SYNC: PSS/SSS not found...\n"); } cnt++; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index a2d517a02..e4b618158 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -256,11 +256,6 @@ void phy::cell_search_start() sf_recv.cell_search_start(); } -void phy::cell_search_stop() -{ - sf_recv.cell_search_stop(); -} - void phy::cell_search_next() { sf_recv.cell_search_next(); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 7f5683867..8a05595c7 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -161,14 +161,15 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_ // RRC indicates that the UE has gone through all EARFCN and finished PLMN selection void nas::plmn_search_end() { if (known_plmns.size() > 0) { - nas_log->info("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", - plmn_id_to_string(home_plmn).c_str(), - plmn_id_to_string(known_plmns[0]).c_str()); - - nas_log->console("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", - plmn_id_to_string(home_plmn).c_str(), - plmn_id_to_string(known_plmns[0]).c_str()); - + if (home_plmn.mcc != known_plmns[0].mcc && home_plmn.mnc != known_plmns[0].mnc) { + nas_log->info("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", + plmn_id_to_string(home_plmn).c_str(), + plmn_id_to_string(known_plmns[0]).c_str()); + + nas_log->console("Could not find Home PLMN Id=%s, trying to connect to PLMN Id=%s\n", + plmn_id_to_string(home_plmn).c_str(), + plmn_id_to_string(known_plmns[0]).c_str()); + } rrc->plmn_select(known_plmns[0]); } else { nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n"); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 1aecb273b..cdd19f22c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -212,10 +212,8 @@ void rrc::run_thread() { plmn_select_timeout++; if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) { rrc_log->info("RRC PLMN Search: timeout expired\n"); - phy->cell_search_stop(); - sleep(1); - rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n"); - + rrc_log->console("\nRRC PLMN Search: timeout expired.\n"); + state = RRC_STATE_IDLE; } break; case RRC_STATE_CELL_SELECTING: @@ -236,14 +234,13 @@ void rrc::run_thread() { } } // Don't time out during reestablishment (T311 running) - if (!mac_timers->timer_get(t311)->is_running()) { + if (!mac_timers->timer_get(t311)->is_running() || !phy->sync_status()) { select_cell_timeout++; if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n"); - plmn_select_timeout = 0; select_cell_timeout = 0; + state = RRC_STATE_PLMN_START; serving_cell->in_sync = false; - phy->cell_search_start(); } } break; @@ -457,17 +454,30 @@ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) { if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) { rrc_log->info("Already camping on selected PLMN, connecting...\n"); - state = RRC_STATE_CELL_SELECTING; - select_cell_timeout = 0; } else { - rrc_log->info("PLMN Id=%s selected\n", plmn_id_to_string(plmn_id).c_str()); - // Sort cells according to RSRP - selected_plmn_id = plmn_id; - select_cell_timeout = 0; - state = RRC_STATE_CELL_SELECTING; + if (serving_cell->plmn_equals(selected_plmn_id)) { + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + } else { + bool found = false; + for (uint32_t i=0;iplmn_equals(selected_plmn_id)) { + rrc_log->info("PLMN Id=%s selected, PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); + phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); + found = true; + } + } + if (!found) { + rrc_log->warning("Could not find any cell for the selected PLMN\n"); + state = RRC_STATE_IDLE; + return; + } + } } + + state = RRC_STATE_CELL_SELECTING; + select_cell_timeout = 0; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); } @@ -988,7 +998,6 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause, break; default: rrc_log->info("Unsupported integrity algorithm during reestablishment\n"); - return; } // Prepare ConnectionRestalishmentRequest packet From 8591049e928da086cfb599b08799a1d46f992c18 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 14:33:51 +0100 Subject: [PATCH 42/52] Added mutex to ul/dl harq reset --- lib/src/common/pdu_queue.cc | 12 ++++++++---- srsue/hdr/mac/dl_harq.h | 16 +++++++++++++++- srsue/hdr/mac/ul_harq.h | 11 ++++++++++- srsue/src/upper/rrc.cc | 2 ++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/src/common/pdu_queue.cc b/lib/src/common/pdu_queue.cc index 3a116e641..061433033 100644 --- a/lib/src/common/pdu_queue.cc +++ b/lib/src/common/pdu_queue.cc @@ -76,10 +76,14 @@ void pdu_queue::deallocate(uint8_t* pdu) */ void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp) { - pdu_t *pdu = (pdu_t*) ptr; - pdu->len = len; - pdu->tstamp = tstamp; - pdu_q.push(pdu); + if (ptr) { + pdu_t *pdu = (pdu_t*) ptr; + pdu->len = len; + pdu->tstamp = tstamp; + pdu_q.push(pdu); + } else { + log_h->warning("Error pushing pdu: ptr is empty\n"); + } } bool pdu_queue::process_pdus() diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 261fb0d41..982a6eac6 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -196,6 +196,8 @@ private: is_initiated = false; ack = false; bzero(&cur_grant, sizeof(Tgrant)); + + pthread_mutex_init(&mutex, NULL); } ~dl_tb_process() { @@ -220,16 +222,23 @@ private: } void reset(void) { + pthread_mutex_lock(&mutex); is_first_tb = true; ack = false; - payload_buffer_ptr = NULL; + if (payload_buffer_ptr) { + harq_entity->demux_unit->deallocate(payload_buffer_ptr); + } bzero(&cur_grant, sizeof(Tgrant)); if (is_initiated) { srslte_softbuffer_rx_reset(&softbuffer); } + pthread_mutex_unlock(&mutex); } void new_grant_dl(Tgrant grant, Taction *action) { + + pthread_mutex_lock(&mutex); + // Compute RV for BCCH when not specified in PDCCH format if (pid == HARQ_BCCH_PID && grant.rv[tid] == -1) { uint32_t k; @@ -271,6 +280,7 @@ private: if (!action->payload_ptr[tid]) { action->decode_enabled[tid] = false; Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes[tid]); + pthread_mutex_unlock(&mutex); return; } action->decode_enabled[tid]= true; @@ -299,6 +309,8 @@ private: Debug("Generating ACK\n"); } } + + pthread_mutex_unlock(&mutex); } void tb_decoded(bool ack_) { @@ -364,6 +376,8 @@ private: return is_new_transmission; } + pthread_mutex_t mutex; + bool is_initiated; dl_harq_entity *harq_entity; srslte::log *log_h; diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 5c44a222e..4ab4756b9 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -159,6 +159,8 @@ private: tti_last_tx = 0; payload_buffer = NULL; bzero(&cur_grant, sizeof(Tgrant)); + + pthread_mutex_init(&mutex, NULL); } ~ul_harq_process() @@ -193,17 +195,21 @@ private: void reset() { + pthread_mutex_lock(&mutex); current_tx_nb = 0; current_irv = 0; tti_last_tx = 0; is_grant_configured = false; bzero(&cur_grant, sizeof(Tgrant)); + pthread_mutex_unlock(&mutex); } void reset_ndi() { cur_grant.ndi[0] = false; } void run_tti(uint32_t tti_tx, Tgrant *grant, bool *ack, Taction* action) { + pthread_mutex_lock(&mutex); + if (ack) { if (grant) { if (grant->ndi[0] == get_ndi() && grant->phy_grant.ul.mcs.tbs != 0) { @@ -276,6 +282,8 @@ private: } harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes[0], grant->rnti, get_nof_retx(), tti_tx); } + + pthread_mutex_unlock(&mutex); } uint32_t get_rv() @@ -304,7 +312,8 @@ private: bool is_msg3; bool is_initiated; uint32_t tti_last_tx; - + + pthread_mutex_t mutex; const static int payload_buffer_len = 128*1024; uint8_t *payload_buffer; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 8ffdc1868..f2373ce2c 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -768,6 +768,8 @@ void rrc::earfcn_end() { // If searching for PLMN, indicate NAS we scanned all frequencies if (state == RRC_STATE_PLMN_SELECTION) { nas->plmn_search_end(); + } else if (state == RRC_STATE_CONNECTED) { + leave_connected(); } } From f53cb11e82c3cc4a0818c05226d54083c3da0a08 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 14:54:01 +0100 Subject: [PATCH 43/52] Remove mutex from ul_harq --- srsue/hdr/mac/ul_harq.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 4ab4756b9..ee9bc6279 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -159,8 +159,6 @@ private: tti_last_tx = 0; payload_buffer = NULL; bzero(&cur_grant, sizeof(Tgrant)); - - pthread_mutex_init(&mutex, NULL); } ~ul_harq_process() @@ -195,21 +193,17 @@ private: void reset() { - pthread_mutex_lock(&mutex); current_tx_nb = 0; current_irv = 0; tti_last_tx = 0; is_grant_configured = false; bzero(&cur_grant, sizeof(Tgrant)); - pthread_mutex_unlock(&mutex); } void reset_ndi() { cur_grant.ndi[0] = false; } void run_tti(uint32_t tti_tx, Tgrant *grant, bool *ack, Taction* action) { - pthread_mutex_lock(&mutex); - if (ack) { if (grant) { if (grant->ndi[0] == get_ndi() && grant->phy_grant.ul.mcs.tbs != 0) { @@ -282,8 +276,6 @@ private: } harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes[0], grant->rnti, get_nof_retx(), tti_tx); } - - pthread_mutex_unlock(&mutex); } uint32_t get_rv() @@ -313,7 +305,6 @@ private: bool is_initiated; uint32_t tti_last_tx; - pthread_mutex_t mutex; const static int payload_buffer_len = 128*1024; uint8_t *payload_buffer; From 23f308666976d347b9792cd77b30b0bd486b2778 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 15:13:24 +0100 Subject: [PATCH 44/52] Deallocate properly on dl_harq --- srsue/hdr/mac/dl_harq.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 982a6eac6..562008d61 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -227,6 +227,7 @@ private: ack = false; if (payload_buffer_ptr) { harq_entity->demux_unit->deallocate(payload_buffer_ptr); + payload_buffer_ptr = NULL; } bzero(&cur_grant, sizeof(Tgrant)); if (is_initiated) { @@ -314,6 +315,7 @@ private: } void tb_decoded(bool ack_) { + pthread_mutex_lock(&mutex); ack = ack_; if (ack) { if (pid == HARQ_BCCH_PID) { @@ -344,11 +346,15 @@ private: harq_entity->demux_unit->deallocate(payload_buffer_ptr); } + payload_buffer_ptr = NULL; + Info("DL %d (TB %d): %s tbs=%d, rv=%d, ack=%s, ndi=%d (%d), tti=%d (%d)\n", pid, tid, is_new_transmission ? "newTX" : "reTX ", cur_grant.n_bytes[tid], cur_grant.rv[tid], ack ? "OK" : "KO", cur_grant.ndi[tid], cur_grant.last_ndi[tid], cur_grant.tti, cur_grant.last_tti); + pthread_mutex_unlock(&mutex); + if (ack && pid == HARQ_BCCH_PID) { reset(); } From b8b39d6d1bd8f5fd4dbfde4a36efd4fd5ff575cf Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 15:16:21 +0100 Subject: [PATCH 45/52] NULL payload buffer in dl_harq in the constructor --- srsue/hdr/mac/dl_harq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 562008d61..9d7d8f48e 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -196,7 +196,7 @@ private: is_initiated = false; ack = false; bzero(&cur_grant, sizeof(Tgrant)); - + payload_buffer_ptr = NULL; pthread_mutex_init(&mutex, NULL); } From 09594d805871b539e540d4d1c219f040beffc4c6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:18:40 +0100 Subject: [PATCH 46/52] Restart RX stream on srate change --- lib/src/radio/radio.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 7008790a3..fc21b73be 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -301,7 +301,9 @@ void radio::set_master_clock_rate(double rate) void radio::set_rx_srate(double srate) { + srslte_rf_stop_rx_stream(&rf_device); srslte_rf_set_rx_srate(&rf_device, srate); + srslte_rf_start_rx_stream(&rf_device, false); } void radio::set_tx_freq(double freq) From 76ed6fd8d809bd9aa6dc197080d27bbedcc35ba7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:19:26 +0100 Subject: [PATCH 47/52] Check cell state before infra_freq.meas --- srsue/src/phy/phch_recv.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ddb0c6a38..b05a88205 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -553,7 +553,7 @@ void phch_recv::run_thread() switch (sfn_p.run_subframe(&cell, &tti)) { case sfn_sync::SFN_FOUND: - if (prev_state == CELL_SEARCH) { + if (prev_state != CELL_SEARCH) { log_h->info("Sync OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; rrc->cell_camping(earfcn[cur_earfcn_index], cell); @@ -662,7 +662,9 @@ void phch_recv::run_thread() if ((tti%5) == 0 && worker_com->args->sic_pss_enabled) { srslte_pss_sic(&ue_sync.strack.pss, &buffer[0][SRSLTE_SF_LEN_PRB(cell.nof_prb)/2-ue_sync.strack.fft_size]); } - intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); + if (srslte_cell_isvalid(&cell)) { + intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); + } break; case 0: Warning("SYNC: Out-of-sync detected in PSS/SSS\n"); From 8b1ba55eaf7ecec4ab2c200a98c64ea0a04c5e3d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:20:06 +0100 Subject: [PATCH 48/52] Check payload length before demux --- srsue/src/mac/demux.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 56446bda9..99f7c036c 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -165,7 +165,14 @@ void demux::process_sch_pdu(srslte::sch_pdu *pdu_msg) // Route logical channel if (route_pdu) { Info("Delivering PDU for lcid=%d, %d bytes\n", pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_payload_size()); - rlc->write_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); + if (pdu_msg->get()->get_payload_size() < MAX_PDU_LEN) { + rlc->write_pdu(pdu_msg->get()->get_sdu_lcid(), pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_payload_size()); + } else { + char tmp[1024]; + srslte_vec_sprint_hex(tmp, pdu_msg->get()->get_sdu_ptr(), 32); + Error("PDU size %d exceeds maximum PDU buffer size, lcid=%d, hex=[%s]\n", + pdu_msg->get()->get_payload_size(), pdu_msg->get()->get_sdu_lcid(), tmp); + } } } else { // Process MAC Control Element From defe16767299d26086ef56b6c0477a460ad135a6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:20:45 +0100 Subject: [PATCH 49/52] Do not lock on set_crnti worker --- srsue/src/phy/phch_worker.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 3075b0b30..de73764f4 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -199,11 +199,9 @@ void phch_worker::set_sample_offset(float sample_offset) void phch_worker::set_crnti(uint16_t rnti) { - pthread_mutex_lock(&mutex); srslte_ue_dl_set_rnti(&ue_dl, rnti); srslte_ue_ul_set_rnti(&ue_ul, rnti); rnti_is_set = true; - pthread_mutex_unlock(&mutex); } float phch_worker::get_ref_cfo() From dcdb2d64496844761c674af8574c48c9fc1468f5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 16:26:51 +0100 Subject: [PATCH 50/52] Make sure request connection when NAS attaching --- srsue/src/upper/rrc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index f2373ce2c..11cb432fa 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -187,6 +187,7 @@ void rrc::run_thread() { sleep(1); rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); plmn_select_rrc(selected_plmn_id); + connection_requested = true; } // If not camping on a cell } else { From 5f0bd0e74bd1bdafbf8e831a137d84f3150f37c8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 17:18:51 +0100 Subject: [PATCH 51/52] Add mutex to libfftw mkplan/destroyplan functions --- lib/src/phy/dft/dft_fftw.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index ede6ce69b..d9318fa0d 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -45,6 +45,7 @@ #define FFTW_TYPE 0 #endif +pthread_mutex_t fft_mutex = PTHREAD_MUTEX_INITIALIZER; void srslte_dft_load() { #ifdef FFTW_WISDOM_FILE @@ -101,10 +102,15 @@ int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan, const int new_dft_points, const fftwf_iodim iodim = {new_dft_points, istride, ostride}; const fftwf_iodim howmany_dims = {how_many, idist, odist}; + pthread_mutex_lock(&fft_mutex); + /* Destroy current plan */ fftwf_destroy_plan(plan->p); plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE); + + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -116,11 +122,15 @@ int srslte_dft_replan_guru_c(srslte_dft_plan_t *plan, const int new_dft_points, int srslte_dft_replan_c(srslte_dft_plan_t *plan, const int new_dft_points) { int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; + + pthread_mutex_lock(&fft_mutex); if (plan->p) { fftwf_destroy_plan(plan->p); plan->p = NULL; } plan->p = fftwf_plan_dft_1d(new_dft_points, plan->in, plan->out, sign, FFTW_TYPE); + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -136,10 +146,14 @@ int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan, const int dft_points, srslte const fftwf_iodim iodim = {dft_points, istride, ostride}; const fftwf_iodim howmany_dims = {how_many, idist, odist}; + pthread_mutex_lock(&fft_mutex); + plan->p = fftwf_plan_guru_dft(1, &iodim, 1, &howmany_dims, in_buffer, out_buffer, sign, FFTW_TYPE); if (!plan->p) { return -1; } + pthread_mutex_unlock(&fft_mutex); + plan->size = dft_points; plan->init_size = plan->size; plan->mode = SRSLTE_DFT_COMPLEX; @@ -156,8 +170,14 @@ int srslte_dft_plan_guru_c(srslte_dft_plan_t *plan, const int dft_points, srslte int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) { allocate(plan,sizeof(fftwf_complex),sizeof(fftwf_complex), dft_points); + + pthread_mutex_lock(&fft_mutex); + int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_FORWARD : FFTW_BACKWARD; plan->p = fftwf_plan_dft_1d(dft_points, plan->in, plan->out, sign, FFTW_TYPE); + + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -177,11 +197,15 @@ int srslte_dft_plan_c(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_ int srslte_dft_replan_r(srslte_dft_plan_t *plan, const int new_dft_points) { int sign = (plan->dir == SRSLTE_DFT_FORWARD) ? FFTW_R2HC : FFTW_HC2R; + + pthread_mutex_lock(&fft_mutex); if (plan->p) { fftwf_destroy_plan(plan->p); plan->p = NULL; } plan->p = fftwf_plan_r2r_1d(new_dft_points, plan->in, plan->out, sign, FFTW_TYPE); + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -192,7 +216,11 @@ int srslte_dft_replan_r(srslte_dft_plan_t *plan, const int new_dft_points) { int srslte_dft_plan_r(srslte_dft_plan_t *plan, const int dft_points, srslte_dft_dir_t dir) { allocate(plan,sizeof(float),sizeof(float), dft_points); int sign = (dir == SRSLTE_DFT_FORWARD) ? FFTW_R2HC : FFTW_HC2R; + + pthread_mutex_lock(&fft_mutex); plan->p = fftwf_plan_r2r_1d(dft_points, plan->in, plan->out, sign, FFTW_TYPE); + pthread_mutex_unlock(&fft_mutex); + if (!plan->p) { return -1; } @@ -311,11 +339,15 @@ void srslte_dft_run_r(srslte_dft_plan_t *plan, const float *in, float *out) { void srslte_dft_plan_free(srslte_dft_plan_t *plan) { if (!plan) return; if (!plan->size) return; + + pthread_mutex_lock(&fft_mutex); if (!plan->is_guru) { if (plan->in) fftwf_free(plan->in); if (plan->out) fftwf_free(plan->out); } if (plan->p) fftwf_destroy_plan(plan->p); + pthread_mutex_unlock(&fft_mutex); + bzero(plan, sizeof(srslte_dft_plan_t)); } From 154623ed63f743227714a0e6a09b6592269e36f2 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 5 Mar 2018 17:39:34 +0100 Subject: [PATCH 52/52] Decrease the in-sync SNR threshold --- srsue/src/phy/phch_worker.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index de73764f4..3a1dcbc98 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -410,7 +410,7 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -30.0) { + if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db > -20.0) { log_h->debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), phy->avg_rsrp_dbm); chest_loop->in_sync();