From 47fff7226a2d9b8b292f5d23fce4fea1b2a4b4d0 Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Mon, 1 Feb 2021 10:51:49 +0100 Subject: [PATCH] Send NAS PDU in E-RAB Release Command and issue RRCConnectionReconfiguration to UE This commit addresses the following points - If a NAS-PDU IE is contained in the E-RAB RELEASE COMMAND message, the eNB shall pass it to the UE. - Issue RRCConnectionReconfiguration for the DRB to be removed - Cleaning of DRB in RLC and GTP-U - Fix for Malformed E-RAB Setup Response upon reaching max. DRBs --- srsenb/hdr/stack/rrc/rrc_bearer_cfg.h | 1 + srsenb/hdr/stack/rrc/rrc_ue.h | 4 +++- srsenb/src/stack/rrc/rrc.cc | 4 ++++ srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 11 +++++++++++ srsenb/src/stack/rrc/rrc_ue.cc | 20 ++++++++++++++++++-- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index e94c422d3..6a0d13382 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -96,6 +96,7 @@ public: uint32_t teid_out, uint32_t addr, const gtpu_interface_rrc::bearer_props* props = nullptr); + void rem_gtpu_bearer(gtpu_interface_rrc* gtpu, uint32_t erab_id); void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg); const std::map& get_erabs() const { return erabs; } diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 6ac025062..026f17270 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -47,7 +47,9 @@ public: void send_connection_reject(); void send_connection_release(); void send_connection_reest_rej(); - void send_connection_reconf(srslte::unique_byte_buffer_t sdu = {}, bool phy_cfg_updated = true); + void send_connection_reconf(srslte::unique_byte_buffer_t sdu = {}, + bool phy_cfg_updated = true, + const asn1::unbounded_octstring* nas_pdu = nullptr); void send_security_mode_command(); void send_ue_cap_enquiry(); void send_ue_info_req(); diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 6453e91fc..d985835b9 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -334,6 +334,10 @@ void rrc::release_erabs(uint32_t rnti, erabs_failed_to_release->push_back(erab_to_release.erab_id); } } + const asn1::unbounded_octstring* nas_pdu = + msg.protocol_ies.nas_pdu_present ? &msg.protocol_ies.nas_pdu.value : nullptr; + user_it->second->send_connection_reconf(nullptr, false, nas_pdu); + return; } diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index aed8b8e99..de0a832a8 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -339,6 +339,17 @@ uint32_t bearer_cfg_handler::add_gtpu_bearer(uint32_t return bearer.teid_in; } +void bearer_cfg_handler::rem_gtpu_bearer(srsenb::gtpu_interface_rrc* gtpu, uint32_t erab_id) +{ + auto it = erabs.find(erab_id); + if (it != erabs.end()) { + // Map e.g. E-RAB 5 to LCID 3 (==DRB1) + gtpu->rem_bearer(rnti, erab_id - 2); + } else { + logger.error("Removing erab_id=%d to GTPU\n", erab_id); + } +} + void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg) { // Add space for NAS messages diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index e31ac80fb..8011e45ad 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -506,7 +506,9 @@ void rrc::ue::send_connection_reest_rej() /* * Connection Reconfiguration */ -void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, bool phy_cfg_updated) +void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, + bool phy_cfg_updated, + const asn1::unbounded_octstring* nas_pdu) { parent->logger.debug("RRC state %d", state); @@ -545,6 +547,17 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu, bool phy_ // UE MAC scheduler updates mac_ctrl.handle_con_reconf(recfg_r8, ue_capabilities); + // Fill in NAS PDU - Only for RRC Connection Reconfiguration during E-RAB Release Command + if (nas_pdu != nullptr and nas_pdu->size() > 0 and !recfg_r8.ded_info_nas_list_present) { + recfg_r8.ded_info_nas_list_present = true; + recfg_r8.ded_info_nas_list.resize(recfg_r8.rr_cfg_ded.drb_to_release_list.size()); + // Add NAS PDU + for (uint32_t idx = 0; idx < recfg_r8.rr_cfg_ded.drb_to_release_list.size(); idx++) { + recfg_r8.ded_info_nas_list[idx].resize(nas_pdu->size()); + memcpy(recfg_r8.ded_info_nas_list[idx].data(), nas_pdu->data(), nas_pdu->size()); + } + } + // Reuse same PDU if (pdu != nullptr) { pdu->clear(); @@ -932,6 +945,7 @@ void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_se res.protocol_ies.erab_failed_to_setup_list_bearer_su_res_present = true; res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.push_back({}); auto& item = res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.back(); + item.load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); item.value.erab_item().erab_id = id; item.value.erab_item().cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; @@ -1206,7 +1220,9 @@ void rrc::ue::apply_rlc_rb_updates(const rr_cfg_ded_s& pending_rr_cfg) parent->rlc->add_bearer(rnti, srb.srb_id, srslte::rlc_config_t::srb_config(srb.srb_id)); } if (pending_rr_cfg.drb_to_release_list.size() > 0) { - parent->logger.error("Removing DRBs not currently supported"); + for (uint8_t drb_id : pending_rr_cfg.drb_to_release_list) { + parent->rlc->del_bearer(rnti, drb_id + 2); + } } for (const drb_to_add_mod_s& drb : pending_rr_cfg.drb_to_add_mod_list) { if (not drb.rlc_cfg_present) {