moved serving cell to meas_cell_list

master
Francisco Paisana 4 years ago
parent 928459408e
commit d746115130

@ -238,11 +238,13 @@ private:
}
}
// List of strongest neighbour cell
cell_list neighbour_cells;
// Measurements private subclass
class rrc_meas;
std::unique_ptr<rrc_meas> measurements;
typedef std::unique_ptr<cell_t> unique_cell_t;
unique_cell_t serving_cell = nullptr;
// List of strongest neighbour cell
using unique_cell_t = std::unique_ptr<cell_t>;
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<rrc_meas> measurements;
// Interface from rrc_meas
void send_srb1_msg(const asn1::rrc::ul_dcch_msg_s& msg);
std::set<uint32_t> get_cells(const uint32_t earfcn);

@ -131,20 +131,54 @@ private:
std::map<uint32_t, uint32_t> 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 <typename T>
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 <typename T>
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 <typename T, typename U>
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<cell_t> 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<phy_meas_t>& meas,
const std::function<void(cell_t&, const phy_meas_t&)>& 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<unique_cell_t>::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<unique_cell_t> neighbour_cells;
};

@ -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<rrc_meas>(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<phy_meas_t>& meas)
{
bool neighbour_added = false;
const static std::function<void(cell_t&, const phy_meas_t&)> 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<phy_meas_t>& 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<uint32_t> 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(&current_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

@ -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<uint32_t> cell_list::get_neighbour_pcis(uint32_t earfcn) const
std::set<uint32_t> meas_cell_list::get_neighbour_pcis(uint32_t earfcn) const
{
std::set<uint32_t> pcis = {};
for (const unique_cell_t& cell : neighbour_cells) {
@ -316,9 +323,73 @@ std::set<uint32_t> 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<phy_meas_t>& meas,
const std::function<void(cell_t&, const phy_meas_t&)>& 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

@ -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<uint32_t>&
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<uint32_t> 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;

Loading…
Cancel
Save