+ /*[Step 1]: rbgIndex to locate in FreqDomainResource parmaeter in
+ * SearchSpace*/
+ rbgIndex = cceIndex / (pdcchInfo->cRSetRef->duration);
+
+ /*Extract StartPRB for that RBGIndex*/
+ startPrb = extractStartPrbForRBG(pdcchInfo->cRSetRef->freqDomainRsrc, rbgIndex);
+ if(startPrb == MAX_NUM_RB)
+ {
+ DU_LOG("\nERROR --> SCH: No RBG is allocated for PDCCH in this Coreset");
+ return false;
+ }
+ /*[Step 2]: Adjust StartPrb based on CCEIndex and duration*/
+ startPrb = startPrb + ((cceIndex % pdcchInfo->cRSetRef->duration) * (pdcchInfo->nrOfPRBPerCce));
+ startSymbol = findSsStartSymbol(pdcchInfo->ssRef->mSymbolsWithinSlot);
+
+ /*numPrb will also get adjusted with duration*/
+ numPrb = (NUM_PRBS_PER_RBG * aggLvl) / pdcchInfo->cRSetRef->duration;
+ DU_LOG("\nDEBUG --> SCH: RBG found for cceIndex:%d, AggLvl:%d and SymbolDuration%d with StartPrb:%d, numPrb:%d",\
+ cceIndex, aggLvl, pdcchInfo->cRSetRef->duration, startPrb, numPrb);
+
+ ret = allocatePrbDl(cellCb, slotTime, startSymbol,\
+ pdcchInfo->cRSetRef->duration, &startPrb, numPrb);
+
+ if(ret == RFAILED)
+ {
+ DU_LOG("\nERROR --> SCH: PRBs can't be allocated as they are unavailable");
+ return false;
+ }
+ return true;
+
+}
+
+/*
+ * @brief: Function to select particular UE based on validation of PDCCH allocation
+ *
+ * Function:
+ * This function will have multiple layers of validation for PDCCH allocation
+ * based on CORESET and SearchSpace configuration and availability.
+ *
+ * [Step 1]: Check if the slot is pdcch Slot or not based on SearchSpace's
+ * monitoringSlotInfo.
+ * [Step 2]: Check the CQI for this UE and decide upon which Agg Level has to
+ * be used for this PDCCH transmission
+ * [Step 3]: find the AggLevel for this CQI = base aggregation level
+ * [Step 4]: NextLowerAggLvl will be the next lower aggLevel when PDCCH
+ * allocation fails for base agg Level.
+ * [Step 5]: For each candidate , calculate the CCE Index as per TS
+ * 38.213v15, Sec 10.1 and also check PRBs falling in that CCEIndex is free.
+ * [Step 6]: If Step 5 fails, move to next candidate and if Candidate gets
+ * exhausted then fallback to nextAggLevel. Because as we decrease aggLevel,
+ * numberOfCCEReq decreases so chances of PDCCH allocation increases even
+ * though lowerAggLevel will not guarantee transmission of PDCCH as per CQI
+ * reported.(CQI less, AggiLvlRequried is More)
+ *
+ * @params[IN]: SchUeCb and PdcchTime
+ * [RETURN]: isPDCCHAllocted flag(true = UE can be selected as a
+ * candidate )
+ * */
+bool schDlCandidateSelection(SchUeCb *ueCb, SlotTimingInfo pdcchTime)
+{
+ uint8_t cRSetIdx = 0, cceIndex = 0;
+ uint8_t cqi = 0, candIdx = 0;
+ uint8_t baseAggLvl = 0, nextLowerAggLvl = 0, numCandidates = 0;
+ SchPdcchInfo *pdcchInfo = NULLP;
+ uint32_t a = 0, b = 0;
+
+ for(cRSetIdx = 0; cRSetIdx < MAX_NUM_CRSET; cRSetIdx++)
+ {
+ pdcchInfo = &ueCb->pdcchInfo[cRSetIdx];
+ if(pdcchInfo->cRSetRef == NULLP)
+ {
+ DU_LOG("\nINFO --> SCH: Coreset is not availabe at Index:%d",cRSetIdx);
+ continue;
+ }
+ /*[Step 1]:*/
+ if(false == schPdcchSlotValidation(pdcchTime, pdcchInfo->ssRef, ueCb->cellCb->numSlots))
+ {
+ DU_LOG("\nINFO --> SCH: This slot is not valid for PDCCH in this CORESET:%d.",pdcchInfo->cRSetRef->cRSetId);
+ break;
+ }
+ /*[Step 2]:*/
+ /*TODO: CQI is reported in DL_CQI_IND which has to be processed and
+ * report has to be stored in ueCb.For now, HardCoding the value*/
+ cqi = 5;
+
+ /*[Step 3]: */
+ baseAggLvl = pdcchInfo->cqiIndxAggLvlMap[cqi];
+
+ /*[Step 4]:*/
+ nextLowerAggLvl = baseAggLvl;
+
+ /*Loop to traverse through each AggLvl from higher value of aggLevel to
+ * 1 AggLvl*/
+ do
+ {
+ /*Configured num of candidates for each Agg Level in search space */
+ numCandidates = extractNumOfCandForAggLvl(pdcchInfo->ssRef, nextLowerAggLvl);
+ if(!numCandidates)
+ {
+ DU_LOG("\nINFO --> SCH: Num Of Candidates configured for this AggLvel:%d is ZERO",baseAggLvl);
+ }
+
+ /*[Step 5]:*/
+ for(candIdx= 0; candIdx < numCandidates; candIdx++)
+ {
+ /*Formula reference 3GPP TS 38.213v15, Sec 10.1, Variable 'a' and
+ * 'b' is used for segmenting the formulat for readability purpose
+ * */
+ a = pdcchInfo->y[pdcchTime.slot] + \
+ ceil((candIdx * pdcchInfo->totalCceCount)/(baseAggLvl * numCandidates));
+ b = ceil(pdcchInfo->totalCceCount * baseAggLvl);
+ cceIndex = baseAggLvl * (a % b);
+ if(schCheckPdcchAvail(ueCb->cellCb, pdcchTime, cceIndex, pdcchInfo,nextLowerAggLvl) == true)
+ {
+ DU_LOG("\nINFO --> SCH: PDCCH allocation is successful at cceIndex:%d",cceIndex);
+ return true;
+ }
+ }
+ nextLowerAggLvl = nextLowerAggLvl >> 1;
+ }while(nextLowerAggLvl > 0 && nextLowerAggLvl <= 16);
+ }
+ return false;
+}