From 799d0b3ab51b64fc77c5e6845d6fdf63c04244de Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 9 Mar 2023 14:01:33 +0100 Subject: [PATCH] reworking response to MSG3 with DCCH/DTCH --- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair2/LAYER2/NR_MAC_gNB/config.c | 2 - openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 652 +++++++++++------- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 31 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 18 +- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 8 +- 7 files changed, 440 insertions(+), 279 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index ed171523de..c1276c68b0 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -799,7 +799,7 @@ int main(int argc, char **argv) N_RB_DL = gNB->frame_parms.N_RB_DL; NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0]; - configure_UE_BWP(RC.nrmac[0], scc, &UE_info->UE_sched_ctrl, NULL, UE_info); + configure_UE_BWP(RC.nrmac[0], scc, &UE_info->UE_sched_ctrl, NULL, UE_info, -1, -1); // stub to configure frame_parms // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 08a3f291fb..5ed4df95c4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -547,7 +547,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, RC.nrmac[Mod_idP]->sib1_tda = sib1_tda; for (int n=0;nra[n].cfra = false; - cc->ra[n].msg3_dcch_dtch = false; cc->ra[n].rnti = 0; cc->ra[n].preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES; cc->ra[n].preambles.preamble_list = (uint8_t *) malloc(MAX_NUM_NR_PRACH_PREAMBLES*sizeof(uint8_t)); @@ -613,7 +612,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++) ra->preambles.preamble_list[i] = i; } - ra->msg3_dcch_dtch = false; LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti); } else { // CellGroup has been updated NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info, rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 06d58bae57..7a2ec89ead 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -571,7 +571,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); // Configure RA BWP - configure_UE_BWP(nr_mac, scc, NULL, ra, NULL); + configure_UE_BWP(nr_mac, scc, NULL, ra, NULL, -1, -1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); @@ -680,6 +680,8 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { case Msg3_retransmission: nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra); break; + case Msg3_dcch_dtch: + nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra); case Msg4: nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra); break; @@ -1400,8 +1402,374 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } } -void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { +void prepare_dl_pdus(gNB_MAC_INST *nr_mac, + NR_RA_t *ra, + NR_UE_DL_BWP_t *dl_bwp, + nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch_t *pucch, + NR_pdsch_dmrs_t dmrs_info, + NR_tda_info_t tda, + int aggregation_level, + int CCEIndex, + int tb_size, int ndi, + int tpc, int delta_PRI, + int current_harq_pid, + int time_domain_assignment, + int CC_id, int rnti, int round, + int mcsIndex, int tb_scaling, + int pduindex, int rbStart, int rbSize) +{ + // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially + // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them + NR_ControlResourceSet_t *coreset = ra->coreset; + const int coresetid = coreset->controlResourceSetId; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; + if (!pdcch_pdu_rel15) { + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + dl_req->nPDUs += 1; + pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); + nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; + } + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + dl_req->nPDUs+=1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + + long BWPStart = 0; + long BWPSize = 0; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; + NR_SearchSpace_t *ss = ra->ra_ss; + if(*ss->controlResourceSetId!=0) { + BWPStart = dl_bwp->BWPStart; + BWPSize = dl_bwp->BWPSize; + } else { + type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; + BWPStart = type0_PDCCH_CSS_config->cset_start_rb; + BWPSize = type0_PDCCH_CSS_config->num_rbs; + } + + int mcsTableIdx = dl_bwp->mcsTableIdx; + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = rnti; + pdsch_pdu_rel15->pduIndex = pduindex; + pdsch_pdu_rel15->BWPSize = BWPSize; + pdsch_pdu_rel15->BWPStart = BWPStart; + pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + int R = nr_get_code_rate_dl(mcsIndex,mcsTableIdx); + pdsch_pdu_rel15->targetCodeRate[0] = R; + int Qm = nr_get_Qm_dl(mcsIndex, mcsTableIdx); + pdsch_pdu_rel15->qamModOrder[0] = Qm; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[round % 4]; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; + pdsch_pdu_rel15->dmrsConfigType = dmrs_info.dmrsConfigType; + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = dmrs_info.numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; + pdsch_pdu_rel15->VRBtoPRBMapping = 0; + pdsch_pdu_rel15->StartSymbolIndex = tda.startSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = tda.nrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = dmrs_info.dl_dmrs_symb_pos; + + int x_Overhead = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); + + int bw_tbslbrm = get_dlbw_tbslbrm(dl_bwp->initial_BWPSize, ra->CellGroup); + pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, + bw_tbslbrm, + 1); + pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(tb_size<<3,R); + + pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1; + pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275; + pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=1; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; + + /* Fill PDCCH DL DCI PDU */ + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; + pdcch_pdu_rel15->numDlDci++; + dci_pdu->RNTI = rnti; + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + dci_pdu->AggregationLevel = aggregation_level; + dci_pdu->CceIndex = CCEIndex; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + dci_pdu_rel15_t dci_payload; + dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart, + BWPSize); + + dci_payload.format_indicator = 1; + dci_payload.time_domain_assignment.val = time_domain_assignment; + dci_payload.vrb_to_prb_mapping.val = 0; + dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_payload.tb_scaling = tb_scaling; + dci_payload.rv = pdsch_pdu_rel15->rvIndex[0]; + dci_payload.harq_pid = current_harq_pid; + dci_payload.ndi = ndi; + dci_payload.dai[0].val = pucch ? (pucch->dai_c-1) & 3 : 0; + dci_payload.tpc = tpc; // TPC for PUCCH: table 7.2.1-1 in 38.213 + dci_payload.pucch_resource_indicator = delta_PRI; // This is delta_PRI from 9.2.1 in 38.213 + dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch ? pucch->timing_indicator : 0; + + LOG_D(NR_MAC, + "[RAPROC] DCI 1_0 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d pucchres %d harqtiming %d\n", + dci_payload.frequency_domain_assignment.val, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->BWPSize, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, + dci_payload.tb_scaling, + dci_payload.pucch_resource_indicator, + dci_payload.pdsch_to_harq_feedback_timing_indicator.val); + + LOG_D(NR_MAC, + "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d, BWPsize %d\n", + pdcch_pdu_rel15->dci_pdu[0].RNTI, + NR_RNTI_TC, + NR_DL_DCI_FORMAT_1_0, + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols, + pdsch_pdu_rel15->BWPSize); + + fill_dci_pdu_rel15(scc, + ra->CellGroup, + dl_bwp, + &ra->UL_BWP, + &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], + &dci_payload, + NR_DL_DCI_FORMAT_1_0, + NR_RNTI_TC, + dl_bwp->bwp_id, + ss, + coreset, + nr_mac->cset0_bwp_size); + + LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); + LOG_D(NR_MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart); + LOG_D(NR_MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing); + LOG_D(NR_MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix); + LOG_D(NR_MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex); + LOG_D(NR_MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols); + for(int n=0;n<6;n++) LOG_D(NR_MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]); + LOG_D(NR_MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType); + LOG_D(NR_MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize); + LOG_D(NR_MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize); + LOG_D(NR_MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType); + LOG_D(NR_MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); + LOG_D(NR_MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); + LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); +} + +void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) +{ + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + + // proceed only if it is a DL slot + if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) + return; + + // UE is known by the network, C-RNTI to be used instead of TC-RNTI + int rnti = ra->crnti; + + NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, rnti); + if (!UE) { + LOG_E(NR_MAC, "Received Msg3 with C-RNTI but rnti %04x not in the table\n", rnti); + return; + } + + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_SearchSpace_t *ss = ra->ra_ss; + + NR_ControlResourceSet_t *coreset = ra->coreset; + AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n"); + + // Only need to schedule DCI with and empty DL + NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; + long BWPStart = 0; + long BWPSize = 0; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; + if(*ss->controlResourceSetId!=0) { + BWPStart = dl_bwp->BWPStart; + BWPSize = dl_bwp->BWPSize; + } else { + type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; + BWPStart = type0_PDCCH_CSS_config->cset_start_rb; + BWPSize = type0_PDCCH_CSS_config->num_rbs; + } + + // get CCEindex, needed also for PUCCH and then later for PDCCH + uint8_t aggregation_level; + int CCEIndex = get_cce_index(nr_mac, + CC_id, slotP, 0, + &aggregation_level, + ss, + coreset, + &ra->sched_pdcch, + true); + + if (CCEIndex < 0) { + LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, rnti); + return; + } + + // Checking if the DCI allocation is feasible in current subframe + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { + LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti); + return; + } + + uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); + int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; + NR_tda_info_t tda = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, time_domain_assignment, + scc->dmrs_TypeA_Position, mux_pattern, NR_RNTI_C, coreset->controlResourceSetId, false); + + NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, + dl_bwp, + &tda, + 1); + + int subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT); + int pdu_length = subheader_len + 7; // 7 is contetion resolution length + + int mcsTableIdx = dl_bwp->mcsTableIdx; + int mcsIndex = 0; + int rbStart = 0; + int rbSize = 0; + int tb_scaling = 0; + uint32_t tb_size = 0; + + // increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size + do { + if(rbSize < BWPSize) + rbSize++; + else + mcsIndex++; + LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT); + tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), + nr_get_code_rate_dl(mcsIndex, mcsTableIdx), + rbSize, tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3; + } while (tb_size < pdu_length && mcsIndex<=28); + + AssertFatal(tb_size >= pdu_length,"Cannot allocate response to MSG3 with DCCH\n"); + + int i = 0; + uint16_t *vrb_map = cc[CC_id].vrb_map; + while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { + if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(tda.startSymbolIndex, tda.nrOfSymbols)) { + rbStart += i+1; + i = 0; + } else { + i++; + } + } + + if (rbStart > (BWPSize - rbSize)) { + LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, rnti); + return; + } + + // Remove UE associated to TC-RNTI + mac_remove_nr_ue(nr_mac, ra->rnti); + + + // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful if the UE receives a PDCCH transmission which has its CRC bits scrambled by the C-RNTI + // Just send padding LCID + uint8_t buf[tb_size]; + NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[0]; + padding->R = 0; + padding->LCID = DL_SCH_LCID_PADDING; + for(int k = 1; k < tb_size; k++) + buf[k] = 0; + + T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti), + T_INT(frameP), T_INT(slotP), T_INT(0), T_BUFFER(buf, tb_size)); + + // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control + // information to data and is reset every slot. + const int pduindex = nr_mac->pdu_index[CC_id]++; + + prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, NULL, dmrs_info, tda, aggregation_level, CCEIndex, tb_size, 0, 0, 0, + 0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize); + + // DL TX request + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size); + tx_req->PDU_length = tb_size; + tx_req->PDU_index = pduindex; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = tb_size + 2; + nr_mac->TX_req[CC_id].SFN = frameP; + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].Slot = slotP; + + // Mark the corresponding symbols and RBs as used + fill_pdcch_vrb_map(nr_mac, + CC_id, + &ra->sched_pdcch, + CCEIndex, + aggregation_level); + for (int rb = 0; rb < rbSize; rb++) + vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(tda.startSymbolIndex, tda.nrOfSymbols); + + + // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH + LOG_A(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti); + nr_clear_ra_proc(module_idP, CC_id, frameP, ra); + UE->Msg4_ACKed = true; + UE->ra_timer = 0; + + if(!UE->CellGroup) { + // In the specific scenario where UE correctly received MSG4 (assuming it decoded RRCsetup with CellGroup) and gNB didn't correctly received an ACK, + // the UE would already have CG but the UE-dedicated gNB structure wouldn't (because RA didn't complete on gNB side). + uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, //might be added prefix later + (void **)&UE->CellGroup, + (uint8_t *)UE->cg_buf, + (UE->enc_rval.encoded+7)/8, 0, 0); + } + + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + process_CellGroup(UE->CellGroup, sched_ctrl); + // switching to initial BWP + configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, 0, 0); + + // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE + sched_ctrl->pusch_consecutive_dtx_cnt = 0; + sched_ctrl->ul_failure = 0; +} + +void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) +{ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; @@ -1418,12 +1786,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra uint16_t mac_sdu_length = 0; - // If UE is known by the network, C-RNTI to be used instead of TC-RNTI - rnti_t tc_rnti = ra->rnti; - if (ra->msg3_dcch_dtch) { - ra->rnti = ra->crnti; - } - NR_UE_info_t *UE = find_nr_UE(&nr_mac->UE_info, ra->rnti); if (!UE) { LOG_E(NR_MAC, "want to generate Msg4, but rnti %04x not in the table\n", ra->rnti); @@ -1435,7 +1797,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra int current_harq_pid = sched_ctrl->retrans_dl_harq.head; logical_chan_id_t lcid = DL_SCH_LCID_CCCH; - if (ra->msg3_dcch_dtch == false && current_harq_pid < 0) { + if (current_harq_pid < 0) { // Check for data on SRB0 (RRCSetup) mac_rlc_status_resp_t srb_status = mac_rlc_status_ind(module_idP, ra->rnti, module_idP, frameP, slotP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0, 0); @@ -1543,7 +1905,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra return; } - const int delta_PRI=0; + const int delta_PRI = 0; int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); @@ -1569,11 +1931,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra harq->is_waiting = true; ra->harq_pid = current_harq_pid; - // Remove UE associated to TC-RNTI - if(harq->round==0 && ra->msg3_dcch_dtch) { - mac_remove_nr_ue(nr_mac, tc_rnti); - } - NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; harq->feedback_slot = pucch->ul_slot; harq->feedback_frame = pucch->frame; @@ -1582,187 +1939,45 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra uint8_t *buf = (uint8_t *) harq->transportBlock; // Bytes to be transmitted if (harq->round == 0) { - if (ra->msg3_dcch_dtch) { - // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful if the UE receives a PDCCH transmission which has its CRC bits scrambled by the C-RNTI - // Just send padding LCID - ra->mac_pdu_length = 0; + // UE Contention Resolution Identity MAC CE + uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id); + LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length); + uint8_t buffer[CCCH_SDU_SIZE]; + uint8_t mac_subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT); + // Get RLC data on the SRB (RRCSetup, RRCReestablishment) + mac_sdu_length = mac_rlc_data_req(module_idP, + ra->rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + CCCH_SDU_SIZE, + (char *)buffer, + 0, + 0); + + if (mac_sdu_length < 256) { + ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->R = 0; + ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->F = 0; + ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->LCID = lcid; + ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->L = mac_sdu_length; + ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT); } else { - // UE Contention Resolution Identity MAC CE - uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id); - LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length); - uint8_t buffer[CCCH_SDU_SIZE]; - uint8_t mac_subheader_len = sizeof(NR_MAC_SUBHEADER_SHORT); - // Get RLC data on the SRB (RRCSetup, RRCReestablishment) - mac_sdu_length = mac_rlc_data_req(module_idP, - ra->rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - CCCH_SDU_SIZE, - (char *)buffer, - 0, - 0); - - if (mac_sdu_length < 256) { - ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->R = 0; - ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->F = 0; - ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->LCID = lcid; - ((NR_MAC_SUBHEADER_SHORT *)&buf[mac_pdu_length])->L = mac_sdu_length; - ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT); - } else { - mac_subheader_len = sizeof(NR_MAC_SUBHEADER_LONG); - ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->R = 0; - ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->F = 1; - ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->LCID = lcid; - ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->L = htons(mac_sdu_length); - ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_LONG); - } - LOG_I(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, mac_subheader_len, ra->mac_pdu_length); - memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length); + mac_subheader_len = sizeof(NR_MAC_SUBHEADER_LONG); + ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->R = 0; + ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->F = 1; + ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->LCID = lcid; + ((NR_MAC_SUBHEADER_LONG *)&buf[mac_pdu_length])->L = htons(mac_sdu_length); + ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_LONG); } + LOG_I(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, mac_subheader_len, ra->mac_pdu_length); + memcpy(&buf[mac_pdu_length + mac_subheader_len], buffer, mac_sdu_length); } - // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially - // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them - const int coresetid = coreset->controlResourceSetId; - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; - if (!pdcch_pdu_rel15) { - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - dl_req->nPDUs += 1; - pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); - nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; - } - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - dl_req->nPDUs+=1; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - - LOG_A(NR_MAC, "[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); - - // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control - // information to data and is reset every slot. const int pduindex = nr_mac->pdu_index[CC_id]++; - - pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = ra->rnti; - pdsch_pdu_rel15->pduIndex = pduindex; - pdsch_pdu_rel15->BWPSize = BWPSize; - pdsch_pdu_rel15->BWPStart = BWPStart; - pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; - pdsch_pdu_rel15->CyclicPrefix = 0; - pdsch_pdu_rel15->NrOfCodewords = 1; - int R = nr_get_code_rate_dl(mcsIndex,mcsTableIdx); - pdsch_pdu_rel15->targetCodeRate[0] = R; - int Qm = nr_get_Qm_dl(mcsIndex, mcsTableIdx); - pdsch_pdu_rel15->qamModOrder[0] = Qm; - pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; - pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round%4]; - pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; - pdsch_pdu_rel15->nrOfLayers = 1; - pdsch_pdu_rel15->transmissionScheme = 0; - pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = dmrs_info.dmrsConfigType; - pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; - pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = dmrs_info.numDmrsCdmGrpsNoData; - pdsch_pdu_rel15->dmrsPorts = 1; - pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = rbStart; - pdsch_pdu_rel15->rbSize = rbSize; - pdsch_pdu_rel15->VRBtoPRBMapping = 0; - pdsch_pdu_rel15->StartSymbolIndex = msg4_tda.startSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = msg4_tda.nrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = dmrs_info.dl_dmrs_symb_pos; - - int x_Overhead = 0; - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); - - int bw_tbslbrm = get_dlbw_tbslbrm(dl_bwp->initial_BWPSize, ra->CellGroup); - pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, - bw_tbslbrm, - 1); - pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(harq->tb_size<<3,R); - - pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1; - pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275; - pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=1; - pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; - pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; - - /* Fill PDCCH DL DCI PDU */ - nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; - pdcch_pdu_rel15->numDlDci++; - dci_pdu->RNTI = ra->rnti; - dci_pdu->ScramblingId = *scc->physCellId; - dci_pdu->ScramblingRNTI = 0; - dci_pdu->AggregationLevel = aggregation_level; - dci_pdu->CceIndex = CCEIndex; - dci_pdu->beta_PDCCH_1_0 = 0; - dci_pdu->powerControlOffsetSS = 1; - - dci_pdu_rel15_t dci_payload; - dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart, - BWPSize); - - dci_payload.format_indicator = 1; - dci_payload.time_domain_assignment.val = time_domain_assignment; - dci_payload.vrb_to_prb_mapping.val = 0; - dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; - dci_payload.tb_scaling = tb_scaling; - dci_payload.rv = pdsch_pdu_rel15->rvIndex[0]; - dci_payload.harq_pid = current_harq_pid; - dci_payload.ndi = harq->ndi; - dci_payload.dai[0].val = (pucch->dai_c-1)&3; - dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213 - dci_payload.pucch_resource_indicator = delta_PRI; // This is delta_PRI from 9.2.1 in 38.213 - dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; - - LOG_D(NR_MAC, - "[RAPROC] DCI 1_0 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d pucchres %d harqtiming %d\n", - dci_payload.frequency_domain_assignment.val, - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->BWPSize, - dci_payload.time_domain_assignment.val, - dci_payload.vrb_to_prb_mapping.val, - dci_payload.mcs, - dci_payload.tb_scaling, - dci_payload.pucch_resource_indicator, - dci_payload.pdsch_to_harq_feedback_timing_indicator.val); - - LOG_D(NR_MAC, - "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d, BWPsize %d\n", - pdcch_pdu_rel15->dci_pdu[0].RNTI, - NR_RNTI_TC, - NR_DL_DCI_FORMAT_1_0, - (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, - pdcch_pdu_rel15->StartSymbolIndex, - pdcch_pdu_rel15->DurationSymbols, - pdsch_pdu_rel15->BWPSize); - - fill_dci_pdu_rel15(scc, - ra->CellGroup, - dl_bwp, - &ra->UL_BWP, - &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], - &dci_payload, - NR_DL_DCI_FORMAT_1_0, - NR_RNTI_TC, - dl_bwp->bwp_id, - ss, - coreset, - nr_mac->cset0_bwp_size); + prepare_dl_pdus(nr_mac, ra, dl_bwp, dl_req, pucch, dmrs_info, msg4_tda, aggregation_level, CCEIndex, tb_size, harq->ndi, sched_ctrl->tpc1, delta_PRI, + current_harq_pid, time_domain_assignment, CC_id, ra->rnti, harq->round, mcsIndex, tb_scaling, pduindex, rbStart, rbSize); // Add padding header and zero rest out if there is space left if (ra->mac_pdu_length < harq->tb_size) { @@ -1794,58 +2009,12 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra &ra->sched_pdcch, CCEIndex, aggregation_level); - for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) { - vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); + for (int rb = 0; rb < rbSize; rb++) { + vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } - LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); - LOG_D(NR_MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart); - LOG_D(NR_MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing); - LOG_D(NR_MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix); - LOG_D(NR_MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex); - LOG_D(NR_MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols); - for(int n=0;n<6;n++) LOG_D(NR_MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]); - LOG_D(NR_MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType); - LOG_D(NR_MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize); - LOG_D(NR_MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize); - LOG_D(NR_MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType); - LOG_D(NR_MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); - LOG_D(NR_MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); - LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); - - if(ra->msg3_dcch_dtch) { - // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH - LOG_A(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti); - nr_clear_ra_proc(module_idP, CC_id, frameP, ra); - UE->Msg3_dcch_dtch = true; - UE->Msg4_ACKed = true; - UE->ra_timer = 0; - - remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - harq->feedback_slot = -1; - harq->is_waiting = false; - add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); - harq->round = 0; - harq->ndi ^= 1; - - if(!UE->CellGroup) - // In the specific scenario where UE correctly received MSG4 (assuming it decoded RRCsetup with CellGroup) and gNB didn't correctly received an ACK, - // the UE would already have CG but the UE-dedicated gNB structure wouldn't (because RA didn't complete on gNB side). - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&UE->CellGroup, - (uint8_t *)UE->cg_buf, - (UE->enc_rval.encoded+7)/8, 0, 0); - process_CellGroup(UE->CellGroup, sched_ctrl); - configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE); - - // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE - UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0; - UE->UE_sched_ctrl.ul_failure = 0; - } else { - ra->state = WAIT_Msg4_ACK; - LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); - } + ra->state = WAIT_Msg4_ACK; + LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); } } @@ -1897,7 +2066,6 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t ra->timing_offset = 0; ra->RRC_timer = 20; ra->msg3_round = 0; - ra->msg3_dcch_dtch = false; ra->crnti = 0; if(ra->cfra == false) { ra->rnti = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index fea0531bee..251566f64b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2021,8 +2021,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, NR_UE_sched_ctrl_t *sched_ctrl, NR_RA_t *ra, - NR_UE_info_t *UE) { - + NR_UE_info_t *UE, + int dl_bwp_switch, + int ul_bwp_switch) +{ AssertFatal((ra != NULL && UE == NULL) || (ra == NULL && UE != NULL), "RA and UE structures are mutually exlusive in BWP configuration\n"); NR_CellGroupConfig_t *CellGroup; @@ -2067,23 +2069,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - if(UE && UE->Msg3_dcch_dtch) { - // switching to initial BWP - DL_BWP->bwp_id = 0; - UL_BWP->bwp_id = 0; - UE->Msg3_dcch_dtch = false; - - // Schedule BWP switching to the first active BWP (previous active BWP before RA with Msg3 carrying DCCH or DTCH message) - if (servingCellConfig->firstActiveDownlinkBWP_Id) { - sched_ctrl->next_dl_bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id; - } else { - sched_ctrl->next_dl_bwp_id = 0; - } - if (servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) { - sched_ctrl->next_ul_bwp_id = *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; - } else { - sched_ctrl->next_ul_bwp_id = 0; - } + if(dl_bwp_switch >= 0 && ul_bwp_switch >= 0) { + 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; } else { // (re)configuring BWP @@ -2335,7 +2324,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf memset(dl_bwp, 0, sizeof(*dl_bwp)); NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; memset(ul_bwp, 0, sizeof(*ul_bwp)); - configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE); + configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, -1, -1); /* set illegal time domain allocation to force recomputation of all fields */ sched_ctrl->sched_pdsch.time_domain_allocation = -1; @@ -2811,7 +2800,7 @@ void nr_mac_update_timers(module_id_t module_id, process_CellGroup(cg,&UE->UE_sched_ctrl); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - configure_UE_BWP(RC.nrmac[module_id], scc, sched_ctrl, NULL, UE); + configure_UE_BWP(RC.nrmac[module_id], scc, sched_ctrl, NULL, UE, -1, -1); if (get_softmodem_params()->sa) { // add all available DL HARQ processes for this UE in SA diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 25089b2edf..3a75c03f28 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -227,7 +227,7 @@ int nr_process_mac_pdu(instance_t module_idP, NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) { ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); - ra->msg3_dcch_dtch = true; + ra->state = Msg3_dcch_dtch; LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti); break; } @@ -755,9 +755,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, // harq_pid set a non valid value because it is not used in this call // the function is only called to decode the contention resolution sub-header if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) { - ra->state = Msg4; - if (ra->msg3_dcch_dtch) { + if (ra->state == Msg3_dcch_dtch) { // Check if the UE identified by C-RNTI still exists at the gNB NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->crnti); if (!UE_C) { @@ -775,13 +774,18 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, reset_dl_harq_list(&UE_C->UE_sched_ctrl); reset_ul_harq_list(&UE_C->UE_sched_ctrl); } + LOG_I(NR_MAC, "Activating scheduling response to MSG3 with DCCH/DTCCH and RNTI 0x%04x (state %d)\n", + ra->crnti, ra->state); + } + else { + LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %d)\n", + ra->rnti, ra->state); + ra->state = Msg4; } - LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %d)\n", - (ra->msg3_dcch_dtch?ra->crnti:ra->rnti), ra->state); } else { - nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); } } return; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index ff74e34c4a..f5b4428a50 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -343,7 +343,9 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, NR_UE_sched_ctrl_t *sched_ctrl, NR_RA_t *ra, - NR_UE_info_t *UE); + NR_UE_info_t *UE, + int dl_bwp_switch, + int ul_bwp_switch); NR_UE_info_t* add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup); @@ -371,6 +373,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra); +void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); + int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index b4fa43c40f..521833add0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -94,8 +94,9 @@ typedef enum { Msg2 = 1, WAIT_Msg3 = 2, Msg3_retransmission = 3, - Msg4 = 4, - WAIT_Msg4_ACK = 5 + Msg3_dcch_dtch = 4, + Msg4 = 5, + WAIT_Msg4_ACK = 6 } RA_gNB_state_t; typedef struct NR_preamble_ue { @@ -163,8 +164,6 @@ typedef struct { uint8_t msg3_cqireq; /// Round of Msg3 HARQ uint8_t msg3_round; - /// Flag to indicate if Msg3 carries a DCCH or DTCH message - bool msg3_dcch_dtch; int msg3_startsymb; int msg3_nrsymb; /// TBS used for Msg4 @@ -659,7 +658,6 @@ typedef struct { asn_enc_rval_t enc_rval; // UE selected beam index uint8_t UE_beam_index; - bool Msg3_dcch_dtch; bool Msg4_ACKed; uint32_t ra_timer; float ul_thr_ue;