srsue: fix A1/S2 reports with CA. Fix some unstability issues when doing HO with multiple carriers due to frequent call to update_phy

master
Ismael Gomez 3 years ago
parent bdbfc3478b
commit 7f8ac07b65

@ -247,6 +247,10 @@ public:
// serving cell handling // serving cell handling
int set_serving_cell(phy_cell_t phy_cell, bool discard_serving); int set_serving_cell(phy_cell_t phy_cell, bool discard_serving);
// Set serving cell and earfcn for each cc_idx
void set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci);
bool get_scell_cc_idx(uint32_t earfcn, uint32_t& pci);
T& serving_cell() { return *serv_cell; } T& serving_cell() { return *serv_cell; }
const T& serving_cell() const { return *serv_cell; } const T& serving_cell() const { return *serv_cell; }
@ -263,6 +267,9 @@ private:
unique_meas_cell serv_cell; unique_meas_cell serv_cell;
std::vector<unique_meas_cell> neighbour_cells; std::vector<unique_meas_cell> neighbour_cells;
// store serving pci and earfcn for each carrier
std::array<std::pair<uint32_t, uint32_t>, SRSRAN_MAX_CARRIERS> current_cell_pci_earfcn = {};
}; };
} // namespace srsue } // namespace srsue

@ -129,16 +129,18 @@ sync::~sync()
void sync::stop() void sync::stop()
{ {
running = false; running = false;
wait_thread_finish();
std::lock_guard<std::mutex> lock(intra_freq_cfg_mutex); std::lock_guard<std::mutex> lock(intra_freq_cfg_mutex);
worker_com->semaphore.wait_all();
for (auto& q : intra_freq_meas) { for (auto& q : intra_freq_meas) {
q->stop(); q->stop();
} }
// Reset (stop Rx stream) as soon as possible to avoid base-band Rx buffer overflow // Reset (stop Rx stream) as soon as possible to avoid base-band Rx buffer overflow
radio_h->reset(); radio_h->reset();
// let the sync FSM finish before waiting for workers semaphores to avoid workers locking
wait_thread_finish();
worker_com->semaphore.wait_all();
} }
void sync::reset() void sync::reset()

@ -457,7 +457,8 @@ void rrc::process_new_cell_meas(const std::vector<phy_meas_t>& meas)
bool neighbour_added = meas_cells.process_new_cell_meas(meas, filter); 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 // Instruct measurements subclass to update phy with new cells to measure based on strongest neighbours
if (state == RRC_STATE_CONNECTED && neighbour_added) { // Avoid updating PHY while HO procedure is busy
if (state == RRC_STATE_CONNECTED && neighbour_added && !ho_handler.is_busy()) {
measurements->update_phy(); measurements->update_phy();
} }
} }
@ -2482,6 +2483,8 @@ void rrc::apply_phy_scell_config(const scell_to_add_mod_r10_s& scell_config, boo
logger.error("Adding SCell cc_idx=%d", scell_config.scell_idx_r10); logger.error("Adding SCell cc_idx=%d", scell_config.scell_idx_r10);
} else if (!phy_ctrl->set_cell_config(scell_cfg, scell_config.scell_idx_r10)) { } else if (!phy_ctrl->set_cell_config(scell_cfg, scell_config.scell_idx_r10)) {
logger.error("Setting SCell configuration for cc_idx=%d", scell_config.scell_idx_r10); logger.error("Setting SCell configuration for cc_idx=%d", scell_config.scell_idx_r10);
} else {
meas_cells.set_scell_cc_idx(scell_config.scell_idx_r10, earfcn, scell.id);
} }
} }

@ -434,6 +434,25 @@ int meas_cell_list<T>::set_serving_cell(phy_cell_t phy_cell, bool discard_servin
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
template <class T>
void meas_cell_list<T>::set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci)
{
current_cell_pci_earfcn[cc_idx].first = earfcn;
current_cell_pci_earfcn[cc_idx].second = pci;
}
template <class T>
bool meas_cell_list<T>::get_scell_cc_idx(uint32_t earfcn, uint32_t& pci)
{
for (auto& cell : current_cell_pci_earfcn) {
if (cell.first == earfcn) {
pci = cell.second;
return true;
}
}
return false;
}
template <class T> template <class T>
bool meas_cell_list<T>::process_new_cell_meas(const std::vector<phy_meas_t>& meas, bool meas_cell_list<T>::process_new_cell_meas(const std::vector<phy_meas_t>& meas,
const std::function<void(T&, const phy_meas_t&)>& filter_meas) const std::function<void(T&, const phy_meas_t&)>& filter_meas)

