diff --git a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc index 52b448935..bf7ce232b 100644 --- a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc +++ b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc @@ -91,7 +91,7 @@ alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx, // RAR allocation successful. bwp_pdcch_slot.dl_prbs |= prbs; // Generate DCI for SIB - pdcch_dl_t& pdcch = bwp_pdcch_slot.dl.phy.pdcch_dl.back(); + pdcch_dl_t& pdcch = bwp_pdcch_slot.dl.phy.pdcch_dl.back(); pdcch.dci_cfg.coreset0_bw = srsran_coreset_get_bw(&cfg.cfg.pdcch.coreset[0]); if (not fill_dci_sib(prbs, si_idx, si_ntx, *bwp_grid.cfg, pdcch.dci)) { // Cancel on-going PDCCH allocation @@ -367,6 +367,11 @@ alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_pr max_nof_candidates = nof_candidates; } } + if (max_nof_candidates == 0) { + // Could not find space in PDCCH + logger.warning("SCHED: No PDCCH candidates for any of the rnti=0x%x search spaces", ue->rnti); + return alloc_result::no_cch_space; + } uint32_t coreset_id = ue->phy().pdcch.search_space[ss_id].coreset_id; if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci( pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue.cfg())) { diff --git a/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc b/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc index e6813cb3d..2a7212e3e 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc @@ -20,10 +20,10 @@ } \ } while (0) -#define INVALID_PARAM(x, fmt, ...) \ +#define RETURN_IF_NOT(x, fmt, ...) \ do { \ if (not(x)) { \ - fprintf(stderr, "ERROR: " fmt, ##__VA_ARGS__); \ + fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__); \ return SRSRAN_ERROR; \ } \ } while (0) @@ -85,7 +85,7 @@ int derive_coreset0_params(rrc_cell_cfg_nr_t& cell) cell.phy_cell.carrier.scs, cell.coreset0_idx, &cell.phy_cell.pdcch.coreset[0]); - INVALID_PARAM(ret == SRSRAN_SUCCESS, "Failed to generate CORESET#0"); + RETURN_IF_NOT(ret == SRSRAN_SUCCESS, "Failed to generate CORESET#0"); return SRSRAN_SUCCESS; } @@ -98,11 +98,11 @@ int derive_ssb_params(bool is_sa, srsran_ssb_cfg_t& ssb) { // Verify essential parameters are specified and valid - INVALID_PARAM(dl_arfcn > 0, "Invalid DL ARFCN=%d", dl_arfcn); - INVALID_PARAM(band > 0, "Band is a mandatory parameter"); - INVALID_PARAM(pdcch_scs < srsran_subcarrier_spacing_invalid, "Invalid carrier SCS"); - INVALID_PARAM(coreset0_idx < 15, "Invalid controlResourceSetZero"); - INVALID_PARAM(nof_prb > 0, "Invalid DL number of PRBS=%d", nof_prb); + RETURN_IF_NOT(dl_arfcn > 0, "Invalid DL ARFCN=%d", dl_arfcn); + RETURN_IF_NOT(band > 0, "Band is a mandatory parameter"); + RETURN_IF_NOT(pdcch_scs < srsran_subcarrier_spacing_invalid, "Invalid carrier SCS"); + RETURN_IF_NOT(coreset0_idx < 15, "Invalid controlResourceSetZero"); + RETURN_IF_NOT(nof_prb > 0, "Invalid DL number of PRBS=%d", nof_prb); srsran::srsran_band_helper band_helper; @@ -133,13 +133,13 @@ int derive_ssb_params(bool is_sa, if (is_sa) { // Get offset in RBs between CORESET#0 and SSB coreset0_rb_offset = srsran_coreset0_ssb_offset(coreset0_idx, ssb.scs, pdcch_scs); - INVALID_PARAM(coreset0_rb_offset >= 0, "Failed to compute RB offset between CORESET#0 and SSB"); + RETURN_IF_NOT(coreset0_rb_offset >= 0, "Failed to compute RB offset between CORESET#0 and SSB"); } else { // TODO: Verify if specified SSB frequency is valid } uint32_t ssb_abs_freq_point = band_helper.get_abs_freq_ssb_arfcn(band, ssb.scs, dl_absolute_freq_point_a, coreset0_rb_offset); - INVALID_PARAM(ssb_abs_freq_point > 0, + RETURN_IF_NOT(ssb_abs_freq_point > 0, "Can't derive SSB freq point for dl_arfcn=%d and band %d", band_helper.freq_to_nr_arfcn(dl_freq_hz), band); @@ -162,7 +162,7 @@ int derive_ssb_params(bool is_sa, int derive_phy_cell_freq_params(uint32_t dl_arfcn, uint32_t ul_arfcn, phy_cell_cfg_nr_t& phy_cell) { // Verify essential parameters are specified and valid - INVALID_PARAM(dl_arfcn > 0, "DL ARFCN is a mandatory parameter"); + RETURN_IF_NOT(dl_arfcn > 0, "DL ARFCN is a mandatory parameter"); // Use helper class to derive NR carrier parameters srsran::srsran_band_helper band_helper; @@ -178,7 +178,7 @@ int derive_phy_cell_freq_params(uint32_t dl_arfcn, uint32_t ul_arfcn, phy_cell_c if (ul_arfcn == 0) { // derive UL ARFCN from given DL ARFCN ul_arfcn = band_helper.get_ul_arfcn_from_dl_arfcn(dl_arfcn); - INVALID_PARAM(ul_arfcn > 0, "Can't derive UL ARFCN from DL ARFCN %d", dl_arfcn); + RETURN_IF_NOT(ul_arfcn > 0, "Can't derive UL ARFCN from DL ARFCN %d", dl_arfcn); } phy_cell.ul_freq_hz = band_helper.nr_arfcn_to_freq(ul_arfcn); } @@ -193,9 +193,9 @@ int derive_phy_cell_freq_params(uint32_t dl_arfcn, uint32_t ul_arfcn, phy_cell_c int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell) { // Verify essential parameters are specified and valid - INVALID_PARAM(cell.dl_arfcn > 0, "DL ARFCN is a mandatory parameter"); - INVALID_PARAM(cell.band > 0, "Band is a mandatory parameter"); - INVALID_PARAM(cell.phy_cell.carrier.nof_prb > 0, "Number of PRBs is a mandatory parameter"); + RETURN_IF_NOT(cell.dl_arfcn > 0, "DL ARFCN is a mandatory parameter"); + RETURN_IF_NOT(cell.band > 0, "Band is a mandatory parameter"); + RETURN_IF_NOT(cell.phy_cell.carrier.nof_prb > 0, "Number of PRBs is a mandatory parameter"); // Use helper class to derive NR carrier parameters srsran::srsran_band_helper band_helper; @@ -203,7 +203,7 @@ int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell) if (cell.ul_arfcn == 0) { // derive UL ARFCN from given DL ARFCN cell.ul_arfcn = band_helper.get_ul_arfcn_from_dl_arfcn(cell.dl_arfcn); - INVALID_PARAM(cell.ul_arfcn > 0, "Can't derive UL ARFCN from DL ARFCN %d", cell.dl_arfcn); + RETURN_IF_NOT(cell.ul_arfcn > 0, "Can't derive UL ARFCN from DL ARFCN %d", cell.dl_arfcn); } // duplex mode @@ -298,7 +298,7 @@ int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell) int check_nr_cell_cfg_valid(const rrc_cell_cfg_nr_t& cell, bool is_sa) { // verify SSB params are consistent - INVALID_PARAM(cell.ssb_cfg.center_freq_hz == cell.phy_cell.dl_freq_hz, "Invalid SSB param generation"); + RETURN_IF_NOT(cell.ssb_cfg.center_freq_hz == cell.phy_cell.dl_freq_hz, "Invalid SSB param generation"); RETURN_IF_ERROR(check_nr_phy_cell_cfg_valid(cell.phy_cell)); return SRSRAN_SUCCESS; @@ -313,14 +313,22 @@ int check_nr_phy_cell_cfg_valid(const phy_cell_cfg_nr_t& phy_cell) int check_nr_pdcch_cfg_valid(const srsran_pdcch_cfg_nr_t& pdcch) { // Verify Search Spaces + std::array used_coresets{}; for (uint32_t ss_id = 0; ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++ss_id) { if (pdcch.search_space_present[ss_id]) { const srsran_search_space_t& ss = pdcch.search_space[ss_id]; - INVALID_PARAM(ss.id == ss_id, "SearchSpace#%d should match list index", ss_id); + RETURN_IF_NOT(ss.id == ss_id, "SearchSpace#%d should match list index", ss_id); uint32_t cs_id = ss.coreset_id; - INVALID_PARAM(pdcch.coreset_present[cs_id], "SearchSpace#%d points to absent CORESET#%d", ss_id, cs_id); + RETURN_IF_NOT(pdcch.coreset_present[cs_id], "SearchSpace#%d points to absent CORESET#%d", ss_id, cs_id); + used_coresets[cs_id] = true; } } + + // Verify CORESET id + for (uint32_t cs_id = 0; cs_id < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; ++cs_id) { + RETURN_IF_NOT(pdcch.coreset_present[cs_id] == used_coresets[cs_id], "CORESET#%d is configured but not used", cs_id); + } + return SRSRAN_SUCCESS; }