diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index dd138e5265..85d9a641fa 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1536,12 +1536,6 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, corr32_im[symb][group][aa]+((int16_t*)(&prod_im[aa]))[0]); #endif - LOG_D(PHY,"pucch2 cw %d group %d aa %d: (%d,%d)+(%d,%d) = (%d,%d)\n",cw,group,aa, - corr32_re[symb][group][aa],corr32_im[symb][group][aa], - ((int16_t*)(&prod_re[aa]))[0], - ((int16_t*)(&prod_im[aa]))[0], - corr32_re[symb][group][aa]+((int16_t*)(&prod_re[aa]))[0], - corr32_im[symb][group][aa]+((int16_t*)(&prod_im[aa]))[0]); corr_re = ( corr32_re[symb][group][aa]+((int16_t*)(&prod_re[aa]))[0]); corr_im = ( corr32_im[symb][group][aa]+((int16_t*)(&prod_im[aa]))[0]); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 94bb084f89..253b85cfce 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -4427,7 +4427,7 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *ty } -void find_period_offest_SR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset) { +void find_period_offset_SR(const NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset) { NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR P_O = SchedulingReqRec->periodicityAndOffset->present; switch (P_O){ case NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl1: diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 9a8750ae51..e3ad29b43f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -221,7 +221,7 @@ uint16_t compute_pucch_prb_size(uint8_t format, int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH); -void find_period_offest_SR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset); +void find_period_offset_SR(const NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset); void csi_period_offset(NR_CSI_ReportConfig_t *csirep, struct NR_CSI_ResourcePeriodicityAndOffset *periodicityAndOffset, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 161cdb7079..963a8d4b2f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2388,7 +2388,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id]; int SR_period; int SR_offset; - find_period_offest_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); + find_period_offset_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); int sfn_sf = frame * n_slots_frame + slot; if ((sfn_sf - SR_offset) % SR_period == 0) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 7155a633ee..6f9011e6ed 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1469,7 +1469,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI); - int alloc = nr_acknack_scheduling(module_idP, UE, frameP, slotP, r_pucch, 1); + int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); if (alloc<0) { LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n",frameP,slotP); return; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 3215ab1764..adba522db9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -508,7 +508,7 @@ bool allocate_dl_retransmission(module_id_t module_id, * allocation after CCE alloc fail would be more complex) */ int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0); + const int alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, r_pucch, 0); if (alloc<0) { LOG_D(MAC, "could not find PUCCH for UE %04x@%d.%d\n", @@ -701,7 +701,7 @@ void pf_dl(module_id_t module_id, * allocation after CCE alloc fail would be more complex) */ int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(module_id, iterator->UE, frame, slot, r_pucch, 0); + const int alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, r_pucch, 0); if (alloc<0) { LOG_D(NR_MAC, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 5136c7fc53..6238016cb3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -277,7 +277,7 @@ void nr_preprocessor_phytest(module_id_t module_id, UE->rnti); int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0); + const int alloc = nr_acknack_scheduling(RC.nrmac[module_id], UE, frame, slot, r_pucch, 0); if (alloc < 0) { LOG_D(MAC, "%s(): could not find PUCCH for UE %04x@%d.%d\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 36ba747e72..db4649008c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2210,6 +2210,20 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca } } + +void set_max_fb_time(NR_UE_UL_BWP_t *UL_BWP, const NR_UE_DL_BWP_t *DL_BWP) +{ + UL_BWP->max_fb_time = 8; // default value + // take the maximum in dl_DataToUL_ACK list + if (DL_BWP->dci_format != NR_DL_DCI_FORMAT_1_0 && UL_BWP->pucch_Config) { + const struct NR_PUCCH_Config__dl_DataToUL_ACK *fb_times = UL_BWP->pucch_Config->dl_DataToUL_ACK; + for (int i = 0; i < fb_times->list.count; i++) { + if(*fb_times->list.array[i] > UL_BWP->max_fb_time) + UL_BWP->max_fb_time = *fb_times->list.array[i]; + } + } +} + // main function to configure parameters of current BWP void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, @@ -2410,17 +2424,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, if (UL_BWP->csi_MeasConfig) compute_csi_bitlen (UL_BWP->csi_MeasConfig, UE->csi_report_template); - UL_BWP->max_fb_time = 0; - if(DL_BWP->dci_format != NR_DL_DCI_FORMAT_1_0 && - UL_BWP->pucch_Config) { - for (int i=0; ipucch_Config->dl_DataToUL_ACK->list.count; i++) { - if(*UL_BWP->pucch_Config->dl_DataToUL_ACK->list.array[i] > UL_BWP->max_fb_time) - UL_BWP->max_fb_time = *UL_BWP->pucch_Config->dl_DataToUL_ACK->list.array[i]; - } - } - else - UL_BWP->max_fb_time = 8; // default value - + set_max_fb_time(UL_BWP, DL_BWP); set_sched_pucch_list(sched_ctrl, UL_BWP, scc); } @@ -2567,21 +2571,19 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf } void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl, - NR_UE_UL_BWP_t *ul_bwp, - NR_ServingCellConfigCommon_t *scc) { + const NR_UE_UL_BWP_t *ul_bwp, + const NR_ServingCellConfigCommon_t *scc) { const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; + // PUCCH list size is given by the number of UL slots in the PUCCH period + // the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead const int list_size = n_ul_slots_period << (ul_bwp->max_fb_time/nr_slots_period); if(!sched_ctrl->sched_pucch) { - sched_ctrl->sched_pucch = malloc(list_size * sizeof(*sched_ctrl->sched_pucch)); + sched_ctrl->sched_pucch = calloc(list_size, sizeof(*sched_ctrl->sched_pucch)); sched_ctrl->sched_pucch_size = list_size; - for(int i=0; isched_pucch[i]; - memset(curr_pucch, 0, sizeof(*curr_pucch)); - } } else if (list_size > sched_ctrl->sched_pucch_size) { sched_ctrl->sched_pucch = realloc(sched_ctrl->sched_pucch, list_size * sizeof(*sched_ctrl->sched_pucch)); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index f718c6703c..b9373c85cb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -131,6 +131,20 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = { }; +int get_pucch_index(int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size) +{ + // PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots + // this functions return the index to the structure for slot passed to the function + const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; + const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; + const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; + // ((slot % nr_slots_period) - first_ul_slot_period) gives the progressive number of the slot in a TDD period + // ((slot / nr_slots_period) * n_ul_slots_period) adds up the number of UL slots in the previous TDD periods + // the sum gives the index of current UL slot in the frame which is normalized wrt sched_pucch_size + return ((slot % nr_slots_period) - first_ul_slot_period + (slot / nr_slots_period) * n_ul_slots_period) % sched_pucch_size; + +} + void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP) @@ -140,20 +154,25 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, UE_iterator(nrmac->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - for (int i = 0; i < sched_ctrl->sched_pucch_size; i++) { - NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[i]; - const uint16_t O_ack = curr_pucch->dai_c; - const uint16_t O_csi = curr_pucch->csi_bits; - const uint8_t O_sr = curr_pucch->sr_flag; - if (curr_pucch->active == true && - frameP == curr_pucch->frame && - slotP == curr_pucch->ul_slot) { - LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n", - i,UE->rnti,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi); - nr_fill_nfapi_pucch(nrmac, frameP, slotP, curr_pucch, UE); - memset(curr_pucch, 0, sizeof(*curr_pucch)); - } - } + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; + const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[0].ServingCellConfigCommon; + const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n"); + const int pucch_index = get_pucch_index(slotP, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); + NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index]; + if (!curr_pucch->active) + continue; + DevAssert(frameP == curr_pucch->frame && slotP == curr_pucch->ul_slot); + + const uint16_t O_ack = curr_pucch->dai_c; + const uint16_t O_csi = curr_pucch->csi_bits; + const uint8_t O_sr = curr_pucch->sr_flag; + LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n", + pucch_index,UE->rnti,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi); + nr_fill_nfapi_pucch(nrmac, frameP, slotP, curr_pucch, UE); + memset(curr_pucch, 0, sizeof(*curr_pucch)); + } } @@ -207,10 +226,7 @@ void nr_csi_meas_reporting(int Mod_idP, const NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || RC.nrmac[Mod_idP]->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n"); - const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; - const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; - const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; - const int pucch_index = ((sched_slot % nr_slots_period) - first_ul_slot_period + (sched_slot / nr_slots_period) * n_ul_slots_period) % sched_ctrl->sched_pucch_size; + const int pucch_index = get_pucch_index(sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; AssertFatal(curr_pucch->active == false, "CSI structure is scheduled in advance. It should be free!\n"); curr_pucch->r_pucch = -1; @@ -995,17 +1011,12 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, } } -bool test_pucch0_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl, - NR_sched_pucch_t *pucch, - uint16_t *vrb_map_UL, - const NR_ServingCellConfigCommon_t *scc, - NR_PUCCH_Config_t *pucch_Config, - int r_pucch, - int bwp_start, - int bwp_size) { - - // We assume initial cyclic shift is always 0 so different pucch resources can't overlap - +void set_pucch_allocation(const NR_PUCCH_Config_t *pucch_Config, + const NR_ServingCellConfigCommon_t *scc, + const int r_pucch, + const int bwp_size, + NR_sched_pucch_t *pucch) +{ if(r_pucch<0){ const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[0]; DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); @@ -1024,6 +1035,14 @@ bool test_pucch0_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl, &pucch->nr_of_symb, &pucch->start_symb); } +} + +bool test_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, + uint16_t *vrb_map_UL, + const int bwp_start, + const int bwp_size) { + + // We assume initial cyclic shift is always 0 so different pucch resources can't overlap // verifying occupation of PRBs for ACK/NACK on dedicated pucch for (int l=0; lnr_of_symb; l++) { @@ -1041,9 +1060,24 @@ bool test_pucch0_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl, return true; } +void set_pucch0_vrb_occupation(const NR_sched_pucch_t *pucch, + uint16_t *vrb_map_UL, + const int bwp_start) +{ + for (int l=0; lnr_of_symb; l++) { + uint16_t symb = SL_to_bitmap(pucch->start_symb+l, 1); + int prb; + if (l==1 && pucch->second_hop_prb != 0) + prb = pucch->second_hop_prb; + else + prb = pucch->prb_start; + vrb_map_UL[bwp_start+prb] |= symb; + } +} + // this function returns an index to NR_sched_pucch structure // if the function returns -1 it was not possible to schedule acknack -int nr_acknack_scheduling(int mod_id, +int nr_acknack_scheduling(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t frame, sub_frame_t slot, @@ -1052,27 +1086,20 @@ int nr_acknack_scheduling(int mod_id, { const int CC_id = 0; - const int minfbtime = RC.nrmac[mod_id]->minRXTXTIMEpdsch; - const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[CC_id].ServingCellConfigCommon; + const int minfbtime = mac->minRXTXTIMEpdsch; + const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; - AssertFatal(tdd || RC.nrmac[mod_id]->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); + AssertFatal(tdd || mac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; - const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; - /* for the moment, we consider: - * * only pucch_sched[0] holds HARQ (and SR) - * * we do not multiplex with CSI, which is always in pucch_sched[2] - * * SR uses format 0 and is allocated in the first UL (mixed) slot (and not - * later) - * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */ NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; - int bwp_start = ul_bwp->BWPStart; - int bwp_size = ul_bwp->BWPSize; + const int bwp_start = ul_bwp->BWPStart; + const int bwp_size = ul_bwp->BWPSize; nr_dci_format_t dci_format = NR_DL_DCI_FORMAT_1_0; if(is_common == 0) @@ -1090,7 +1117,8 @@ int nr_acknack_scheduling(int mod_id, if(pucch_slot%nr_slots_period < first_ul_slot_period) continue; const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f]) / n_slots_frame)) & 1023; - const int pucch_index = ((pucch_slot % nr_slots_period) - first_ul_slot_period + (pucch_slot / nr_slots_period) * n_ul_slots_period) % sched_ctrl->sched_pucch_size; + // we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures + const int pucch_index = get_pucch_index(pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; if (curr_pucch->active && curr_pucch->frame == pucch_frame && @@ -1102,8 +1130,8 @@ int nr_acknack_scheduling(int mod_id, curr_pucch->dai_c == 2) continue; // if there is CSI but simultaneous HARQ+CSI is disable we can't schedule - if(!curr_pucch->simultaneous_harqcsi && - curr_pucch->csi_bits>0) + if(curr_pucch->csi_bits > 0 && + !curr_pucch->simultaneous_harqcsi) continue; // TODO we can't schedule more than 11 bits in PUCCH2 for now if (curr_pucch->csi_bits + curr_pucch->dai_c >= 10) @@ -1118,19 +1146,15 @@ int nr_acknack_scheduling(int mod_id, return pucch_index; // index of current PUCCH structure } else if (curr_pucch->active) { - LOG_E(NR_MAC, "This shouldn't happen! curr_pucch frame.slot %d.%d not matching with computed frame.slot %d.%d\n", - curr_pucch->frame, curr_pucch->ul_slot, pucch_frame, pucch_slot); - continue; + AssertFatal(1==0, "This shouldn't happen! curr_pucch frame.slot %d.%d not matching with computed frame.slot %d.%d\n", + curr_pucch->frame, curr_pucch->ul_slot, pucch_frame, pucch_slot); } else { // unoccupied occasion // checking if in ul_slot the resources potentially to be assigned to this PUCCH are available - uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch_slot * MAX_BWP_SIZE]; - bool ret = test_pucch0_vrb_occupation(sched_ctrl, - curr_pucch, + set_pucch_allocation(pucch_Config, scc, r_pucch, bwp_size, curr_pucch); + uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[pucch_slot * MAX_BWP_SIZE]; + bool ret = test_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, - scc, - pucch_Config, - r_pucch, bwp_start, bwp_size); if(!ret) { @@ -1151,13 +1175,7 @@ int nr_acknack_scheduling(int mod_id, frame,slot,curr_pucch->frame,curr_pucch->ul_slot,pucch_index,f,curr_pucch->dai_c); // blocking resources for current PUCCH in VRB map - for (int l=0; lnr_of_symb; l++) { - uint16_t symb = SL_to_bitmap(curr_pucch->start_symb+l, 1); - int prb = curr_pucch->prb_start; - if (l==1 && curr_pucch->second_hop_prb != 0) - prb = curr_pucch->second_hop_prb; - vrb_map_UL[bwp_start+prb] |= symb; - } + set_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, bwp_start); return pucch_index; // index of current PUCCH structure } @@ -1171,7 +1189,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) { if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot)) return; - int CC_id = 0; + const int CC_id = 0; UE_iterator(nrmac->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; @@ -1189,13 +1207,13 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) int SR_period; int SR_offset; - find_period_offest_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); + find_period_offset_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); // convert to int to avoid underflow of uint int sfn_sf = SFN * n_slots_frame + slot; LOG_D(NR_MAC,"SR_resource_id %d: SR_period %d, SR_offset %d\n",SR_resource_id,SR_period,SR_offset); if ((sfn_sf - SR_offset) % SR_period != 0) continue; - LOG_D(NR_MAC, "%4d.%2d Scheduling Request identified\n", SFN, slot); + LOG_D(NR_MAC, "%4d.%2d Scheduling Request UE %04x identified\n", SFN, slot, UE->rnti); NR_PUCCH_ResourceId_t *PucchResourceId = SchedulingRequestResourceConfig->resource; int idx = -1; @@ -1210,10 +1228,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || nrmac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); - const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; - const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; - const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; - const int pucch_index = ((slot % nr_slots_period) - first_ul_slot_period + (slot / nr_slots_period) * n_ul_slots_period) % sched_ctrl->sched_pucch_size; + const int pucch_index = get_pucch_index(slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; if (curr_pucch->active && @@ -1222,20 +1237,17 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) curr_pucch->resource_indicator == idx) curr_pucch->sr_flag = true; else if (curr_pucch->active) { - LOG_E(NR_MAC, "This shouldn't happen! curr_pucch frame.slot %d.%d not matching with SR function frame.slot %d.%d\n", - curr_pucch->frame, curr_pucch->ul_slot, SFN, slot); + AssertFatal(1==0, "This shouldn't happen! curr_pucch frame.slot %d.%d not matching with SR function frame.slot %d.%d\n", + curr_pucch->frame, curr_pucch->ul_slot, SFN, slot); continue; } else { uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[slot * MAX_BWP_SIZE]; - int bwp_start = ul_bwp->BWPStart; - int bwp_size = ul_bwp->BWPSize; - bool ret = test_pucch0_vrb_occupation(sched_ctrl, - curr_pucch, + const int bwp_start = ul_bwp->BWPStart; + const int bwp_size = ul_bwp->BWPSize; + set_pucch_allocation(pucch_Config, scc, -1, bwp_size, curr_pucch); + bool ret = test_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, - scc, - pucch_Config, - -1, bwp_start, bwp_size); if (!ret) { @@ -1248,15 +1260,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) curr_pucch->resource_indicator = idx; curr_pucch->r_pucch = -1; curr_pucch->active = true; - for (int l=0; lnr_of_symb; l++) { - uint16_t symb = SL_to_bitmap(curr_pucch->start_symb+l, 1); - int prb; - if (l==1 && curr_pucch->second_hop_prb != 0) - prb = curr_pucch->second_hop_prb; - else - prb = curr_pucch->prb_start; - vrb_map_UL[bwp_start+prb] |= symb; - } + set_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, bwp_start); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 2e3ccf4ba6..a322c4917b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -209,7 +209,7 @@ void nr_csi_meas_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); -int nr_acknack_scheduling(int Mod_idP, +int nr_acknack_scheduling(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t frameP, sub_frame_t slotP, @@ -466,8 +466,8 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx); uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format); void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl, - NR_UE_UL_BWP_t *ul_bwp, - NR_ServingCellConfigCommon_t *scc); + const NR_UE_UL_BWP_t *ul_bwp, + const NR_ServingCellConfigCommon_t *scc); const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 17f0504e15..b28fd0ffee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -563,8 +563,9 @@ typedef struct { int cce_index; uint8_t aggregation_level; - /// Array of PUCCH scheduling information. + /// Array of PUCCH scheduling information /// Its size depends on TDD configuration and max feedback time + /// There will be a structure for each UL slot in the active period determined by the size NR_sched_pucch_t *sched_pucch; int sched_pucch_size;