Add PDCCH UESS aggregation level configuration option

Added uess_agg_levels configuration option which changes the number of PDCCH
candidates per aggregation level.
This commit is contained in:
Bartosz Podrygajlo
2025-02-13 10:57:25 +01:00
parent 16f028dba5
commit 095b791929
12 changed files with 168 additions and 42 deletions
+79 -26
View File
@@ -72,6 +72,50 @@ static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp)
return clone;
}
/**
* @brief Verifies the aggregation level candidates
*
* This function checks the input aggregation level candidates and translates the value provided
* in the config to a valid field in RRC message.
*
* @param[in] num_cce_in_coreset number of CCE in coreset
* @param[in] in_num_agg_level_candidates input array of aggregation level candidates, interpreted as number of candidates.
* @param[in] coresetid coreset id
* @param[in] searchspaceid searchspace id
* @param[out] out_num_agg_level_candidates array of aggregation level candidates, output is a valid 3gpp field value.
*
*/
static void verify_agg_levels(int num_cce_in_coreset,
const int in_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS],
int coresetid,
int searchspaceid,
int out_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS])
{
int agg_level_to_n_cces[] = {1, 2, 4, 8, 16};
for (int i = 0; i < NUM_PDCCH_AGG_LEVELS; i++) {
// 7 is not a valid value, the mapping in 38.331 is from 0-7 mapped to 0-8 candidates and value 7 means 8 candidates instead. If
// the user wants 7 candidates round it up to 8.
int num_agg_level_candidates = in_num_agg_level_candidates[i];
if (num_agg_level_candidates == 7) {
num_agg_level_candidates = 8;
}
if (num_agg_level_candidates * agg_level_to_n_cces[i] > num_cce_in_coreset) {
int new_agg_level_candidates = num_cce_in_coreset / agg_level_to_n_cces[i];
LOG_E(NR_RRC,
"Invalid configuration: Not enough CCEs in coreset %d, searchspace %d, agg_level %d, number of requested "
"candidates = %d, number of CCES in coreset %d. Aggregation level candidates limited to %d\n",
coresetid,
searchspaceid,
agg_level_to_n_cces[i],
in_num_agg_level_candidates[i],
num_cce_in_coreset,
new_agg_level_candidates);
num_agg_level_candidates = new_agg_level_candidates;
}
out_num_agg_level_candidates[i] = min(num_agg_level_candidates, 7);
}
}
static NR_SetupRelease_RACH_ConfigCommon_t *clone_rach_configcommon(const NR_SetupRelease_RACH_ConfigCommon_t *rcc)
{
if (rcc == NULL || rcc->present == NR_SetupRelease_RACH_ConfigCommon_PR_NOTHING)
@@ -208,9 +252,11 @@ static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int b
return nb_pucch2;
}
NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int coresetid)
NR_SearchSpace_t *rrc_searchspace_config(bool is_common,
int searchspaceid,
int coresetid,
const int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS])
{
NR_SearchSpace_t *ss = calloc(1,sizeof(*ss));
ss->searchSpaceId = searchspaceid;
ss->controlResourceSetId = calloc(1,sizeof(*ss->controlResourceSetId));
@@ -226,23 +272,12 @@ NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int
ss->monitoringSymbolsWithinSlot->buf[1] = 0x0;
ss->monitoringSymbolsWithinSlot->bits_unused = 2;
ss->nrofCandidates = calloc(1,sizeof(*ss->nrofCandidates));
// TODO temporary hardcoded implementation
ss->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
if (get_softmodem_params()->usim_test) {
ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1;
} else {
if (is_common) {
ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
} else {
ss->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n2;
ss->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0;
}
ss->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
}
ss->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
ss->nrofCandidates->aggregationLevel1 = num_agg_level_candidates[PDCCH_AGG_LEVEL1];
ss->nrofCandidates->aggregationLevel2 = num_agg_level_candidates[PDCCH_AGG_LEVEL2];
ss->nrofCandidates->aggregationLevel4 = num_agg_level_candidates[PDCCH_AGG_LEVEL4];
ss->nrofCandidates->aggregationLevel8 = num_agg_level_candidates[PDCCH_AGG_LEVEL8];
ss->nrofCandidates->aggregationLevel16 = num_agg_level_candidates[PDCCH_AGG_LEVEL16];
ss->searchSpaceType = calloc(1,sizeof(*ss->searchSpaceType));
if (is_common) {
ss->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
@@ -1545,7 +1580,8 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp,
int dl_antenna_ports,
bool force_256qam_off,
int bwp_loop,
bool is_SA)
bool is_SA,
const int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS])
{
bwp->bwp_Common = calloc(1,sizeof(*bwp->bwp_Common));
@@ -1577,8 +1613,12 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp,
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList));
NR_SearchSpace_t *ss = rrc_searchspace_config(true, 5+bwp->bwp_Id, coreset->controlResourceSetId);
asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss);
int searchspaceid = 5 + bwp->bwp_Id;
int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration);
verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates);
asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss);
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation=NULL;
@@ -1613,7 +1653,11 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp,
NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, curr_bwp, ssb_bitmap);
asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset2);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, 10+bwp->bwp_Id, coreset2->controlResourceSetId);
searchspaceid = 10 + bwp->bwp_Id;
num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration);
verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss2 =
rrc_searchspace_config(false, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates);
asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2);
bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToReleaseList = NULL;
@@ -3069,7 +3113,15 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
asn1cSeqAdd(&bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, 5, coreset->controlResourceSetId);
int searchspaceid = 5;
int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration);
verify_agg_levels(num_cces,
configuration->num_agg_level_candidates,
coreset->controlResourceSetId,
searchspaceid,
rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates);
asn1cSeqAdd(&bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2);
bwp_Dedicated->pdsch_Config = config_pdsch(bitmap, 0, pdsch_AntennaPorts);
@@ -3113,7 +3165,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
calloc(1, sizeof(*SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList));
for (int bwp_loop = 0; bwp_loop < n_dl_bwp; bwp_loop++) {
NR_BWP_Downlink_t *bwp = calloc(1, sizeof(*bwp));
config_downlinkBWP(bwp, scc, servingcellconfigdedicated, NULL, 0, false, bwp_loop, true);
config_downlinkBWP(bwp, scc, servingcellconfigdedicated, NULL, 0, false, bwp_loop, true, configuration->num_agg_level_candidates);
asn1cSeqAdd(&SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list, bwp);
}
const NR_BWP_Id_t *firstActiveDownlinkBWP_Id = servingcellconfigdedicated->firstActiveDownlinkBWP_Id;
@@ -3575,7 +3627,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
dl_antenna_ports,
configuration->force_256qam_off,
bwp_loop,
false);
false,
configuration->num_agg_level_candidates);
asn1cSeqAdd(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list, bwp);
}
secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id =
+4 -1
View File
@@ -55,7 +55,10 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
int curr_bwp);
void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay);
NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int coresetid);
NR_SearchSpace_t *rrc_searchspace_config(bool is_common,
int searchspaceid,
int coresetid,
const int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]);
void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
NR_ServingCellConfigCommon_t *scc,