[Epic-ID: ODUHIGH-405][Task-ID: ODUHIGH-437] Establishing communication between Sourc...
[o-du/l2.git] / src / 5gnrsch / sch_slot_ind.c
index 52a3067..920562d 100644 (file)
@@ -112,6 +112,7 @@ void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue)
    ADD_DELTA_TO_TIME(slotInd, schSlotValue->broadcastTime, PHY_DELTA_DL + SCHED_DELTA);
    ADD_DELTA_TO_TIME(slotInd, schSlotValue->rarTime, PHY_DELTA_DL + SCHED_DELTA);
    ADD_DELTA_TO_TIME(slotInd, schSlotValue->dlMsgTime, PHY_DELTA_DL + SCHED_DELTA);
+   ADD_DELTA_TO_TIME(slotInd, schSlotValue->ulDciTime, PHY_DELTA_DL + SCHED_DELTA);
 }
 
 /*******************************************************************
@@ -187,6 +188,117 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime)
    return NO_TRANSMISSION;
 }
 
+/*******************************************************************
+ *
+ * @brief find correct combination of k0-k1 value
+ *
+ * @details
+ *
+ *    Function : findValidK0K1Value
+ *
+ *    Functionality:
+ *       find correct combination of k0-k1 value
+ *
+ * @params[in]
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ *******************************************************************/
+bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg, uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime,  SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime)
+{
+   uint8_t numK0 = 0, k0TblIdx = 0, k0Val = 0, k0Index =0 ;
+   uint8_t k1TblIdx = 0, k1Index = 0, k1Val = 0, numK1 = 0;
+   SchUeCb *ueCb = NULLP;
+   SchK0K1TimingInfoTbl *k0K1InfoTbl;
+
+   ADD_DELTA_TO_TIME(currTime, (*pdcchTime), PHY_DELTA_DL + SCHED_DELTA);
+#ifdef NR_TDD
+   if(schGetSlotSymbFrmt(pdcchTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+   {
+      /* If it is not a DL slot, cannot schedule PDCCH. Return from here. */
+      return false;
+   }
+#endif
+
+   if(cell->schDlSlotInfo[pdcchTime->slot]->pdcchUe != 0)
+   {
+      return false;
+   }
+
+   if(dedMsg == true)
+   {
+      ueCb = &cell->ueCb[ueId-1];
+      k0K1InfoTbl = &ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1InfoTbl;
+   }
+   else
+   {
+      k0K1InfoTbl = &cell->cellCfg.schInitialDlBwp.k0K1InfoTbl;
+   }
+
+   numK0 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].numK0;
+   for(k0TblIdx = 0; k0TblIdx < numK0; k0TblIdx++)
+   {
+      k0Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k0Index;
+      if(dedMsg != true)
+      {
+         k0Val = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].k0;
+         *pdschStartSymbol = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].startSymbol;
+         *pdschSymblLen = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].lengthSymbol;
+      }
+      else
+      {
+         if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0 != NULLP)
+         {
+            k0Val = *(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0);
+            *pdschStartSymbol = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].startSymbol;
+            *pdschSymblLen = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].symbolLength;
+         }
+      }
+
+      ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val);
+#ifdef NR_TDD
+      if(schGetSlotSymbFrmt(pdschTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+      {
+         continue;
+      }
+#endif
+      if(cell->schDlSlotInfo[pdschTime->slot]->pdschUe != 0)
+      {
+         continue; 
+      }
+
+      numK1 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.numK1;
+      for(k1TblIdx = 0; k1TblIdx < numK1; k1TblIdx++)
+      {
+         k1Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.k1Indexes[k1TblIdx];
+         if(dedMsg != true)
+         {
+            k1Val = defaultUlAckTbl[k1Index];
+         }
+         else
+         {
+            if(ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck)
+            {
+               k1Val = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck->dlDataToUlAckList[k1Index];
+            }
+         }
+         ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val);
+#ifdef NR_TDD
+         if(schGetSlotSymbFrmt(pucchTime->slot, cell->slotFrmtBitMap) == DL_SLOT)
+         {
+            continue;
+         }
+#endif
+         if(cell->schUlSlotInfo[pucchTime->slot]->pucchUe != 0)
+         {
+            continue; 
+         }
+         return true;
+      }
+   }
+   return false;
+}
+
 /*******************************************************************
  *
  * @brief 
@@ -203,15 +315,17 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlMsgAlloc *dlMsgAlloc)
+bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
 {
-   uint8_t ueIdx = 0, lcIdx = 0, pdschSymbols = 0;
-   uint16_t slot = 0,  startPrb = 0, maxFreePRB = 0;
+   uint8_t lcIdx = 0;
+   uint8_t pdschNumSymbols = 0, pdschStartSymbol = 0;
+   uint16_t startPrb = 0, maxFreePRB = 0;
    uint16_t crnti = 0, mcsIdx = 0;
    uint32_t accumalatedSize = 0;
    SchUeCb *ueCb = NULLP;
    CmLListCp *lcLL = NULLP;
-   SchPdschConfig pdschCfg;
+   DlMsgAlloc *dciSlotAlloc, *dlMsgAlloc;
+   SlotTimingInfo pdcchTime, pdschTime, pucchTime;
 
    /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size
     * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated.
@@ -219,169 +333,243 @@ uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlM
     * else if only Default list is present then first node in this List will add this overhead len*/
    bool isTxPayloadLenAdded = FALSE;
 
