From 0ccf1879ae28dcb792132bc12064962c4905b0b8 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 29 May 2025 12:21:17 +0100 Subject: [PATCH 01/12] Improve SearchSpace selection There is a removal of the NR_SearchSpace__searchSpaceType_PR because, at this point, the gNB already selected the searchspace and it calls this function only to find the coreset with controlResourceSetId based on the previously searchspace id selected; There is no need to send a pointer to the entire searchspace structure because we only need the controlResourceSetId: NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId; It also prevents a segmentation fault, in develop when NR_SearchSpace__searchSpaceType_PR_common because gNB calls sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, sched_ctrl->search_space, target_ss); the bwpd is NR_BWP_DownlinkDedicated_t *bwpd = NULL; and is it incompatible with the cast to NR_BWP_Downlink_t in coreset = ((NR_BWP_Downlink_t*)bwp)->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; this was never noticed until now because gNB barely used NR_SearchSpace__searchSpaceType_PR_common --- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e732148b08..ed49f3451d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -405,28 +405,31 @@ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, } static NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, - NR_BWP_DownlinkDedicated_t *bwp_Dedicated, + NR_BWP_DownlinkDedicated_t *bwp_dedicated, NR_SearchSpace__searchSpaceType_PR target_ss) { - int n = 0; - if(bwp_Dedicated) - n = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count; - else - n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count; + if (bwp_dedicated) { + const int n = bwp_dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count; + for (int i = 0; i < n; i++) { + NR_SearchSpace_t *ss = bwp_dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + if (ss->searchSpaceType->present == target_ss) { + AssertFatal(ss->controlResourceSetId, "searchSpaceId %ld has a NULL controlResourceSetId\n", ss->searchSpaceId); + return ss; + } + } + AssertFatal(false, "Couldn't find an adequate SearchSpace for target SearchSpace %d in BWP_DownlinkDedicated\n", target_ss); + } - for (int i=0;ipdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - else - ss = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); + const int n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count; + for (int i = 0; i < n; i++) { + NR_SearchSpace_t *ss = + scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i]; if (ss->searchSpaceType->present == target_ss) { + AssertFatal(ss->controlResourceSetId, "searchSpaceId %ld has a NULL controlResourceSetId\n", ss->searchSpaceId); return ss; } } - AssertFatal(0, "Couldn't find an adequate searchspace bwp_Dedicated %p\n",bwp_Dedicated); + AssertFatal(false, "Couldn't find an adequate SearchSpace for target SearchSpace %d in ServingCellConfigCommon\n", target_ss); } NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, From 641cf84c0c4a59816d9495870fe225b21aaf1fcb Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 29 May 2025 12:22:55 +0100 Subject: [PATCH 02/12] Improve CORESET selection --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 3 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 52 ++++++++----------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 5 +- 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 76e9db4fb3..a6d48037a7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -686,7 +686,8 @@ static void other_sib_sched_control(module_id_t module_idP, } AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n"); - NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common); + AssertFatal(ss->controlResourceSetId, "ss->controlResourceSetId is NULL\n"); + NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, *ss->controlResourceSetId); if (!gNB_mac->sched_pdcch_otherSI) { gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI)); *gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index ed49f3451d..f8c842706c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -369,39 +369,31 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc, NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, - void *bwp, - NR_SearchSpace_t *ss, - NR_SearchSpace__searchSpaceType_PR ss_type) { - - NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId; - - if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space - NR_ControlResourceSet_t *coreset; - if(coreset_id == 0) { - coreset = nrmac->sched_ctrlCommon->coreset; // this is coreset 0 - } else if (bwp) { - coreset = ((NR_BWP_Downlink_t*)bwp)->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; - } else if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) { - coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; - } else { - coreset = NULL; - } - - if (coreset) AssertFatal(coreset_id == coreset->controlResourceSetId, - "ID of common ss coreset does not correspond to id set in the " - "search space\n"); - return coreset; - } else { - const int n = ((NR_BWP_DownlinkDedicated_t*)bwp)->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count; + NR_BWP_DownlinkDedicated_t *bwp_dedicated, + NR_ControlResourceSetId_t coreset_id) +{ + if (coreset_id == 0) { + return nrmac->sched_ctrlCommon->coreset; // this is coreset 0 + } + if (bwp_dedicated) { + const int n = bwp_dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count; for (int i = 0; i < n; i++) { - NR_ControlResourceSet_t *coreset = - ((NR_BWP_DownlinkDedicated_t*)bwp)->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i]; - if (coreset_id == coreset->controlResourceSetId) { + NR_ControlResourceSet_t *coreset = bwp_dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i]; + if (coreset->controlResourceSetId == coreset_id) { return coreset; } } - AssertFatal(0, "Couldn't find coreset with id %ld\n", coreset_id); + AssertFatal(false, "Couldn't find CORESET with id %ld in BWP_DownlinkDedicated\n", coreset_id); } + if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) { + NR_ControlResourceSet_t *coreset = + scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; + if (coreset->controlResourceSetId == coreset_id) { + return coreset; + } + AssertFatal(false, "Couldn't find CORESET with id %ld in commonControlResourceSet\n", coreset_id); + } + AssertFatal(false, "Couldn't find coreset with id %ld\n", coreset_id); } static NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, @@ -2594,7 +2586,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, // setting PDCCH related structures for sched_ctrl sched_ctrl->search_space = get_searchspace(scc, bwpd, target_ss); - sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, sched_ctrl->search_space, target_ss); + sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, *sched_ctrl->search_space->controlResourceSetId); sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, sched_ctrl->search_space, @@ -2635,7 +2627,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, } AssertFatal(sched_ctrl->search_space != NULL, "SearchSpace cannot be null for RA\n"); - sched_ctrl->coreset = get_coreset(nr_mac, scc, dl_bwp, sched_ctrl->search_space, NR_SearchSpace__searchSpaceType_PR_common); + sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, *sched_ctrl->search_space->controlResourceSetId); NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; int ssb_index = cc->ssb_index[UE->UE_beam_index]; sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index ea07fbeea4..66a9262f22 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -283,9 +283,8 @@ void set_r_pucch_parms(int rsetindex, /* find coreset within the search space */ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, - void *bwp, - NR_SearchSpace_t *ss, - NR_SearchSpace__searchSpaceType_PR ss_type); + NR_BWP_DownlinkDedicated_t *bwp_dedicated, + NR_ControlResourceSetId_t coreset_id); long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, From 8c58abf85acee6148901c57b5895c28f76ace8b9 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 29 May 2025 12:30:42 +0100 Subject: [PATCH 03/12] Fix fill 'initialDownlinkBWP->pdsch_Config' when there are DedicatedBWPs This fixes the reported 'RSRP = 0' issue when the UE is in the InitialBWP and we have DedicatedBWPs configured --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index c7fc724747..30ba85c76a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -3276,16 +3276,16 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, } asn1cSeqAdd(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list, ssbresset0); - int bwp_loop_end = n_dl_bwp > 0 ? n_dl_bwp : 1; + int bwp_loop_end = n_dl_bwp + 1; for (int bwp_loop = 0; bwp_loop < bwp_loop_end; bwp_loop++) { int curr_bwp, bwp_id; struct NR_SetupRelease_PDSCH_Config *pdsch_Config; - if (n_dl_bwp == 0) { + if (bwp_loop == 0) { pdsch_Config = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config; curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); bwp_id = 0; } else { - NR_BWP_Downlink_t *bwp = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_loop]; + NR_BWP_Downlink_t *bwp = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_loop - 1]; pdsch_Config = bwp->bwp_Dedicated->pdsch_Config; curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); bwp_id = bwp->bwp_Id; From 7a5d1e55f0286666da8b341f122fce7d5c3770a5 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 29 May 2025 12:46:00 +0100 Subject: [PATCH 04/12] Add a 'common' type SearchSpace in the NR_BWP_DownlinkDedicated IE for DedicatedBWPs to get DCIs decoded in common searchspace of a DedicatedBWP After RRCSetup, until RRCReconfigurationComplete, gNB continues to schedule ULSCH using DCIs in a common searchspace. In theory, the UE should decode DCIs in: ... However, due to the limited amount of time to investigate this issue, the easy way I found to get DCIs decoded in common searchspace of a DedicatedBWP was by adding a common searchspace in the bwp-Dedicated: ... This way, let's call it a workaround. --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 30ba85c76a..5052ca6e7a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1631,13 +1631,18 @@ 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); - 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); + verify_agg_levels(num_cces, num_agg_level_candidates, coreset2->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates); + + searchspaceid = 10 + bwp->bwp_Id; + NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); + searchspaceid = 20 + bwp->bwp_Id; + NR_SearchSpace_t *ss3 = + rrc_searchspace_config(false, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); + asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss3); + bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToReleaseList = NULL; bwp->bwp_Dedicated->pdsch_Config = config_pdsch(ssb_bitmap, bwp->bwp_Id, dl_antenna_ports); From 72d9761698097dc5e33b2497a8835332f0138943 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 29 May 2025 12:37:24 +0100 Subject: [PATCH 05/12] Remove 'searchspaceid' from 'verify_agg_levels' function because it was used only for LOG --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 5052ca6e7a..02f02089c4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -80,7 +80,6 @@ static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp) 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}; @@ -94,10 +93,9 @@ static void verify_agg_levels(int num_cce_in_coreset, 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 " + "Invalid configuration: Not enough CCEs in coreset %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, @@ -1594,7 +1592,7 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, 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); + verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, 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); @@ -1632,7 +1630,7 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset2); num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration); - verify_agg_levels(num_cces, num_agg_level_candidates, coreset2->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates); + verify_agg_levels(num_cces, num_agg_level_candidates, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); searchspaceid = 10 + bwp->bwp_Id; NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); @@ -3178,7 +3176,6 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, 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, ss); From 0aa19da5680c09664749ce2f75c83427de494b8d Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Thu, 29 May 2025 12:11:14 +0100 Subject: [PATCH 06/12] CI: Add DedicatedBWP to '40 MHz TDD F1+E1 SA' in 'RAN-SA-B200-Module-SABOX-Container' --- .../gnb-du.sa.band78.106prb.usrpb200.conf | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 45482642b9..66e721ef84 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -34,11 +34,9 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL - # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) - absoluteFrequencySSB = 641280; + absoluteFrequencySSB = 641280; # GSCN: 7929, Freq: 3619.200 MHz dl_frequencyBand = 78; - # this is 3600 MHz - dl_absoluteFrequencyPointA = 640008; + dl_absoluteFrequencyPointA = 640752; # 3611.280 MHz #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing @@ -47,13 +45,12 @@ gNBs = dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=27,L=48 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 + initialDLBWPlocationAndBandwidth = 13750; # RBstart=0, L=51 (275*(L-1))+RBstart # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPcontrolResourceSetZero = 10; initialDLBWPsearchSpaceZero = 0; #uplinkConfigCommon @@ -68,7 +65,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 28875; + initialULBWPlocationAndBandwidth = 13750; # RBstart=0, L=51 (275*(L-1))+RBstart # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -152,6 +149,18 @@ gNBs = ); + servingCellConfigDedicated = ({ + dl_bwp-Id_1 = 1; + dl_bwp1_locationAndBandwidth = 28875; # RBstart=0, L=106 (275*(L-1))+RBstart + dl_bwp1_subcarrierSpacing = 1; + firstActiveDownlinkBWP-Id = 1; + defaultDownlinkBWP-Id = 1; + ul_bwp-Id_1 = 1; + ul_bwp1_locationAndBandwidth = 28875; # RBstart=0, L=106 (275*(L-1))+RBstart + ul_bwp1_subcarrierSpacing = 1; + firstActiveUplinkBWP-Id = 1; + }); + # ------- SCTP definitions SCTP : From d9145418388c738679ff59cabf8f639a31ce7994 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 27 Jun 2025 17:53:57 +0200 Subject: [PATCH 07/12] use CSET0 for common search space in dedicated BWP --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index 02f02089c4..eba1152cd0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1590,17 +1590,27 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList)); 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, rrc_num_agg_level_candidates); - NR_SearchSpace_t *ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates); + int agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; + NR_SearchSpace_t *ss = NULL; + if (!is_SA) { + int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration); + verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, agg_level_candidates); + ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, agg_level_candidates); + } else { + agg_level_candidates[PDCCH_AGG_LEVEL1] = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; + agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + ss = rrc_searchspace_config(true, searchspaceid, 0, 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; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->pagingSearchSpace=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=NULL; - if(is_SA == false) { + if(!is_SA) { bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)); *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=ss->searchSpaceId; } @@ -1628,12 +1638,12 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp, // frees 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); - - num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration); + int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; + int num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration); verify_agg_levels(num_cces, num_agg_level_candidates, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); searchspaceid = 10 + bwp->bwp_Id; - NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); + NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, is_SA ? 0 : coreset2->controlResourceSetId, agg_level_candidates); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); searchspaceid = 20 + bwp->bwp_Id; From ea8e5d85be7b462657fadb13c7d84fa84ccf6382 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Jul 2025 07:31:28 +0200 Subject: [PATCH 08/12] Add telnet command to get UE's BWP --- common/utils/telnetsrv/telnetsrv_ci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index fff1423c16..d58071baf2 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -215,6 +215,19 @@ int force_ue_release(char *buf, int debug, telnet_printfunc_t prnt) return 0; } +static int get_current_bwp(char *buf, int debug, telnet_printfunc_t prnt) +{ + int rnti = fetch_rnti(buf, prnt); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + int dl_bwp = UE->current_DL_BWP.bwp_id; + const char *dl_bwp_text = dl_bwp > 0 ? "dedicated" : "initial"; + int ul_bwp = UE->current_UL_BWP.bwp_id; + const char *ul_bwp_text = ul_bwp > 0 ? "dedicated" : "initial"; + + prnt("UE %04x DL BWP ID %d (%s) UL BWP ID %d (%s)\n", UE->rnti, dl_bwp, dl_bwp_text, ul_bwp, ul_bwp_text); + return 0; +} + static telnetshell_cmddef_t cicmds[] = { {"get_single_rnti", "", get_single_rnti}, {"force_reestab", "[rnti(hex,opt)]", trigger_reestab}, @@ -223,6 +236,7 @@ static telnetshell_cmddef_t cicmds[] = { {"force_ul_failure", "[rnti(hex,opt)]", force_ul_failure}, {"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho}, {"fetch_du_by_ue_id", "[rrc_ue_id(int,opt)]", fetch_du_by_ue_id}, + {"get_current_bwp", "[rnti(hex,opt)]", get_current_bwp}, {"", "", NULL}, }; From aa4c2df59391bdce8fa1213aae4d651519e8a281 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Jul 2025 07:36:41 +0200 Subject: [PATCH 09/12] Remove non-existing XML steps --- ci-scripts/xml_files/container_sa_e1_b200_quectel.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml index b9535e6ea4..84234e5372 100644 --- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml @@ -30,9 +30,7 @@ 310000 800813 330101 - 800814 330102 - 800815 330103 310001 350000 From 128a6f3945f992a3d827e0f2103c6b5190a7f051 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 9 Jul 2025 07:38:00 +0200 Subject: [PATCH 10/12] Add XML step to check UE is on dedicated BWP --- ci-scripts/xml_files/container_sa_e1_b200_quectel.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml index 84234e5372..4fbffbd9e8 100644 --- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml @@ -33,6 +33,7 @@ 330102 330103 310001 + 400001 350000 370001 370000 @@ -145,6 +146,13 @@ 95 + + Custom_Command + Check UE is on dedicated BWP ID 1 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 1 (dedicated) UL BWP ID 1 (dedicated)' + + Iperf iperf (UL/8Mbps/UDP)(30 sec) From 93196e630bae4f10bb876cfd1f9dd210fe5c83f7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 30 Jul 2025 16:58:43 +0200 Subject: [PATCH 11/12] Bugfix: when no UE found, return -1 --- common/utils/telnetsrv/telnetsrv_ci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index d58071baf2..4b84a8ca93 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -42,7 +42,7 @@ #define TELNETSERVERCODE #include "telnetsrv.h" -#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0) +#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return -1; } while (0) static int get_single_ue_rnti_mac(void) { From b77be2ae28d7acc86d27e208320d3a82a45d75df Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 30 Jul 2025 17:20:57 +0200 Subject: [PATCH 12/12] Telnet CI: Handle error of no RNTI --- common/utils/telnetsrv/telnetsrv_ci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 4b84a8ca93..24dba02191 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -136,6 +136,8 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) if (!RC.nrmac) ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n"); int rnti = fetch_rnti(buf, prnt); + if (rnti < 0) + ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); nr_rlc_test_trigger_reestablishment(rnti); prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti); return 0; @@ -199,6 +201,8 @@ int force_ul_failure(char *buf, int debug, telnet_printfunc_t prnt) if (!RC.nrmac) ERROR_MSG_RET("no MAC/RLC present, force_ul_failure failed\n"); int rnti = fetch_rnti(buf, prnt); + if (rnti < 0) + ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); return 0; @@ -208,6 +212,8 @@ int force_ue_release(char *buf, int debug, telnet_printfunc_t prnt) { force_ul_failure(buf, debug, prnt); int rnti = fetch_rnti(buf, prnt); + if (rnti < 0) + ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; sched_ctrl->ul_failure_timer = 2; @@ -218,6 +224,8 @@ int force_ue_release(char *buf, int debug, telnet_printfunc_t prnt) static int get_current_bwp(char *buf, int debug, telnet_printfunc_t prnt) { int rnti = fetch_rnti(buf, prnt); + if (rnti < 0) + ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); int dl_bwp = UE->current_DL_BWP.bwp_id; const char *dl_bwp_text = dl_bwp > 0 ? "dedicated" : "initial";