diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index f41e9348f..d3f545151 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -64,6 +64,7 @@ public: asn1::rrc::meas_obj_to_add_mod_list_l& meas_objs() { return var_meas.meas_obj_list; } asn1::rrc::report_cfg_to_add_mod_list_l& rep_cfgs() { return var_meas.report_cfg_list; } asn1::rrc::meas_id_to_add_mod_list_l& meas_ids() { return var_meas.meas_id_list; } + std::string to_string() const; static var_meas_cfg_t make(const asn1::rrc::meas_cfg_s& meas_cfg); diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index a19c3298d..379c2f00d 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -386,6 +386,13 @@ void var_meas_cfg_t::compute_diff_quant_cfg(const var_meas_cfg_t& target_cfg, as } } +std::string var_meas_cfg_t::to_string() const +{ + asn1::json_writer js; + var_meas.to_json(js); + return js.to_string(); +} + /** * Convert MeasCfg asn1 struct to var_meas_cfg_t * @param meas_cfg @@ -787,6 +794,8 @@ bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(const var_meas_cfg_t& source // Update user varMeasCfg to target rrc_ue->mobility_handler->ue_var_meas = target_var_ptr; + rrc_log->debug_long( + "New rnti=0x%x varMeasConfig: %s", rrc_ue->rnti, rrc_ue->mobility_handler->ue_var_meas->to_string().c_str()); return meas_cfg_present; } @@ -1176,6 +1185,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho // Save measConfig ue_var_meas = std::make_shared(var_meas_cfg_t::make(ho_prep.as_cfg.source_meas_cfg)); + rrc_log->debug_long("New rnti=0x%x varMeasConfig: %s", rrc_ue->rnti, ue_var_meas->to_string().c_str()); return true; } diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 95f3a799c..01be3b211 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -360,9 +360,10 @@ private: void log_mac_config_dedicated(); void apply_rr_config_common(asn1::rrc::rr_cfg_common_s* config, bool send_lower_layers); - bool apply_rr_config_dedicated(const asn1::rrc::rr_cfg_ded_s* cnfg); + bool apply_rr_config_dedicated(const asn1::rrc::rr_cfg_ded_s* cnfg, bool is_handover = false); + bool apply_rr_config_dedicated_on_ho_complete(const asn1::rrc::rr_cfg_ded_s& cnfg); void apply_scell_config(asn1::rrc::rrc_conn_recfg_r8_ies_s* reconfig_r8); - void apply_phy_config_dedicated(const asn1::rrc::phys_cfg_ded_s& phy_cnfg); + void apply_phy_config_dedicated(const asn1::rrc::phys_cfg_ded_s& phy_cnfg, bool is_handover); void apply_phy_scell_config(const asn1::rrc::scell_to_add_mod_r10_s& scell_config); void apply_mac_config_dedicated_default(); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 14b9b3517..d246baac6 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -2016,9 +2016,14 @@ void rrc::set_phy_config_dedicated_default() } // Apply provided PHY config -void rrc::apply_phy_config_dedicated(const phys_cfg_ded_s& phy_cnfg) +void rrc::apply_phy_config_dedicated(const phys_cfg_ded_s& phy_cnfg, bool is_handover) { set_phy_cfg_t_dedicated_cfg(¤t_phy_cfg, phy_cnfg); + if (is_handover) { + current_phy_cfg.ul_cfg.pucch.sr_configured = false; + current_phy_cfg.dl_cfg.cqi_report.periodic_configured = false; + current_phy_cfg.dl_cfg.cqi_report.aperiodic_configured = false; + } log_phy_config_dedicated(); @@ -2108,12 +2113,19 @@ void rrc::apply_mac_config_dedicated_default() log_mac_config_dedicated(); } -bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg) +/** + * Applies RadioResource Config changes to lower layers + * @param cnfg + * @param is_handover - whether the SR, CQI, SRS, measurement configs take effect immediately (see TS + * 36.331 5.3.5.4) + * @return + */ +bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg, bool is_handover) { if (cnfg->phys_cfg_ded_present) { - apply_phy_config_dedicated(cnfg->phys_cfg_ded); + apply_phy_config_dedicated(cnfg->phys_cfg_ded, is_handover); // Apply SR configuration to MAC - if (cnfg->phys_cfg_ded.sched_request_cfg_present) { + if (not is_handover and cnfg->phys_cfg_ded.sched_request_cfg_present) { set_mac_cfg_t_sched_request_cfg(¤t_mac_cfg, cnfg->phys_cfg_ded.sched_request_cfg); } } @@ -2125,7 +2137,7 @@ bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg) set_mac_cfg_t_main_cfg(¤t_mac_cfg, cnfg->mac_main_cfg.explicit_value()); } mac->set_config(current_mac_cfg); - } else if (cnfg->phys_cfg_ded.sched_request_cfg_present) { + } else if (not is_handover and cnfg->phys_cfg_ded.sched_request_cfg_present) { // If MAC-main not set but SR config is set, use directly mac->set_config to update config mac->set_config(current_mac_cfg); log_mac_config_dedicated(); @@ -2164,6 +2176,29 @@ bool rrc::apply_rr_config_dedicated(const rr_cfg_ded_s* cnfg) return true; } +bool rrc::apply_rr_config_dedicated_on_ho_complete(const rr_cfg_ded_s& cnfg) +{ + // Apply SR+CQI configuration to PHY + if (cnfg.phys_cfg_ded_present) { + current_phy_cfg.ul_cfg.pucch.sr_configured = cnfg.phys_cfg_ded.sched_request_cfg_present; + if (cnfg.phys_cfg_ded.cqi_report_cfg_present) { + current_phy_cfg.dl_cfg.cqi_report.periodic_configured = + cnfg.phys_cfg_ded.cqi_report_cfg.cqi_report_periodic_present and + cnfg.phys_cfg_ded.cqi_report_cfg.cqi_report_periodic.type().value == setup_opts::setup; + current_phy_cfg.dl_cfg.cqi_report.aperiodic_configured = + cnfg.phys_cfg_ded.cqi_report_cfg.cqi_report_mode_aperiodic_present; + } + phy->set_config(current_phy_cfg); + } + + // Apply SR configuration to MAC + if (cnfg.phys_cfg_ded.sched_request_cfg_present) { + set_mac_cfg_t_sched_request_cfg(¤t_mac_cfg, cnfg.phys_cfg_ded.sched_request_cfg); + mac->set_config(current_mac_cfg); + } + return true; +} + /* * Extracts and applies SCell configuration from an ASN.1 reconfiguration struct */ diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index fe11f872d..02d482f6f 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1486,7 +1486,8 @@ srslte::proc_outcome_t rrc::ho_proc::step() rrc_ptr->apply_rr_config_common(&recfg_r8.mob_ctrl_info.rr_cfg_common, !recfg_r8.rr_cfg_ded_present); if (recfg_r8.rr_cfg_ded_present) { - rrc_ptr->apply_rr_config_dedicated(&recfg_r8.rr_cfg_ded); + // Note: Disable SR config until RA completion + rrc_ptr->apply_rr_config_dedicated(&recfg_r8.rr_cfg_ded, true); } cell_t* target_cell = @@ -1515,22 +1516,27 @@ srslte::proc_outcome_t rrc::ho_proc::react(ra_completed_ev ev) Warning("Received unexpected RA Complete Event\n"); return proc_outcome_t::yield; } + bool ho_successful = ev.success and not sec_cfg_failed; - if (ev.success and not sec_cfg_failed) { + // TS 36.331, sec. 5.3.5.4, last "1>" + rrc_ptr->t304.stop(); + rrc_ptr->apply_rr_config_dedicated_on_ho_complete(recfg_r8.rr_cfg_ded); + + if (ho_successful) { if (not rrc_ptr->measurements->parse_meas_config(&recfg_r8, true, ho_src_cell.get_earfcn())) { Error("Parsing measurementConfig. TODO: Send ReconfigurationReject\n"); + ho_successful = false; } } - Info("HO %ssuccessful\n", ev.success ? "" : "un"); - rrc_ptr->rrc_log->console("HO %ssuccessful\n", ev.success ? "" : "un"); - - return ev.success ? proc_outcome_t::success : proc_outcome_t::error; + return ho_successful ? proc_outcome_t::success : proc_outcome_t::error; } void rrc::ho_proc::then(const srslte::proc_state_t& result) { - Info("Finished HO Preparation %s\n", result.is_success() ? "successfully" : "with error"); + Info("HO %ssuccessful\n", result.is_success() ? "" : "un"); + rrc_ptr->rrc_log->console("HO %ssuccessful\n", result.is_success() ? "" : "un"); + if (result.is_success()) { rrc_ptr->t304.stop(); } else if (rrc_ptr->t304.is_running()) {