diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index 59d8c78df..639672418 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -79,6 +79,9 @@ public: bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_); + /// Called after RRCReestablishmentComplete, to add E-RABs of old rnti + void reestablish_bearers(bearer_cfg_handler&& old_rnti_bearers); + int add_erab(uint8_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr, diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 594a86af6..e0fc3d266 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -204,6 +204,14 @@ bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gt rnti(rnti_), cfg(&cfg_), gtpu(gtpu_), logger(&srslog::fetch_basic_logger("RRC")) {} +void bearer_cfg_handler::reestablish_bearers(bearer_cfg_handler&& old_rnti_bearers) +{ + erab_info_list = std::move(old_rnti_bearers.erab_info_list); + erabs = std::move(old_rnti_bearers.erabs); + current_drbs = std::move(old_rnti_bearers.current_drbs); + old_rnti_bearers.current_drbs.clear(); +} + int bearer_cfg_handler::add_erab(uint8_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr, diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index d3d910c8c..a1cec4f48 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -665,8 +665,8 @@ void rrc::ue::handle_rrc_con_reest_complete(rrc_conn_reest_complete_s* msg, srsr parent->pdcp->enable_integrity(rnti, srb_to_lcid(lte_srb::srb1)); parent->pdcp->enable_encryption(rnti, srb_to_lcid(lte_srb::srb1)); - // Reestablish current DRBs during ConnectionReconfiguration - bearer_list = std::move(parent->users.at(old_reest_rnti)->bearer_list); + // Reestablish E-RABs of old rnti during ConnectionReconfiguration + bearer_list.reestablish_bearers(std::move(parent->users.at(old_reest_rnti)->bearer_list)); // remove old RNTI parent->rem_user_thread(old_reest_rnti); diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index aec0d9df8..cb3a0814d 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -126,16 +126,20 @@ bool gtpu_tunnel_manager::update_rnti(uint16_t old_rnti, uint16_t new_rnti) auto* old_rnti_ptr = find_rnti_tunnels(old_rnti); logger.info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x", old_rnti, new_rnti); - // Change RNTI bearers map - ue_teidin_db.insert(new_rnti, std::move(*old_rnti_ptr)); - ue_teidin_db.erase(old_rnti); - - // Change TEID in existing tunnels - auto* new_rnti_ptr = find_rnti_tunnels(new_rnti); - for (lcid_tunnel& bearer : *new_rnti_ptr) { + // create new RNTI and update TEIDs of old rnti to reflect new rnti + if (not ue_teidin_db.insert(new_rnti, ue_lcid_tunnel_list())) { + logger.error("Failure to create new rnti=0x%x", new_rnti); + return false; + } + std::swap(ue_teidin_db[new_rnti], *old_rnti_ptr); + auto& new_rnti_obj = ue_teidin_db[new_rnti]; + for (lcid_tunnel& bearer : new_rnti_obj) { tunnels[bearer.teid].rnti = new_rnti; } + // Leave old_rnti as zombie to be removed later + old_rnti_ptr->clear(); + return true; }