From 8c86d2084dbd70757953d3671cf50a2386813567 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 17 Mar 2021 17:08:46 +0100 Subject: [PATCH] Adding NR phy config RRC parsing Added error handling Reworked flattening error handling --- lib/include/srsran/asn1/rrc_nr_utils.h | 44 +- .../srsran/interfaces/ue_usim_interfaces.h | 4 +- lib/src/asn1/rrc_nr_utils.cc | 519 +++++++++++++++- lib/test/asn1/rrc_nr_utils_test.cc | 492 ++++++++++++++++ srsue/hdr/stack/rrc/rrc_nr.h | 18 +- srsue/hdr/stack/upper/usim_base.h | 4 +- srsue/src/stack/rrc/rrc_nr.cc | 556 +++++++++++++++++- srsue/src/stack/upper/usim_base.cc | 14 +- 8 files changed, 1615 insertions(+), 36 deletions(-) diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index df4263a48..28cc6eb82 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -32,6 +32,22 @@ struct pdcp_cfg_s; struct lc_ch_cfg_s; struct rach_cfg_common_s; +// Phy +struct tdd_ul_dl_cfg_common_s; +struct phys_cell_group_cfg_s; +struct search_space_s; +struct search_space_s; +struct csi_report_cfg_s; +struct ctrl_res_set_s; +struct pdsch_time_domain_res_alloc_s; +struct pusch_time_domain_res_alloc_s; +struct pucch_format_cfg_s; +struct pucch_res_s; +struct sched_request_res_cfg_s; +struct dmrs_ul_cfg_s; +struct beta_offsets_s; +struct uci_on_pusch_s; + } // namespace rrc_nr } // namespace asn1 @@ -42,7 +58,33 @@ namespace srsran { plmn_id_t make_plmn_id_t(const asn1::rrc_nr::plmn_id_s& asn1_type); void to_asn1(asn1::rrc_nr::plmn_id_s* asn1_type, const plmn_id_t& cfg); - +/*************************** + * PHY Config + **************************/ +bool make_phy_tdd_cfg(const asn1::rrc_nr::tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common, + srsran_tdd_config_nr_t* srsran_tdd_config_nr); +bool make_phy_harq_ack_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg, + srsran_ue_dl_nr_harq_ack_cfg_t* srsran_ue_dl_nr_harq_ack_cfg); +bool make_phy_coreset_cfg(const asn1::rrc_nr::ctrl_res_set_s& ctrl_res_set, srsran_coreset_t* srsran_coreset); +bool make_phy_search_space_cfg(const asn1::rrc_nr::search_space_s& search_space, + srsran_search_space_t* srsran_search_space); +bool make_phy_csi_report(const asn1::rrc_nr::csi_report_cfg_s& csi_report_cfg, + srsran_csi_hl_report_cfg_t* srsran_csi_hl_report_cfg); +bool make_phy_common_time_ra(const asn1::rrc_nr::pdsch_time_domain_res_alloc_s& pdsch_time_domain_res_alloc, + srsran_sch_time_ra_t* srsran_sch_time_ra); +bool make_phy_common_time_ra(const asn1::rrc_nr::pusch_time_domain_res_alloc_s& pusch_time_domain_res_allo, + srsran_sch_time_ra_t* srsran_sch_time_ra); +bool make_phy_max_code_rate(const asn1::rrc_nr::pucch_format_cfg_s& pucch_format_cfg, uint32_t* max_code_rate); +bool make_phy_res_config(const asn1::rrc_nr::pucch_res_s& pucch_res, + uint32_t format_2_max_code_rate, + srsran_pucch_nr_resource_t* srsran_pucch_nr_resource); +bool make_phy_sr_resource(const asn1::rrc_nr::sched_request_res_cfg_s& sched_request_res_cfg, + srsran_pucch_nr_sr_resource_t* srsran_pucch_nr_sr_resource); +bool make_phy_dmrs_additional_pos(const asn1::rrc_nr::dmrs_ul_cfg_s& dmrs_ul_cfg, + srsran_dmrs_sch_add_pos_t* srsran_dmrs_sch_add_pos); +bool make_phy_beta_offsets(const asn1::rrc_nr::beta_offsets_s& beta_offsets, + srsran_beta_offsets_t* srsran_beta_offsets); +bool make_phy_pusch_scaling(const asn1::rrc_nr::uci_on_pusch_s& uci_on_pusch, float* scaling); /*************************** * MAC Config **************************/ diff --git a/lib/include/srsran/interfaces/ue_usim_interfaces.h b/lib/include/srsran/interfaces/ue_usim_interfaces.h index 8ad50cf9f..ae1112b44 100644 --- a/lib/include/srsran/interfaces/ue_usim_interfaces.h +++ b/lib/include/srsran/interfaces/ue_usim_interfaces.h @@ -56,8 +56,8 @@ public: class usim_interface_rrc_nr { public: - virtual void generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) = 0; - virtual void update_nr_context(srsran::as_security_config_t* sec_cfg) = 0; + virtual bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) = 0; + virtual bool update_nr_context(srsran::as_security_config_t* sec_cfg) = 0; }; } // namespace srsue diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 0ba2c5eac..5b1b67da7 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2020 Software Radio Systems Limited * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of @@ -194,6 +194,521 @@ srsran::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue return cfg; } +bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common, + srsran_tdd_config_nr_t* in_srsran_tdd_config_nr) +{ + srsran_tdd_config_nr_t srsran_tdd_config_nr = {}; + switch (tdd_ul_dl_cfg_common.pattern1.dl_ul_tx_periodicity) { + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1: + srsran_tdd_config_nr.pattern1.period_ms = 1; + break; + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2: + srsran_tdd_config_nr.pattern1.period_ms = 2; + break; + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5: + srsran_tdd_config_nr.pattern1.period_ms = 5; + break; + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10: + srsran_tdd_config_nr.pattern1.period_ms = 10; + break; + + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1p25: + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms0p5: + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms0p625: + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2p5: + default: + asn1::log_warning("Invalid option for dl_ul_tx_periodicity_opts %s", + tdd_ul_dl_cfg_common.pattern1.dl_ul_tx_periodicity.to_string()); + return false; + } + srsran_tdd_config_nr.pattern1.nof_dl_slots = tdd_ul_dl_cfg_common.pattern1.nrof_dl_slots; + srsran_tdd_config_nr.pattern1.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_dl_symbols; + srsran_tdd_config_nr.pattern1.nof_ul_slots = tdd_ul_dl_cfg_common.pattern1.nrof_ul_slots; + srsran_tdd_config_nr.pattern1.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_ul_symbols; + // Copy and return struct + *in_srsran_tdd_config_nr = srsran_tdd_config_nr; + return true; +} + +bool make_phy_harq_ack_cfg(const phys_cell_group_cfg_s& phys_cell_group_cfg, + srsran_ue_dl_nr_harq_ack_cfg_t* in_srsran_ue_dl_nr_harq_ack_cfg) +{ + srsran_ue_dl_nr_harq_ack_cfg_t srsran_ue_dl_nr_harq_ack_cfg; + switch (phys_cell_group_cfg.pdsch_harq_ack_codebook) { + case phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value: + srsran_ue_dl_nr_harq_ack_cfg.pdsch_harq_ack_codebook = srsran_pdsch_harq_ack_codebook_dynamic; + break; + case phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::semi_static: + srsran_ue_dl_nr_harq_ack_cfg.pdsch_harq_ack_codebook = srsran_pdsch_harq_ack_codebook_semi_static; + break; + case phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::nulltype: + srsran_ue_dl_nr_harq_ack_cfg.pdsch_harq_ack_codebook = srsran_pdsch_harq_ack_codebook_none; + break; + default: + asn1::log_warning("Invalid option for pdsch_harq_ack_codebook %s", + phys_cell_group_cfg.pdsch_harq_ack_codebook.to_string()); + return false; + } + *in_srsran_ue_dl_nr_harq_ack_cfg = srsran_ue_dl_nr_harq_ack_cfg; + return true; +} + +bool make_phy_search_space_cfg(const search_space_s& search_space, srsran_search_space_t* in_srsran_search_space) +{ + srsran_search_space_t srsran_search_space = {}; + srsran_search_space.id = search_space.search_space_id; + if (not search_space.ctrl_res_set_id_present) { + asn1::log_warning("ctrl_res_set_id option not present"); + return false; + } + srsran_search_space.coreset_id = search_space.ctrl_res_set_id; + + if (not search_space.nrof_candidates_present) { + asn1::log_warning("nrof_candidates_present option not present"); + return false; + } + srsran_search_space.nof_candidates[0] = search_space.nrof_candidates.aggregation_level1.value; + srsran_search_space.nof_candidates[1] = search_space.nrof_candidates.aggregation_level2.value; + srsran_search_space.nof_candidates[2] = search_space.nrof_candidates.aggregation_level4.value; + srsran_search_space.nof_candidates[3] = search_space.nrof_candidates.aggregation_level8.value; + srsran_search_space.nof_candidates[4] = search_space.nrof_candidates.aggregation_level16.value; + + if (not search_space.search_space_type_present) { + asn1::log_warning("nrof_candidates option not present"); + return false; + } + switch (search_space.search_space_type.type()) { + case search_space_s::search_space_type_c_::types_opts::options::common: + srsran_search_space.type = srsran_search_space_type_common_3; + break; + case search_space_s::search_space_type_c_::types_opts::options::ue_specific: + srsran_search_space.type = srsran_search_space_type_ue; + break; + default: + asn1::log_warning("Invalid option for search_space_type %s", search_space.search_space_type.type().to_string()); + return false; + } + // Copy struct and return value + *in_srsran_search_space = srsran_search_space; + return true; +} + +bool make_phy_csi_report(const csi_report_cfg_s& csi_report_cfg, + srsran_csi_hl_report_cfg_t* in_srsran_csi_hl_report_cfg) +{ + srsran_csi_hl_report_cfg_t srsran_csi_hl_report_cfg = {}; + switch (csi_report_cfg.report_cfg_type.type()) { + case csi_report_cfg_s::report_cfg_type_c_::types_opts::options::nulltype: + srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_NONE; + break; + case csi_report_cfg_s::report_cfg_type_c_::types_opts::options::periodic: + srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_PERIODIC; + break; + case csi_report_cfg_s::report_cfg_type_c_::types_opts::options::aperiodic: + srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_APERIODIC; + break; + case csi_report_cfg_s::report_cfg_type_c_::types_opts::options::semi_persistent_on_pucch: + srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_SEMI_PERSISTENT_ON_PUCCH; + break; + case csi_report_cfg_s::report_cfg_type_c_::types_opts::options::semi_persistent_on_pusch: + srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_SEMI_PERSISTENT_ON_PUSCH; + break; + default: + asn1::log_warning("Invalid option for report_cfg_type %s", csi_report_cfg.report_cfg_type.type().to_string()); + return false; + } + + if (srsran_csi_hl_report_cfg.type = SRSRAN_CSI_REPORT_TYPE_PERIODIC) { + srsran_csi_hl_report_cfg.periodic.period = + csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type().to_number(); + switch (csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type()) { + case csi_report_periodicity_and_offset_c::types_opts::slots4: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots4(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots5: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots5(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots8: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots8(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots10: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots10(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots16: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots16(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots20: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots20(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots40: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots40(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots80: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots80(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots160: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots160(); + break; + case csi_report_periodicity_and_offset_c::types_opts::slots320: + srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots320(); + break; + default: + asn1::log_warning("Invalid option for report_slot_cfg %s", + csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type().to_string()); + return false; + } + } + + srsran_csi_hl_report_cfg.channel_meas_id = csi_report_cfg.res_for_ch_meas; + + srsran_csi_hl_report_cfg.interf_meas_present = csi_report_cfg.csi_im_res_for_interference_present; + srsran_csi_hl_report_cfg.interf_meas_id = csi_report_cfg.csi_im_res_for_interference; + + switch (csi_report_cfg.report_quant.type()) { + case csi_report_cfg_s::report_quant_c_::types_opts::none: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::cri_ri_pmi_cqi: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::cri_ri_i1: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_I1; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::cri_ri_i1_cqi: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_I1_CQI; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::cri_ri_cqi: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_CQI; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::cri_rsrp: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RSRP; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::ssb_idx_rsrp: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_SSB_INDEX_RSRP; + break; + case csi_report_cfg_s::report_quant_c_::types_opts::cri_ri_li_pmi_cqi: + srsran_csi_hl_report_cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_LI_PMI_CQI; + break; + default: + asn1::log_warning("Invalid option for report_quant %s", csi_report_cfg.report_quant.type().to_string()); + return false; + } + + if (not csi_report_cfg.report_freq_cfg_present) { + asn1::log_warning("report_freq_cfg_present option not present"); + return false; + } + + if (not csi_report_cfg.report_freq_cfg.cqi_format_ind_present) { + asn1::log_warning("cqi_format_ind option not present"); + return false; + } + + switch (csi_report_cfg.report_freq_cfg.cqi_format_ind) { + case csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi: + srsran_csi_hl_report_cfg.freq_cfg = SRSRAN_CSI_REPORT_FREQ_WIDEBAND; + break; + case csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::subband_cqi: + srsran_csi_hl_report_cfg.freq_cfg = SRSRAN_CSI_REPORT_FREQ_SUBBAND; + break; + default: + asn1::log_warning("Invalid option for cqi_format_ind %s", + csi_report_cfg.report_freq_cfg.cqi_format_ind.to_string()); + return false; + + break; + } + + if (not csi_report_cfg.cqi_table_present) { + asn1::log_warning("cqi_table_present not present"); + return false; + } + + switch (csi_report_cfg.cqi_table) { + case csi_report_cfg_s::cqi_table_opts::table1: + srsran_csi_hl_report_cfg.cqi_table = SRSRAN_CSI_CQI_TABLE_1; + break; + case csi_report_cfg_s::cqi_table_opts::table2: + srsran_csi_hl_report_cfg.cqi_table = SRSRAN_CSI_CQI_TABLE_2; + break; + case csi_report_cfg_s::cqi_table_opts::table3: + srsran_csi_hl_report_cfg.cqi_table = SRSRAN_CSI_CQI_TABLE_3; + break; + default: + asn1::log_warning("Invalid option for cqi_table %s", csi_report_cfg.cqi_table.to_string()); + return false; + } + *in_srsran_csi_hl_report_cfg = srsran_csi_hl_report_cfg; + return true; +} + +bool make_phy_coreset_cfg(const ctrl_res_set_s& ctrl_res_set, srsran_coreset_t* in_srsran_coreset) +{ + srsran_coreset_t srsran_coreset = {}; + srsran_coreset.coreset_id = ctrl_res_set.ctrl_res_set_id; + + switch (ctrl_res_set.precoder_granularity) { + case ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle: + srsran_coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle; + break; + case ctrl_res_set_s::precoder_granularity_opts::all_contiguous_rbs: + srsran_coreset.precoder_granularity = srsran_coreset_precoder_granularity_contiguous; + default: + asn1::log_warning("Invalid option for precoder_granularity %s", ctrl_res_set.precoder_granularity.to_string()); + return false; + }; + srsran_coreset.duration = ctrl_res_set.dur; + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + srsran_coreset.freq_resources[i] = ctrl_res_set.freq_domain_res.get(SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE - 1 - i); + } + *in_srsran_coreset = srsran_coreset; + return true; +} + +bool make_phy_common_time_ra(const pdsch_time_domain_res_alloc_s& pdsch_time_domain_res_alloc, + srsran_sch_time_ra_t* in_srsran_sch_time_ra) +{ + srsran_sch_time_ra_t srsran_sch_time_ra = {}; + srsran_sch_time_ra.sliv = pdsch_time_domain_res_alloc.start_symbol_and_len; + switch (pdsch_time_domain_res_alloc.map_type) { + case pdsch_time_domain_res_alloc_s::map_type_opts::type_a: + srsran_sch_time_ra.mapping_type = srsran_sch_mapping_type_A; + break; + case pdsch_time_domain_res_alloc_s::map_type_opts::type_b: + srsran_sch_time_ra.mapping_type = srsran_sch_mapping_type_B; + break; + default: + asn1::log_warning("Invalid option for map_type: %s", pdsch_time_domain_res_alloc.map_type.to_string()); + return false; + } + + if (pdsch_time_domain_res_alloc.k0_present) { + srsran_sch_time_ra.k = pdsch_time_domain_res_alloc.k0; + } else { + srsran_sch_time_ra.k = 0; + } + *in_srsran_sch_time_ra = srsran_sch_time_ra; + return true; +} + +bool make_phy_common_time_ra(const pusch_time_domain_res_alloc_s& pusch_time_domain_res_alloc, + srsran_sch_time_ra_t* in_srsran_sch_time_ra) +{ + srsran_sch_time_ra_t srsran_sch_time_ra = {}; + srsran_sch_time_ra.sliv = pusch_time_domain_res_alloc.start_symbol_and_len; + switch (pusch_time_domain_res_alloc.map_type) { + case pusch_time_domain_res_alloc_s::map_type_opts::type_a: + srsran_sch_time_ra.mapping_type = srsran_sch_mapping_type_A; + break; + case pusch_time_domain_res_alloc_s::map_type_opts::type_b: + srsran_sch_time_ra.mapping_type = srsran_sch_mapping_type_B; + break; + default: + asn1::log_warning("Invalid option for map_type: %s", pusch_time_domain_res_alloc.map_type.to_string()); + return false; + } + + if (pusch_time_domain_res_alloc.k2_present) { + srsran_sch_time_ra.k = pusch_time_domain_res_alloc.k2; + } else { + srsran_sch_time_ra.k = 0; + } + *in_srsran_sch_time_ra = srsran_sch_time_ra; + return true; +} + +bool make_phy_max_code_rate(const pucch_format_cfg_s& pucch_format_cfg, uint32_t* in_max_code_rate) +{ + if (not pucch_format_cfg.max_code_rate_present) { + asn1::log_warning("max_code_rate option not present"); + return false; + } + *in_max_code_rate = pucch_format_cfg.max_code_rate.value; + return true; +} + +bool make_phy_res_config(const pucch_res_s& pucch_res, + uint32_t format_2_max_code_rate, + srsran_pucch_nr_resource_t* in_srsran_pucch_nr_resource) +{ + srsran_pucch_nr_resource_t srsran_pucch_nr_resource = {}; + srsran_pucch_nr_resource.starting_prb = pucch_res.start_prb; + switch (pucch_res.format.type()) { + case pucch_res_s::format_c_::types_opts::format0: + srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_0; + break; + case pucch_res_s::format_c_::types_opts::format1: + srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_1; + srsran_pucch_nr_resource.initial_cyclic_shift = pucch_res.format.format1().init_cyclic_shift; + srsran_pucch_nr_resource.nof_symbols = pucch_res.format.format1().nrof_symbols; + srsran_pucch_nr_resource.start_symbol_idx = pucch_res.format.format1().start_symbol_idx; + srsran_pucch_nr_resource.time_domain_occ = pucch_res.format.format1().time_domain_occ; + break; + case pucch_res_s::format_c_::types_opts::format2: + srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_2; + srsran_pucch_nr_resource.nof_symbols = pucch_res.format.format2().nrof_symbols; + srsran_pucch_nr_resource.start_symbol_idx = pucch_res.format.format2().start_symbol_idx; + srsran_pucch_nr_resource.nof_prb = pucch_res.format.format2().nrof_prbs; + break; + case pucch_res_s::format_c_::types_opts::format3: + srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_3; + asn1::log_warning("SRSRAN_PUCCH_NR_FORMAT_3 conversion not supported"); + return false; + case pucch_res_s::format_c_::types_opts::format4: + srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_4; + asn1::log_warning("SRSRAN_PUCCH_NR_FORMAT_4 conversion not supported"); + return false; + default: + srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_ERROR; + return false; + } + srsran_pucch_nr_resource.max_code_rate = format_2_max_code_rate; + *in_srsran_pucch_nr_resource = srsran_pucch_nr_resource; + return true; +} + +bool make_phy_sr_resource(const sched_request_res_cfg_s& sched_request_res_cfg, + srsran_pucch_nr_sr_resource_t* in_srsran_pucch_nr_sr_resource) +{ + srsran_pucch_nr_sr_resource_t srsran_pucch_nr_sr_resource = {}; + srsran_pucch_nr_sr_resource.sr_id = sched_request_res_cfg.sched_request_id; + if (sched_request_res_cfg.periodicity_and_offset_present && sched_request_res_cfg.res_present) { + srsran_pucch_nr_sr_resource.configured = true; + switch (sched_request_res_cfg.periodicity_and_offset.type()) { + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl2: + srsran_pucch_nr_sr_resource.period = 2; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl2(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl4: + srsran_pucch_nr_sr_resource.period = 4; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl4(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl5: + srsran_pucch_nr_sr_resource.period = 5; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl5(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl8: + srsran_pucch_nr_sr_resource.period = 8; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl8(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl10: + srsran_pucch_nr_sr_resource.period = 10; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl10(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl16: + srsran_pucch_nr_sr_resource.period = 16; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl16(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl20: + srsran_pucch_nr_sr_resource.period = 20; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl20(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl40: + srsran_pucch_nr_sr_resource.period = 40; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl40(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl80: + srsran_pucch_nr_sr_resource.period = 80; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl80(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl160: + srsran_pucch_nr_sr_resource.period = 160; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl160(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl320: + srsran_pucch_nr_sr_resource.period = 320; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl320(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl640: + srsran_pucch_nr_sr_resource.period = 640; + srsran_pucch_nr_sr_resource.offset = sched_request_res_cfg.periodicity_and_offset.sl640(); + break; + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sym2: + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sym6or7: + case sched_request_res_cfg_s::periodicity_and_offset_c_::types_opts::sl1: + default: + srsran_pucch_nr_sr_resource.configured = false; + asn1::log_warning("Invalid option for periodicity_and_offset %s", + sched_request_res_cfg.periodicity_and_offset.type().to_string()); + return false; + } + + } else { + srsran_pucch_nr_sr_resource.configured = false; + } + *in_srsran_pucch_nr_sr_resource = srsran_pucch_nr_sr_resource; + return true; +} + +bool make_phy_dmrs_additional_pos(const dmrs_ul_cfg_s& dmrs_ul_cfg, + srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos) +{ + srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos = {}; + if (not dmrs_ul_cfg.dmrs_add_position_present) { + asn1::log_warning("dmrs_add_position option not present"); + } + + switch (dmrs_ul_cfg.dmrs_add_position) { + case dmrs_ul_cfg_s::dmrs_add_position_opts::pos0: + srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_0; + break; + case dmrs_ul_cfg_s::dmrs_add_position_opts::pos1: + srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_1; + break; + case dmrs_ul_cfg_s::dmrs_add_position_opts::pos3: + srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_3; + break; + default: + asn1::log_warning("Invalid option for dmrs_add_position %s", dmrs_ul_cfg.dmrs_add_position.to_string()); + return false; + } + *in_srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos; + return true; +} + +bool make_phy_beta_offsets(const beta_offsets_s& beta_offsets, srsran_beta_offsets_t* in_srsran_beta_offsets) +{ + srsran_beta_offsets_t srsran_beta_offsets = {}; + + srsran_beta_offsets.ack_index1 = beta_offsets.beta_offset_ack_idx1_present ? beta_offsets.beta_offset_ack_idx1 : 11; + srsran_beta_offsets.ack_index2 = beta_offsets.beta_offset_ack_idx2_present ? beta_offsets.beta_offset_ack_idx2 : 11; + srsran_beta_offsets.ack_index3 = beta_offsets.beta_offset_ack_idx3_present ? beta_offsets.beta_offset_ack_idx3 : 11; + srsran_beta_offsets.csi1_index1 = + beta_offsets.beta_offset_csi_part1_idx1_present ? beta_offsets.beta_offset_csi_part1_idx1 : 13; + srsran_beta_offsets.csi1_index2 = + beta_offsets.beta_offset_csi_part1_idx2_present ? beta_offsets.beta_offset_csi_part1_idx2 : 13; + srsran_beta_offsets.csi2_index1 = + beta_offsets.beta_offset_csi_part2_idx1_present ? beta_offsets.beta_offset_csi_part2_idx1 : 13; + srsran_beta_offsets.csi2_index2 = + beta_offsets.beta_offset_csi_part2_idx2_present ? beta_offsets.beta_offset_csi_part2_idx2 : 13; + *in_srsran_beta_offsets = srsran_beta_offsets; + return true; +} + +bool make_phy_pusch_scaling(const uci_on_pusch_s& uci_on_pusch, float* in_scaling) +{ + float pusch_scaling = 0; + switch (uci_on_pusch.scaling) { + case uci_on_pusch_s::scaling_opts::f0p5: + pusch_scaling = 0.5; + break; + case uci_on_pusch_s::scaling_opts::f0p65: + pusch_scaling = 0.65; + break; + case uci_on_pusch_s::scaling_opts::f0p8: + pusch_scaling = 0.8; + break; + case uci_on_pusch_s::scaling_opts::f1: + pusch_scaling = 1.0; + break; + default: + asn1::log_warning("Invalid option for scaling %s", uci_on_pusch.scaling.to_string()); + return false; + } + *in_scaling = pusch_scaling; + return true; +} + } // namespace srsran namespace srsenb { @@ -213,7 +728,7 @@ int set_sched_cell_cfg_sib1(srsenb::sched_interface::cell_cfg_t* sched_cfg, cons // setup PRACH if (not sib1.si_sched_info.si_request_cfg.rach_occasions_si_present) { - asn1::log_error("Expected RA Resp Win present\n"); + asn1::log_warning("rach_occasions_si option not present"); return SRSRAN_ERROR; } sched_cfg->prach_rar_window = sib1.si_sched_info.si_request_cfg.rach_occasions_si.rach_cfg_si.ra_resp_win.to_number(); diff --git a/lib/test/asn1/rrc_nr_utils_test.cc b/lib/test/asn1/rrc_nr_utils_test.cc index 59e41ce24..ea71a2f14 100644 --- a/lib/test/asn1/rrc_nr_utils_test.cc +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -19,6 +19,7 @@ #include "srsran/common/test_common.h" using namespace srsran; +using namespace asn1::rrc_nr; int test_rlc_config() { @@ -66,6 +67,485 @@ int test_mac_rach_common_config() return SRSRAN_SUCCESS; } +// Phy tests + +int make_phy_tdd_cfg_test() +{ + // tdd-UL-DL-ConfigurationCommon + // referenceSubcarrierSpacing: kHz15 (0) + // pattern1 + // dl-UL-TransmissionPeriodicity: ms10 (7) + // nrofDownlinkSlots: 7 + // nrofDownlinkSymbols: 6 + // nrofUplinkSlots: 2 + // nrofUplinkSymbols: 4 + tdd_ul_dl_cfg_common_s tdd_ul_dl_cfg_common = {}; + + tdd_ul_dl_cfg_common.ref_subcarrier_spacing = subcarrier_spacing_opts::khz15; + tdd_ul_dl_cfg_common.pattern1.dl_ul_tx_periodicity = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; + tdd_ul_dl_cfg_common.pattern1.nrof_dl_slots = 7; + tdd_ul_dl_cfg_common.pattern1.nrof_dl_symbols = 6; + tdd_ul_dl_cfg_common.pattern1.nrof_ul_slots = 2; + tdd_ul_dl_cfg_common.pattern1.nrof_ul_symbols = 4; + + srsran_tdd_config_nr_t srsran_tdd_config_nr; + TESTASSERT(make_phy_tdd_cfg(tdd_ul_dl_cfg_common, &srsran_tdd_config_nr) == true); + + TESTASSERT(srsran_tdd_config_nr.pattern1.period_ms == 10); + TESTASSERT(srsran_tdd_config_nr.pattern1.nof_dl_slots == 7); + TESTASSERT(srsran_tdd_config_nr.pattern1.nof_dl_symbols == 6); + TESTASSERT(srsran_tdd_config_nr.pattern1.nof_ul_slots == 2); + TESTASSERT(srsran_tdd_config_nr.pattern1.nof_ul_symbols == 4); + TESTASSERT(srsran_tdd_config_nr.pattern2.period_ms == 0); + return SRSRAN_SUCCESS; +} + +int make_phy_harq_ack_cfg_test() +{ + // physicalCellGroupConfig + // pdsch-HARQ-ACK-Codebook: dynamic (1) + phys_cell_group_cfg_s phys_cell_group_cfg = {}; + phys_cell_group_cfg.pdsch_harq_ack_codebook = phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value; + + srsran_ue_dl_nr_harq_ack_cfg_t srsran_ue_dl_nr_harq_ack_cfg; + TESTASSERT(make_phy_harq_ack_cfg(phys_cell_group_cfg, &srsran_ue_dl_nr_harq_ack_cfg) == true); + + TESTASSERT(srsran_ue_dl_nr_harq_ack_cfg.pdsch_harq_ack_codebook == srsran_pdsch_harq_ack_codebook_dynamic); + return SRSRAN_SUCCESS; +} + +int make_phy_coreset_cfg_test() +{ + ctrl_res_set_s ctrl_res_set = {}; + ctrl_res_set.ctrl_res_set_id = 1; + ctrl_res_set.precoder_granularity = ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; + ctrl_res_set.dur = 1; + ctrl_res_set.cce_reg_map_type.set_non_interleaved(); + ctrl_res_set.freq_domain_res.from_string("111111110000000000000000000000000000000000000"); + + srsran_coreset_t srsran_coreset; + TESTASSERT(make_phy_coreset_cfg(ctrl_res_set, &srsran_coreset) == true); + + TESTASSERT(srsran_coreset.coreset_id == 1); + TESTASSERT(srsran_coreset.precoder_granularity == srsran_coreset_precoder_granularity_reg_bundle); + TESTASSERT(srsran_coreset.duration == 1); + TESTASSERT(srsran_coreset.mapping_type == srsran_coreset_mapping_type_non_interleaved); + + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + TESTASSERT(srsran_coreset.freq_resources[i] == (i < 8)); + } + + return SRSRAN_SUCCESS; +} + +int make_phy_search_space_cfg_test() +{ + // SearchSpace + // searchSpaceId: 1 + // controlResourceSetId: 1 + // monitoringSlotPeriodicityAndOffset: sl1 (0) + // sl1: NULL + // monitoringSymbolsWithinSlot: 8000 [bit length 14, 2 LSB pad bits, 1000 0000 0000 00.. decimal value 8192] + // nrofCandidates + // aggregationLevel1: n0 (0) + // aggregationLevel2: n0 (0) + // aggregationLevel4: n1 (1) + // aggregationLevel8: n0 (0) + // aggregationLevel16: n0 (0) + // searchSpaceType: common (0) + // common + // dci-Format0-0-AndFormat1-0 + search_space_s search_space = {}; + search_space.search_space_id = 1; + search_space.ctrl_res_set_id_present = true; + search_space.ctrl_res_set_id = 1; + search_space.monitoring_slot_periodicity_and_offset_present = true; + search_space.monitoring_slot_periodicity_and_offset.set_sl1(); + search_space.monitoring_symbols_within_slot_present = true; + search_space.monitoring_symbols_within_slot.from_string("10000000000000"); + search_space.nrof_candidates_present = true; + search_space.nrof_candidates.aggregation_level1 = + search_space_s::nrof_candidates_s_::aggregation_level1_opts::options::n0; + search_space.nrof_candidates.aggregation_level2 = + search_space_s::nrof_candidates_s_::aggregation_level2_opts::options::n0; + search_space.nrof_candidates.aggregation_level4 = + search_space_s::nrof_candidates_s_::aggregation_level4_opts::options::n1; + search_space.nrof_candidates.aggregation_level8 = + search_space_s::nrof_candidates_s_::aggregation_level8_opts::options::n0; + search_space.nrof_candidates.aggregation_level16 = + search_space_s::nrof_candidates_s_::aggregation_level16_opts::options::n0; + search_space.search_space_type_present = true; + search_space.search_space_type.set_common(); + search_space.search_space_type.common().dci_format0_minus0_and_format1_minus0_present = true; + + srsran_search_space_t srsran_search_space; + TESTASSERT(make_phy_search_space_cfg(search_space, &srsran_search_space) == true); + + TESTASSERT(srsran_search_space.id == 1); + TESTASSERT(srsran_search_space.coreset_id == 1); + TESTASSERT(srsran_search_space.nof_candidates[0] == 0); + TESTASSERT(srsran_search_space.nof_candidates[1] == 0); + TESTASSERT(srsran_search_space.nof_candidates[2] == 1); + TESTASSERT(srsran_search_space.nof_candidates[3] == 0); + TESTASSERT(srsran_search_space.nof_candidates[4] == 0); + TESTASSERT(srsran_search_space.type == srsran_search_space_type_common_3); + + // searchSpacesToAddModList: 1 item + // Item 0 + // SearchSpace + // searchSpaceId: 2 + // controlResourceSetId: 2 + // monitoringSlotPeriodicityAndOffset: sl1 (0) + // sl1: NULL + // monitoringSymbolsWithinSlot: 8000 [bit length 14, 2 LSB pad bits, 1000 0000 0000 + // 00.. decimal value 8192] nrofCandidates + // aggregationLevel1: n0 (0) + // aggregationLevel2: n2 (2) + // aggregationLevel4: n1 (1) + // aggregationLevel8: n0 (0) + // aggregationLevel16: n0 (0) + // searchSpaceType: ue-Specific (1) + // ue-Specific + // dci-Formats: formats0-0-And-1-0 (0) + + search_space_s search_space_2 = {}; + search_space_2.search_space_id = 2; + search_space_2.ctrl_res_set_id_present = true; + search_space_2.ctrl_res_set_id = 2; + search_space_2.monitoring_slot_periodicity_and_offset_present = true; + search_space_2.monitoring_slot_periodicity_and_offset.set_sl1(); + search_space_2.monitoring_symbols_within_slot_present = true; + search_space_2.monitoring_symbols_within_slot.from_string("10000000000000"); + search_space_2.nrof_candidates_present = true; + search_space_2.nrof_candidates.aggregation_level1 = + search_space_s::nrof_candidates_s_::aggregation_level1_opts::options::n0; + search_space_2.nrof_candidates.aggregation_level2 = + search_space_s::nrof_candidates_s_::aggregation_level2_opts::options::n2; + search_space_2.nrof_candidates.aggregation_level4 = + search_space_s::nrof_candidates_s_::aggregation_level4_opts::options::n1; + search_space_2.nrof_candidates.aggregation_level8 = + search_space_s::nrof_candidates_s_::aggregation_level8_opts::options::n0; + search_space_2.nrof_candidates.aggregation_level16 = + search_space_s::nrof_candidates_s_::aggregation_level16_opts::options::n0; + search_space_2.search_space_type_present = true; + search_space_2.search_space_type.set_ue_specific(); + search_space_2.search_space_type.ue_specific().dci_formats = + search_space_s::search_space_type_c_::ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; + + srsran_search_space_t srsran_search_space_2; + TESTASSERT(make_phy_search_space_cfg(search_space_2, &srsran_search_space_2) == true); + + TESTASSERT(srsran_search_space_2.id == 2); + TESTASSERT(srsran_search_space_2.coreset_id == 2); + TESTASSERT(srsran_search_space_2.nof_candidates[0] == 0); + TESTASSERT(srsran_search_space_2.nof_candidates[1] == 2); + TESTASSERT(srsran_search_space_2.nof_candidates[2] == 1); + TESTASSERT(srsran_search_space_2.nof_candidates[3] == 0); + TESTASSERT(srsran_search_space_2.nof_candidates[4] == 0); + TESTASSERT(srsran_search_space_2.type == srsran_search_space_type_ue); + + return SRSRAN_SUCCESS; +} + +int make_phy_csi_report_test() +{ + // csi-ReportConfigToAddModList: 1 item + // Item 0 + // CSI-ReportConfig + // reportConfigId: 0 + // resourcesForChannelMeasurement: 0 + // csi-IM-ResourcesForInterference: 1 + // reportConfigType: periodic (0) + // periodic + // reportSlotConfig: slots80 (7) + // slots80: 9 + // pucch-CSI-ResourceList: 1 item + // Item 0 + // PUCCH-CSI-Resource + // uplinkBandwidthPartId: 0 + // pucch-Resource: 17 + // reportQuantity: cri-RI-PMI-CQI (1) + // cri-RI-PMI-CQI: NULL + // reportFreqConfiguration + // cqi-FormatIndicator: widebandCQI (0) + // timeRestrictionForChannelMeasurements: notConfigured (1) + // timeRestrictionForInterferenceMeasurements: notConfigured (1) + // groupBasedBeamReporting: disabled (1) + // disabled + // cqi-Table: table2 (1) + // subbandSize: value1 (0) + csi_report_cfg_s csi_report_cfg = {}; + csi_report_cfg.report_cfg_id = 0; + csi_report_cfg.res_for_ch_meas = 0; + csi_report_cfg.csi_im_res_for_interference_present = true; + csi_report_cfg.csi_im_res_for_interference = 1; + csi_report_cfg.report_cfg_type.set_periodic(); + csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.set_slots80(); + csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots80() = 9; + pucch_csi_res_s pucch_csi_res; + pucch_csi_res.pucch_res = 17; + pucch_csi_res.ul_bw_part_id = 0; + csi_report_cfg.report_cfg_type.periodic().pucch_csi_res_list.push_back(pucch_csi_res); + csi_report_cfg.report_quant.set_cri_ri_pmi_cqi(); + csi_report_cfg.report_freq_cfg_present = true; + csi_report_cfg.report_freq_cfg.cqi_format_ind_present = true; + csi_report_cfg.report_freq_cfg.cqi_format_ind = + csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; + csi_report_cfg.cqi_table_present = true; + csi_report_cfg.cqi_table = csi_report_cfg_s::cqi_table_opts::table2; + csi_report_cfg.subband_size = csi_report_cfg_s::subband_size_opts::value1; + + srsran_csi_hl_report_cfg_t srsran_csi_hl_report_cfg; + TESTASSERT(make_phy_csi_report(csi_report_cfg, &srsran_csi_hl_report_cfg) == true); + + TESTASSERT(srsran_csi_hl_report_cfg.type == SRSRAN_CSI_REPORT_TYPE_PERIODIC); + TESTASSERT(srsran_csi_hl_report_cfg.channel_meas_id == 0); + TESTASSERT(srsran_csi_hl_report_cfg.interf_meas_present == true); + TESTASSERT(srsran_csi_hl_report_cfg.interf_meas_id == 1); + TESTASSERT(srsran_csi_hl_report_cfg.periodic.period == 80); + TESTASSERT(srsran_csi_hl_report_cfg.periodic.offset == 9); + TESTASSERT(srsran_csi_hl_report_cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI); + TESTASSERT(srsran_csi_hl_report_cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND); + TESTASSERT(srsran_csi_hl_report_cfg.cqi_table == SRSRAN_CSI_CQI_TABLE_2); + return SRSRAN_SUCCESS; +} + +int make_phy_common_time_ra_test() +{ + // Test 1 & 2 + // pdsch-ConfigCommon: setup (1) + // setup + // pdsch-TimeDomainAllocationList: 2 items + // Item 0 + // PDSCH-TimeDomainResourceAllocation + // mappingType: typeA (0) + // startSymbolAndLength: 40 + // Item 1 + // PDSCH-TimeDomainResourceAllocation + // mappingType: typeA (0) + // startSymbolAndLength: 57 + srsran_sch_time_ra_t srsran_sch_time_ra = {}; + + pdsch_time_domain_res_alloc_s pdsch_time_domain_res_alloc = {}; + pdsch_time_domain_res_alloc.start_symbol_and_len = 40; + pdsch_time_domain_res_alloc.map_type = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; + + TESTASSERT(make_phy_common_time_ra(pdsch_time_domain_res_alloc, &srsran_sch_time_ra) == true); + + TESTASSERT(srsran_sch_time_ra.mapping_type == srsran_sch_mapping_type_A); + TESTASSERT(srsran_sch_time_ra.sliv == 40); + TESTASSERT(srsran_sch_time_ra.k == 0); + + pdsch_time_domain_res_alloc.start_symbol_and_len = 57; + pdsch_time_domain_res_alloc.map_type = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; + + TESTASSERT(make_phy_common_time_ra(pdsch_time_domain_res_alloc, &srsran_sch_time_ra) == true); + TESTASSERT(srsran_sch_time_ra.mapping_type == srsran_sch_mapping_type_A); + TESTASSERT(srsran_sch_time_ra.sliv == 57); + TESTASSERT(srsran_sch_time_ra.k == 0); + + // Test 3 & 4 + + // pusch-ConfigCommon: setup (1) + // setup + // pusch-TimeDomainAllocationList: 2 items + // Item 0 + // PUSCH-TimeDomainResourceAllocation + // k2: 4 + // mappingType: typeA (0) + // startSymbolAndLength: 27 + // Item 1 + // PUSCH-TimeDomainResourceAllocation + // k2: 5 + // mappingType: typeA (0) + // startSymbolAndLength: 27 + // p0-NominalWithGrant: -90dBm + + srsran_sch_time_ra = {}; + pusch_time_domain_res_alloc_s pusch_time_domain_res_alloc = {}; + pusch_time_domain_res_alloc.k2_present = true; + pusch_time_domain_res_alloc.k2 = 4; + pusch_time_domain_res_alloc.start_symbol_and_len = 27; + pusch_time_domain_res_alloc.map_type = pusch_time_domain_res_alloc_s::map_type_opts::type_a; + + TESTASSERT(make_phy_common_time_ra(pusch_time_domain_res_alloc, &srsran_sch_time_ra) == true); + + TESTASSERT(srsran_sch_time_ra.mapping_type == srsran_sch_mapping_type_A); + TESTASSERT(srsran_sch_time_ra.sliv == 27); + TESTASSERT(srsran_sch_time_ra.k == 4); + + pusch_time_domain_res_alloc = {}; + pusch_time_domain_res_alloc.k2_present = true; + pusch_time_domain_res_alloc.k2 = 5; + pusch_time_domain_res_alloc.start_symbol_and_len = 27; + pusch_time_domain_res_alloc.map_type = pusch_time_domain_res_alloc_s::map_type_opts::type_a; + + TESTASSERT(make_phy_common_time_ra(pusch_time_domain_res_alloc, &srsran_sch_time_ra) == true); + + TESTASSERT(srsran_sch_time_ra.mapping_type == srsran_sch_mapping_type_A); + TESTASSERT(srsran_sch_time_ra.sliv == 27); + TESTASSERT(srsran_sch_time_ra.k == 5); + + return SRSRAN_SUCCESS; +} + +int make_phy_max_code_rate_test() +{ + // format1: setup (1) + // setup + // format2: setup (1) + // setup + // maxCodeRate: zeroDot25 (2) + pucch_format_cfg_s pucch_format_cfg = {}; + pucch_format_cfg.max_code_rate_present = true; + pucch_format_cfg.max_code_rate = pucch_max_code_rate_opts::options::zero_dot25; + uint32_t max_code_rate; + TESTASSERT(make_phy_max_code_rate(pucch_format_cfg, &max_code_rate) == true); + TESTASSERT(max_code_rate == 2); + return SRSRAN_SUCCESS; +} + +int make_phy_res_config_test() +{ + uint32_t format_2_max_code_rate = 2; + pucch_res_s pucch_res = {}; + + // Item 0 + // PUCCH-Resource + // pucch-ResourceId: 0 + // startingPRB: 0 + // format: format1 (1) + // format1 + // initialCyclicShift: 0 + // nrofSymbols: 14 + // startingSymbolIndex: 0 + // timeDomainOCC: 0 + + pucch_res.pucch_res_id = 0; + pucch_res.start_prb = 0; + pucch_res.format.set_format1(); + pucch_res.format.format1().init_cyclic_shift = 0; + pucch_res.format.format1().nrof_symbols = 14; + pucch_res.format.format1().start_symbol_idx = 0; + pucch_res.format.format1().time_domain_occ = 0; + + srsran_pucch_nr_resource_t srsran_pucch_nr_resource; + + TESTASSERT(make_phy_res_config(pucch_res, format_2_max_code_rate, &srsran_pucch_nr_resource) == true); + + TESTASSERT(srsran_pucch_nr_resource.format == SRSRAN_PUCCH_NR_FORMAT_1); + TESTASSERT(srsran_pucch_nr_resource.starting_prb == 0); + TESTASSERT(srsran_pucch_nr_resource.initial_cyclic_shift == 0); + TESTASSERT(srsran_pucch_nr_resource.nof_symbols == 14); + TESTASSERT(srsran_pucch_nr_resource.start_symbol_idx == 0); + TESTASSERT(srsran_pucch_nr_resource.time_domain_occ == 0); + TESTASSERT(srsran_pucch_nr_resource.max_code_rate == 2); + + return SRSRAN_SUCCESS; +} + +int make_phy_sr_resource_test() +{ + // schedulingRequestResourceToAddModList: 1 item + // Item 0 + // SchedulingRequestResourceConfig + // schedulingRequestResourceId: 1 + // schedulingRequestID: 0 + // periodicityAndOffset: sl40 (10) + // sl40: 8 + // resource: 16 + sched_request_res_cfg_s sched_request_res_cfg; + sched_request_res_cfg.sched_request_res_id = 1; + sched_request_res_cfg.sched_request_id = 0; + sched_request_res_cfg.periodicity_and_offset_present = true; + sched_request_res_cfg.periodicity_and_offset.set_sl40(); + sched_request_res_cfg.periodicity_and_offset.sl40() = 8; + sched_request_res_cfg.res_present = true; + sched_request_res_cfg.res = 16; + + srsran_pucch_nr_sr_resource_t srsran_pucch_nr_sr_resource; + TESTASSERT(make_phy_sr_resource(sched_request_res_cfg, &srsran_pucch_nr_sr_resource) == true); + + TESTASSERT(srsran_pucch_nr_sr_resource.sr_id == 0); + TESTASSERT(srsran_pucch_nr_sr_resource.period == 40); + TESTASSERT(srsran_pucch_nr_sr_resource.offset == 8); + TESTASSERT(srsran_pucch_nr_sr_resource.configured == true); + + return SRSRAN_SUCCESS; +} + +int make_phy_dmrs_additional_pos_test() +{ + // pusch-Config: setup (1) + // setup + // dmrs-UplinkForPUSCH-MappingTypeA: setup (1) + // setup + // dmrs-AdditionalPosition: pos1 (1) + // transformPrecodingDisabled + dmrs_ul_cfg_s dmrs_ul_cfg; + dmrs_ul_cfg.dmrs_add_position_present = true; + dmrs_ul_cfg.dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1; + srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; + TESTASSERT(make_phy_dmrs_additional_pos(dmrs_ul_cfg, &srsran_dmrs_sch_add_pos) == true); + + TESTASSERT(srsran_dmrs_sch_add_pos == srsran_dmrs_sch_add_pos_1); + + return SRSRAN_SUCCESS; +} + +int make_phy_beta_offsets_test() +{ + // uci-OnPUSCH: setup (1) + // setup + // betaOffsets: semiStatic (1) + // semiStatic + // betaOffsetACK-Index1: 9 + // betaOffsetACK-Index2: 9 + // betaOffsetACK-Index3: 9 + // betaOffsetCSI-Part1-Index1: 6 + // betaOffsetCSI-Part1-Index2: 6 + // betaOffsetCSI-Part2-Index1: 6 + // betaOffsetCSI-Part2-Index2: 6 + + beta_offsets_s beta_offsets; + beta_offsets.beta_offset_ack_idx1_present = true; + beta_offsets.beta_offset_ack_idx1 = 9; + beta_offsets.beta_offset_ack_idx2_present = true; + beta_offsets.beta_offset_ack_idx2 = 9; + beta_offsets.beta_offset_ack_idx3_present = true; + beta_offsets.beta_offset_ack_idx3 = 9; + beta_offsets.beta_offset_csi_part1_idx1_present = true; + beta_offsets.beta_offset_csi_part1_idx1 = 6; + beta_offsets.beta_offset_csi_part1_idx2_present = true; + beta_offsets.beta_offset_csi_part1_idx2 = 6; + beta_offsets.beta_offset_csi_part2_idx1_present = true; + beta_offsets.beta_offset_csi_part2_idx1 = 6; + beta_offsets.beta_offset_csi_part2_idx2_present = true; + beta_offsets.beta_offset_csi_part2_idx2 = 6; + + srsran_beta_offsets_t srsran_beta_offsets; + TESTASSERT(make_phy_beta_offsets(beta_offsets, &srsran_beta_offsets) == true); + + TESTASSERT(srsran_beta_offsets.ack_index1 == 9); + TESTASSERT(srsran_beta_offsets.ack_index2 == 9); + TESTASSERT(srsran_beta_offsets.ack_index3 == 9); + TESTASSERT(srsran_beta_offsets.csi1_index1 == 6); + TESTASSERT(srsran_beta_offsets.csi1_index2 == 6); + TESTASSERT(srsran_beta_offsets.csi2_index1 == 6); + TESTASSERT(srsran_beta_offsets.csi2_index2 == 6); + return SRSRAN_SUCCESS; +} + +int make_phy_pusch_scaling_test() +{ + uci_on_pusch_s uci_on_pusch; + uci_on_pusch.scaling = uci_on_pusch_s::scaling_opts::f1; + float scaling; + TESTASSERT(make_phy_pusch_scaling(uci_on_pusch, &scaling) == true); + TESTASSERT(scaling = 1.0); + return SRSRAN_SUCCESS; +} + int main() { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -80,6 +560,18 @@ int main() TESTASSERT(test_rlc_config() == SRSRAN_SUCCESS); TESTASSERT(test_mac_rach_common_config() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_tdd_cfg_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_harq_ack_cfg_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_search_space_cfg_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_csi_report_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_coreset_cfg_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_common_time_ra_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_max_code_rate_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_res_config_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_sr_resource_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_dmrs_additional_pos_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_beta_offsets_test() == SRSRAN_SUCCESS); + TESTASSERT(make_phy_pusch_scaling_test() == SRSRAN_SUCCESS); srslog::flush(); diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 4f99ce10a..2e04a88b3 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -119,7 +119,7 @@ public: uint32_t sk_counter_r15, bool nr_radio_bearer_cfg1_r15_present, asn1::dyn_octstring nr_radio_bearer_cfg1_r15); - void configure_sk_counter(uint16_t sk_counter); + bool configure_sk_counter(uint16_t sk_counter); bool is_config_pending(); // STACK interface void cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell); @@ -136,6 +136,9 @@ private: bool running = false; srsran::block_queue cmd_q; + // PHY config + srsran::phy_cfg_nr_t phy_cfg = {}; + phy_interface_rrc_nr* phy = nullptr; mac_interface_rrc_nr* mac = nullptr; rlc_interface_rrc* rlc = nullptr; @@ -179,11 +182,24 @@ private: std::map drb_eps_bearer_id; // Map of drb id to eps_bearer_id + // temporary maps for building the pucch nr resources + std::map res_list; + std::map res_list_present; + bool apply_cell_group_cfg(const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg); bool apply_radio_bearer_cfg(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg); bool apply_rlc_add_mod(const asn1::rrc_nr::rlc_bearer_cfg_s& rlc_bearer_cfg); bool apply_mac_cell_group(const asn1::rrc_nr::mac_cell_group_cfg_s& mac_cell_group_cfg); bool apply_sp_cell_cfg(const asn1::rrc_nr::sp_cell_cfg_s& sp_cell_cfg); + bool apply_phy_cell_group_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg); + bool apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_common); + bool apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_common); + bool apply_sp_cell_init_dl_pdcch(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg); + bool apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg); + bool apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_cfg); + bool apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg); + bool apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg); + bool apply_res_csi_report_cfg(const asn1::rrc_nr::csi_report_cfg_s& csi_report_cfg); bool apply_drb_add_mod(const asn1::rrc_nr::drb_to_add_mod_s& drb_cfg); bool apply_security_cfg(const asn1::rrc_nr::security_cfg_s& security_cfg); diff --git a/srsue/hdr/stack/upper/usim_base.h b/srsue/hdr/stack/upper/usim_base.h index bb26040b7..cdb3019aa 100644 --- a/srsue/hdr/stack/upper/usim_base.h +++ b/srsue/hdr/stack/upper/usim_base.h @@ -93,8 +93,8 @@ public: void restore_keys_from_failed_ho(srsran::as_security_config_t* as_ctx) final; // NR RRC interface - void generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) final; - void update_nr_context(srsran::as_security_config_t* sec_cfg) final; + bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) final; + bool update_nr_context(srsran::as_security_config_t* sec_cfg) final; // Helpers std::string get_mcc_str(const uint8_t* imsi_vec); diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index 171f1582d..836805994 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -128,7 +128,7 @@ void rrc_nr::log_rrc_message(const std::string& source, (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); - logger.debug("Content:\n%s", json_writer.to_string().c_str()); + logger.debug("Content:%s", json_writer.to_string().c_str()); } else if (logger.info.enabled()) { logger.info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), pdu->N_bytes); } @@ -151,7 +151,7 @@ void rrc_nr::log_rrc_message(const std::string& source, (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); - logger.debug("Content:\n%s", json_writer.to_string().c_str()); + logger.debug("Content:%s", json_writer.to_string().c_str()); } else if (logger.info.enabled()) { logger.info("%s - %s %s (%d B)", source.c_str(), (dir == Rx) ? "Rx" : "Tx", msg_type.c_str(), oct.size()); } @@ -457,11 +457,15 @@ void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15) fake_measurement_timer.run(); } -void rrc_nr::configure_sk_counter(uint16_t sk_counter) +bool rrc_nr::configure_sk_counter(uint16_t sk_counter) { logger.info("[NR] Configure new SK counter %d. Update Key for secondary gnb", sk_counter); - usim->generate_nr_context(sk_counter, &sec_cfg); + if (usim->generate_nr_context(sk_counter, &sec_cfg) == false) { + return false; + } + return true; } + bool rrc_nr::is_config_pending() { if (conn_recfg_proc.is_busy()) { @@ -499,9 +503,11 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) rlc_bearer_cfg.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len != rlc_bearer_cfg.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len) { logger.warning("NR RLC sequence number length is not the same in uplink and downlink"); + return false; } } else { logger.warning("NR RLC type is not unacknowledged mode bidirectional"); + return false; } } else { logger.warning("In RLC bearer cfg does not contain rlc cfg"); @@ -525,6 +531,8 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list_present) { if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() > 1) { logger.warning("Only handling 1 scheduling request index to add"); + return false; + } else { sr_cfg.dsr_transmax = mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[1].sr_trans_max; mac->set_config(sr_cfg); } @@ -532,6 +540,7 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_release_list_present) { logger.warning("Not handling sched request to release list"); + return false; } } if (mac_cell_group_cfg.sched_request_cfg_present) @@ -558,24 +567,507 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg return true; } +bool rrc_nr::apply_sp_cell_init_dl_pdcch(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg) +{ + if (pdcch_cfg.search_spaces_to_add_mod_list_present) { + for (uint32_t i = 0; i < pdcch_cfg.search_spaces_to_add_mod_list.size(); i++) { + srsran_search_space_t search_space; + if (make_phy_search_space_cfg(pdcch_cfg.search_spaces_to_add_mod_list[i], &search_space) == true) { + phy_cfg.pdcch.search_space[search_space.id] = search_space; + phy_cfg.pdcch.search_space_present[search_space.id] = true; + } else { + logger.warning("Warning while building search_space structure"); + return false; + } + } + } else { + logger.warning("Option search_spaces_to_add_mod_list not present"); + return false; + } + return true; +} + +bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg) +{ + return true; +} + +bool rrc_nr::apply_res_csi_report_cfg(const asn1::rrc_nr::csi_report_cfg_s& csi_report_cfg) +{ + uint32_t report_cfg_id = csi_report_cfg.report_cfg_id; + srsran_csi_hl_report_cfg_t srsran_csi_hl_report_cfg; + if (make_phy_csi_report(csi_report_cfg, &srsran_csi_hl_report_cfg) == true) { + phy_cfg.csi.reports[report_cfg_id] = srsran_csi_hl_report_cfg; + } else { + logger.warning("Warning while building report structure"); + return false; + } + if (csi_report_cfg.report_cfg_type.type() == csi_report_cfg_s::report_cfg_type_c_::types_opts::options::periodic) { + if (csi_report_cfg.report_cfg_type.periodic().pucch_csi_res_list.size() > 0) { + uint32_t res_id = csi_report_cfg.report_cfg_type.periodic() + .pucch_csi_res_list[0] + .pucch_res; // TODO: support and check more items + if (res_list_present[res_id] == true) { + phy_cfg.csi.reports[report_cfg_id].periodic.resource = res_list[res_id]; + } else { + logger.error("Resources set not present for assigning pucch sets (res_id %d)", res_id); + return false; + } + } else { + logger.warning("List size to small: pucch_csi_res_list.size() < 0"); + return false; + } + } + return true; +} + +bool rrc_nr::apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg) +{ + if (csi_meas_cfg.csi_report_cfg_to_add_mod_list_present) { + for (uint32_t i = 0; i < csi_meas_cfg.csi_report_cfg_to_add_mod_list.size(); i++) { + if (apply_res_csi_report_cfg(csi_meas_cfg.csi_report_cfg_to_add_mod_list[i]) == false) { + return false; + } + } + } else { + logger.warning("Option csi_report_cfg_to_add_mod_list not present"); + return false; + } + return true; +} + +bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_common) +{ + if (dl_cfg_common.init_dl_bwp_present) { + if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common_present) { + if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common.type() == + asn1::rrc_nr::setup_release_c::types_opts::setup) { + const pdcch_cfg_common_s& pdcch_cfg_common = dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(); + if (pdcch_cfg_common.common_ctrl_res_set_present) { + srsran_coreset_t coreset; + if (make_phy_coreset_cfg(pdcch_cfg_common.common_ctrl_res_set, &coreset) == true) { + phy_cfg.pdcch.coreset[coreset.coreset_id] = coreset; + phy_cfg.pdcch.coreset_present[coreset.coreset_id] = true; + } else { + logger.warning("Warning while building coreset structure"); + return false; + } + } else { + logger.warning("Option common_ctrl_res_set not present"); + return false; + } + if (pdcch_cfg_common.common_search_space_list_present) { + for (uint32_t i = 0; i < pdcch_cfg_common.common_search_space_list.size(); i++) { + srsran_search_space_t search_space; + if (make_phy_search_space_cfg(pdcch_cfg_common.common_search_space_list[i], &search_space) == true) { + phy_cfg.pdcch.search_space[search_space.id] = search_space; + phy_cfg.pdcch.search_space_present[search_space.id] = true; + } else { + logger.warning("Warning while building search_space structure"); + return false; + } + } + } else { + logger.warning("Option common_search_space_list not present"); + return false; + } + if (pdcch_cfg_common.ra_search_space_present) { + if (phy_cfg.pdcch.search_space_present[pdcch_cfg_common.ra_search_space] == true) { + // phy_cfg.pdcch.ra_rnti = 0x16; //< Supposed to be deduced from PRACH configuration + phy_cfg.pdcch.ra_search_space = phy_cfg.pdcch.search_space[pdcch_cfg_common.ra_search_space]; + phy_cfg.pdcch.ra_search_space_present = true; + phy_cfg.pdcch.ra_search_space.type = srsran_search_space_type_common_3; + } else { + logger.warning("Search space %d not presenet for random access search space", + pdcch_cfg_common.ra_search_space); + } + } else { + logger.warning("Option ra_search_space not present"); + return false; + } + } else { + logger.warning("Option pdsch_cfg_common not of type setup"); + return false; + } + } else { + logger.warning("Option pdsch_cfg_common not present"); + return false; + } + if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common_present) { + if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common.type() == setup_release_c::types::setup) { + pdsch_cfg_common_s pdsch_cfg_common = dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup(); + if (pdsch_cfg_common.pdsch_time_domain_alloc_list_present) { + for (uint32_t i = 0; i < pdsch_cfg_common.pdsch_time_domain_alloc_list.size(); i++) { + srsran_sch_time_ra_t common_time_ra; + if (make_phy_common_time_ra(pdsch_cfg_common.pdsch_time_domain_alloc_list[i], &common_time_ra) == true) { + phy_cfg.pdsch.common_time_ra[i] = common_time_ra; + phy_cfg.pdsch.nof_common_time_ra = i; + } else { + logger.warning("Warning while building common_time_ra structure"); + return false; + } + } + } else { + logger.warning("Option pdsch_time_domain_alloc_list not present"); + return false; + } + } else { + logger.warning("Option pdsch_cfg_common not of type setup"); + return false; + } + } else { + logger.warning("Option pdsch_cfg_common not present"); + return false; + } + } else { + logger.warning("Option init_dl_bwp not present"); + return false; + } + return true; +} + +bool rrc_nr::apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_common) +{ + if (ul_cfg_common.init_ul_bwp_present) { + if (ul_cfg_common.init_ul_bwp.rach_cfg_common_present) { + if (ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == setup_release_c::types_opts::setup) { + rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(ul_cfg_common.init_ul_bwp.rach_cfg_common.setup()); + phy_cfg.pdcch.ra_rnti = ul_cfg_common.init_ul_bwp.rach_cfg_common.setup().rach_cfg_generic.prach_cfg_idx; + mac->set_config(rach_nr_cfg); + } else { + logger.warning("Option rach_cfg_common not of type setup"); + return false; + } + } else { + logger.warning("Option rach_cfg_common not present"); + return false; + } + if (ul_cfg_common.init_ul_bwp.pusch_cfg_common_present) { + if (ul_cfg_common.init_ul_bwp.pusch_cfg_common.type() == setup_release_c::types_opts::setup) { + if (ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list_present) { + for (uint32_t i = 0; + i < ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list.size(); + i++) { + srsran_sch_time_ra_t common_time_ra; + if (make_phy_common_time_ra( + ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list[i], + &common_time_ra) == true) { + phy_cfg.pusch.common_time_ra[i] = common_time_ra; + phy_cfg.pusch.nof_common_time_ra = i + 1; + } else { + logger.warning("Warning while building common_time_ra structure"); + } + } + } else { + logger.warning("Option pusch_time_domain_alloc_list not present"); + return false; + } + } else { + logger.warning("Option pusch_cfg_common not of type setup"); + return false; + } + } else { + logger.warning("Option pusch_cfg_common not present"); + return false; + } + if (ul_cfg_common.init_ul_bwp.pucch_cfg_common_present) { + if (ul_cfg_common.init_ul_bwp.pucch_cfg_common.type() == setup_release_c::types_opts::setup) { + } else { + logger.warning("Option pucch_cfg_common not of type setup"); + return false; + } + } else { + logger.warning("Option pucch_cfg_common not present"); + return false; + } + } else { + logger.warning("Option init_ul_bwp not present"); + return false; + } + return true; +} + +bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_cfg) +{ + // determine format 2 max code rate + uint32_t format_2_max_code_rate = 0; + if (pucch_cfg.format2_present && pucch_cfg.format2.type() == setup_release_c::types::setup) { + if (pucch_cfg.format2.setup().max_code_rate_present) { + if (make_phy_max_code_rate(pucch_cfg.format2.setup(), &format_2_max_code_rate) == false) { + logger.warning("Warning while building format_2_max_code_rate"); + } + } + } else { + logger.warning("Option format2 not present or not of type setup"); + return false; + } + + // now look up resource and assign into internal struct + if (pucch_cfg.res_to_add_mod_list_present) { + for (uint32_t i = 0; i < pucch_cfg.res_to_add_mod_list.size(); i++) { + uint32_t res_id = pucch_cfg.res_to_add_mod_list[i].pucch_res_id; + if (make_phy_res_config(pucch_cfg.res_to_add_mod_list[i], format_2_max_code_rate, &res_list[res_id]) == true) { + res_list_present[res_id] = true; + } else { + logger.warning("Warning while building pucch_nr_resource structure"); + return false; + } + } + } else { + logger.warning("Option res_to_add_mod_list not present"); + return false; + } + + // Check first all resource lists and + phy_cfg.pucch.enabled = true; + if (pucch_cfg.res_set_to_add_mod_list_present) { + for (uint32_t i = 0; i < pucch_cfg.res_set_to_add_mod_list.size(); i++) { + uint32_t set_id = pucch_cfg.res_set_to_add_mod_list[i].pucch_res_set_id; + phy_cfg.pucch.sets[set_id].nof_resources = pucch_cfg.res_set_to_add_mod_list[i].res_list.size(); + for (uint32_t j = 0; j < pucch_cfg.res_set_to_add_mod_list[i].res_list.size(); j++) { + uint32_t res_id = pucch_cfg.res_set_to_add_mod_list[i].res_list[j]; + if (res_list_present[res_id] == true) { + phy_cfg.pucch.sets[set_id].resources[j] = res_list[res_id]; + } else { + logger.error( + "Resources set not present for assign pucch sets (res_id %d, setid %d, j %d)", res_id, set_id, j); + } + } + } + } + + if (pucch_cfg.sched_request_res_to_add_mod_list_present) { + for (uint32_t i = 0; i < pucch_cfg.sched_request_res_to_add_mod_list.size(); i++) { + uint32_t res_id = pucch_cfg.sched_request_res_to_add_mod_list[i].sched_request_res_id; + srsran_pucch_nr_sr_resource_t srsran_pucch_nr_sr_resource; + if (make_phy_sr_resource(pucch_cfg.sched_request_res_to_add_mod_list[i], &srsran_pucch_nr_sr_resource) == + true) { // TODO: fix that if indexing is solved + phy_cfg.pucch.sr_resources[res_id] = srsran_pucch_nr_sr_resource; + } else { + logger.warning("Warning while building srsran_pucch_nr_sr_resource structure"); + return false; + } + } + } else { + logger.warning("Option sched_request_res_to_add_mod_list not present"); + return false; + } + + if (pucch_cfg.dl_data_to_ul_ack_present) { + for (uint32_t i = 0; i < pucch_cfg.dl_data_to_ul_ack.size(); i++) { + phy_cfg.harq_ack.dl_data_to_ul_ack[i] = pucch_cfg.dl_data_to_ul_ack[i]; + } + phy_cfg.harq_ack.nof_dl_data_to_ul_ack = pucch_cfg.dl_data_to_ul_ack.size(); + } else { + logger.warning("Option dl_data_to_ul_ack not present"); + return false; + } + + return true; +}; + +bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg) +{ + if (pusch_cfg.dmrs_ul_for_pusch_map_type_a_present) { + if (pusch_cfg.dmrs_ul_for_pusch_map_type_a.type() == setup_release_c::types_opts::setup) { + srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; + if (make_phy_dmrs_additional_pos(pusch_cfg.dmrs_ul_for_pusch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) == + true) { + phy_cfg.pusch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos; + phy_cfg.pusch.dmrs_typeA.present = true; + } else { + logger.warning("Warning while build srsran_dmrs_sch_add_pos structure"); + return false; + } + } else { + logger.warning("Option dmrs_ul_for_pusch_map_type_a not of type setup"); + return false; + return false; + } + } else { + logger.warning("Option dmrs_ul_for_pusch_map_type_a not present"); + return false; + } + if (pusch_cfg.uci_on_pusch_present) { + if (pusch_cfg.uci_on_pusch.type() == setup_release_c::types_opts::setup) { + if (pusch_cfg.uci_on_pusch.setup().beta_offsets_present) { + if (pusch_cfg.uci_on_pusch.setup().beta_offsets.type() == + uci_on_pusch_s::beta_offsets_c_::types_opts::semi_static) { + srsran_beta_offsets_t beta_offsets; + if (make_phy_beta_offsets(pusch_cfg.uci_on_pusch.setup().beta_offsets.semi_static(), &beta_offsets) == true) { + phy_cfg.pusch.beta_offsets = beta_offsets; + } else { + logger.warning("Warning while building beta_offsets structure"); + return false; + } + } else { + logger.warning("Option beta_offsets not of type semi_static"); + return false; + } + if (make_phy_pusch_scaling(pusch_cfg.uci_on_pusch.setup(), &phy_cfg.pusch.scaling) == false) { + logger.warning("Warning while building scaling structure"); + return false; + } + } else { + logger.warning("Option beta_offsets not present"); + return false; + } + } else { + logger.warning("Option uci_on_pusch of type setup"); + return false; + } + } else { + logger.warning("Option uci_on_pusch not present"); + return false; + } + return true; +}; + bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) { if (sp_cell_cfg.recfg_with_sync_present) { const recfg_with_sync_s& recfg_with_sync = sp_cell_cfg.recfg_with_sync; mac->set_crnti(recfg_with_sync.new_ue_id); + // Common config if (recfg_with_sync.sp_cell_cfg_common_present) { if (recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present) { - const bwp_ul_common_s* bwp_ul_common = &recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp; - if (bwp_ul_common->rach_cfg_common_present) { - if (bwp_ul_common->rach_cfg_common.type() == setup_release_c::types_opts::setup) { - const rach_cfg_common_s& rach_cfg_common = bwp_ul_common->rach_cfg_common.setup(); - rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(rach_cfg_common); - mac->set_config(rach_nr_cfg); + if (apply_ul_common_cfg(recfg_with_sync.sp_cell_cfg_common.ul_cfg_common) == false) { + return false; + } + } else { + logger.warning("Secondary primary cell ul cfg common not present"); + return false; + } + if (recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present) { + if (apply_dl_common_cfg(recfg_with_sync.sp_cell_cfg_common.dl_cfg_common) == false) { + return false; + } + } else { + logger.warning("DL cfg common not present"); + return false; + } + if (recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present) { + srsran_tdd_config_nr_t tdd; + if (make_phy_tdd_cfg(recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common, &tdd) == true) { + phy_cfg.tdd = tdd; + } else { + logger.warning("Warning while building tdd structure"); + return false; + } + } else { + logger.warning("TDD UL DL config not present"); + return false; + } + } + } else { + logger.warning("Reconfig with with sync not present"); + return false; + } + + // Dedicated config + if (sp_cell_cfg.sp_cell_cfg_ded_present) { + // Dedicated Downlink + if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.type() == + setup_release_c::types_opts::setup) { + if (apply_sp_cell_init_dl_pdcch(sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup()) == false) { + return false; } + } else { + logger.warning("Option pdcch_cfg not of type setup"); + return false; + } + } else { + logger.warning("Option pdcch_cfg not present"); + return false; + } + if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg.type() == + setup_release_c::types_opts::setup) { + apply_sp_cell_init_dl_pdsch(sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg.setup()); + } else { + logger.warning("Option pdsch_cfg_cfg not of type setup"); + return false; } + } else { + logger.warning("Option pdsch_cfg not present"); + return false; } + } else { + logger.warning("Option init_dl_bwp not present"); + return false; } - mac->start_ra_procedure(); + // Dedicated Uplink + if (sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg.type() == + setup_release_c::types_opts::setup) { + if (apply_sp_cell_ded_ul_pucch(sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg.setup()) == false) { + return false; + } + } else { + logger.warning("Option pucch_cfg not of type setup"); + return false; + } + } else { + logger.warning("Option pucch_cfg not present"); + return false; + } + if (sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg.type() == + setup_release_c::types_opts::setup) { + if (apply_sp_cell_ded_ul_pusch(sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg.setup()) == false) { + return false; + } + } else { + logger.warning("Option pusch_cfg not of type setup"); + return false; + } + } else { + logger.warning("Option pusch_cfg not present"); + return false; + } + } else { + logger.warning("Option init_ul_bwp not present"); + return false; + } + } else { + logger.warning("Option ul_cfg not present"); + return false; + } + if (sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present) { + if (sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.type() == setup_release_c::types_opts::setup) { + if (apply_csi_meas_cfg(sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup()) == false) { + return false; + } + } else { + logger.warning("Option csi_meas_cfg not of type setup"); + return false; + } + } else { + logger.warning("Option csi_meas_cfg not present"); + return false; + } + + } else { + logger.warning("Option sp_cell_cfg_ded not present"); + return false; + } + phy->set_config(phy_cfg); + mac->start_ra_procedure(); + return true; +} + +bool rrc_nr::apply_phy_cell_group_cfg(const phys_cell_group_cfg_s& phys_cell_group_cfg) +{ + srsran_ue_dl_nr_harq_ack_cfg_t harq_ack; + if (make_phy_harq_ack_cfg(phys_cell_group_cfg, &harq_ack) == true) { + phy_cfg.harq_ack = harq_ack; + } else { + logger.warning("Warning while building harq_ack structure"); + return false; } return true; } @@ -584,17 +1076,25 @@ bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) { if (cell_group_cfg.rlc_bearer_to_add_mod_list_present) { for (uint32_t i = 0; i < cell_group_cfg.rlc_bearer_to_add_mod_list.size(); i++) { - apply_rlc_add_mod(cell_group_cfg.rlc_bearer_to_add_mod_list[i]); + if (apply_rlc_add_mod(cell_group_cfg.rlc_bearer_to_add_mod_list[i]) == false) { + return false; + } } } if (cell_group_cfg.mac_cell_group_cfg_present) { - apply_mac_cell_group(cell_group_cfg.mac_cell_group_cfg); + if (apply_mac_cell_group(cell_group_cfg.mac_cell_group_cfg) == false) { + return false; + } } if (cell_group_cfg.phys_cell_group_cfg_present) { - logger.warning("Not handling physical cell group config"); + if (apply_phy_cell_group_cfg(cell_group_cfg.phys_cell_group_cfg) == false) { + return false; + } } if (cell_group_cfg.sp_cell_cfg_present) { - apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg); + if (apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg) == false) { + return false; + } } return true; } @@ -644,6 +1144,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) if (security_cfg.key_to_use_present) { if (security_cfg.key_to_use.value != security_cfg_s::key_to_use_opts::options::secondary) { logger.warning("Only secondary key supported yet"); + return false; } } @@ -662,8 +1163,8 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) sec_cfg.cipher_algo = CIPHERING_ALGORITHM_ID_128_EEA3; break; default: - logger.warning("Unsupported algorithm"); - break; + logger.warning("Unsupported algorithm %s", security_cfg.security_algorithm_cfg.ciphering_algorithm.to_string()); + return false; } if (security_cfg.security_algorithm_cfg.integrity_prot_algorithm_present) { @@ -681,11 +1182,14 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) sec_cfg.integ_algo = INTEGRITY_ALGORITHM_ID_128_EIA3; break; default: - logger.warning("Unsupported algorithm"); - break; + logger.warning("Unsupported algorithm %s", + security_cfg.security_algorithm_cfg.integrity_prot_algorithm.to_string()); + return false; } } - usim->update_nr_context(&sec_cfg); + if (usim->update_nr_context(&sec_cfg) == false) { + return false; + } } // Apply security config for all known NR lcids @@ -700,11 +1204,15 @@ bool rrc_nr::apply_radio_bearer_cfg(const radio_bearer_cfg_s& radio_bearer_cfg) { if (radio_bearer_cfg.drb_to_add_mod_list_present) { for (uint32_t i = 0; i < radio_bearer_cfg.drb_to_add_mod_list.size(); i++) { - apply_drb_add_mod(radio_bearer_cfg.drb_to_add_mod_list[i]); + if (apply_drb_add_mod(radio_bearer_cfg.drb_to_add_mod_list[i]) == false) { + return false; + } } } if (radio_bearer_cfg.security_cfg_present) { - apply_security_cfg(radio_bearer_cfg.security_cfg); + if (apply_security_cfg(radio_bearer_cfg.security_cfg) == false) { + return false; + } } return true; } @@ -734,7 +1242,9 @@ proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool if (sk_counter_r15_present) { Info("Applying Cell Group Cfg"); - rrc_ptr->configure_sk_counter((uint16_t)sk_counter_r15); + if (!rrc_ptr->configure_sk_counter((uint16_t)sk_counter_r15)) { + return proc_outcome_t::error; + } } Info("Applying Radio Bearer Cfg"); diff --git a/srsue/src/stack/upper/usim_base.cc b/srsue/src/stack/upper/usim_base.cc index eef44aee6..9d9c7dd92 100644 --- a/srsue/src/stack/upper/usim_base.cc +++ b/srsue/src/stack/upper/usim_base.cc @@ -269,24 +269,27 @@ void usim_base::restore_keys_from_failed_ho(srsran::as_security_config_t* as_ctx * NR RRC Interface */ -void usim_base::generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) +bool usim_base::generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) { if (!initiated) { logger.error("USIM not initiated!"); - return; + return false; } logger.info("Generating Keys. SCG Counter %d", sk_counter); srsran::security_generate_sk_gnb(k_enb_ctx.k_enb.data(), k_gnb_ctx.sk_gnb.data(), sk_counter); logger.info(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb"); - update_nr_context(sec_cfg); + if (update_nr_context(sec_cfg) == false) { + return false; + } + return true; } -void usim_base::update_nr_context(srsran::as_security_config_t* sec_cfg) +bool usim_base::update_nr_context(srsran::as_security_config_t* sec_cfg) { if (!initiated) { logger.error("USIM not initiated!"); - return; + return false; } logger.info(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb"); // Generate K_rrc_enc and K_rrc_int @@ -307,6 +310,7 @@ void usim_base::update_nr_context(srsran::as_security_config_t* sec_cfg) logger.debug(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "NR K_RRC_enc"); logger.debug(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "NR K_UP_int"); logger.debug(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "NR K_UP_enc"); + return true; } } // namespace srsue