diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index c506fd020..6162acdce 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -238,11 +238,13 @@ private: } } - // List of strongest neighbour cell - cell_list neighbour_cells; + // Measurements private subclass + class rrc_meas; + std::unique_ptr measurements; - typedef std::unique_ptr unique_cell_t; - unique_cell_t serving_cell = nullptr; + // List of strongest neighbour cell + using unique_cell_t = std::unique_ptr; + meas_cell_list meas_cells; bool initiated = false; asn1::rrc::reest_cause_e m_reest_cause = asn1::rrc::reest_cause_e::nulltype; @@ -251,10 +253,6 @@ private: bool reestablishment_started = false; bool reestablishment_successful = false; - // Measurements private subclass - class rrc_meas; - std::unique_ptr measurements; - // Interface from rrc_meas void send_srb1_msg(const asn1::rrc::ul_dcch_msg_s& msg); std::set get_cells(const uint32_t earfcn); diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index b849804e2..bfb21ff36 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -131,20 +131,54 @@ private: std::map sib_info_map; ///< map of sib_index to index of schedInfoList in SIB1 }; -class cell_list +//! Universal methods to extract pci/earfcn and compare the two values +template +uint32_t get_pci(const T& t) { + return t.pci; +} +template <> +inline uint32_t get_pci(const cell_t& t) +{ + return t.get_pci(); +} +template +uint32_t get_earfcn(const T& t) +{ + return t.earfcn; +} +template <> +inline uint32_t get_earfcn(const cell_t& t) +{ + return t.get_earfcn(); +} +template +bool is_same_cell(const T& lhs, const U& rhs) +{ + return get_pci(lhs) == get_pci(rhs) and get_earfcn(lhs) == get_earfcn(rhs); +} + +class meas_cell_list +{ + using phy_meas_t = rrc_interface_phy_lte::phy_meas_t; + public: const static int NEIGHBOUR_TIMEOUT = 5; const static int MAX_NEIGHBOUR_CELLS = 8; typedef std::unique_ptr unique_cell_t; - bool add_neighbour_cell(const rrc_interface_phy_lte::phy_meas_t& meas); + meas_cell_list(); + + bool add_neighbour_cell(const phy_meas_t& meas); bool add_neighbour_cell(unique_cell_t cell); void rem_last_neighbour(); unique_cell_t remove_neighbour_cell(uint32_t earfcn, uint32_t pci); void clean_neighbours(); void sort_neighbour_cells(); + bool process_new_cell_meas(const std::vector& meas, + const std::function& filter_meas); + cell_t* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci); const cell_t* get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const; void log_neighbour_cells() const; @@ -156,6 +190,12 @@ public: const cell_t& operator[](size_t idx) const { return *neighbour_cells[idx]; } cell_t& at(size_t idx) { return *neighbour_cells.at(idx); } + // serving cell handling + int set_serving_cell(phy_interface_rrc_lte::phy_cell_t phy_cell, bool discard_serving); + + cell_t& serving_cell() { return *serv_cell; } + const cell_t& serving_cell() const { return *serv_cell; } + using iterator = std::vector::iterator; iterator begin() { return neighbour_cells.begin(); } iterator end() { return neighbour_cells.end(); } @@ -165,7 +205,7 @@ private: srslte::log_ref log_h{"RRC"}; - unique_cell_t serving_cell; + unique_cell_t serv_cell; std::vector neighbour_cells; }; diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 406a45149..efee8ecee 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -55,6 +55,7 @@ rrc::rrc(stack_interface_rrc* stack_) : last_state(RRC_STATE_CONNECTED), drb_up(false), rrc_log("RRC"), + measurements(new rrc_meas()), phy_cell_selector(this), cell_searcher(this), si_acquirer(this), @@ -66,11 +67,8 @@ rrc::rrc(stack_interface_rrc* stack_) : plmn_searcher(this), cell_reselector(this), connection_reest(this), - ho_handler(this), - serving_cell(unique_cell_t(new cell_t())) -{ - measurements = std::unique_ptr(new rrc_meas()); -} + ho_handler(this) +{} rrc::~rrc() = default; @@ -167,7 +165,7 @@ void rrc::get_metrics(rrc_metrics_t& m) { m.state = state; // Save strongest cells metrics - for (unique_cell_t& c : neighbour_cells) { + for (unique_cell_t& c : meas_cells) { rrc_interface_phy_lte::phy_meas_t meas = {}; meas.cfo_hz = c->get_cfo_hz(); meas.earfcn = c->get_earfcn(); @@ -250,7 +248,7 @@ void rrc::run_tti() // Clean old neighbours cell_clean_cnt++; if (cell_clean_cnt == 1000) { - neighbour_cells.clean_neighbours(); + meas_cells.clean_neighbours(); cell_clean_cnt = 0; } } @@ -267,12 +265,12 @@ void rrc::run_tti() uint16_t rrc::get_mcc() { - return serving_cell->get_mcc(); + return meas_cells.serving_cell().get_mcc(); } uint16_t rrc::get_mnc() { - return serving_cell->get_mnc(); + return meas_cells.serving_cell().get_mnc(); } /* NAS interface to search for available PLMNs. @@ -358,46 +356,19 @@ void rrc::process_cell_meas() } process_new_cell_meas(m); } - neighbour_cells.sort_neighbour_cells(); } void rrc::process_new_cell_meas(const std::vector& meas) { - bool neighbour_added = false; + const static std::function filter = [this](cell_t& c, const phy_meas_t& m) { + c.set_rsrp(measurements->rsrp_filter(m.rsrp, c.get_rsrp())); + c.set_rsrq(measurements->rsrq_filter(m.rsrq, c.get_rsrq())); + c.set_cfo(m.cfo_hz); + }; + rrc_log->debug("MEAS: Processing measurement of %zd cells\n", meas.size()); - for (auto& m : meas) { - cell_t* c = nullptr; - // Get serving_cell handle if it's the serving cell - if (m.earfcn == 0 or (m.earfcn == serving_cell->get_earfcn() and m.pci == serving_cell->get_pci())) { - c = serving_cell.get(); - if (c == nullptr || !serving_cell->is_valid()) { - rrc_log->error("MEAS: Received serving cell measurement but undefined or invalid\n"); - return; - } - // Or update/add RRC neighbour cell database - } else { - c = neighbour_cells.get_neighbour_cell_handle(m.earfcn, m.pci); - } - // Filter RSRP/RSRQ measurements if cell exits - if (c != nullptr) { - c->set_rsrp(measurements->rsrp_filter(m.rsrp, c->get_rsrp())); - c->set_rsrq(measurements->rsrq_filter(m.rsrq, c->get_rsrq())); - c->set_cfo(m.cfo_hz); - } else { - // or just set initial value - neighbour_added |= neighbour_cells.add_neighbour_cell(m); - } - if (m.earfcn == 0) { - rrc_log->info("MEAS: New measurement serving cell: rsrp=%.2f dBm.\n", m.rsrp); - } else { - rrc_log->info("MEAS: New measurement neighbour cell: earfcn=%d, pci=%d, rsrp=%.2f dBm, cfo=%+.1f Hz\n", - m.earfcn, - m.pci, - m.rsrp, - m.cfo_hz); - } - } + bool neighbour_added = meas_cells.process_new_cell_meas(meas, filter); // Instruct measurements subclass to update phy with new cells to measure based on strongest neighbours if (state == RRC_STATE_CONNECTED && neighbour_added) { @@ -409,7 +380,7 @@ void rrc::process_new_cell_meas(const std::vector& meas) void rrc::out_of_sync() { // CAUTION: We do not lock in this function since they are called from real-time threads - if (serving_cell && rrc_log) { + if (meas_cells.serving_cell().is_valid() && rrc_log) { phy_sync_state = phy_out_of_sync; // upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300, @@ -464,7 +435,7 @@ void rrc::in_sync() // Cell selection criteria Section 5.2.3.2 of 36.304 bool rrc::cell_selection_criteria(float rsrp, float rsrq) { - return (get_srxlev(rsrp) > 0 || !serving_cell->has_sib3()); + return (get_srxlev(rsrp) > 0 || !meas_cells.serving_cell().has_sib3()); } float rrc::get_srxlev(float Qrxlevmeas) @@ -489,8 +460,8 @@ void rrc::cell_reselection(float rsrp, float rsrq) phy->meas_stop(); } else { // UE must start intra-frequency measurements - auto pci = neighbour_cells.get_neighbour_pcis(serving_cell->get_earfcn()); - phy->set_cells_to_meas(serving_cell->get_earfcn(), pci); + auto pci = meas_cells.get_neighbour_pcis(meas_cells.serving_cell().get_earfcn()); + phy->set_cells_to_meas(meas_cells.serving_cell().get_earfcn(), pci); } // TODO: Inter-frequency cell reselection @@ -499,25 +470,7 @@ void rrc::cell_reselection(float rsrp, float rsrq) // Set new serving cell void rrc::set_serving_cell(phy_interface_rrc_lte::phy_cell_t phy_cell, bool discard_serving) { - if (has_neighbour_cell(phy_cell.earfcn, phy_cell.pci)) { - // Remove future serving cell from neighbours to make space for current serving cell - unique_cell_t new_serving_cell = neighbour_cells.remove_neighbour_cell(phy_cell.earfcn, phy_cell.pci); - bool same_cell = (phy_cell.earfcn == serving_cell->get_earfcn() and phy_cell.pci == serving_cell->get_pci()); - - // Move serving cell to neighbours list - if (serving_cell->is_valid() and not same_cell and not discard_serving) { - if (not neighbour_cells.add_neighbour_cell(std::move(serving_cell))) { - rrc_log->info("Serving cell not added to list of neighbours. Worse than current neighbours\n"); - } - } - // Set new serving cell - serving_cell = std::move(new_serving_cell); - rrc_log->info("Setting serving cell %s, nof_neighbours=%zd\n", - serving_cell->to_string().c_str(), - neighbour_cells.nof_neighbours()); - } else { - rrc_log->error("Setting serving cell: Unknown cell with earfcn=%d, PCI=%d\n", phy_cell.earfcn, phy_cell.pci); - } + meas_cells.set_serving_cell(phy_cell, discard_serving); } int rrc::start_cell_select() @@ -532,7 +485,7 @@ int rrc::start_cell_select() bool rrc::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const { - return neighbour_cells.has_neighbour_cell(earfcn, pci); + return meas_cells.has_neighbour_cell(earfcn, pci); } /******************************************************************************* @@ -546,7 +499,7 @@ bool rrc::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const *******************************************************************************/ std::string rrc::print_mbms() { - mcch_msg_type_c msg = serving_cell->mcch.msg; + mcch_msg_type_c msg = meas_cells.serving_cell().mcch.msg; std::stringstream ss; for (uint32_t i = 0; i < msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9.size(); i++) { ss << "PMCH: " << i << std::endl; @@ -572,14 +525,14 @@ std::string rrc::print_mbms() bool rrc::mbms_service_start(uint32_t serv, uint32_t port) { bool ret = false; - if (!serving_cell->has_mcch) { + if (!meas_cells.serving_cell().has_mcch) { rrc_log->error("MCCH not available at MBMS Service Start\n"); return ret; } rrc_log->info("%s\n", print_mbms().c_str()); - mcch_msg_type_c msg = serving_cell->mcch.msg; + mcch_msg_type_c msg = meas_cells.serving_cell().mcch.msg; for (uint32_t i = 0; i < msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9.size(); i++) { pmch_info_r9_s* pmch = &msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[i]; for (uint32_t j = 0; j < pmch->mbms_session_info_list_r9.size(); j++) { @@ -723,10 +676,10 @@ void rrc::send_con_restablish_request(reest_cause_e cause, uint16_t crnti, uint1 cellid = ho_src_cell.get_cell_id(); } else if (cause == reest_cause_e::other_fail) { // use source PCI after RLF - cellid = serving_cell->get_cell_id(); + cellid = meas_cells.serving_cell().get_cell_id(); } else { - pci = serving_cell->get_pci(); - cellid = serving_cell->get_cell_id(); + pci = meas_cells.serving_cell().get_pci(); + cellid = meas_cells.serving_cell().get_cell_id(); } // Compute shortMAC-I @@ -1095,24 +1048,24 @@ void rrc::send_srb1_msg(const ul_dcch_msg_s& msg) std::set rrc::get_cells(const uint32_t earfcn) { - return neighbour_cells.get_neighbour_pcis(earfcn); + return meas_cells.get_neighbour_pcis(earfcn); } float rrc::get_cell_rsrp(const uint32_t earfcn, const uint32_t pci) { - cell_t* c = neighbour_cells.get_neighbour_cell_handle(earfcn, pci); + cell_t* c = meas_cells.get_neighbour_cell_handle(earfcn, pci); return (c != nullptr) ? c->get_rsrp() : NAN; } float rrc::get_cell_rsrq(const uint32_t earfcn, const uint32_t pci) { - cell_t* c = neighbour_cells.get_neighbour_cell_handle(earfcn, pci); + cell_t* c = meas_cells.get_neighbour_cell_handle(earfcn, pci); return (c != nullptr) ? c->get_rsrq() : NAN; } cell_t* rrc::get_serving_cell() { - return serving_cell.get(); + return &meas_cells.serving_cell(); } /******************************************************************************* @@ -1163,7 +1116,7 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_c::c1_c_::types::sib_type1) { rrc_log->info("Processing SIB1 (1/1)\n"); - serving_cell->set_sib1(dlsch_msg.msg.c1().sib_type1()); + meas_cells.serving_cell().set_sib1(dlsch_msg.msg.c1().sib_type1()); si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); handle_sib1(); } else { @@ -1173,22 +1126,22 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) rrc_log->info("Processing SIB%d (%d/%d)\n", sib_list[i].type().to_number(), i, sib_list.size()); switch (sib_list[i].type().value) { case sib_info_item_c::types::sib2: - if (not serving_cell->has_sib2()) { - serving_cell->set_sib2(sib_list[i].sib2()); + if (not meas_cells.serving_cell().has_sib2()) { + meas_cells.serving_cell().set_sib2(sib_list[i].sib2()); si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); } handle_sib2(); break; case sib_info_item_c::types::sib3: - if (not serving_cell->has_sib3()) { - serving_cell->set_sib3(sib_list[i].sib3()); + if (not meas_cells.serving_cell().has_sib3()) { + meas_cells.serving_cell().set_sib3(sib_list[i].sib3()); si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); } handle_sib3(); break; case sib_info_item_c::types::sib13_v920: - if (not serving_cell->has_sib13()) { - serving_cell->set_sib13(sib_list[i].sib13_v920()); + if (not meas_cells.serving_cell().has_sib13()) { + meas_cells.serving_cell().set_sib13(sib_list[i].sib13_v920()); si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); } handle_sib13(); @@ -1202,9 +1155,9 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) void rrc::handle_sib1() { - const sib_type1_s* sib1 = serving_cell->sib1ptr(); + const sib_type1_s* sib1 = meas_cells.serving_cell().sib1ptr(); rrc_log->info("SIB1 received, CellID=%d, si_window=%d, sib2_period=%d\n", - serving_cell->get_cell_id() & 0xfff, + meas_cells.serving_cell().get_cell_id() & 0xfff, sib1->si_win_len.to_number(), sib1->sched_info_list[0].si_periodicity.to_number()); @@ -1230,7 +1183,7 @@ void rrc::handle_sib2() { rrc_log->info("SIB2 received\n"); - const sib_type2_s* sib2 = serving_cell->sib2ptr(); + const sib_type2_s* sib2 = meas_cells.serving_cell().sib2ptr(); // Apply RACH and timeAlginmentTimer configuration set_mac_cfg_t_rach_cfg_common(¤t_mac_cfg, sib2->rr_cfg_common.rach_cfg_common); @@ -1298,7 +1251,7 @@ void rrc::handle_sib3() { rrc_log->info("SIB3 received\n"); - const sib_type3_s* sib3 = serving_cell->sib3ptr(); + const sib_type3_s* sib3 = meas_cells.serving_cell().sib3ptr(); // cellReselectionInfoCommon cell_resel_cfg.q_hyst = sib3->cell_resel_info_common.q_hyst.to_number(); @@ -1319,7 +1272,7 @@ void rrc::handle_sib13() { rrc_log->info("SIB13 received\n"); - const sib_type13_r9_s* sib13 = serving_cell->sib13ptr(); + const sib_type13_r9_s* sib13 = meas_cells.serving_cell().sib13ptr(); phy->set_config_mbsfn_sib13(srslte::make_sib13(*sib13)); add_mrb(0, 0); // Add MRB0 @@ -1388,7 +1341,7 @@ void rrc::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) return; } // TODO: handle MCCH notifications and update MCCH - if (0 != lcid or serving_cell->has_mcch) { + if (0 != lcid or meas_cells.serving_cell().has_mcch) { return; } parse_pdu_mch(lcid, std::move(pdu)); @@ -1397,14 +1350,15 @@ void rrc::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) void rrc::parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) { asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); - if (serving_cell->mcch.unpack(bref) != asn1::SRSASN_SUCCESS or - serving_cell->mcch.msg.type().value != mcch_msg_type_c::types_opts::c1) { + if (meas_cells.serving_cell().mcch.unpack(bref) != asn1::SRSASN_SUCCESS or + meas_cells.serving_cell().mcch.msg.type().value != mcch_msg_type_c::types_opts::c1) { rrc_log->error("Failed to unpack MCCH message\n"); return; } - serving_cell->has_mcch = true; - phy->set_config_mbsfn_mcch(srslte::make_mcch_msg(serving_cell->mcch)); - log_rrc_message("MCH", Rx, pdu.get(), serving_cell->mcch, serving_cell->mcch.msg.c1().type().to_string()); + meas_cells.serving_cell().has_mcch = true; + phy->set_config_mbsfn_mcch(srslte::make_mcch_msg(meas_cells.serving_cell().mcch)); + log_rrc_message( + "MCH", Rx, pdu.get(), meas_cells.serving_cell().mcch, meas_cells.serving_cell().mcch.msg.c1().type().to_string()); if (args.mbms_service_id >= 0) { rrc_log->info("Attempting to auto-start MBMS service %d\n", args.mbms_service_id); mbms_service_start(args.mbms_service_id, args.mbms_service_port); @@ -1640,8 +1594,8 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) *******************************************************************************/ void rrc::enable_capabilities() { - bool enable_ul_64 = - args.ue_category >= 5 && serving_cell->sib2ptr()->rr_cfg_common.pusch_cfg_common.pusch_cfg_basic.enable64_qam; + bool enable_ul_64 = args.ue_category >= 5 && + meas_cells.serving_cell().sib2ptr()->rr_cfg_common.pusch_cfg_common.pusch_cfg_basic.enable64_qam; rrc_log->info("%s 64QAM PUSCH\n", enable_ul_64 ? "Enabling" : "Disabling"); } @@ -2067,7 +2021,7 @@ void rrc::apply_phy_scell_config(const scell_to_add_mod_r10_s& scell_config) } // Initialise default parameters from primary cell - earfcn = serving_cell->get_earfcn(); + earfcn = meas_cells.serving_cell().get_earfcn(); // Parse identification if (scell_config.cell_identif_r10_present) { @@ -2282,7 +2236,7 @@ void rrc::handle_con_reest(rrc_conn_reest_s* setup) // Update RRC Integrity keys int ncc = setup->crit_exts.c1().rrc_conn_reest_r8().next_hop_chaining_count; - usim->generate_as_keys_ho(serving_cell->get_pci(), serving_cell->get_earfcn(), ncc, &sec_cfg); + usim->generate_as_keys_ho(meas_cells.serving_cell().get_pci(), meas_cells.serving_cell().get_earfcn(), ncc, &sec_cfg); pdcp->config_security_all(sec_cfg); // Apply the Radio Resource configuration diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index cdb27ac21..b7a7ec361 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -150,7 +150,9 @@ uint16_t cell_t::get_mnc() const * Neighbour Cell List ********************************************/ -cell_t* cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) +meas_cell_list::meas_cell_list() : serv_cell(new cell_t()) {} + +cell_t* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) { auto it = find_if(neighbour_cells.begin(), neighbour_cells.end(), [&](const unique_cell_t& cell) { return cell->equals(earfcn, pci); @@ -158,7 +160,7 @@ cell_t* cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) return it != neighbour_cells.end() ? it->get() : nullptr; } -const cell_t* cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const +const cell_t* meas_cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci) const { auto it = find_if(neighbour_cells.begin(), neighbour_cells.end(), [&](const unique_cell_t& cell) { return cell->equals(earfcn, pci); @@ -167,7 +169,7 @@ const cell_t* cell_list::get_neighbour_cell_handle(uint32_t earfcn, uint32_t pci } // If only neighbour PCI is provided, copy full cell from serving cell -bool cell_list::add_neighbour_cell(const rrc_interface_phy_lte::phy_meas_t& meas) +bool meas_cell_list::add_neighbour_cell(const rrc_interface_phy_lte::phy_meas_t& meas) { phy_interface_rrc_lte::phy_cell_t phy_cell = {}; phy_cell.earfcn = meas.earfcn; @@ -179,7 +181,7 @@ bool cell_list::add_neighbour_cell(const rrc_interface_phy_lte::phy_meas_t& meas return add_neighbour_cell(std::move(c)); } -bool cell_list::add_neighbour_cell(unique_cell_t new_cell) +bool meas_cell_list::add_neighbour_cell(unique_cell_t new_cell) { bool ret = add_neighbour_cell_unsorted(std::move(new_cell)); if (ret) { @@ -188,7 +190,7 @@ bool cell_list::add_neighbour_cell(unique_cell_t new_cell) return ret; } -bool cell_list::add_neighbour_cell_unsorted(unique_cell_t new_cell) +bool meas_cell_list::add_neighbour_cell_unsorted(unique_cell_t new_cell) { // Make sure cell is valid if (!new_cell->is_valid()) { @@ -196,6 +198,11 @@ bool cell_list::add_neighbour_cell_unsorted(unique_cell_t new_cell) return false; } + if (is_same_cell(serving_cell(), *new_cell)) { + log_h->error("Added neighbour cell %s is equal to serving cell\n", new_cell->to_string().c_str()); + return false; + } + // If cell exists, update RSRP value cell_t* existing_cell = get_neighbour_cell_handle(new_cell->get_earfcn(), new_cell->get_pci()); if (existing_cell != nullptr) { @@ -222,7 +229,7 @@ bool cell_list::add_neighbour_cell_unsorted(unique_cell_t new_cell) return true; } -void cell_list::rem_last_neighbour() +void meas_cell_list::rem_last_neighbour() { if (not neighbour_cells.empty()) { unique_cell_t& c = neighbour_cells.back(); @@ -231,7 +238,7 @@ void cell_list::rem_last_neighbour() } } -cell_list::unique_cell_t cell_list::remove_neighbour_cell(uint32_t earfcn, uint32_t pci) +meas_cell_list::unique_cell_t meas_cell_list::remove_neighbour_cell(uint32_t earfcn, uint32_t pci) { auto it = find_if(neighbour_cells.begin(), neighbour_cells.end(), [&](const unique_cell_t& cell) { return cell->equals(earfcn, pci); @@ -245,7 +252,7 @@ cell_list::unique_cell_t cell_list::remove_neighbour_cell(uint32_t earfcn, uint3 } // Sort neighbour cells by decreasing order of RSRP -void cell_list::sort_neighbour_cells() +void meas_cell_list::sort_neighbour_cells() { std::sort(std::begin(neighbour_cells), std::end(neighbour_cells), [](const unique_cell_t& a, const unique_cell_t& b) { return a->greater(b.get()); @@ -254,7 +261,7 @@ void cell_list::sort_neighbour_cells() log_neighbour_cells(); } -void cell_list::log_neighbour_cells() const +void meas_cell_list::log_neighbour_cells() const { if (not neighbour_cells.empty()) { const int32_t MAX_STR_LEN = 512; @@ -276,7 +283,7 @@ void cell_list::log_neighbour_cells() const } //! Called by main RRC thread to remove neighbours from which measurements have not been received in a while -void cell_list::clean_neighbours() +void meas_cell_list::clean_neighbours() { struct timeval now; gettimeofday(&now, nullptr); @@ -291,7 +298,7 @@ void cell_list::clean_neighbours() } } -std::string cell_list::print_neighbour_cells() const +std::string meas_cell_list::print_neighbour_cells() const { if (neighbour_cells.empty()) { return ""; @@ -305,7 +312,7 @@ std::string cell_list::print_neighbour_cells() const return s; } -std::set cell_list::get_neighbour_pcis(uint32_t earfcn) const +std::set meas_cell_list::get_neighbour_pcis(uint32_t earfcn) const { std::set pcis = {}; for (const unique_cell_t& cell : neighbour_cells) { @@ -316,9 +323,73 @@ std::set cell_list::get_neighbour_pcis(uint32_t earfcn) const return pcis; } -bool cell_list::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const +bool meas_cell_list::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const { return get_neighbour_cell_handle(earfcn, pci) != nullptr; } +int meas_cell_list::set_serving_cell(phy_interface_rrc_lte::phy_cell_t phy_cell, bool discard_serving) +{ + // Remove future serving cell from neighbours to make space for current serving cell + unique_cell_t new_serving_cell = remove_neighbour_cell(phy_cell.earfcn, phy_cell.pci); + if (new_serving_cell == nullptr) { + log_h->error("Setting serving cell: Unknown cell with earfcn=%d, PCI=%d\n", phy_cell.earfcn, phy_cell.pci); + return SRSLTE_ERROR; + } + + // Set new serving cell + std::swap(serv_cell, new_serving_cell); + auto& old_serv_cell = new_serving_cell; + log_h->info("Setting serving cell %s, nof_neighbours=%zd\n", serv_cell->to_string().c_str(), nof_neighbours()); + + // Re-add old serving cell to list of neighbours + if (old_serv_cell->is_valid() and not is_same_cell(phy_cell, *old_serv_cell) and not discard_serving) { + if (not add_neighbour_cell(std::move(old_serv_cell))) { + log_h->info("Serving cell not added to list of neighbours. Worse than current neighbours\n"); + } + } + return SRSLTE_SUCCESS; +} + +bool meas_cell_list::process_new_cell_meas(const std::vector& meas, + const std::function& filter_meas) +{ + bool neighbour_added = false; + for (const auto& m : meas) { + cell_t* c = nullptr; + + // Get serving_cell handle if it's the serving cell + bool is_serving_cell = m.earfcn == 0 or is_same_cell(m, serving_cell()); + if (is_serving_cell) { + c = serv_cell.get(); + if (not serving_cell().is_valid()) { + log_h->error("MEAS: Received serving cell measurement but undefined or invalid\n"); + continue; + } + } else { + // Or update/add RRC neighbour cell database + c = get_neighbour_cell_handle(m.earfcn, m.pci); + } + + // Filter RSRP/RSRQ measurements if cell exits + if (c != nullptr) { + filter_meas(*c, m); + } else { + // or just set initial value + neighbour_added |= add_neighbour_cell(m); + } + + if (is_serving_cell) { + log_h->info("MEAS: New measurement serving cell: rsrp=%.2f dBm.\n", m.rsrp); + } else { + log_h->info("MEAS: New measurement neighbour cell: earfcn=%d, pci=%d, rsrp=%.2f dBm, cfo=%+.1f Hz\n", + m.earfcn, + m.pci, + m.rsrp, + m.cfo_hz); + } + } + return neighbour_added; +} + } // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 076cb8d65..ed97e299e 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -121,16 +121,16 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_interface_rrc_ Info("Cell found in this frequency. Setting new serving cell EARFCN=%d PCI=%d ...\n", new_cell.earfcn, new_cell.pci); // Create a cell with NaN RSRP. Will be updated by new_phy_meas() during SIB search. - if (not rrc_ptr->neighbour_cells.add_neighbour_cell(unique_cell_t(new cell_t(new_cell)))) { + if (not rrc_ptr->meas_cells.add_neighbour_cell(unique_cell_t(new cell_t(new_cell)))) { Error("Could not add new found cell\n"); return proc_outcome_t::error; } - rrc_ptr->set_serving_cell(new_cell, false); + rrc_ptr->meas_cells.set_serving_cell(new_cell, false); // set new serving cell in PHY state = state_t::phy_cell_select; - if (not rrc_ptr->phy_cell_selector.launch(*rrc_ptr->serving_cell)) { + if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) { Error("Couldn't start phy cell selection\n"); return proc_outcome_t::error; } @@ -139,11 +139,11 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_interface_rrc_ proc_outcome_t rrc::cell_search_proc::step_wait_measurement() { - if (not std::isnormal(rrc_ptr->serving_cell->get_rsrp())) { + if (not std::isnormal(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { return proc_outcome_t::yield; } - if (rrc_ptr->serving_cell->has_sib1()) { + if (rrc_ptr->meas_cells.serving_cell().has_sib1()) { Info("Cell has SIB1\n"); // What do we do???? return proc_outcome_t::success; @@ -176,7 +176,7 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_select_event_t& event) return proc_outcome_t::error; } - if (not std::isnormal(rrc_ptr->serving_cell->get_rsrp())) { + if (not std::isnormal(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { Info("No valid measurement found for the serving cell. Wait for valid measurement...\n"); } state = state_t::wait_measurement; @@ -297,7 +297,7 @@ rrc::si_acquire_proc::si_acquire_proc(rrc* parent_) : proc_outcome_t rrc::si_acquire_proc::init(uint32_t sib_index_) { // make sure we dont already have the SIB of interest - if (rrc_ptr->serving_cell->has_sib(sib_index_)) { + if (rrc_ptr->meas_cells.serving_cell().has_sib(sib_index_)) { Info("The UE has already acquired SIB%d\n", sib_index + 1); return proc_outcome_t::success; } @@ -305,13 +305,13 @@ proc_outcome_t rrc::si_acquire_proc::init(uint32_t sib_index_) // make sure SIB1 is captured before other SIBs sib_index = sib_index_; - if (sib_index > 0 and not rrc_ptr->serving_cell->has_sib1()) { + if (sib_index > 0 and not rrc_ptr->meas_cells.serving_cell().has_sib1()) { Error("Trying to acquire SIB%d but SIB1 not received yet\n", sib_index + 1); return proc_outcome_t::error; } // compute the si-Periodicity and schedInfoList index - auto ret = compute_si_periodicity_and_idx(sib_index, rrc_ptr->serving_cell->sib1ptr()); + auto ret = compute_si_periodicity_and_idx(sib_index, rrc_ptr->meas_cells.serving_cell().sib1ptr()); if (ret.second < 0) { Info("Could not find SIB%d scheduling in SIB1\n", sib_index + 1); return proc_outcome_t::error; @@ -347,7 +347,8 @@ void rrc::si_acquire_proc::start_si_acquire() // Instruct MAC to decode SIB (non-blocking) tti_point tti = rrc_ptr->stack->get_current_tti(); - auto ret = compute_si_window(tti.to_uint(), sib_index, sched_index, period, rrc_ptr->serving_cell->sib1ptr()); + auto ret = + compute_si_window(tti.to_uint(), sib_index, sched_index, period, rrc_ptr->meas_cells.serving_cell().sib1ptr()); tti_point si_win_start = tti_point{ret.first}; if (si_win_start < tti) { Error("The SI Window start was incorrectly calculated. si_win_start=%d, tti=%d\n", @@ -375,12 +376,12 @@ void rrc::si_acquire_proc::start_si_acquire() proc_outcome_t rrc::si_acquire_proc::react(sib_received_ev ev) { - return rrc_ptr->serving_cell->has_sib(sib_index) ? proc_outcome_t::success : proc_outcome_t::yield; + return rrc_ptr->meas_cells.serving_cell().has_sib(sib_index) ? proc_outcome_t::success : proc_outcome_t::yield; } proc_outcome_t rrc::si_acquire_proc::react(si_acq_timer_expired ev) { - if (rrc_ptr->serving_cell->has_sib(sib_index)) { + if (rrc_ptr->meas_cells.serving_cell().has_sib(sib_index)) { return proc_outcome_t::success; } @@ -423,7 +424,7 @@ proc_outcome_t rrc::serving_cell_config_proc::init(const std::vector& return proc_outcome_t::error; } - rrc_ptr->serving_cell->has_mcch = false; + rrc_ptr->meas_cells.serving_cell().has_mcch = false; req_idx = 0; return launch_sib_acquire(); @@ -434,8 +435,8 @@ srslte::proc_outcome_t rrc::serving_cell_config_proc::launch_sib_acquire() // Obtain the SIBs if not available or apply the configuration if available for (; req_idx < required_sibs.size(); req_idx++) { uint32_t required_sib = required_sibs[req_idx]; - if (not rrc_ptr->serving_cell->has_sib(required_sib)) { - if (required_sib < 2 or rrc_ptr->serving_cell->is_sib_scheduled(required_sib)) { + if (not rrc_ptr->meas_cells.serving_cell().has_sib(required_sib)) { + if (required_sib < 2 or rrc_ptr->meas_cells.serving_cell().is_sib_scheduled(required_sib)) { Info("Cell has no SIB%d. Obtaining SIB%d\n", required_sib + 1, required_sib + 1); if (not rrc_ptr->si_acquirer.launch(&si_acquire_fut, required_sib)) { Error("SI Acquire is already running...\n"); @@ -471,7 +472,7 @@ proc_outcome_t rrc::serving_cell_config_proc::step() return proc_outcome_t::yield; } uint32_t required_sib = required_sibs[req_idx]; - if (si_acquire_fut.is_error() or not rrc_ptr->serving_cell->has_sib(required_sib)) { + if (si_acquire_fut.is_error() or not rrc_ptr->meas_cells.serving_cell().has_sib(required_sib)) { if (required_sib < 2) { log_h->warning("Serving Cell Configuration has failed\n"); return proc_outcome_t::error; @@ -494,7 +495,7 @@ rrc::cell_selection_proc::cell_selection_proc(rrc* parent_) : rrc_ptr(parent_) { */ proc_outcome_t rrc::cell_selection_proc::init() { - if (rrc_ptr->neighbour_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and + if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and rrc_ptr->phy->cell_is_camping()) { // don't bother with cell selection if there are no neighbours and we are already camping Debug("Skipping Cell Selection Procedure as there are no neighbour and cell is camping.\n"); @@ -503,16 +504,16 @@ proc_outcome_t rrc::cell_selection_proc::init() } Info("Starting...\n"); - Info("Current neighbor cells: [%s]\n", rrc_ptr->neighbour_cells.print_neighbour_cells().c_str()); + Info("Current neighbor cells: [%s]\n", rrc_ptr->meas_cells.print_neighbour_cells().c_str()); Info("Current PHY state: %s\n", rrc_ptr->phy_sync_state == phy_in_sync ? "in-sync" : "out-of-sync"); - if (rrc_ptr->serving_cell->has_sib3()) { + if (rrc_ptr->meas_cells.serving_cell().has_sib3()) { Info("Cell selection criteria: Qrxlevmin=%f, Qrxlevminoffset=%f\n", rrc_ptr->cell_resel_cfg.Qrxlevmin, rrc_ptr->cell_resel_cfg.Qrxlevminoffset); } else { Info("Cell selection criteria: not available\n"); } - Info("Current serving cell: %s\n", rrc_ptr->serving_cell->to_string().c_str()); + Info("Current serving cell: %s\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str()); neigh_index = 0; cs_result = cs_result_t::no_cell; state = search_state_t::cell_selection; @@ -546,10 +547,10 @@ proc_outcome_t rrc::cell_selection_proc::start_serv_cell_selection() return proc_outcome_t::success; } - Info("Not camping on serving cell %s. Selecting it...\n", rrc_ptr->serving_cell->to_string().c_str()); + Info("Not camping on serving cell %s. Selecting it...\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str()); state = search_state_t::serv_cell_camp; - if (not rrc_ptr->phy_cell_selector.launch(*rrc_ptr->serving_cell)) { + if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) { Error("Failed to launch PHY Cell Selection\n"); return proc_outcome_t::error; } @@ -560,28 +561,29 @@ proc_outcome_t rrc::cell_selection_proc::start_serv_cell_selection() proc_outcome_t rrc::cell_selection_proc::start_cell_selection() { // Neighbour cells are sorted in descending order of RSRP - for (; neigh_index < rrc_ptr->neighbour_cells.nof_neighbours(); ++neigh_index) { + for (; neigh_index < rrc_ptr->meas_cells.nof_neighbours(); ++neigh_index) { // If the serving cell is stronger, attempt to select it - if (not serv_cell_select_attempted and rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp()) and - rrc_ptr->serving_cell->greater(&rrc_ptr->neighbour_cells[neigh_index])) { + if (not serv_cell_select_attempted and + rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp()) and + rrc_ptr->meas_cells.serving_cell().greater(&rrc_ptr->meas_cells[neigh_index])) { return start_serv_cell_selection(); } /*TODO: CHECK that PLMN matches. Currently we don't receive SIB1 of neighbour cells - * neighbour_cells[i]->plmn_equals(selected_plmn_id) && */ + * meas_cells[i]->plmn_equals(selected_plmn_id) && */ // Matches S criteria - float rsrp = rrc_ptr->neighbour_cells.at(neigh_index).get_rsrp(); + float rsrp = rrc_ptr->meas_cells.at(neigh_index).get_rsrp(); if (rrc_ptr->phy_sync_state != phy_in_sync or - (rrc_ptr->cell_selection_criteria(rsrp) and rsrp > rrc_ptr->serving_cell->get_rsrp() + 5)) { + (rrc_ptr->cell_selection_criteria(rsrp) and rsrp > rrc_ptr->meas_cells.serving_cell().get_rsrp() + 5)) { // currently connected and verifies cell selection criteria // Try to select Cell - rrc_ptr->set_serving_cell(rrc_ptr->neighbour_cells.at(neigh_index).phy_cell, discard_serving); + rrc_ptr->set_serving_cell(rrc_ptr->meas_cells.at(neigh_index).phy_cell, discard_serving); discard_serving = false; - Info("Selected cell: %s\n", rrc_ptr->serving_cell->to_string().c_str()); + Info("Selected cell: %s\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str()); state = search_state_t::cell_selection; - if (not rrc_ptr->phy_cell_selector.launch(*rrc_ptr->serving_cell)) { + if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) { Error("Failed to launch PHY Cell Selection\n"); return proc_outcome_t::error; } @@ -593,7 +595,7 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection() // If serving cell is weaker, but couldn't select neighbors if (serv_cell_select_attempted) { return proc_outcome_t::error; - } else if (rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp())) { + } else if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { return start_serv_cell_selection(); } @@ -634,15 +636,15 @@ srslte::proc_outcome_t rrc::cell_selection_proc::step_serv_cell_camp(const cell_ } rrc_ptr->phy_sync_state = phy_unknown_sync; - rrc_ptr->serving_cell->set_rsrp(-INFINITY); + rrc_ptr->meas_cells.serving_cell().set_rsrp(-INFINITY); Warning("Could not camp on serving cell.\n"); - return neigh_index >= rrc_ptr->neighbour_cells.nof_neighbours() ? proc_outcome_t::error : proc_outcome_t::yield; + return neigh_index >= rrc_ptr->meas_cells.nof_neighbours() ? proc_outcome_t::error : proc_outcome_t::yield; } proc_outcome_t rrc::cell_selection_proc::step_wait_in_sync() { if (rrc_ptr->phy_sync_state == phy_in_sync) { - if (rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp())) { + if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { Info("PHY is in SYNC and cell selection passed\n"); if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, rrc_ptr->ue_required_sibs)) { return proc_outcome_t::error; @@ -681,7 +683,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_config() return proc_outcome_t::yield; } if (serv_cell_cfg_fut.is_success()) { - rrc_ptr->rrc_log->console("Selected cell: %s\n", rrc_ptr->serving_cell->to_string().c_str()); + rrc_ptr->rrc_log->console("Selected cell: %s\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str()); Info("All SIBs of serving cell obtained successfully\n"); cs_result = cs_result_t::changed_cell; return proc_outcome_t::success; @@ -757,12 +759,12 @@ proc_outcome_t rrc::plmn_search_proc::step() } if (cell_search_fut.value()->found == phy_interface_rrc_lte::cell_search_ret_t::CELL_FOUND) { - if (rrc_ptr->serving_cell->has_sib1()) { + if (rrc_ptr->meas_cells.serving_cell().has_sib1()) { // Save PLMN and TAC to NAS - for (uint32_t i = 0; i < rrc_ptr->serving_cell->nof_plmns(); i++) { + for (uint32_t i = 0; i < rrc_ptr->meas_cells.serving_cell().nof_plmns(); i++) { if (nof_plmns < MAX_FOUND_PLMNS) { - found_plmns[nof_plmns].plmn_id = rrc_ptr->serving_cell->get_plmn(i); - found_plmns[nof_plmns].tac = rrc_ptr->serving_cell->get_tac(); + found_plmns[nof_plmns].plmn_id = rrc_ptr->meas_cells.serving_cell().get_plmn(i); + found_plmns[nof_plmns].tac = rrc_ptr->meas_cells.serving_cell().get_tac(); nof_plmns++; } else { Error("No more space for plmns (%d)\n", nof_plmns); @@ -1012,7 +1014,7 @@ proc_outcome_t rrc::process_pcch_proc::step() if (paging.sys_info_mod_present) { Info("Received System Information notification update request.\n"); // invalidate and then update all SIBs of serving cell - rrc_ptr->serving_cell->reset_sibs(); + rrc_ptr->meas_cells.serving_cell().reset_sibs(); // create a serving cell config procedure and push it to callback list if (not rrc_ptr->serv_cell_cfg.launch(&serv_cfg_fut, rrc_ptr->ue_required_sibs)) { @@ -1130,7 +1132,7 @@ rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rr proc_outcome_t rrc::cell_reselection_proc::init() { - if (rrc_ptr->neighbour_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and + if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and rrc_ptr->phy->cell_is_camping()) { // don't bother with cell selection if there are no neighbours and we are already camping return proc_outcome_t::success; @@ -1207,8 +1209,8 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) // Save reestablishment cause and current C-RNTI reest_rnti = uernti.crnti; reest_cause = cause; - reest_source_pci = rrc_ptr->serving_cell->get_pci(); // needed for reestablishment with another cell - reest_source_freq = rrc_ptr->serving_cell->get_earfcn(); + reest_source_pci = rrc_ptr->meas_cells.serving_cell().get_pci(); // needed for reestablishment with another cell + reest_source_freq = rrc_ptr->meas_cells.serving_cell().get_earfcn(); // the initiation of reestablishment procedure as indicates in 3GPP 36.331 Section 5.3.7.2 // Cannot be called from here because it has PHY-MAC re-configuration that should be performed in a different thread @@ -1274,14 +1276,15 @@ srslte::proc_outcome_t rrc::connection_reest_proc::step_cell_reselection() // Cell reselection finished or not started if (rrc_ptr->phy_sync_state == phy_in_sync) { // In-sync, check SIBs - if (rrc_ptr->serving_cell->has_sib1() && rrc_ptr->serving_cell->has_sib2() && rrc_ptr->serving_cell->has_sib3()) { + if (rrc_ptr->meas_cells.serving_cell().has_sib1() && rrc_ptr->meas_cells.serving_cell().has_sib2() && + rrc_ptr->meas_cells.serving_cell().has_sib3()) { Info("In-sync, SIBs available. Going to cell criteria\n"); return cell_criteria(); } else { Info("SIBs missing (%d, %d, %d), launching serving cell configuration procedure\n", - rrc_ptr->serving_cell->has_sib1(), - rrc_ptr->serving_cell->has_sib2(), - rrc_ptr->serving_cell->has_sib3()); + rrc_ptr->meas_cells.serving_cell().has_sib1(), + rrc_ptr->meas_cells.serving_cell().has_sib2(), + rrc_ptr->meas_cells.serving_cell().has_sib3()); std::vector required_sibs = {0, 1, 2}; if (!rrc_ptr->serv_cell_cfg.launch(required_sibs)) { Error("Failed to initiate configure serving cell\n"); @@ -1317,7 +1320,8 @@ proc_outcome_t rrc::connection_reest_proc::step_cell_configuration() // SIBs adquisition not started or finished if (rrc_ptr->phy_sync_state == phy_in_sync) { // In-sync - if (rrc_ptr->serving_cell->has_sib1() && rrc_ptr->serving_cell->has_sib2() && rrc_ptr->serving_cell->has_sib3()) { + if (rrc_ptr->meas_cells.serving_cell().has_sib1() && rrc_ptr->meas_cells.serving_cell().has_sib2() && + rrc_ptr->meas_cells.serving_cell().has_sib3()) { // All SIBs are available return cell_criteria(); } else { @@ -1342,7 +1346,7 @@ proc_outcome_t rrc::connection_reest_proc::step_cell_configuration() srslte::proc_outcome_t rrc::connection_reest_proc::cell_criteria() { // Perform cell selection in accordance to 36.304 - if (rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp())) { + if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { // Actions following cell reselection while T311 is running 5.3.7.3 // Upon selecting a suitable E-UTRA cell, the UE shall: Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n", @@ -1407,7 +1411,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc recfg_r8 = rrc_reconf.crit_exts.c1().rrc_conn_recfg_r8(); asn1::rrc::mob_ctrl_info_s* mob_ctrl_info = &recfg_r8.mob_ctrl_info; - if (recfg_r8.mob_ctrl_info.target_pci == rrc_ptr->serving_cell->get_pci()) { + if (recfg_r8.mob_ctrl_info.target_pci == rrc_ptr->meas_cells.serving_cell().get_pci()) { rrc_ptr->rrc_log->console("Warning: Received HO command to own cell\n"); Warning("Received HO command to own cell\n"); return proc_outcome_t::error; @@ -1419,18 +1423,18 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc recfg_r8.security_cfg_ho.handov_type.intra_lte().next_hop_chaining_count); target_earfcn = (mob_ctrl_info->carrier_freq_present) ? mob_ctrl_info->carrier_freq.dl_carrier_freq - : rrc_ptr->serving_cell->get_earfcn(); + : rrc_ptr->meas_cells.serving_cell().get_earfcn(); if (not rrc_ptr->has_neighbour_cell(target_earfcn, mob_ctrl_info->target_pci)) { rrc_ptr->rrc_log->console("Received HO command to unknown PCI=%d\n", mob_ctrl_info->target_pci); Error("Could not find target cell earfcn=%d, pci=%d\n", - rrc_ptr->serving_cell->get_earfcn(), + rrc_ptr->meas_cells.serving_cell().get_earfcn(), mob_ctrl_info->target_pci); return proc_outcome_t::error; } // Save serving cell and current configuration - ho_src_cell = *rrc_ptr->serving_cell; + ho_src_cell = rrc_ptr->meas_cells.serving_cell(); mac_interface_rrc::ue_rnti_t uernti; rrc_ptr->mac->get_rntis(&uernti); ho_src_rnti = uernti.crnti; @@ -1450,8 +1454,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(srsue::cell_select_event_t ev) return proc_outcome_t::yield; } // Check if cell has not been deleted in the meantime - cell_t* target_cell = - rrc_ptr->neighbour_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci); + cell_t* target_cell = rrc_ptr->meas_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci); if (target_cell == nullptr) { Error("Cell removed from list of neighbours. Aborting handover preparation\n"); return proc_outcome_t::error; @@ -1460,7 +1463,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(srsue::cell_select_event_t ev) if (not ev.cs_ret) { Error("Could not synchronize with target cell %s. Removing cell and trying to return to source %s\n", target_cell->to_string().c_str(), - rrc_ptr->serving_cell->to_string().c_str()); + rrc_ptr->meas_cells.serving_cell().to_string().c_str()); // Remove cell from list to avoid cell re-selection, picking the same cell target_cell->set_rsrp(-INFINITY); @@ -1503,7 +1506,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(srsue::cell_select_event_t ev) } rrc_ptr->usim->generate_as_keys_ho( - recfg_r8.mob_ctrl_info.target_pci, rrc_ptr->serving_cell->get_earfcn(), ncc, &rrc_ptr->sec_cfg); + recfg_r8.mob_ctrl_info.target_pci, rrc_ptr->meas_cells.serving_cell().get_earfcn(), ncc, &rrc_ptr->sec_cfg); rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg); @@ -1539,7 +1542,7 @@ srslte::proc_outcome_t rrc::ho_proc::step() } cell_t* target_cell = - rrc_ptr->neighbour_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci); + rrc_ptr->meas_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci); if (not rrc_ptr->phy_cell_selector.launch(*target_cell)) { Error("Failed to launch the selection of target cell %s\n", target_cell->to_string().c_str()); return proc_outcome_t::error;