-   while(cell->boIndBitMap)
+   GET_CRNTI(crnti,ueId);
+   ueCb = &cell->ueCb[ueId-1];
+
+   if(findValidK0K1Value(cell, currTime, ueId, ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1TblPrsnt,\
+            &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, &pucchTime) != true )
    {
-      slot = dlSchedInfo->schSlotValue.dlMsgTime.slot;
+      /* If a valid combination of slots to scheduled PDCCH, PDSCH and PUCCH is
+       * not found, do not perform resource allocation. Return from here. */
+      return false;
+   }
 
-      GET_RIGHT_MOST_SET_BIT(cell->boIndBitMap, ueIdx);
-      GET_CRNTI(crnti,ueIdx);
-      ueCb = &cell->ueCb[ueIdx-1];
+   /* allocate PDCCH and PDSCH resources for the ue */
+   if(cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] == NULL)
+   {
 
-      /* allocate PDCCH and PDSCH resources for the ue */
-      SCH_ALLOC(dlMsgAlloc, sizeof(DlMsgAlloc));
-      if(!dlMsgAlloc)
+      SCH_ALLOC(dciSlotAlloc, sizeof(DlMsgAlloc));
+      if(!dciSlotAlloc)
       {
          DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for ded DL msg alloc");
-         return RFAILED;
+         return false;
       }
-      memset(dlMsgAlloc, 0, sizeof(DlMsgAlloc));
-      dlSchedInfo->dlMsgAlloc = dlMsgAlloc;
-      dlMsgAlloc->crnti = crnti;
-
-      pdschCfg = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg; 
-      mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
-
-      /*TODO: K0Index must be used instead of 0th Index in
-       * pdschCfg.timeDomRsrcAllociList*/
-      pdschSymbols = pdschCfg.timeDomRsrcAllociList[0].symbolLength;
-      /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */
-      memcpy(&dlMsgAlloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \
-            sizeof(DlMsgInfo));
+      cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = dciSlotAlloc;
+      memset(dciSlotAlloc, 0, sizeof(DlMsgAlloc));
+      dciSlotAlloc->crnti = crnti;
+   }
+   else
+   {
+      dciSlotAlloc = cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1];
+   }
+   /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */
+   fillDlMsgInfo(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].dlMsgInfo, dciSlotAlloc->crnti);
 
-      /*Re-Initalization per UE*/
-      /* scheduled LC data fill */
-      dlMsgAlloc->numLc = 0;
-      isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
-      accumalatedSize = 0;
+   /*Re-Initalization per UE*/
+   /* scheduled LC data fill */
+   dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].numLc = 0;
+   isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
+   accumalatedSize = 0;
 
