From 25f34502a7cb522f0eaeb75ee0864af08c3b6da6 Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 11 Oct 2021 18:03:21 +0100 Subject: [PATCH] nr,gnb,rrc: restore the GTPU TEIDs back from NR RNTI to LTE RNTI when RRC reconfiguration fails --- srsenb/hdr/stack/rrc/rrc_endc.h | 7 +++++-- srsenb/src/stack/rrc/rrc_endc.cc | 12 +++++++++++- srsenb/src/stack/rrc/rrc_ue.cc | 4 ++++ srsenb/src/stack/upper/gtpu.cc | 6 ++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index 3cb993b16..3f82acb10 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -36,8 +36,9 @@ public: struct sgnb_add_req_ack_ev { sgnb_addition_ack_params_t params; }; - struct sgnb_add_req_reject_ev {}; + /// Called when Reconf fails + struct rrc_reest_rx_ev {}; /** * @brief Non-standard event sent from NR-RRC to EUTRA when UE has attached to NR cell @@ -98,6 +99,7 @@ private: // FSM transition handlers void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); + void handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev); protected: // states @@ -120,7 +122,8 @@ protected: row< wait_sgnb_add_req_resp_st, prepare_recfg_st, sgnb_add_req_ack_ev, &fsm::handle_sgnb_add_req_ack >, row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, - row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev > + row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev >, + row< wait_add_complete_st, endc_deactivated_st, rrc_reest_rx_ev, &fsm::handle_rrc_reest > // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ >; // clang-format on diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 47d5f6991..cbdc5cefa 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -168,7 +168,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn .non_crit_ext_present = true; rrc_conn_recfg_v1510_ies_s& reconf_v1510 = conn_recfg->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; - reconf_v1510.nr_cfg_r15_present = true; + reconf_v1510.nr_cfg_r15_present = true; reconf_v1510.nr_cfg_r15.set_setup(); reconf_v1510.nr_cfg_r15.setup().endc_release_and_add_r15 = false; @@ -319,4 +319,14 @@ bool rrc::ue::rrc_endc::is_endc_supported() return endc_supported; } +void rrc::ue::rrc_endc::handle_rrc_reest(wait_add_complete_st& s, const rrc_reest_rx_ev& ev) +{ + auto& sgnb_config = get_state()->sgnb_config; + + // Transition GTPU tunnel rnti back from NR RNTI to LTE RNTI, given that the reconfiguration failed + rrc_enb->gtpu->mod_bearer_rnti(sgnb_config.nr_rnti, rrc_ue->rnti); + + rrc_enb->bearer_manager.rem_user(sgnb_config.nr_rnti); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index db516cefb..cc5648914 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -652,6 +652,10 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) srsran::console( "User 0x%x requesting RRC Reestablishment as 0x%x. Cause: %s\n", rnti, old_rnti, req_r8.reest_cause.to_string()); + if (endc_handler != nullptr) { + old_ue->endc_handler->trigger(rrc_endc::rrc_reest_rx_ev{}); + } + // Cancel Handover in Target eNB if on-going asn1::s1ap::cause_c cause; cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::interaction_with_other_proc; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 658a4933e..e221311e8 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -124,14 +124,16 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t bool gtpu_tunnel_manager::update_rnti(uint16_t old_rnti, uint16_t new_rnti) { auto* old_rnti_ptr = find_rnti_tunnels(old_rnti); - if (old_rnti_ptr == nullptr or find_rnti_tunnels(new_rnti) != nullptr) { + auto* new_rnti_ptr = find_rnti_tunnels(new_rnti); + if (old_rnti_ptr == nullptr or (new_rnti_ptr != nullptr and not new_rnti_ptr->empty())) { + // The old rnti must exist and the new rnti TEID list must be empty logger.error("Modifying bearer rnti. Old rnti=0x%x, new rnti=0x%x", old_rnti, new_rnti); return false; } logger.info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x", old_rnti, new_rnti); // create new RNTI and update TEIDs of old rnti to reflect new rnti - if (not ue_teidin_db.insert(new_rnti, ue_bearer_tunnel_list())) { + if (new_rnti_ptr == nullptr and not ue_teidin_db.insert(new_rnti, ue_bearer_tunnel_list())) { logger.error("Failure to create new rnti=0x%x", new_rnti); return false; }