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

This commit is contained in:
Ismael Gomez 2022-02-01 22:54:22 +01:00
parent bdbfc3478b
commit 7f8ac07b65
6 changed files with 60 additions and 11 deletions

View File

@ -247,6 +247,10 @@ public:
// serving cell handling
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; }
const T& serving_cell() const { return *serv_cell; }
@ -263,6 +267,9 @@ private:
unique_meas_cell serv_cell;
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

View File

@ -129,16 +129,18 @@ sync::~sync()
void sync::stop()
{
running = false;
wait_thread_finish();
std::lock_guard<std::mutex> lock(intra_freq_cfg_mutex);
worker_com->semaphore.wait_all();
for (auto& q : intra_freq_meas) {
q->stop();
}
// Reset (stop Rx stream) as soon as possible to avoid base-band Rx buffer overflow
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()

View File

@ -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);
// 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();
}
}
@ -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);
} 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);
} else {
meas_cells.set_scell_cc_idx(scell_config.scell_idx_r10, earfcn, scell.id);
}
}

View File

@ -434,6 +434,25 @@ int meas_cell_list<T>::set_serving_cell(phy_cell_t phy_cell, bool discard_servin
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>
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)

View File

@ -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)
{
meas_cfg.ho_reest_finish(src_earfcn, dst_earfcn);
update_phy();
}
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) {
// report neighbour cells only
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(),
cell.pci,
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));
var_meas.carrier_freq);
continue;
}
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;
float Ms = is_rsrp(report_cfg.trigger_quant.value) ? serv_cell->get_rsrp() : serv_cell->get_rsrq();
if (!std::isnormal(Ms)) {
logger.debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers", Ms);
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) {
// A1 & A2 are for serving cell only
if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3) {

View File

@ -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;
rrc_ptr->measurements->ho_reest_actions(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
// 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;
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
// directed at the old RNTI.
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");
rrc_ptr->t304.stop();
rrc_ptr->measurements->update_phy();
}
} // namespace srsue