-      for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+   for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+   {
+      if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
       {
-         if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
+         /*Check the LC is Dedicated or default and accordingly LCList will
+          * be used*/
+         if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
          {
-            /*Check the LC is Dedicated or default and accordingly LCList will
-             * be used*/
-            if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
-            {
-               lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
-            }
-            else
-            {
-               lcLL = &(ueCb->dlLcPrbEst.defLcList);
-            }
+            lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
+         }
+         else
+         {
+            lcLL = &(ueCb->dlLcPrbEst.defLcList);
+         }
 
-            /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
-            if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
-                     (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
+         /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
+         if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
+                  (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
+         {
+            DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
+            /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+            if(dciSlotAlloc->numSchedInfo == 0)
             {
-               DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
-               /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
-               SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc));
-               dlSchedInfo->dlMsgAlloc = NULLP;
-               return RFAILED;
+               SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+               cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
             }
+            else
+               memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+            return false;
          }
-         ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
-      }//End of for loop
+      }
+      ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
+   }//End of for loop
 
 
-      if ((ueCb->dlLcPrbEst.defLcList.count == 0) && \
-            ((ueCb->dlLcPrbEst.dedLcInfo != NULL) && (ueCb->dlLcPrbEst.dedLcInfo->dedLcList.count == 0)))
+   if ((ueCb->dlLcPrbEst.defLcList.count == 0) && \
+         ((ueCb->dlLcPrbEst.dedLcInfo == NULL) || (ueCb->dlLcPrbEst.dedLcInfo->dedLcList.count == 0)))
+   {
+      DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
+      UNSET_ONE_BIT(ueId, cell->boIndBitMap);
+
+      /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+      if(dciSlotAlloc->numSchedInfo == 0)
       {
-         DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
-         /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
-         SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc));
-         dlSchedInfo->dlMsgAlloc = NULLP;
-         return ROK;
+         SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+         cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
       }
+      else
+         memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
 
-      /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
-      maxFreePRB = searchLargestFreeBlockDL(cell, dlSchedInfo->schSlotValue.dlMsgTime, &startPrb);
+      /*TRUE because this UE has nothing to be scheduled*/
+      return true;
+   }
+
+   /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
+   maxFreePRB = searchLargestFreeBlock(cell, pdschTime, &startPrb, DIR_DL);
 
-      /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
-       * the list based on RRM policy*/
+   /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
+    * the list based on RRM policy*/
 
-      /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
-       * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
-      if(maxFreePRB != 0)
+   /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
+    * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
+   if(maxFreePRB != 0)
+   {
+      mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
+      if((ueCb->dlLcPrbEst.dedLcInfo == NULLP) 
+            || ((maxFreePRB <  ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB)))
+      { 
+         ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB;
+         DU_LOG("\nDEBUG  --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
+               ueCb->dlLcPrbEst.sharedNumPrb);
+
+         /*PRB Alloc for Default LCs*/
+         prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
+               &(ueCb->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
+      }
+      else
       {
-         if((ueCb->dlLcPrbEst.dedLcInfo == NULLP) 
-               || ((maxFreePRB <  ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB)))
-         { 
-            ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB;
-            DU_LOG("\nWARNING  --> SCH : Only Default Slice is scheduled, sharedPRB Count:%d",\
-                  ueCb->dlLcPrbEst.sharedNumPrb);
-
-            /*PRB Alloc for Default LCs*/
-            prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschSymbols,\
-                  &(ueCb->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded);
-         }
-         else
-         {
-            ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB;
+         ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB;
 
-            /*PRB Alloc for Dedicated LCs*/
-            prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, pdschSymbols,\
-                  &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded);
+         /*PRB Alloc for Dedicated LCs*/
+         prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
+               &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
 
-            /*PRB Alloc for Default LCs*/
-            prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschSymbols, \
-                  &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded);
-         }
+         /*PRB Alloc for Default LCs*/
+         prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
+               &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
       }
+   }
 
-      /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
-       * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ 
-      if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
-         updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), dlMsgAlloc, &(accumalatedSize));
+   /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
+    * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ 
+   if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
+      updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
 
-      updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.defLcList), dlMsgAlloc, &(accumalatedSize));
+   updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
 
-      /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
-      if (!accumalatedSize)
+   /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
+   if (!accumalatedSize)
+   {
+      if(maxFreePRB == 0)
       {
-         if(maxFreePRB == 0)
-         {
-            DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
-         }
-         else
-         {
-            /*Schedule the LC for next slot*/
-            DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
-         }
-         /*Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
-          * Allocation can be done in next slot*/
-         return ROK;
+         DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
       }
-      /*[Step6]: pdcch and pdsch data is filled */
-      if((schDlRsrcAllocDlMsg(cell, dlSchedInfo->schSlotValue.dlMsgTime, \
-                  crnti, accumalatedSize, dlMsgAlloc, startPrb)) != ROK)
+      else
       {
-         DU_LOG("\nERROR  --> SCH : Scheduling of DL dedicated message failed");
-         /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
-         SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc));
-         dlSchedInfo->dlMsgAlloc = NULLP;
-         return RFAILED;
+         /*Schedule the LC for next slot*/
+         DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
       }
