diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index 60c38cfa5..6114faa41 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -60,6 +60,9 @@ struct pdcch_cfg_common_s; struct pdcch_cfg_s; struct mib_s; +struct srb_to_add_mod_s; +struct drb_to_add_mod_s; + } // namespace rrc_nr } // namespace asn1 @@ -144,4 +147,16 @@ pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const } // namespace srsran +/************************ + * ASN1 RRC extensions + ***********************/ +namespace asn1 { + +namespace rrc_nr { +bool operator==(const srb_to_add_mod_s& lhs, const srb_to_add_mod_s& rhs); +bool operator==(const drb_to_add_mod_s& lhs, const drb_to_add_mod_s& rhs); +} // namespace rrc_nr + +} // namespace asn1 + #endif // SRSRAN_RRC_NR_UTILS_H diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index b44ecfc4e..f345d84db 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1624,3 +1624,29 @@ ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::report_cfg_to_add_mod_s, report_cfg_id); ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::meas_id_to_add_mod_s, meas_id); } // namespace srsran + +namespace asn1 { + +namespace rrc_nr { + +bool operator==(const srb_to_add_mod_s& lhs, const srb_to_add_mod_s& rhs) +{ + if (lhs.srb_id != rhs.srb_id or lhs.pdcp_cfg_present != rhs.pdcp_cfg_present) { + return false; + } + // TODO: check remaining fields + return true; +} +bool operator==(const drb_to_add_mod_s& lhs, const drb_to_add_mod_s& rhs) +{ + if (lhs.drb_id != rhs.drb_id or lhs.pdcp_cfg_present != rhs.pdcp_cfg_present or + lhs.cn_assoc_present != rhs.cn_assoc_present) { + return false; + } + // TODO: check remaining fields + return true; +} + +} // namespace rrc_nr + +} // namespace asn1 diff --git a/srsgnb/hdr/stack/rrc/cell_asn1_config.h b/srsgnb/hdr/stack/rrc/cell_asn1_config.h index 5809f704f..e94046d03 100644 --- a/srsgnb/hdr/stack/rrc/cell_asn1_config.h +++ b/srsgnb/hdr/stack/rrc/cell_asn1_config.h @@ -30,6 +30,15 @@ int fill_master_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1 int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s& mib); int fill_sib1_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sib1_s& sib1); +/** + * Based on the previous and new radio bearer config, generate ASN1 diff + * @return if a change was detected + */ +bool compute_diff_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, + const asn1::rrc_nr::radio_bearer_cfg_s& prev_bearers, + const asn1::rrc_nr::radio_bearer_cfg_s& next_bearers, + asn1::rrc_nr::radio_bearer_cfg_s& diff); + /// Apply radioBearerConfig updates to CellGroupConfig void fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, const asn1::rrc_nr::radio_bearer_cfg_s& bearers, diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h index 57dfd8400..36e108679 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h @@ -149,7 +149,7 @@ private: // RRC configs for UEs asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; - asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; + asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg, next_radio_bearer_cfg; // MAC controller sched_nr_interface::ue_cfg_t uecfg{}; diff --git a/srsgnb/src/stack/rrc/cell_asn1_config.cc b/srsgnb/src/stack/rrc/cell_asn1_config.cc index bd2cfec42..4838a3680 100644 --- a/srsgnb/src/stack/rrc/cell_asn1_config.cc +++ b/srsgnb/src/stack/rrc/cell_asn1_config.cc @@ -11,6 +11,7 @@ */ #include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc_nr_utils.h" #include "srsran/common/band_helper.h" #include @@ -1169,6 +1170,28 @@ int fill_sib1_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::s //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool compute_diff_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, + const radio_bearer_cfg_s& prev_bearers, + const radio_bearer_cfg_s& next_bearers, + radio_bearer_cfg_s& diff) +{ + // Compute SRB differences + std::vector srbs_to_rem; + srsran::compute_cfg_diff( + prev_bearers.srb_to_add_mod_list, next_bearers.srb_to_add_mod_list, diff.srb_to_add_mod_list, srbs_to_rem); + diff.srb_to_add_mod_list_present = diff.srb_to_add_mod_list.size() > 0; + + // Compute DRB differences + srsran::compute_cfg_diff(prev_bearers.drb_to_add_mod_list, + next_bearers.drb_to_add_mod_list, + diff.drb_to_add_mod_list, + diff.drb_to_release_list); + diff.drb_to_add_mod_list_present = diff.drb_to_add_mod_list.size() > 0; + diff.drb_to_release_list_present = diff.drb_to_release_list.size() > 0; + + return diff.srb_to_add_mod_list_present or diff.drb_to_release_list_present or diff.drb_to_add_mod_list_present; +} + void fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, const asn1::rrc_nr::radio_bearer_cfg_s& bearers, asn1::rrc_nr::cell_group_cfg_s& out) diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index 349425c89..6a5f743fe 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -879,23 +879,28 @@ void rrc_nr::ue::send_rrc_setup() { const uint8_t max_wait_time_secs = 16; + // Add SRB1 to UE context + // Note: See 5.3.5.6.3 - SRB addition/modification + next_radio_bearer_cfg.srb_to_add_mod_list_present = true; + next_radio_bearer_cfg.srb_to_add_mod_list.resize(1); + srb_to_add_mod_s& srb1 = next_radio_bearer_cfg.srb_to_add_mod_list[0]; + srb1.srb_id = 1; + + // Generate RRC setup message + dl_ccch_msg_s msg; rrc_setup_s& setup = msg.msg.set_c1().set_rrc_setup(); setup.rrc_transaction_id = (uint8_t)((transaction_id++) % 4); rrc_setup_ies_s& setup_ies = setup.crit_exts.set_rrc_setup(); // Fill RRC Setup - // Note: See 5.3.5.6.3 - SRB addition/modification - setup_ies.radio_bearer_cfg.srb_to_add_mod_list_present = true; - setup_ies.radio_bearer_cfg.srb_to_add_mod_list.resize(1); - srb_to_add_mod_s& srb1 = setup_ies.radio_bearer_cfg.srb_to_add_mod_list[0]; - srb1.srb_id = 1; + // - Setup SRB1 + compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, setup_ies.radio_bearer_cfg); + // - Setup masterCellGroup asn1::rrc_nr::cell_group_cfg_s master_cell_group = *parent->cell_ctxt->master_cell_group; - - // Derive master cell group config bearers + // - Derive master cell group config bearers fill_cellgroup_with_radio_bearer_cfg(parent->cfg, setup_ies.radio_bearer_cfg, master_cell_group); - { srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; @@ -921,7 +926,8 @@ void rrc_nr::ue::send_rrc_setup() /// TS 38.331, RRCSetupComplete void rrc_nr::ue::handle_rrc_setup_complete(const asn1::rrc_nr::rrc_setup_complete_s& msg) { - // TODO: handle RRCSetupComplete + // Update current radio bearer cfg + radio_bearer_cfg = next_radio_bearer_cfg; // Create UE context in NGAP using ngap_cause_t = asn1::ngap_nr::rrcestablishment_cause_opts::options; @@ -959,6 +965,10 @@ void rrc_nr::ue::send_rrc_reconfiguration() dl_dcch_msg.msg.set_c1().set_rrc_recfg().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); rrc_recfg_ies_s& ies = dl_dcch_msg.msg.c1().rrc_recfg().crit_exts.set_rrc_recfg(); + // Add new SRBs/DRBs + ies.radio_bearer_cfg_present = + compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, ies.radio_bearer_cfg); + ies.non_crit_ext_present = true; ies.non_crit_ext.master_cell_group_present = false; // TODO @@ -969,7 +979,7 @@ void rrc_nr::ue::send_rrc_reconfiguration() void rrc_nr::ue::handle_rrc_reconfiguration_complete(const asn1::rrc_nr::rrc_recfg_complete_s& msg) { - // TODO: handle RRCReconfComplete + radio_bearer_cfg = next_radio_bearer_cfg; } void rrc_nr::ue::send_dl_information_transfer(srsran::unique_byte_buffer_t sdu) @@ -991,7 +1001,40 @@ void rrc_nr::ue::handle_ul_information_transfer(const asn1::rrc_nr::ul_info_tran parent->ngap->write_pdu(rnti, msg.crit_exts.ul_info_transfer().ded_nas_msg); } -void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) {} +void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) +{ + // Add SRB2, if not yet added + if (radio_bearer_cfg.srb_to_add_mod_list.size() <= 1) { + next_radio_bearer_cfg.srb_to_add_mod_list_present = true; + next_radio_bearer_cfg.srb_to_add_mod_list.resize(1); + next_radio_bearer_cfg.srb_to_add_mod_list[0].srb_id = 2; + } + + drb_to_add_mod_s drb; + drb.cn_assoc_present = true; + drb.cn_assoc.set_sdap_cfg().pdu_session = 1; + drb.cn_assoc.sdap_cfg().sdap_hdr_dl.value = asn1::rrc_nr::sdap_cfg_s::sdap_hdr_dl_opts::absent; + drb.cn_assoc.sdap_cfg().sdap_hdr_ul.value = asn1::rrc_nr::sdap_cfg_s::sdap_hdr_ul_opts::absent; + drb.cn_assoc.sdap_cfg().default_drb = true; + drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add_present = true; + drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add.resize(1); + drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add[0] = 1; + + drb.drb_id = 1; + drb.pdcp_cfg_present = true; + drb.pdcp_cfg.drb.discard_timer_present = true; + drb.pdcp_cfg.drb.discard_timer.value = pdcp_cfg_s::drb_s_::discard_timer_opts::ms100; + drb.pdcp_cfg.drb.pdcp_sn_size_ul_present = true; + drb.pdcp_cfg.drb.pdcp_sn_size_ul.value = asn1::rrc_nr::pdcp_cfg_s::drb_s_::pdcp_sn_size_ul_opts::len18bits; + drb.pdcp_cfg.drb.pdcp_sn_size_dl_present = true; + drb.pdcp_cfg.drb.pdcp_sn_size_dl.value = asn1::rrc_nr::pdcp_cfg_s::drb_s_::pdcp_sn_size_dl_opts::len18bits; + drb.pdcp_cfg.drb.hdr_compress.set_not_used(); + drb.pdcp_cfg.t_reordering_present = true; + drb.pdcp_cfg.t_reordering.value = asn1::rrc_nr::pdcp_cfg_s::t_reordering_opts::ms0; + + next_radio_bearer_cfg.drb_to_add_mod_list_present = true; + next_radio_bearer_cfg.drb_to_add_mod_list.push_back(drb); +} bool rrc_nr::ue::init_pucch() {