mirror of https://github.com/PentHertz/srsLTE.git
moved serving cell to meas_cell_list
This commit is contained in:
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;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
rrc_log->debug("MEAS: Processing measurement of %zd cells\n", meas.size());
|
||||
|
||||
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(¤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
|
||||
|
|
|
@ -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…
Reference in New Issue