+      /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
+       * Allocation can be done in next slot*/
+      return false;
+   }
+
+   /*[Step6]: pdcch and pdsch data is filled */
+   if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols)) != ROK)
+   {
+      DU_LOG("\nERROR  --> SCH : Scheduling of DL dedicated message failed");
 
-      /* TODO : Update the scheduling byte report for multiple LC based on QCI
-       * and Priority */
-      /* As of now, the total number of bytes scheduled for a slot is divided
-       * equally amongst all LC with pending data. This is avoid starving of any
-       * LC 
-       * */
+      /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+      if(dciSlotAlloc->numSchedInfo == 0)
+      {
+         SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+         cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
+      }
+      else
+         memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+      return false;
+   }
+
+   /* TODO : Update the scheduling byte report for multiple LC based on QCI
+    * and Priority */
+   /* As of now, the total number of bytes scheduled for a slot is divided
+    * equally amongst all LC with pending data. This is avoid starving of any
+    * LC 
+    * */
 #if 0
-      accumalatedSize = accumalatedSize/dlMsgAlloc->numLc;
-      for(lcIdx = 0; lcIdx < dlMsgAlloc->numLc; lcIdx ++)
-         dlMsgAlloc->lcSchInfo[lcIdx].schBytes = accumalatedSize;
+   accumalatedSize = accumalatedSize/dlMsgAlloc->numLc;
+   for(lcIdx = 0; lcIdx < dlMsgAlloc->numLc; lcIdx ++)
+      dlMsgAlloc->lcSchInfo[lcIdx].schBytes = accumalatedSize;
 #endif
-      /* PUCCH resource */
-      schAllocPucchResource(cell, dlMsgAlloc->crnti, slot);
+   
+   /* Check if both DCI and DL_MSG are sent in the same slot.
+    * If not, allocate memory for DL_MSG PDSCH slot to store PDSCH info */
 
-      /* after allocation is done, unset the bo bit for that ue */
-      UNSET_ONE_BIT(ueIdx, cell->boIndBitMap);
+   if(pdcchTime.slot == pdschTime.slot)
+   {
+      dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].pduPres = BOTH;
+      dciSlotAlloc->numSchedInfo++;
+   }
+   else
+   {
+      /* Allocate memory to schedule dlMsgAlloc to send DL_Msg, pointer will be checked at schProcessSlotInd() */
+      if(cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] == NULLP)
+      {
+         SCH_ALLOC(dlMsgAlloc, sizeof(DlMsgAlloc));
+         if(dlMsgAlloc == NULLP)
+         {
+            DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dlMsgAlloc");
+            if(dciSlotAlloc->numSchedInfo == 0)
+            {
+               SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+               cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = NULLP;
+            }
+            else
+               memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+            return false;
+         }
+         cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = dlMsgAlloc;
+         memset(dlMsgAlloc, 0, sizeof(DlMsgAlloc));
+         dlMsgAlloc->crnti = dciSlotAlloc->crnti;
+      }
+      else
+         dlMsgAlloc = cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1];
+
+      /* Copy all DL_MSG info */
+      memcpy(&dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo], \
+            &dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], sizeof(DlMsgSchInfo));
+      dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo].dlMsgPdcchCfg.dci.pdschCfg = \
+            &dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo].dlMsgPdschCfg;
+
+      /* Assign correct PDU types in corresponding slots */
+      dlMsgAlloc->dlMsgSchedInfo[dlMsgAlloc->numSchedInfo].pduPres = PDSCH_PDU;
+      dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].pduPres = PDCCH_PDU;
+      dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].pdschSlot = pdschTime.slot;
+
+      dciSlotAlloc->numSchedInfo++;
+      dlMsgAlloc->numSchedInfo++;
    }
 
