From fc49b5a030f05dc235b465c188aa9f3c8d5820d0 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 25 Sep 2020 20:28:50 +0200 Subject: [PATCH] implemented rrc reconfiguration procedure that includes a continuation when phy configuration is complete --- srsue/hdr/stack/rrc/rrc.h | 3 +- srsue/hdr/stack/rrc/rrc_procedures.h | 20 +++++ srsue/src/stack/rrc/rrc.cc | 80 ++++--------------- srsue/src/stack/rrc/rrc_procedures.cc | 108 ++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 68 deletions(-) diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index a20d773e1..8152c45b4 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -295,6 +295,7 @@ private: class serving_cell_config_proc; class cell_selection_proc; class connection_request_proc; + class connection_reconf_no_ho_proc; class plmn_search_proc; class process_pcch_proc; class go_idle_proc; @@ -312,6 +313,7 @@ private: srslte::proc_t cell_reselector; srslte::proc_t connection_reest; srslte::proc_t ho_handler; + srslte::proc_t conn_recfg_proc; srslte::proc_manager_list_t callback_list; @@ -345,7 +347,6 @@ private: void parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu); // Helpers - bool con_reconfig(const asn1::rrc::rrc_conn_recfg_s& reconfig); void con_reconfig_failed(); bool con_reconfig_ho(const asn1::rrc::rrc_conn_recfg_s& reconfig); void ho_failed(); diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 32262a53f..9dd058228 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -197,6 +197,26 @@ private: srslte::proc_future_t serv_cfg_fut; }; +class rrc::connection_reconf_no_ho_proc +{ +public: + explicit connection_reconf_no_ho_proc(rrc* parent_); + srslte::proc_outcome_t init(const asn1::rrc::rrc_conn_recfg_s& recfg_); + srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; } + static const char* name() { return "Connection Reconfiguration"; } + srslte::proc_outcome_t react(const bool& config_complete); + void then(const srslte::proc_state_t& result); + +private: + srslte::proc_outcome_t handle_recfg_complete(); + + // const + rrc* rrc_ptr; + // args + asn1::rrc::rrc_conn_recfg_r8_ies_s rx_recfg; + enum state_t { wait_scell_config, wait_phy_config } state; +}; + class rrc::process_pcch_proc { public: diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 39264b2a6..917570ffe 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -68,7 +68,8 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) : plmn_searcher(this), cell_reselector(this), connection_reest(this), - ho_handler(this) + ho_handler(this), + conn_recfg_proc(this) {} rrc::~rrc() = default; @@ -360,7 +361,13 @@ void rrc::cell_select_complete(bool cs_ret) phy_ctrl->cell_selection_completed(cs_ret); } -void rrc::set_config_complete(bool status) {} +void rrc::set_config_complete(bool status) +{ + // Signal Reconfiguration Procedure that PHY configuration has completed + if (conn_recfg_proc.is_busy()) { + conn_recfg_proc.trigger(status); + } +} void rrc::set_scell_complete(bool status) {} @@ -906,69 +913,6 @@ void rrc::start_go_idle() callback_list.add_proc(idle_setter); } -// Handle RRC Reconfiguration without MobilityInformation Section 5.3.5.3 -bool rrc::con_reconfig(const rrc_conn_recfg_s& reconfig) -{ - const rrc_conn_recfg_r8_ies_s* reconfig_r8 = &reconfig.crit_exts.c1().rrc_conn_recfg_r8(); - - // If first message after reestablishment, resume SRB2 and all DRB - if (reestablishment_successful) { - for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { - if (rlc->has_bearer(i)) { - rlc->resume_bearer(i); - } - } - } - - // If this is the first con_reconfig after a reestablishment - if (reestablishment_successful) { - // Reestablish PDCP and RLC for SRB2 and all DRB - // TODO: Which is the maximum LCID? - reestablishment_successful = false; - for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { - if (rlc->has_bearer(i)) { - pdcp->reestablish(i); - rlc->reestablish(i); - } - } - } - - // Apply RR config as in 5.3.10 - if (reconfig_r8->rr_cfg_ded_present) { - if (!apply_rr_config_dedicated(&reconfig_r8->rr_cfg_ded)) { - return false; - } - } - - // Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside apply_scell_config() - // Note that apply_scell_config() calls set_scell() and set_config() which run in the background. - rrc_conn_recfg_r8_ies_s reconfig_r8_ = *reconfig_r8; - apply_scell_config(&reconfig_r8_, true); - - if (!measurements->parse_meas_config( - reconfig_r8, reestablishment_successful, connection_reest.get()->get_source_earfcn())) { - return false; - } - - // FIXME-@frankist: From here to the end need to be processed when set_config_complete() is called - send_rrc_con_reconfig_complete(); - - unique_byte_buffer_t nas_sdu; - for (uint32_t i = 0; i < reconfig_r8->ded_info_nas_list.size(); i++) { - nas_sdu = srslte::allocate_unique_buffer(*pool); - if (nas_sdu.get()) { - memcpy(nas_sdu->msg, reconfig_r8->ded_info_nas_list[i].data(), reconfig_r8->ded_info_nas_list[i].size()); - nas_sdu->N_bytes = reconfig_r8->ded_info_nas_list[i].size(); - nas->write_pdu(RB_ID_SRB1, std::move(nas_sdu)); - } else { - rrc_log->error("Fatal Error: Couldn't allocate PDU in %s.\n", __FUNCTION__); - return false; - } - } - - return true; -} - // HO failure from T304 expiry 5.3.5.6 void rrc::ho_failed() { @@ -1004,9 +948,11 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, const rrc_conn_recfg_s& reconfi if (reconfig_r8.mob_ctrl_info_present) { con_reconfig_ho(reconfig); } else { - if (!con_reconfig(reconfig)) { - con_reconfig_failed(); + if (not conn_recfg_proc.launch(reconfig)) { + rrc_log->error("Unable to launch Handover Preparation procedure\n"); + return; } + callback_list.add_proc(conn_recfg_proc); } } diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 806ab62a5..b732c34bb 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -940,6 +940,114 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_ } } +/****************************************** + * Connection Reconfiguration Procedure + *****************************************/ + +// Handle RRC Reconfiguration without MobilityInformation Section 5.3.5.3 +rrc::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(srsue::rrc* parent_) : rrc_ptr(parent_) {} + +srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& recfg_) +{ + Info("Starting...\n"); + rx_recfg = recfg_.crit_exts.c1().rrc_conn_recfg_r8(); + + // If first message after reestablishment, resume SRB2 and all DRB + if (rrc_ptr->reestablishment_successful) { + for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { + if (rrc_ptr->rlc->has_bearer(i)) { + rrc_ptr->rlc->resume_bearer(i); + } + } + } + + // If this is the first con_reconfig after a reestablishment + if (rrc_ptr->reestablishment_successful) { + // Reestablish PDCP and RLC for SRB2 and all DRB + // TODO: Which is the maximum LCID? + rrc_ptr->reestablishment_successful = false; + for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) { + if (rrc_ptr->rlc->has_bearer(i)) { + rrc_ptr->pdcp->reestablish(i); + rrc_ptr->rlc->reestablish(i); + } + } + } + + // Apply RR config as in 5.3.10 + if (rx_recfg.rr_cfg_ded_present) { + if (!rrc_ptr->apply_rr_config_dedicated(&rx_recfg.rr_cfg_ded)) { + return proc_outcome_t::error; + } + } + + // Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside apply_scell_config() + // Note that apply_scell_config() calls set_scell() and set_config() which run in the background. + rrc_ptr->apply_scell_config(&rx_recfg, true); + + if (!rrc_ptr->measurements->parse_meas_config( + &rx_recfg, rrc_ptr->reestablishment_successful, rrc_ptr->connection_reest.get()->get_source_earfcn())) { + return proc_outcome_t::error; + } + + // Wait for PHY configurations to be complete + if (std::count(&rrc_ptr->current_scell_configured[0], &rrc_ptr->current_scell_configured[SRSLTE_MAX_CARRIERS], true) > + 0) { + state = wait_scell_config; + } else { + state = wait_phy_config; + } + + return proc_outcome_t::yield; +} + +srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& config_complete) +{ + if (not config_complete) { + rrc_ptr->rrc_log->error("Failed to config PHY\n"); + return proc_outcome_t::error; + } + + // in case there are scell to configure, wait for second phy configuration + if (state == wait_scell_config) { + state = wait_phy_config; + return proc_outcome_t::yield; + } + + return handle_recfg_complete(); +} + +srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::handle_recfg_complete() +{ + rrc_ptr->send_rrc_con_reconfig_complete(); + + srslte::unique_byte_buffer_t nas_sdu; + for (uint32_t i = 0; i < rx_recfg.ded_info_nas_list.size(); i++) { + nas_sdu = srslte::allocate_unique_buffer(*rrc_ptr->pool); + if (nas_sdu.get()) { + memcpy(nas_sdu->msg, rx_recfg.ded_info_nas_list[i].data(), rx_recfg.ded_info_nas_list[i].size()); + nas_sdu->N_bytes = rx_recfg.ded_info_nas_list[i].size(); + rrc_ptr->nas->write_pdu(RB_ID_SRB1, std::move(nas_sdu)); + } else { + rrc_ptr->rrc_log->error("Fatal Error: Couldn't allocate PDU in %s.\n", __FUNCTION__); + return proc_outcome_t::error; + } + } + + return proc_outcome_t::success; +} + +void rrc::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result) +{ + if (result.is_success()) { + rrc_ptr->rrc_log->info("Finished %s successfully\n", name()); + return; + } + + // Section 5.3.5.5 - Reconfiguration failure + rrc_ptr->con_reconfig_failed(); +} + /************************************** * Process PCCH procedure *************************************/