@ -118,7 +118,6 @@ bool rrc::rrc_meas::parse_meas_config(const rrc_conn_recfg_r8_ies_s* mob_reconf_
void rrc::rrc_meas::ho_reest_actions(const uint32_t src_earfcn, const uint32_t dst_earfcn) void rrc::rrc_meas::ho_reest_actions(const uint32_t src_earfcn, const uint32_t dst_earfcn)
{ {
meas_cfg.ho_reest_finish(src_earfcn, dst_earfcn); meas_cfg.ho_reest_finish(src_earfcn, dst_earfcn);
update_phy();
} }
void rrc::rrc_meas::run_tti() void rrc::rrc_meas::run_tti()
@ -224,12 +223,10 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s*
for (auto& cell : var_meas.cell_triggered_list) { for (auto& cell : var_meas.cell_triggered_list) {
// report neighbour cells only // report neighbour cells only
if (cell.pci == serv_cell->get_pci() && cell.earfcn == serv_cell->get_earfcn()) { if (cell.pci == serv_cell->get_pci() && cell.earfcn == serv_cell->get_earfcn()) {
logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f", logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d",
neigh_list.size(), neigh_list.size(),
cell.pci, cell.pci,
var_meas.carrier_freq, var_meas.carrier_freq);
rrc_ptr->get_cell_rsrp(var_meas.carrier_freq, cell.pci),
rrc_ptr->get_cell_rsrq(var_meas.carrier_freq, cell.pci));
continue; continue;
} }
if (neigh_list.size() <= var_meas.report_cfg_eutra.max_report_cells) { if (neigh_list.size() <= var_meas.report_cfg_eutra.max_report_cells) {
@ -767,16 +764,31 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i
} }
}; };
eutra_event_s::event_id_c_ event_id = report_cfg.trigger_type.event().event_id;
// For A1/A2 events, get serving cell from current carrier
if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3 &&
meas_obj.carrier_freq != serv_cell->get_earfcn()) {
uint32_t scell_pci = 0;
if (!rrc_ptr->meas_cells.get_scell_cc_idx(meas_obj.carrier_freq, scell_pci)) {
logger.error("MEAS: Could not find serving cell for carrier earfcn=%d", meas_obj.carrier_freq);
return;
}
serv_cell = rrc_ptr->meas_cells.get_neighbour_cell_handle(meas_obj.carrier_freq, scell_pci);
if (!serv_cell) {
logger.error(
"MEAS: Could not find serving cell for carrier earfcn=%d and pci=%d", meas_obj.carrier_freq, scell_pci);
return;
}
}
double hyst = 0.5 * report_cfg.trigger_type.event().hysteresis; double hyst = 0.5 * report_cfg.trigger_type.event().hysteresis;
float Ms = is_rsrp(report_cfg.trigger_quant.value) ? serv_cell->get_rsrp() : serv_cell->get_rsrq(); float Ms = is_rsrp(report_cfg.trigger_quant.value) ? serv_cell->get_rsrp() : serv_cell->get_rsrq();
if (!std::isnormal(Ms)) { if (!std::isnormal(Ms)) {
logger.debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers", Ms); logger.debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers", Ms);
return; return;
} }
eutra_event_s::event_id_c_ event_id = report_cfg.trigger_type.event().event_id;
if (report_cfg.trigger_type.type() == report_cfg_eutra_s::trigger_type_c_::types::event) { if (report_cfg.trigger_type.type() == report_cfg_eutra_s::trigger_type_c_::types::event) {
// A1 & A2 are for serving cell only // A1 & A2 are for serving cell only
if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3) { if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3) {

@ -1555,6 +1555,8 @@ srsran::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_co
// 1> perform the measurement related actions as specified in 5.5.6.1; // 1> perform the measurement related actions as specified in 5.5.6.1;
rrc_ptr->measurements->ho_reest_actions(rrc_ptr->get_serving_cell()->get_earfcn(), rrc_ptr->measurements->ho_reest_actions(rrc_ptr->get_serving_cell()->get_earfcn(),
rrc_ptr->get_serving_cell()->get_earfcn()); rrc_ptr->get_serving_cell()->get_earfcn());
// Update PHY measurements after HO Reestablishment actions.
rrc_ptr->measurements->update_phy();
// 1> submit the RRCConnectionReestablishmentComplete message to lower layers for transmission, upon which the // 1> submit the RRCConnectionReestablishmentComplete message to lower layers for transmission, upon which the
// procedure ends; // procedure ends;
@ -1738,6 +1740,8 @@ srsran::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc
// perform the measurement related actions as specified in 5.5.6.1; // perform the measurement related actions as specified in 5.5.6.1;
rrc_ptr->measurements->ho_reest_actions(ho_src_cell.earfcn, target_earfcn); rrc_ptr->measurements->ho_reest_actions(ho_src_cell.earfcn, target_earfcn);
// Do not update PHY measurements here since it will be updated after the HO procedure finishes
// Note: We delay the enqueuing of RRC Reconf Complete message to avoid that the message goes in an UL grant // Note: We delay the enqueuing of RRC Reconf Complete message to avoid that the message goes in an UL grant
// directed at the old RNTI. // directed at the old RNTI.
rrc_ptr->task_sched.defer_callback(4, [this]() { rrc_ptr->task_sched.defer_callback(4, [this]() {
@ -1796,6 +1800,8 @@ void rrc::ho_proc::then(const srsran::proc_state_t& result)
srsran::console("HO %ssuccessful\n", result.is_success() ? "" : "un"); srsran::console("HO %ssuccessful\n", result.is_success() ? "" : "un");
rrc_ptr->t304.stop(); rrc_ptr->t304.stop();
rrc_ptr->measurements->update_phy();
} }
} // namespace srsue } // namespace srsue

Loading…
Cancel
Save