-   return ROK;
+   schAllocPucchResource(cell, pucchTime, crnti);
+   cell->schDlSlotInfo[pdcchTime.slot]->pdcchUe = ueId;
+   cell->schDlSlotInfo[pdschTime.slot]->pdschUe = ueId;
+   cell->schUlSlotInfo[pucchTime.slot]->pucchUe = ueId;
+
+   /* after allocation is done, unset the bo bit for that ue */
+   UNSET_ONE_BIT(ueId, cell->boIndBitMap);
+   return true;
 }
 
 /*******************************************************************
@@ -402,16 +590,18 @@ uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlM
  * ****************************************************************/
 uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
 {
-   uint8_t  ueIdx, lcgIdx, ret = ROK;
-   uint16_t slot;
-   DlSchedInfo dlSchedInfo;
+   uint8_t   ueId, ueIdx, ret = ROK;
+   uint16_t  slot;
+   bool      isRarPending = false, isRarScheduled = false;
+   bool      isMsg4Pending = false, isMsg4Scheduled = false;
+   bool      isUlGrantPending = false, isUlGrantScheduled = false;
+   bool      isDlMsgPending = false, isDlMsgScheduled = false;
+   CmLList       *pendingUeNode;
+   DlSchedInfo   dlSchedInfo;
    DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
-   DlMsgAlloc  *msg4Alloc = NULLP;
-   DlMsgAlloc *dlMsgAlloc = NULLP;
-   SchCellCb  *cell = NULLP;
+   SchCellCb     *cell = NULLP;
 
-   memset(&dlSchedInfo,0,sizeof(DlSchedInfo));
-   dlSchedInfo.dlMsgAlloc = NULLP;
+   memset(&dlSchedInfo, 0, sizeof(DlSchedInfo));
    schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue);
    dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc;
    dlBrdcstAlloc->ssbTrans = NO_TRANSMISSION;
@@ -427,7 +617,6 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
    dlBrdcstAlloc->ssbIdxSupported = SSB_IDX_SUPPORTED;
 
    dlSchedInfo.cellId = cell->cellId;
-
    slot = dlSchedInfo.schSlotValue.broadcastTime.slot;
 
    /* Check for SSB occassion */
@@ -464,111 +653,102 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
       }
    }
 
-   /* Check for Pending RA Requests */
-   schProcessRaReq(*slotInd, cell);
-
-   /* Check for RAR */
-   if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.rarTime.slot]->rarAlloc != NULLP)
+   /* Select first UE in the linked list to be scheduled next */
+   pendingUeNode = cell->ueToBeScheduled.first;
+   if(pendingUeNode)
    {
-      slot = dlSchedInfo.schSlotValue.rarTime.slot;
-      dlSchedInfo.rarAlloc = cell->schDlSlotInfo[slot]->rarAlloc;
-      cell->schDlSlotInfo[slot]->rarAlloc = NULLP;
-   }
-
-   /* Check for MSG4 */
-   if((cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo != NULLP) &&
-      (cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo->isMsg4Pdu))
-   {
-      slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
-
-      SCH_ALLOC(msg4Alloc, sizeof(DlMsgAlloc));
-      if(!msg4Alloc)
+      if(pendingUeNode->node)
       {
-         DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for msg4 alloc");
-         return RFAILED;
-      }
+         ueId = *(uint8_t *)(pendingUeNode->node);
 
-      dlSchedInfo.dlMsgAlloc = msg4Alloc;
+         /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and 
+          * PUSCH to receive MSG3 as per k0-k2 configuration*/
+         if(cell->raReq[ueId-1] != NULLP)
+         {
+            isRarPending = true;
+            isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
+         }
 
-      /* Msg4 info is copied, this was earlier filled in macSchDlRlcBoInfo */
-      memcpy(&msg4Alloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \
-           sizeof(DlMsgInfo));
+         /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
+          * PUCCH to receive UL msg as per k0-k1 configuration  */
+         if(cell->raCb[ueId-1].msg4recvd)
+         {
+            isMsg4Pending = true;
+            isMsg4Scheduled = schProcessMsg4Req(cell, *slotInd, ueId);
+         }
 
-      /* pdcch and pdsch data is filled */
-      if((schDlRsrcAllocMsg4(cell, dlSchedInfo.schSlotValue.dlMsgTime, msg4Alloc)) != ROK)
-      {
-         DU_LOG("\nERROR  -->  SCH : MSG4 scheduling failed");
-         SCH_FREE(msg4Alloc, sizeof(DlMsgAlloc));
-         dlSchedInfo.dlMsgAlloc = NULLP;
-         SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
-         return RFAILED;
-      }
+         if(isRarPending || isMsg4Pending)
+         {
+            /* If RAR or MSG is successfully scheduled then
+             * remove UE from linked list since no pending msgs for this UE */
+            if(isRarScheduled || isMsg4Scheduled)
+            {
+               SCH_FREE(pendingUeNode->node, sizeof(uint8_t));
+               deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
+            }
+            /* If RAR/MSG4 is pending but couldnt be scheduled then,
+             * put this UE at the end of linked list to be scheduled later */
+            else 
+            {
+               cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
+            }
+         }
 
-      /* PUCCH resource */
-      schAllocPucchResource(cell, msg4Alloc->dlMsgInfo.crnti, dlSchedInfo.schSlotValue.dlMsgTime.slot);
+         if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
+         {
+            isUlGrantPending = true;
+            isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId);
+         }
 
