From 5242f9422bb65786cd26137db9cde12ed7adf4f6 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 27 Aug 2020 11:14:30 +0100 Subject: [PATCH] fix deadlock in handover --- srsue/hdr/stack/rrc/rrc_procedures.h | 1 + srsue/src/stack/rrc/rrc.cc | 2 +- srsue/src/stack/rrc/rrc_procedures.cc | 79 ++++++++++++++------------- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index cdab86c2e..0d3e66664 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -307,6 +307,7 @@ private: // state uint32_t target_earfcn; + bool sec_cfg_failed = false; enum state_t { launch_phy_cell_select, wait_phy_cell_select_complete, wait_ra_completion } state; }; diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index a9649e5e4..14b9b3517 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -887,7 +887,7 @@ bool rrc::con_reconfig(const rrc_conn_recfg_s& reconfig) apply_scell_config(&reconfig_r8_); // notify back RRC - task_sched.defer_task([this, reconfig_r8_]() { + task_sched.notify_background_task_result([this, reconfig_r8_]() { const rrc_conn_recfg_r8_ies_s* reconfig_r8 = &reconfig_r8_; if (!measurements->parse_meas_config( diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 1fa9e85bd..fe11f872d 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1348,6 +1348,7 @@ rrc::ho_proc::ho_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) {} srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc_reconf) { Info("Starting...\n"); + sec_cfg_failed = false; 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; @@ -1416,46 +1417,50 @@ srslte::proc_outcome_t rrc::ho_proc::react(const bool& cs_ret) rrc_ptr->set_serving_cell(target_cell->phy_cell, false); // Extract and apply scell config if any - rrc_ptr->apply_scell_config(&recfg_r8); - - if (recfg_r8.mob_ctrl_info.rach_cfg_ded_present) { - Info("Starting non-contention based RA with preamble_idx=%d, mask_idx=%d\n", - recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_preamb_idx, - recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_prach_mask_idx); - rrc_ptr->mac->start_noncont_ho(recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_preamb_idx, - recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_prach_mask_idx); - } else { - Info("Starting contention-based RA\n"); - rrc_ptr->mac->start_cont_ho(); - } - - int ncc = -1; - if (recfg_r8.security_cfg_ho_present) { - auto& sec_intralte = recfg_r8.security_cfg_ho.handov_type.intra_lte(); - ncc = sec_intralte.next_hop_chaining_count; - if (sec_intralte.key_change_ind) { - rrc_ptr->rrc_log->console("keyChangeIndicator in securityConfigHO not supported\n"); - return proc_outcome_t::error; - } - if (sec_intralte.security_algorithm_cfg_present) { - rrc_ptr->sec_cfg.cipher_algo = - (srslte::CIPHERING_ALGORITHM_ID_ENUM)sec_intralte.security_algorithm_cfg.ciphering_algorithm.to_number(); - rrc_ptr->sec_cfg.integ_algo = - (srslte::INTEGRITY_ALGORITHM_ID_ENUM)sec_intralte.security_algorithm_cfg.integrity_prot_algorithm.to_number(); - Info("Changed Ciphering to %s and Integrity to %s\n", - srslte::ciphering_algorithm_id_text[rrc_ptr->sec_cfg.cipher_algo], - srslte::integrity_algorithm_id_text[rrc_ptr->sec_cfg.integ_algo]); - } - } + rrc_ptr->task_sched.enqueue_background_task([this](uint32_t wid) { + rrc_ptr->apply_scell_config(&recfg_r8); + + rrc_ptr->task_sched.notify_background_task_result([this]() { + if (recfg_r8.mob_ctrl_info.rach_cfg_ded_present) { + Info("Starting non-contention based RA with preamble_idx=%d, mask_idx=%d\n", + recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_preamb_idx, + recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_prach_mask_idx); + rrc_ptr->mac->start_noncont_ho(recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_preamb_idx, + recfg_r8.mob_ctrl_info.rach_cfg_ded.ra_prach_mask_idx); + } else { + Info("Starting contention-based RA\n"); + rrc_ptr->mac->start_cont_ho(); + } - rrc_ptr->usim->generate_as_keys_ho( - recfg_r8.mob_ctrl_info.target_pci, rrc_ptr->meas_cells.serving_cell().get_earfcn(), ncc, &rrc_ptr->sec_cfg); + int ncc = -1; + if (recfg_r8.security_cfg_ho_present) { + auto& sec_intralte = recfg_r8.security_cfg_ho.handov_type.intra_lte(); + ncc = sec_intralte.next_hop_chaining_count; + if (sec_intralte.key_change_ind) { + rrc_ptr->rrc_log->console("keyChangeIndicator in securityConfigHO not supported\n"); + sec_cfg_failed = true; + return; + } + if (sec_intralte.security_algorithm_cfg_present) { + rrc_ptr->sec_cfg.cipher_algo = + (srslte::CIPHERING_ALGORITHM_ID_ENUM)sec_intralte.security_algorithm_cfg.ciphering_algorithm.to_number(); + rrc_ptr->sec_cfg.integ_algo = (srslte::INTEGRITY_ALGORITHM_ID_ENUM) + sec_intralte.security_algorithm_cfg.integrity_prot_algorithm.to_number(); + Info("Changed Ciphering to %s and Integrity to %s\n", + srslte::ciphering_algorithm_id_text[rrc_ptr->sec_cfg.cipher_algo], + srslte::integrity_algorithm_id_text[rrc_ptr->sec_cfg.integ_algo]); + } + } - rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg); + rrc_ptr->usim->generate_as_keys_ho( + recfg_r8.mob_ctrl_info.target_pci, rrc_ptr->meas_cells.serving_cell().get_earfcn(), ncc, &rrc_ptr->sec_cfg); - // Have RRCReconfComplete message ready when Msg3 is sent - rrc_ptr->send_rrc_con_reconfig_complete(); + rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg); + // Have RRCReconfComplete message ready when Msg3 is sent + rrc_ptr->send_rrc_con_reconfig_complete(); + }); + }); state = wait_ra_completion; return proc_outcome_t::yield; } @@ -1511,7 +1516,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(ra_completed_ev ev) return proc_outcome_t::yield; } - if (ev.success) { + if (ev.success and not sec_cfg_failed) { if (not rrc_ptr->measurements->parse_meas_config(&recfg_r8, true, ho_src_cell.get_earfcn())) { Error("Parsing measurementConfig. TODO: Send ReconfigurationReject\n"); }