Merge remote-tracking branch 'origin/bwp_switch_fix' into integration_2025_w49 (!3660)

Fixes for BWP switching

This MR fixes some issues when performing BWP switching via
reconfiguration. It also adds a CI test for BWP switching.  # Please
enter a commit message to explain why this merge is necessary,
This commit is contained in:
Robert Schmidt
2025-12-03 17:31:22 +01:00
23 changed files with 399 additions and 370 deletions
+9 -8
View File
@@ -1368,7 +1368,7 @@ void nfapi_stop_l1()
}
}
static void get_bwp_config(nr_mac_config_t *configuration)
static void get_bwp_config(nr_mac_config_t *configuration, const NR_ServingCellConfigCommon_t *scc)
{
char path[MAX_OPTNAME_SIZE * 2 + 8];
snprintf(path, sizeof(path), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
@@ -1377,10 +1377,13 @@ static void get_bwp_config(nr_mac_config_t *configuration)
AssertFatal(configuration->num_additional_bwps >= 0 && configuration->num_additional_bwps <= 4,
"Invalid number of additional BWPs %d\n",
configuration->num_additional_bwps);
int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
for (int i = 0; i < configuration->num_additional_bwps; i++) {
configuration->bwp_config[i].id = i + 1;
int bwp_start = *BWPParamList.paramarray[i][GNB_BWP_START_IDX].iptr;
AssertFatal(bwp_start >= 0 && bwp_start < bw, "Invalid BWP start value %d\n", bwp_start);
int bwp_size = *BWPParamList.paramarray[i][GNB_BWP_SIZE_IDX].iptr;
AssertFatal(bwp_start + bwp_size <= bw, "BWP start %d and BWP size %d exceeds full BW %d\n", bwp_start, bwp_size, bw);
configuration->bwp_config[i].location_and_bw = PRBalloc_to_locationandbandwidth(bwp_size, bwp_start);
configuration->bwp_config[i].scs = *BWPParamList.paramarray[i][GNB_BWP_SCS_IDX].iptr;
LOG_I(GNB_APP,
@@ -1418,12 +1421,6 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
config.pdsch_AntennaPorts.XP,
config.pusch_AntennaPorts);
// BWP
get_bwp_config(&config);
AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n");
config.first_active_bwp = *GNBParamList.paramarray[0][GNB_1ST_ACTIVE_BWP_IDX].iptr;
AssertFatal(config.first_active_bwp <= config.num_additional_bwps, "1st active BWP does not belog to the configured BWPs\n");
// RU
GET_PARAMS_LIST(RUParamList, RUParams, RUPARAMS_DESC, CONFIG_STRING_RU_LIST, NULL);
int num_tx = 0;
@@ -1524,7 +1521,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]);
NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME, config.do_SRS);
//xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc);
// BWP
get_bwp_config(&config, scc);
AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n");
config.first_active_bwp = *GNBParamList.paramarray[0][GNB_1ST_ACTIVE_BWP_IDX].iptr;
AssertFatal(config.first_active_bwp <= config.num_additional_bwps, "1st active BWP does not belog to the configured BWPs\n");
if (MacRLC_ParamList.numelt > 0) {
/* NR RLC config is needed by mac_top_init_gNB() */
@@ -2781,7 +2781,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
nr_dci_format_t format,
nr_rnti_type_t rnti_type,
NR_ControlResourceSet_t *coreset,
int bwp_id,
int ss_type,
uint16_t cset0_bwp_size,
uint16_t alt_size)
@@ -159,7 +159,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
nr_dci_format_t format,
nr_rnti_type_t rnti_type,
NR_ControlResourceSet_t *coreset,
int bwp_id,
int ss_type,
uint16_t cset0_bwp_size,
uint16_t alt_size);
@@ -198,7 +198,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac,
NR_UL_DCI_FORMAT_0_0,
rnti_type,
coreset,
dl_bwp_id,
ss->searchSpaceType->present,
mac->type0_PDCCH_CSS_config.num_rbs,
0);
@@ -211,7 +210,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac,
NR_DL_DCI_FORMAT_1_0,
rnti_type,
coreset,
dl_bwp_id,
ss->searchSpaceType->present,
mac->type0_PDCCH_CSS_config.num_rbs,
0);
@@ -225,7 +223,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac,
dci_format[i],
rnti_type,
coreset,
dl_bwp_id,
ss->searchSpaceType->present,
mac->type0_PDCCH_CSS_config.num_rbs,
alt_size);
+1 -2
View File
@@ -586,11 +586,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0;
pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
if (dci_format == NR_UL_DCI_FORMAT_0_0 && ss_type == NR_SearchSpace__searchSpaceType_PR_common) {
pusch_config_pdu->bwp_start = sc_info->initial_ul_BWPStart;
pusch_config_pdu->bwp_size = sc_info->initial_ul_BWPSize;
} else {
pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize;
}
+21 -2
View File
@@ -1065,6 +1065,24 @@ bool nr_update_sib19(const gnb_sat_position_update_t *sat_position)
return true;
}
bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id)
{
gNB_MAC_INST *nrmac = RC.nrmac[0];
NR_SCHED_LOCK(&nrmac->sched_lock);
NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, rnti);
bool success = false;
if (!UE) {
LOG_W(NR_MAC, "could not find UE for RNTI %04x\n", rnti);
} else if (UE->current_DL_BWP.bwp_id == bwp_id) {
LOG_W(NR_MAC, "UE %04x is already on BWP ID %d, not triggering reconfiguration\n", rnti, bwp_id);
} else { // UE != NULL && current_DL_BWP.bwp_id != bwp_id
nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id);
success = true;
}
NR_SCHED_UNLOCK(&nrmac->sched_lock);
return success;
}
void prepare_du_configuration_update(gNB_MAC_INST *mac,
f1ap_served_cell_info_t *info,
NR_BCCH_BCH_Message_t *mib,
@@ -1116,8 +1134,9 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t
NR_SCHED_LOCK(&nrmac->sched_lock);
NR_UE_info_t *UE = get_new_nr_ue_inst(&nrmac->UE_info.uid_allocator, rnti, CellGroup);
DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // test-mode: we assume we can always create a UE
free_and_zero(UE->ra); // test-mode (sims, phy-test): UE will not do RA
DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // physical simulators: we assume we can always create a UE
free_and_zero(UE->ra); // physical simulators: UE will not do RA
UE->local_bwp_id = 1; // for physical simulators
bool res = add_connected_nr_ue(nrmac, UE);
if (!res) {
LOG_E(NR_MAC, "Error adding UE %04x\n", rnti);
@@ -958,7 +958,6 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
&uldci_payload,
NR_UL_DCI_FORMAT_0_0,
TYPE_TC_RNTI_,
ul_bwp->bwp_id,
ss,
coreset,
0, // parameter not needed for DCI 0_0
@@ -1385,7 +1384,6 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
&dci_payload,
NR_DL_DCI_FORMAT_1_0,
rnti_type,
dl_bwp->bwp_id,
sched_ctrl->search_space,
coreset,
0, // parameter not needed for DCI 1_0
@@ -473,7 +473,6 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac,
&dci_payload,
dci_format,
rnti_type,
0,
search_space,
coreset,
0,
@@ -398,7 +398,8 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
// except for the case when DCI format 1_0 is decoded in any common search space in which case the size of CORESET 0 shall be
// used if CORESET 0 is configured for the cell and the size of initial DL bandwidth part shall be used if CORESET 0 is not
// configured for the cell.
if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 && sched_ctrl->search_space->searchSpaceType
if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0
&& sched_ctrl->search_space->searchSpaceType
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) {
if (sched_ctrl->coreset->controlResourceSetId == 0) {
bwp_info.bwpStart = nr_mac->cset0_bwp_start;
@@ -406,9 +407,9 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
bwp_info.bwpStart = dl_bwp->BWPStart + sched_ctrl->sched_pdcch.rb_start;
}
if (nr_mac->cset0_bwp_size > 0) {
bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, nr_mac->cset0_bwp_size);
bwp_info.bwpSize = min(dl_bwp->BWPSize, nr_mac->cset0_bwp_size);
} else {
bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, UE->sc_info.initial_dl_BWPSize);
bwp_info.bwpSize = min(dl_bwp->BWPSize, UE->sc_info.initial_dl_BWPSize);
}
} else {
bwp_info.bwpSize = dl_bwp->BWPSize;
@@ -592,6 +593,21 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
return true;
}
static void ack_reconfig(gNB_MAC_INST *mac, NR_UE_info_t *UE)
{
if (UE->reconfigSpCellConfig) {
// in case of reestablishment, the spCellConfig had to be released
// temporarily. Reapply now before doing the reconfiguration.
UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig;
// UE->reconfigSpCellConfig to be NULLed after receiving reconfiguration complete
}
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
/* clean BWP structures */
clean_bwp_structures(UE->CellGroup->spCellConfig);
configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1);
UE->await_reconfig = false;
}
typedef struct UEsched_s {
float coef;
NR_UE_info_t * UE;
@@ -866,6 +882,12 @@ static void pf_dl(gNB_MAC_INST *mac,
.tda_info = tda_info,
};
sched_pdsch.action = NULL;
int srb1 = 1;
/* everything that's only 3 bytes is an ack. To be safe, use a bit more. */
if (iterator->UE->await_reconfig && sched_ctrl->rlc_status[srb1].bytes_in_buffer > 10)
sched_pdsch.action = ack_reconfig;
// Fix me: currently, the RLC does not give us the total number of PDUs
// awaiting. Therefore, for the time being, we put a fixed overhead of 12
// (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of
@@ -1191,7 +1213,6 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
&dci_payload,
current_BWP->dci_format,
rnti_type,
bwp_id,
sched_ctrl->search_space,
sched_ctrl->coreset,
UE->pdsch_HARQ_ACK_Codebook,
@@ -907,8 +907,10 @@ dci_pdu_rel15_t prepare_dci_dl_payload(const gNB_MAC_INST *gNB_mac,
dci_payload.dai[0].val = pucch ? (pucch->dai_c - 1) & 3 : 0;
// bwp indicator
// as per table 7.3.1.1.2-1 in 38.212
if (dl_BWP)
dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? dl_BWP->bwp_id : dl_BWP->bwp_id - 1;
if (dl_BWP) {
int ext_bwp_id = dl_BWP->bwp_id ? 1 : 0; // BWP-ID sent to the UE is always 1 except for BWP 0
dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? ext_bwp_id : ext_bwp_id - 1;
}
return dci_payload;
}
@@ -1182,7 +1184,6 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info,
NR_UE_UL_BWP_t *ul_bwp,
NR_SearchSpace__searchSpaceType_PR ss_type)
{
int bwp_id = ul_bwp->bwp_id;
nr_dci_format_t dci_format = ul_bwp->dci_format;
// 3GPP TS 38.214 Section 6.1.2.2.2 Uplink resource allocation type 1
@@ -1214,7 +1215,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info,
LOG_D(NR_MAC,"Configuring DCI Format 0_1\n");
dci_pdu_rel15->dai[0].val = 0; //TODO
// bwp indicator as per table 7.3.1.1.2-1 in 38.212
dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? bwp_id : bwp_id - 1;
int ext_bwp_id = ul_bwp->bwp_id ? 1 : 0; // BWP-ID sent to the UE is always 1 except for BWP 0
dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? ext_bwp_id : ext_bwp_id - 1;
// SRS resource indicator
if (pusch_Config && pusch_Config->txConfig != NULL) {
AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook,
@@ -1640,7 +1642,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo,
dci_pdu_rel15_t *dci_pdu_rel15,
int dci_format,
int rnti_type,
int bwp_id,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
long pdsch_HARQ_ACK_Codebook,
@@ -1671,7 +1672,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo,
NR_UL_DCI_FORMAT_0_0,
rnti_type,
coreset,
bwp_id,
ss->searchSpaceType->present,
cset0_bwp_size,
0);
@@ -1685,7 +1685,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo,
NR_DL_DCI_FORMAT_1_0,
rnti_type,
coreset,
bwp_id,
ss->searchSpaceType->present,
cset0_bwp_size,
0);
@@ -1702,10 +1701,10 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo,
dci_format,
rnti_type,
coreset,
bwp_id,
ss->searchSpaceType->present,
cset0_bwp_size,
alt_size);
if (dci_size == 0)
return;
pdcch_dci_pdu->PayloadSizeBits = dci_size;
@@ -2703,38 +2702,26 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
AssertFatal(dl_bwp_switch == ul_bwp_switch, "Different UL and DL BWP not supported\n");
DL_BWP->bwp_id = dl_bwp_switch;
UL_BWP->bwp_id = ul_bwp_switch;
UE->local_bwp_id = dl_bwp_switch; // assuming they are the same
} else {
// (re)configuring BWP
// TODO BWP switching not via RRC reconfiguration
// via RRC if firstActiveXlinkBWP_Id is NULL, MAC stays on the same BWP as before
if (servingCellConfig->firstActiveDownlinkBWP_Id)
DL_BWP->bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id;
if (servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id)
UL_BWP->bwp_id = *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id;
DL_BWP->bwp_id = UE->local_bwp_id;
UL_BWP->bwp_id = UE->local_bwp_id;
}
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
if(bwpList)
sc_info->n_dl_bwp = bwpList->list.count;
if (DL_BWP->bwp_id>0) {
for (int i=0; i<bwpList->list.count; i++) {
dl_bwp = bwpList->list.array[i];
if(dl_bwp->bwp_Id == DL_BWP->bwp_id)
break;
}
AssertFatal(dl_bwp!=NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n",DL_BWP->bwp_id);
sc_info->n_dl_bwp = 1;
if (DL_BWP->bwp_id > 0) {
dl_bwp = bwpList->list.array[0];
AssertFatal(dl_bwp, "Couldn't find DLBWP corresponding to BWP ID %ld\n", DL_BWP->bwp_id);
}
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
if(ubwpList)
sc_info->n_ul_bwp = ubwpList->list.count;
if (UL_BWP->bwp_id>0) {
for (int i=0; i<ubwpList->list.count; i++) {
ul_bwp = ubwpList->list.array[i];
if(ul_bwp->bwp_Id == UL_BWP->bwp_id)
break;
}
AssertFatal(ul_bwp!=NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id);
sc_info->n_ul_bwp = 1;
if (UL_BWP->bwp_id > 0) {
ul_bwp = ubwpList->list.array[0];
AssertFatal(ul_bwp, "Couldn't find ULBWP corresponding to BWP ID %ld\n", UL_BWP->bwp_id);
}
// selection of dedicated BWPs
@@ -2762,12 +2749,12 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
}
// TDA lists
if (DL_BWP->bwp_id>0)
if (DL_BWP->bwp_id > 0)
DL_BWP->tdaList_Common = dl_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
else
DL_BWP->tdaList_Common = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
if(UL_BWP->bwp_id>0)
if(UL_BWP->bwp_id > 0)
UL_BWP->tdaList_Common = ul_bwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
else
UL_BWP->tdaList_Common = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
@@ -3217,9 +3204,10 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
NR_NZP_CSI_RS_ResourceSetId_t *nzp = NULL;
for (int csi_list=0; csi_list<csi_measconfig->csi_ResourceConfigToAddModList->list.count; csi_list++) {
NR_CSI_ResourceConfig_t *csires = csi_measconfig->csi_ResourceConfigToAddModList->list.array[csi_list];
if(csires->bwp_Id == dl_bwp->bwp_id &&
csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB &&
csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) {
if (csires->bwp_Id > 1)
LOG_E(NR_MAC, "Invalid CSI resource BWP ID %ld, we only configure BWP up to 1\n", csires->bwp_Id);
else if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB &&
csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) {
nzp = csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0];
}
}
@@ -3456,46 +3444,11 @@ void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot
void clean_bwp_structures(NR_SpCellConfig_t *spCellConfig)
{
NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated;
if (spCellConfigDedicated->downlinkBWP_ToReleaseList) {
struct NR_ServingCellConfig__downlinkBWP_ToReleaseList *rel_dl = spCellConfigDedicated->downlinkBWP_ToReleaseList;
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *add_dl = spCellConfigDedicated->downlinkBWP_ToAddModList;
int num_rel = rel_dl->list.count;
int num_add = add_dl->list.count;
for (int i = 0; i < num_rel; i++) {
NR_BWP_Id_t *rel_id = rel_dl->list.array[i];
for (int j = 0; j < num_add; j++) {
NR_BWP_Downlink_t *dl_bwp = add_dl->list.array[j];
if (*rel_id == dl_bwp->bwp_Id) {
asn_sequence_del(&add_dl->list, j, 1);
}
}
asn_sequence_del(&rel_dl->list, i, 1);
}
if (rel_dl->list.count == 0)
free_and_zero(rel_dl);
if (add_dl->list.count == 0)
free_and_zero(add_dl);
}
if (spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList) {
struct NR_UplinkConfig__uplinkBWP_ToReleaseList *rel_ul = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList;
struct NR_UplinkConfig__uplinkBWP_ToAddModList *add_ul = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
int num_rel = rel_ul->list.count;
int num_add = add_ul->list.count;
for (int i = 0; i < num_rel; i++) {
NR_BWP_Id_t *rel_id = rel_ul->list.array[i];
for (int j = 0; j < num_add; j++) {
NR_BWP_Uplink_t *ul_bwp = add_ul->list.array[j];
if (*rel_id == ul_bwp->bwp_Id) {
asn_sequence_del(&add_ul->list, j, 1);
}
}
asn_sequence_del(&rel_ul->list, i, 1);
}
if (rel_ul->list.count == 0)
free_and_zero(rel_ul);
if (add_ul->list.count == 0)
free_and_zero(add_ul);
}
if (spCellConfigDedicated->downlinkBWP_ToAddModList && spCellConfigDedicated->downlinkBWP_ToAddModList->list.count > 1)
asn_sequence_del(&spCellConfigDedicated->downlinkBWP_ToAddModList->list, 0, 1);
if (spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList
&& spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count > 1)
asn_sequence_del(&spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list, 0, 1);
}
void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group)
@@ -3517,8 +3470,6 @@ void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group)
/* remove reestablishRLC, we don't need it anymore */
for (int i = 0; i < cell_group->rlc_BearerToAddModList->list.count; ++i)
free_and_zero(cell_group->rlc_BearerToAddModList->list.array[i]->reestablishRLC);
/* clean BWP structures */
clean_bwp_structures(spCellConfig);
}
int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs)
@@ -3818,6 +3769,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config);
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
UE->CellGroup = cellGroupConfig;
UE->local_bwp_id = mac->radio_config.first_active_bwp;
if (!cellGroupConfig)
return true;
@@ -3922,15 +3874,35 @@ bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *
return false;
}
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id)
static bool verify_bwp_switch(const NR_UE_info_t *UE, const nr_mac_config_t *configuration, int new_bwp_id)
{
if (new_bwp_id == UE->current_DL_BWP.bwp_id) {
LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n");
return false;
}
if (new_bwp_id == 0)
return true;
for (int i = 0; i < configuration->num_additional_bwps; i++) {
const nr_bwp_config_t *bwp_config = &configuration->bwp_config[i];
if (bwp_config->id == new_bwp_id)
return true;
}
LOG_E(NR_MAC, "New BWP %d does not belong to the list of configured BWPs, can't perform switch\n", new_bwp_id);
return false;
}
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id)
{
DevAssert(UE->CellGroup != NULL);
NR_CellGroupConfig_t *cellGroup_for_UE = NULL;
if (new_bwp_id >= 0) {
AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n");
if (new_bwp_id == UE->current_DL_BWP.bwp_id)
LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n");
else
if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id))
return;
else {
UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated
UE->local_bwp_id = new_bwp_id;
cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup,
&nrmac->radio_config,
UE->capability,
@@ -3938,6 +3910,7 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_
UE->uid,
UE->current_DL_BWP.bwp_id,
new_bwp_id);
}
}
uint8_t buf[2048];
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
@@ -3946,6 +3919,7 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_
buf,
sizeof(buf));
AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name);
UE->await_reconfig = true;
du_to_cu_rrc_information_t du2cu = {
.cellGroupConfig = buf,
.cellGroupConfig_length = (enc_rval.encoded + 7) >> 3,
+12 -11
View File
@@ -253,9 +253,10 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
"Only periodic CSI reporting is implemented currently\n");
const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
if(pucchcsires->uplinkBandwidthPartId != ul_bwp->bwp_id)
if(pucchcsires->uplinkBandwidthPartId > 1) {
LOG_E(NR_MAC, "Invalid PUCCH BWP ID %ld, we only configure BWP up to 1\n", pucchcsires->uplinkBandwidthPartId);
continue;
}
// we schedule CSI reporting max_fb_time slots in advance
int period, offset;
csi_period_offset(csirep, NULL, &period, &offset);
@@ -393,16 +394,15 @@ int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_r
return *resource_id;
}
static void handle_dl_harq(NR_UE_info_t * UE,
int8_t harq_pid,
bool success,
int harq_round_max)
static void handle_dl_harq(gNB_MAC_INST *mac, NR_UE_info_t * UE, int8_t harq_pid, bool success, int harq_round_max)
{
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid];
harq->feedback_slot = -1;
harq->is_waiting = false;
if (success) {
if (harq->sched_pdsch.action)
harq->sched_pdsch.action(mac, UE);
finish_nr_dl_harq(sched_ctrl, harq_pid);
} else if (harq->round >= harq_round_max - 1) {
abort_nr_dl_harq(UE, harq_pid);
@@ -749,7 +749,6 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16 =
NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
const int n_slots_frame = nrmac->frame_structure.numb_slots_frame;
int cumul_bits = 0;
@@ -764,8 +763,10 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
uint8_t cqi_table = (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_1 && csirep->cqi_Table) ? *csirep->cqi_Table : NR_CSI_ReportConfig__cqi_Table_table1;
const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
if(pucchcsires->uplinkBandwidthPartId != ul_bwp->bwp_id)
if(pucchcsires->uplinkBandwidthPartId > 1) {
LOG_E(NR_MAC, "Invalid PUCCH BWP ID %ld, we only configure BWP up to 1\n", pucchcsires->uplinkBandwidthPartId);
continue;
}
int period, offset;
csi_period_offset(csirep, NULL, &period, &offset);
// verify if report with current id has been scheduled for this frame and slot
@@ -873,7 +874,7 @@ static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, in
frame,
slot);
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
handle_dl_harq(UE, pid, 0, harq_round_max);
handle_dl_harq(NULL, UE, pid, false, harq_round_max);
pid = sched_ctrl->feedback_dl_harq.head;
if (pid < 0)
return NULL;
@@ -930,7 +931,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
nr_mac_update_pdcch_closed_loop_adjust(sched_ctrl, harq_confidence != 0);
bool success = harq_value == 0 && harq_confidence == 0;
handle_dl_harq(UE, pid, success, nrmac->dl_bler.harq_round_max);
handle_dl_harq(nrmac, UE, pid, success, nrmac->dl_bler.harq_round_max);
if (is_ra) {
bool ue_rejected = nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success);
if (ue_rejected) {
@@ -1009,7 +1010,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit, pid, acknack);
handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max);
handle_dl_harq(nrmac, UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max);
}
free(uci_234->harq.harq_payload);
}
@@ -163,7 +163,8 @@ bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE)
// contiguously allocated non-interleaved virtual resource blocks within the active bandwidth part of size PRBs except for the
// case when DCI format 0_0 is decoded in any common search space in which case the size of the initial UL bandwidth part shall
// be used.
if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 && sched_ctrl->search_space->searchSpaceType
if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0
&& sched_ctrl->search_space->searchSpaceType
&& sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) {
bwp_info.bwpSize = min(ul_bwp->BWPSize, UE->sc_info.initial_ul_BWPSize);
} else {
@@ -772,10 +773,9 @@ static void nr_rx_ra_sdu(const module_id_t mod_id,
nr_mac_reset_ul_failure(sched_ctrl);
reset_dl_harq_list(sched_ctrl);
reset_ul_harq_list(sched_ctrl);
// we configure the UE using common search space with DCIX0 while waiting for a reconfiguration in SA
// in NSA (or do-ra) there is no reconfiguration in NR
int ss_type = IS_SA_MODE(get_softmodem_params()) ? NR_SearchSpace__searchSpaceType_PR_common
: NR_SearchSpace__searchSpaceType_PR_ue_Specific;
// we configure the UE using dedicated search space: In SA (CFRA used for
// handover) and NSA (or do-ra), the UE has the full config already.
int ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1);
// initialize ta_frame in case there is no Msg3 received
UE->UE_sched_ctrl.ta_frame = (frame + 100) % MAX_FRAME_NUMBER;
@@ -2606,7 +2606,6 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE
&uldci_payload,
current_BWP->dci_format,
TYPE_C_RNTI_,
current_BWP->bwp_id,
ss,
coreset,
UE->pdsch_HARQ_ACK_Codebook,
+2
View File
@@ -43,4 +43,6 @@ typedef struct gnb_sat_position_update_s {
bool nr_update_sib19(const gnb_sat_position_update_t *sat_position);
bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id);
#endif /*__LAYER2_NR_MAC_CONFIG_H__*/
+1 -2
View File
@@ -258,7 +258,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo,
dci_pdu_rel15_t *dci_pdu_rel15,
int dci_format,
int rnti_type,
int bwp_id,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
long pdsch_HARQ_ACK_Codebook,
@@ -478,7 +477,7 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac
void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl);
bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl);
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id);
void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id);
bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c);
nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid);
@@ -576,6 +576,7 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C
cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame);
// TODO: in NSA we assign capabilities here, otherwise outside => not logic
UE->capability = cap;
UE->local_bwp_id = 1; // get_default_secondaryCellGroup sets 1st active BWP as 1
}
// note: we don't pass the cellGroupConfig to add_new_nr_ue() because we need
// the uid to create the CellGroupConfig (which is in the UE context created
@@ -770,9 +771,12 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req)
} else if (req->reconfig_compl) {
LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n");
if (UE->reconfigSpCellConfig) {
// in case of reestablishment, the spCellConfig had to be released
// temporarily. Reapply now before doing the reconfiguration.
UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig;
if (UE->await_reconfig) {
// in case of reestablishment, the spCellConfig had to be released
// temporarily. Reapply now before doing the reconfiguration.
UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig;
UE->await_reconfig = false;
}
UE->reconfigSpCellConfig = NULL;
for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) {
nr_lc_config_t *c = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i);
@@ -971,6 +975,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
* reconfiguration has succeeded (indicated by the CU) */
UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig;
UE->CellGroup->spCellConfig = NULL;
UE->await_reconfig = true;
mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id);
pthread_mutex_unlock(&mac->sched_lock);
nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id);
+11 -1
View File
@@ -475,6 +475,9 @@ typedef struct NR_pdsch_dmrs {
NR_PTRS_DownlinkConfig_t *phaseTrackingRS;
} NR_pdsch_dmrs_t;
struct NR_UE_info;
struct gNB_MAC_INST_s;
typedef void (*feedback_action_t)(struct gNB_MAC_INST_s *mac, struct NR_UE_info *ue);
typedef struct NR_sched_pdsch {
/// RB allocation within active BWP
uint16_t rbSize;
@@ -501,6 +504,7 @@ typedef struct NR_sched_pdsch {
// time_domain_allocation is the index of a list of tda
int time_domain_allocation;
NR_tda_info_t tda_info;
feedback_action_t action;
} NR_sched_pdsch_t;
typedef struct NR_UE_harq {
@@ -772,7 +776,7 @@ typedef struct measgap_config {
} measgap_config_t;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
typedef struct {
typedef struct NR_UE_info {
rnti_t rnti;
uid_t uid; // unique ID of this UE
/// scheduling control info
@@ -795,7 +799,13 @@ typedef struct {
float dl_thr_ue;
long pdsch_HARQ_ACK_Codebook;
bool is_redcap;
bool await_reconfig;
NR_RA_t *ra;
// 3GPP mandates that BWPs are enumerated consecutively, but we only send one (dedicated)
// BWP to the UE (and modify that BWP on reconfiguration); consequently, the BWP ID for a
// dedicated BWP is always 1 from the UE's point of view, even if the gNB has multiple BWPs.
// The below ID is the "true" (non-consecutive) BWP ID from the gNB's point of view
NR_BWP_Id_t local_bwp_id;
} NR_UE_info_t;
typedef struct {
+105 -147
View File
@@ -1505,10 +1505,38 @@ static NR_PTRS_UplinkConfig_t *config_ulptrs(const nr_ptrs_config_t *ptrs)
return ulptrs;
}
static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS,
long ue_supported_ul_layers(const NR_UE_NR_Capability_t *uecap)
{
long ul_max_layers = 1;
if (uecap
&& uecap->featureSets
&& uecap->featureSets->featureSetsUplinkPerCC
&& uecap->featureSets->featureSetsUplinkPerCC->list.count > 0) {
NR_FeatureSetUplinkPerCC_t *ul_feature_setup_per_cc = uecap->featureSets->featureSetsUplinkPerCC->list.array[0];
if (ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) {
switch (*ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) {
case NR_MIMO_LayersUL_twoLayers:
ul_max_layers = 2;
break;
case NR_MIMO_LayersUL_fourLayers:
ul_max_layers = 4;
break;
default:
ul_max_layers = 1;
}
}
}
return ul_max_layers;
}
static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_NR_Capability_t *uecap)
{
return min(ue_supported_ul_layers(uecap), configuration->pusch_AntennaPorts);
}
static NR_SetupRelease_PUSCH_Config_t *config_pusch(const nr_mac_config_t *configuration,
const NR_ServingCellConfigCommon_t *scc,
const NR_UE_NR_Capability_t *uecap,
const nr_ptrs_config_t *ptrs)
const NR_UE_NR_Capability_t *uecap)
{
NR_SetupRelease_PUSCH_Config_t *setup_puschconfig = calloc(1, sizeof(*setup_puschconfig));
setup_puschconfig->present = NR_SetupRelease_PUSCH_Config_PR_setup;
@@ -1526,8 +1554,8 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS,
if (!pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)
pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup));
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
if (ptrs) {
NR_PTRS_UplinkConfig_t *ptrs_config = config_ulptrs(ptrs);
if (configuration->ptrs) {
NR_PTRS_UplinkConfig_t *ptrs_config = config_ulptrs(configuration->ptrs);
NR_SetupRelease_PTRS_UplinkConfig_t *phaseTrackingRS = calloc(1, sizeof(*phaseTrackingRS));
phaseTrackingRS->present = NR_SetupRelease_PTRS_UplinkConfig_PR_setup;
phaseTrackingRS->choice.setup = ptrs_config;
@@ -1569,7 +1597,7 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS,
asn1cSeqAdd(&pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList->list, plrefRS);
pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL;
pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL;
if (use_deltaMCS) {
if (configuration->use_deltaMCS) {
if (!pusch_Config->pusch_PowerControl->deltaMCS)
pusch_Config->pusch_PowerControl->deltaMCS = calloc(1, sizeof(*pusch_Config->pusch_PowerControl->deltaMCS));
*pusch_Config->pusch_PowerControl->deltaMCS = NR_PUSCH_PowerControl__deltaMCS_enabled;
@@ -1582,14 +1610,14 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS,
pusch_Config->resourceAllocation = NR_PUSCH_Config__resourceAllocation_resourceAllocationType1;
pusch_Config->pusch_TimeDomainAllocationList = NULL;
pusch_Config->pusch_AggregationFactor = NULL;
set_ul_mcs_table(uecap, scc, pusch_Config);
set_ul_mcs_table(configuration->force_UL256qam_off ? NULL : uecap, scc, pusch_Config);
pusch_Config->transformPrecoder = NULL;
if (!pusch_Config->codebookSubset)
pusch_Config->codebookSubset = calloc(1, sizeof(*pusch_Config->codebookSubset));
*pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent;
if (!pusch_Config->maxRank)
pusch_Config->maxRank = calloc(1, sizeof(*pusch_Config->maxRank));
*pusch_Config->maxRank = 1;
*pusch_Config->maxRank = set_ul_max_layers(configuration, uecap);
pusch_Config->rbg_Size = NULL;
pusch_Config->uci_OnPUSCH = NULL;
pusch_Config->tp_pi2BPSK = NULL;
@@ -1696,20 +1724,18 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t
const NR_UE_NR_Capability_t *uecap,
int dl_antenna_ports,
bool force_256qam_off,
int bwp_loop,
bool is_SA,
const nr_mac_config_t *configuration)
{
NR_BWP_Downlink_t *bwp = calloc_or_fail(1, sizeof(*bwp));
bwp->bwp_Id = 1;
bwp->bwp_Common = calloc(1,sizeof(*bwp->bwp_Common));
if(configuration->num_additional_bwps > 0) {
const nr_bwp_config_t *bwp_config = &configuration->bwp_config[bwp_loop];
bwp->bwp_Id = bwp_config->id;
if(configuration->num_additional_bwps > 0 && configuration->first_active_bwp > 0) {
const nr_bwp_config_t *bwp_config = &configuration->bwp_config[configuration->first_active_bwp - 1];
bwp->bwp_Common->genericParameters.locationAndBandwidth = bwp_config->location_and_bw;
bwp->bwp_Common->genericParameters.subcarrierSpacing = bwp_config->scs;
bwp->bwp_Common->genericParameters.cyclicPrefix = NULL;
} else {
bwp->bwp_Id=bwp_loop+1;
bwp->bwp_Common->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0);
bwp->bwp_Common->genericParameters.subcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
bwp->bwp_Common->genericParameters.cyclicPrefix = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix;
@@ -1743,7 +1769,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t
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);
ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, agg_level_candidates);
}
asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss);
@@ -1784,7 +1810,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t
verify_agg_levels(num_cces, configuration->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, is_SA ? 0 : coreset2->controlResourceSetId, agg_level_candidates);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, coreset2->controlResourceSetId, agg_level_candidates);
asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2);
searchspaceid = 20 + bwp->bwp_Id;
@@ -1802,8 +1828,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t
return bwp;
}
static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop,
bool is_SA,
static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA,
int uid,
int maxMIMO_Layers,
const nr_mac_config_t *configuration,
@@ -1811,14 +1836,14 @@ static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop,
const NR_UE_NR_Capability_t *uecap)
{
NR_BWP_Uplink_t *ubwp = calloc_or_fail(1, sizeof(*ubwp));
ubwp->bwp_Id = 1;
ubwp->bwp_Common = calloc(1, sizeof(*ubwp->bwp_Common));
if(configuration->num_additional_bwps > 0) {
ubwp->bwp_Id = configuration->bwp_config[bwp_loop].id;
ubwp->bwp_Common->genericParameters.locationAndBandwidth = configuration->bwp_config[bwp_loop].location_and_bw;
ubwp->bwp_Common->genericParameters.subcarrierSpacing = configuration->bwp_config[bwp_loop].scs;
if(configuration->num_additional_bwps > 0 && configuration->first_active_bwp > 0) {
int bwp_idx = configuration->first_active_bwp - 1;
ubwp->bwp_Common->genericParameters.locationAndBandwidth = configuration->bwp_config[bwp_idx].location_and_bw;
ubwp->bwp_Common->genericParameters.subcarrierSpacing = configuration->bwp_config[bwp_idx].scs;
ubwp->bwp_Common->genericParameters.cyclicPrefix = NULL;
} else {
ubwp->bwp_Id=bwp_loop+1;
ubwp->bwp_Common->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0);
ubwp->bwp_Common->genericParameters.subcarrierSpacing = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
ubwp->bwp_Common->genericParameters.cyclicPrefix = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix;
@@ -1855,16 +1880,13 @@ static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop,
scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration->use_deltaMCS,
scc,
configuration->force_UL256qam_off ? NULL : uecap,
configuration->ptrs);
ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration, scc, uecap);
ubwp->bwp_Dedicated->srs_Config = get_config_srs(scc,
NULL,
curr_bwp,
uid,
bwp_loop + 1,
ubwp->bwp_Id,
maxMIMO_Layers,
configuration->minRXTXTIME,
configuration->do_SRS);
@@ -3268,6 +3290,7 @@ static void fill_harq_IEs(NR_ServingCellConfig_t *scc, int num_dlharq, int num_u
static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellConfigCommon_t *scc,
const nr_mac_config_t *configuration,
int maxMIMO_Layers,
const NR_UE_NR_Capability_t *uecap,
int id)
{
NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1, sizeof(*initialUplinkBWP));
@@ -3282,14 +3305,14 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo
pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList));
pucch_Config->resourceToReleaseList = NULL;
int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, NULL);
config_pucch_resset1(pucch_Config, id, num_pucch2, NULL);
config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, uecap);
config_pucch_resset1(pucch_Config, id, num_pucch2, uecap);
set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
initialUplinkBWP->pusch_Config = config_pusch(configuration->use_deltaMCS, scc, NULL, configuration->ptrs);
initialUplinkBWP->pusch_Config = config_pusch(configuration, scc, uecap);
// We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1
initialUplinkBWP->srs_Config = get_config_srs(scc, NULL, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0);
initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0);
scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing);
set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, genericParameters->subcarrierSpacing);
@@ -3299,6 +3322,7 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo
static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCellConfigCommon_t *scc,
const int pdsch_AntennaPorts,
uint64_t bitmap,
const NR_UE_NR_Capability_t *uecap,
const nr_mac_config_t *configuration)
{
NR_BWP_DownlinkDedicated_t *bwp_Dedicated = calloc(1, sizeof(*bwp_Dedicated));
@@ -3330,6 +3354,11 @@ static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCell
bwp_Dedicated->pdcch_Config->choice.setup = pdcch_Config;
bwp_Dedicated->pdsch_Config = config_pdsch(bitmap, 0, pdsch_AntennaPorts, configuration->ptrs);
// we might call configuration of initial BWP for BWP switch when we already have UE capabilities
set_dl_mcs_table(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing,
configuration->force_256qam_off ? NULL : uecap,
bwp_Dedicated,
scc);
return bwp_Dedicated;
}
@@ -3367,10 +3396,14 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf
pdsch_Config = configDedicated->initialDownlinkBWP->pdsch_Config;
curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
} else {
NR_BWP_Downlink_t *bwp = configDedicated->downlinkBWP_ToAddModList->list.array[0];
NR_BWP_Downlink_t *bwp = NULL;
for (int i = 0; i < configDedicated->downlinkBWP_ToAddModList->list.count; i++) {
if (bwp_id == configDedicated->downlinkBWP_ToAddModList->list.array[i]->bwp_Id)
bwp = configDedicated->downlinkBWP_ToAddModList->list.array[i];
}
AssertFatal(bwp, "BWP ID doesn't match\n");
pdsch_Config = bwp->bwp_Dedicated->pdsch_Config;
curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
AssertFatal(bwp_id == bwp->bwp_Id, "BWP ID doesn't match\n");
}
const int pdsch_AntennaPorts =
@@ -3501,25 +3534,24 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
uint64_t bitmap = get_ssb_bitmap(scc);
int first_active_bwp = 0;
if (configuration->num_additional_bwps > 0)
first_active_bwp = configuration->first_active_bwp;
first_active_bwp = configuration->first_active_bwp > 0 ? 1 : 0;
asn1cCallocOne(configDedicated->firstActiveDownlinkBWP_Id, first_active_bwp);
asn1cCallocOne(uplinkConfig->firstActiveUplinkBWP_Id, first_active_bwp);
if (first_active_bwp == 0) {
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, uid);
configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, configuration);
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, NULL, uid);
configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, NULL, configuration);
} else {
configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList));
NR_BWP_Downlink_t *bwp = config_downlinkBWP(scc,
NULL,
0,
false,
first_active_bwp - 1,
true,
configuration);
asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp);
uplinkConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList));
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(first_active_bwp - 1, true, uid, maxMIMO_Layers, configuration, scc, NULL);
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(true, uid, maxMIMO_Layers, configuration, scc, NULL);
asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ubwp);
}
@@ -3739,75 +3771,22 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid,
return cellGroupConfig;
}
long ue_supported_ul_layers(const NR_UE_NR_Capability_t *uecap)
{
long ul_max_layers = 1;
if (uecap
&& uecap->featureSets
&& uecap->featureSets->featureSetsUplinkPerCC
&& uecap->featureSets->featureSetsUplinkPerCC->list.count > 0) {
NR_FeatureSetUplinkPerCC_t *ul_feature_setup_per_cc = uecap->featureSets->featureSetsUplinkPerCC->list.array[0];
if (ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) {
switch (*ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) {
case NR_MIMO_LayersUL_twoLayers:
ul_max_layers = 2;
break;
case NR_MIMO_LayersUL_fourLayers:
ul_max_layers = 4;
break;
default:
ul_max_layers = 1;
}
}
}
return ul_max_layers;
}
static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_NR_Capability_t *uecap)
{
return min(ue_supported_ul_layers(uecap), configuration->pusch_AntennaPorts);
}
NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig,
const nr_mac_config_t *configuration,
const NR_UE_NR_Capability_t *uecap,
const NR_ServingCellConfigCommon_t *scc,
int uid,
int old_bwp,
int new_bwp)
NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig,
const nr_mac_config_t *configuration,
const NR_UE_NR_Capability_t *uecap,
const NR_ServingCellConfigCommon_t *scc,
int uid,
int old_bwp,
int new_bwp)
{
NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig;
NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated;
*configDedicated->firstActiveDownlinkBWP_Id = new_bwp;
*configDedicated->firstActiveDownlinkBWP_Id = new_bwp != 0; // 1 for any BWP != 0
NR_UplinkConfig_t *uplinkConfig = configDedicated->uplinkConfig;
*uplinkConfig->firstActiveUplinkBWP_Id = new_bwp;
*uplinkConfig->firstActiveUplinkBWP_Id = new_bwp != 0; // 1 for any BWP != 0
nr_mac_config_t local_config = *configuration;
long ul_maxMIMO_Layers = set_ul_max_layers(configuration, uecap);
// release old BWP
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *dl_BWP_list = configDedicated->downlinkBWP_ToAddModList;
struct NR_UplinkConfig__uplinkBWP_ToAddModList *ul_BWP_list = uplinkConfig->uplinkBWP_ToAddModList;
if (old_bwp > 0) { // we need to remove old BWP only if it is not the initial
AssertFatal(dl_BWP_list, "Source BWP %d should be present in the list\n", old_bwp);
AssertFatal(ul_BWP_list, "Source BWP %d should be present in the list\n", old_bwp);
NR_BWP_Id_t id = dl_BWP_list->list.array[0]->bwp_Id;
if (!configDedicated->downlinkBWP_ToReleaseList)
configDedicated->downlinkBWP_ToReleaseList = calloc_or_fail(1, sizeof(*configDedicated->downlinkBWP_ToReleaseList));
asn1cSequenceAdd(configDedicated->downlinkBWP_ToReleaseList->list, NR_BWP_Id_t, rel_id);
*rel_id = id;
AssertFatal(configDedicated->downlinkBWP_ToReleaseList->list.count == 1,
"logic error: there shouldn't be more than 1 BWP to release, but downlinkBWP_ToReleaseList has %d\n",
configDedicated->downlinkBWP_ToReleaseList->list.count);
id = ul_BWP_list->list.array[0]->bwp_Id;
if (!uplinkConfig->uplinkBWP_ToReleaseList)
uplinkConfig->uplinkBWP_ToReleaseList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToReleaseList));
asn1cSequenceAdd(uplinkConfig->uplinkBWP_ToReleaseList->list, NR_BWP_Id_t, ul_rel_id);
*ul_rel_id = id;
AssertFatal(uplinkConfig->uplinkBWP_ToReleaseList->list.count == 1,
"logic error: there shouldn't be more than 1 BWP to release, but uplinkBWP_ToReleaseList has %d\n",
uplinkConfig->uplinkBWP_ToReleaseList->list.count);
}
local_config.first_active_bwp = new_bwp;
uint64_t bitmap = get_ssb_bitmap(scc);
const int pdsch_AntennaPorts =
configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP;
@@ -3817,23 +3796,22 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_
configDedicated->initialDownlinkBWP = calloc_or_fail(1, sizeof(*configDedicated->initialDownlinkBWP));
if (!uplinkConfig->initialUplinkBWP)
uplinkConfig->initialUplinkBWP = calloc_or_fail(1, sizeof(*uplinkConfig->initialUplinkBWP));
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, ul_maxMIMO_Layers, uid);
configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, configuration);
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, &local_config, ul_maxMIMO_Layers, uecap, uid);
configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, uecap, &local_config);
} else {
if (!configDedicated->downlinkBWP_ToAddModList)
configDedicated->downlinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*configDedicated->downlinkBWP_ToAddModList));
NR_BWP_Downlink_t *dl_bwp = config_downlinkBWP(scc,
uecap,
pdsch_AntennaPorts,
configuration->force_256qam_off,
new_bwp - 1,
local_config.force_256qam_off,
true,
configuration);
&local_config);
asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, dl_bwp);
if (!uplinkConfig->uplinkBWP_ToAddModList)
uplinkConfig->uplinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList));
NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(new_bwp - 1, true, uid, ul_maxMIMO_Layers, configuration, scc, uecap);
NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(true, uid, ul_maxMIMO_Layers, &local_config, scc, uecap);
asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ul_bwp);
}
@@ -3841,9 +3819,9 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_
configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated,
uecap,
scc,
configuration,
&local_config,
uid,
new_bwp,
*uplinkConfig->firstActiveUplinkBWP_Id,
bitmap);
// we temporarily need to keep both the old and the new BWP in the CG used by the gNB
@@ -4055,10 +4033,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
ulConfig->initialUplinkBWP = initialUplinkBWP;
initialUplinkBWP->pucch_Config = NULL;
initialUplinkBWP->pusch_Config = config_pusch(configuration->use_deltaMCS,
servingcellconfigcommon,
uecap,
configuration->ptrs);
initialUplinkBWP->pusch_Config = config_pusch(configuration, servingcellconfigcommon, uecap);
long maxMIMO_Layers = set_ul_max_layers(configuration, uecap);
int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
@@ -4073,44 +4048,27 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
configuration->do_SRS);
// Downlink BWPs
int n_dl_bwp = 1;
int firstActiveDownlinkBWP_Id = 1;
if (configuration->num_additional_bwps > 0) {
n_dl_bwp = configuration->num_additional_bwps;
firstActiveDownlinkBWP_Id = configuration->first_active_bwp;
}
configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList));
for (int bwp_loop = 0; bwp_loop < n_dl_bwp; bwp_loop++) {
NR_BWP_Downlink_t *bwp = config_downlinkBWP(servingcellconfigcommon,
uecap,
dl_antenna_ports,
configuration->force_256qam_off,
bwp_loop,
false,
configuration);
asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp);
configDedicated->firstActiveDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->firstActiveDownlinkBWP_Id));
*configDedicated->firstActiveDownlinkBWP_Id = firstActiveDownlinkBWP_Id;
configDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->defaultDownlinkBWP_Id));
*configDedicated->defaultDownlinkBWP_Id = 1;
}
NR_BWP_Downlink_t *bwp = config_downlinkBWP(servingcellconfigcommon,
uecap,
dl_antenna_ports,
configuration->force_256qam_off,
false,
configuration);
asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp);
configDedicated->firstActiveDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->firstActiveDownlinkBWP_Id));
*configDedicated->firstActiveDownlinkBWP_Id = firstActiveDownlinkBWP_Id;
configDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->defaultDownlinkBWP_Id));
*configDedicated->defaultDownlinkBWP_Id = 1;
// Uplink BWPs
int n_ul_bwp = 1;
int firstActiveUplinkBWP_Id = 1;
if (configuration->num_additional_bwps > 0) {
n_ul_bwp = configuration->num_additional_bwps;
firstActiveUplinkBWP_Id = configuration->first_active_bwp;
}
if (n_ul_bwp > 0) {
ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList));
for (int bwp_loop = 0; bwp_loop < n_ul_bwp; bwp_loop++) {
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(bwp_loop, false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap);
asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp);
}
ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id));
*ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id;
}
ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList));
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap);
asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp);
ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id));
*ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id;
configDedicated->bwp_InactivityTimer = NULL;
configDedicated->downlinkBWP_ToReleaseList = NULL;
+7 -7
View File
@@ -124,13 +124,13 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId,
NR_RLC_Config_PR rlc_conf,
long priority,
const nr_rlc_configuration_t *default_rlc_config);
NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig,
const nr_mac_config_t *configuration,
const NR_UE_NR_Capability_t *uecap,
const NR_ServingCellConfigCommon_t *scc,
int uid,
int old_bwp,
int new_bwp);
NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig,
const nr_mac_config_t *configuration,
const NR_UE_NR_Capability_t *uecap,
const NR_ServingCellConfigCommon_t *scc,
int uid,
int old_bwp,
int new_bwp);
NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len);
measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime);
int encode_measgap_config(const measgap_config_t *c, uint8_t *buf);