diff --git a/lib/include/srslte/asn1/rrc_asn1_utils.h b/lib/include/srslte/asn1/rrc_asn1_utils.h index 07f9d6107..0449c0b65 100644 --- a/lib/include/srslte/asn1/rrc_asn1_utils.h +++ b/lib/include/srslte/asn1/rrc_asn1_utils.h @@ -67,6 +67,9 @@ struct report_cfg_to_add_mod_s; struct meas_id_to_add_mod_s; struct quant_cfg_s; +// UE Capabilities +struct ue_eutra_cap_s; + } // namespace rrc } // namespace asn1 @@ -119,6 +122,26 @@ void set_phy_cfg_t_common_pwr_ctrl(phy_cfg_t* cfg, const asn1::rrc::ul_pwr_ctrl_ void set_phy_cfg_t_scell_config(phy_cfg_t* cfg, const asn1::rrc::scell_to_add_mod_r10_s& asn1_type); void set_phy_cfg_t_enable_64qam(phy_cfg_t* cfg, const bool enabled); +/*************************** + * EUTRA UE Capabilities + **************************/ +typedef struct { + uint8_t release = 8; + uint8_t category = 4; + uint8_t category_dl = 0; + uint8_t category_ul = 0; + bool support_dl_256qam = false; + bool support_ul_64qam = false; +} rrc_ue_eutra_cap_t; + +/** + * Flattens the UE EUTRA capabilities from the ASN.1 message decoder + * + * @param ue_cap Flat UE EUTRA capabilities + * @param eutra_cap_s ASN.1 structure + */ +void set_rrc_ue_eutra_cap_t(rrc_ue_eutra_cap_t& ue_cap, const asn1::rrc::ue_eutra_cap_s eutra_cap_s); + // mbms mbms_notif_cfg_t make_mbms_notif_cfg(const asn1::rrc::mbms_notif_cfg_r9_s& asn1_type); mbsfn_area_info_t make_mbsfn_area_info(const asn1::rrc::mbsfn_area_info_r9_s& asn1_type); diff --git a/lib/src/asn1/rrc_asn1_utils.cc b/lib/src/asn1/rrc_asn1_utils.cc index 4ce8774e5..339dbbce2 100644 --- a/lib/src/asn1/rrc_asn1_utils.cc +++ b/lib/src/asn1/rrc_asn1_utils.cc @@ -794,6 +794,79 @@ void set_phy_cfg_t_scell_config(phy_cfg_t* cfg, const asn1::rrc::scell_to_add_mo } } +/* + * UE Capabilities parser + */ + +template +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_eutra_cap_t& ue_cap, const T& ue_eutra_cap) +{ + if (ue_eutra_cap.non_crit_ext_present) { + set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + } +} + +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_eutra_cap_t& ue_cap, const asn1::rrc::ue_eutra_cap_s& ue_eutra_cap) +{ + ue_cap.release = ue_eutra_cap.access_stratum_release.to_number(); + ue_cap.category = ue_eutra_cap.ue_category; + + if (ue_eutra_cap.non_crit_ext_present) { + set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + } +} + +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_eutra_cap_t& ue_cap, + const asn1::rrc::ue_eutra_cap_v1020_ies_s& ue_eutra_cap) +{ + if (ue_eutra_cap.ue_category_v1020_present) { + ue_cap.category = ue_eutra_cap.ue_category_v1020; + } + + if (ue_eutra_cap.non_crit_ext_present) { + set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + } +} + +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_eutra_cap_t& ue_cap, + const asn1::rrc::ue_eutra_cap_v1250_ies_s& ue_eutra_cap) +{ + if (ue_eutra_cap.ue_category_dl_r12_present) { + ue_cap.category_dl = ue_eutra_cap.ue_category_dl_r12; + } + + if (ue_eutra_cap.ue_category_ul_r12_present) { + ue_cap.category_ul = ue_eutra_cap.ue_category_ul_r12; + } + + if (ue_eutra_cap.rf_params_v1250_present) { + const asn1::rrc::rf_params_v1250_s& rf_params = ue_eutra_cap.rf_params_v1250; + if (rf_params.supported_band_list_eutra_v1250_present) { + ue_cap.support_dl_256qam = true; + + for (const asn1::rrc::supported_band_eutra_v1250_s& supported_band : rf_params.supported_band_list_eutra_v1250) { + ue_cap.support_dl_256qam &= supported_band.dl_minus256_qam_r12_present; + ue_cap.support_ul_64qam &= supported_band.ul_minus64_qam_r12_present; + } + } + } + + if (ue_eutra_cap.non_crit_ext_present) { + set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + } +} + +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_eutra_cap_t& ue_cap, + const asn1::rrc::ue_eutra_cap_v1530_ies_s& ue_eutra_cap) +{ + ; // Do nothing +} + +void set_rrc_ue_eutra_cap_t(rrc_ue_eutra_cap_t& ue_cap, const asn1::rrc::ue_eutra_cap_s eutra_cap_s) +{ + set_rrc_ue_eutra_cap_t_gen(ue_cap, eutra_cap_s); +} + // MBMS mbms_notif_cfg_t make_mbms_notif_cfg(const asn1::rrc::mbms_notif_cfg_r9_s& asn1_type) diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index f380d4d59..5677acd30 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -1780,6 +1780,10 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu) conn_reconf->rr_cfg_ded.phys_cfg_ded_present = true; phys_cfg_ded_s* phy_cfg = &conn_reconf->rr_cfg_ded.phys_cfg_ded; + // Parse UE capabilities + srslte::rrc_ue_eutra_cap_t rrc_ue_eutra_cap; + srslte::set_rrc_ue_eutra_cap_t(rrc_ue_eutra_cap, eutra_capabilities); + // Configure PHY layer phy_cfg->ant_info_present = true; phy_cfg->ant_info.set_explicit_value() = parent->cfg.antenna_info; @@ -1845,6 +1849,14 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu) return; } + // Configure 256QAM + if (rrc_ue_eutra_cap.category_dl >= 11 && rrc_ue_eutra_cap.support_dl_256qam) { + phy_cfg->cqi_report_cfg_pcell_v1250.set_present(true); + cqi_report_cfg_v1250_s* cqi_report_cfg = conn_reconf->rr_cfg_ded.phys_cfg_ded.cqi_report_cfg_pcell_v1250.get(); + cqi_report_cfg->alt_cqi_table_r12_present = true; + cqi_report_cfg->alt_cqi_table_r12 = asn1::rrc::cqi_report_cfg_v1250_s::alt_cqi_table_r12_e_::all_sfs; + } + // Configure SRB2 in RLC and PDCP parent->rlc->add_bearer(rnti, 2, srslte::rlc_config_t::srb_config(2));