-      SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
+         if((cell->boIndBitMap) & (1<<ueId))
+         {
+            isDlMsgPending = true;
+            isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId);
+         }
+         if(!isUlGrantPending && !isDlMsgPending)
+         {
+            /* No action required */  
+         }
+         else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
+         {
+            cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
+         }
+         else
+         {
+            SCH_FREE(pendingUeNode->node, sizeof(uint8_t));
+            deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
+         }
+      }
    }
 
-   /* Check if UL grant must be sent in this slot for a SR/BSR that had been received */
-   for(ueIdx=0; ueIdx<cell->numActvUe; ueIdx++)
+   /* Check if any PDU is scheduled at this slot for any UE */
+   for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
    {
-      uint32_t totDataReq = 0; /* in bytes */
-      DciInfo  *dciInfo = NULLP;
-      SchUeCb *ueCb = NULLP;
-   
-      ueCb = &cell->ueCb[ueIdx];
-      /* check for SR */
-      if(ueCb->srRcvd)
+      /* If RAR PDCCH/PDSCH is scheduled for a UE at this slot, fill RAR specific interface 
+       * structure to send to MAC */
+      if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.rarTime.slot]->rarAlloc[ueIdx] != NULLP)
       {
-         totDataReq = UL_GRANT_SIZE; /*fixing so that all control msgs can be handled in SR */
-         ueCb->srRcvd = false;
+         slot = dlSchedInfo.schSlotValue.rarTime.slot;
+         dlSchedInfo.rarAlloc[ueIdx] = cell->schDlSlotInfo[slot]->rarAlloc[ueIdx];
+         cell->schDlSlotInfo[slot]->rarAlloc[ueIdx] = NULLP;
       }
-      /* check for BSR */
-      for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
+
+      /* If DL-Msg PDCCH/PDSCH is scheduled for a UE at this slot, fill 
+       * specific interface structure to send to MAC */
+      if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgAlloc[ueIdx] != NULLP)
       {
-        totDataReq+= ueCb->bsrInfo[lcgIdx].dataVol;
-        ueCb->bsrInfo[lcgIdx].dataVol = 0;
+         slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
+         dlSchedInfo.dlMsgAlloc[ueIdx] = cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx];
+         cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx] = NULLP;
       }
-      if(totDataReq > 0) /* UL grant must be provided for this UE in this slot */
-      {
-         SchPuschInfo schPuschInfo;
-         memset(&schPuschInfo, 0, sizeof(SchPuschInfo));
 
-         SCH_ALLOC(dciInfo, sizeof(DciInfo));
-         if(!dciInfo)
-         {
-            DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciInfo alloc");
-            return RFAILED;
-         }
-         memset(dciInfo,0,sizeof(DciInfo));
-
-         /* update the SFN and SLOT */
-         memcpy(&dlSchedInfo.schSlotValue.ulDciTime, slotInd, sizeof(SlotTimingInfo));
-
-         /* Update PUSCH allocation */
-         schFillPuschAlloc(ueCb, dlSchedInfo.schSlotValue.ulDciTime, totDataReq, &schPuschInfo);
-
-         /* Fill DCI for UL grant */
-         schFillUlDci(ueCb, schPuschInfo, dciInfo);
-         memcpy(&dciInfo->slotIndInfo, &dlSchedInfo.schSlotValue.ulDciTime, sizeof(SlotTimingInfo));
-         dlSchedInfo.ulGrant = dciInfo;
-      }
    }
 
-   /* Check for pending BO grant for LC */
-   if((cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo != NULLP) &&
-      (!cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo->isMsg4Pdu))
+   if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.ulDciTime.slot]->ulGrant != NULLP)
    {
-      if((schFillBoGrantDlSchedInfo(cell, &dlSchedInfo, dlMsgAlloc)) != ROK)
-      {
-         DU_LOG("\nERROR  -->  SCH : DL MSG scheduling failed");
-         SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
-         return RFAILED;
-      }
-
-      /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
-      SCH_FREE(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgInfo, sizeof(DlMsgInfo));
+      slot = dlSchedInfo.schSlotValue.ulDciTime.slot;
+      dlSchedInfo.ulGrant = cell->schDlSlotInfo[slot]->ulGrant;
+      cell->schDlSlotInfo[slot]->ulGrant = NULLP;
    }
 
    /* Send msg to MAC */