[EPIC-ID: ODUHIGH-488][TASK-ID: ODUHIGH-494]Framework to support for slice based... 03/10403/1
authorlal.harshita <Harshita.Lal@radisys.com>
Wed, 8 Feb 2023 13:04:55 +0000 (18:34 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Wed, 8 Feb 2023 13:05:17 +0000 (18:35 +0530)
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
Change-Id: I407754d42e8925042715b62a0fe778c9c483d149

src/5gnrsch/sch.c
src/5gnrsch/sch.h
src/5gnrsch/sch_fcfs.c
src/5gnrsch/sch_slice_based.c [new file with mode: 0644]
src/5gnrsch/sch_slice_based.h [new file with mode: 0644]

index 32ab5c2..f441a10 100644 (file)
@@ -48,6 +48,7 @@
 #include "sch.h"
 #include "sch_utils.h"
 #include "sch_fcfs.h"
+#include "sch_slice_based.h"
 
 /**
  * @brief Task Initiation function. 
@@ -106,6 +107,7 @@ uint8_t schActvInit(Ent entity, Inst instId, Region region, Reason reason)
 void schAllApisInit(Inst inst)
 {
     schFcfsAllApisInit(&schCb[inst].allApis[SCH_FCFS]);  
+    schSliceBasedAllApisInit(&schCb[inst].allApis[SCH_SLICE_BASED]);
 }
 
 /**
index 5b2da40..8bb6311 100644 (file)
@@ -76,7 +76,7 @@
 #define MAX_DRX_SIZE 512
 #endif
 
-#define NUM_SCH_TYPE 1  /*Supported number of Scheduler Algorithm types*/
+#define NUM_SCH_TYPE 2  /*Supported number of Scheduler Algorithm types*/
 
 typedef struct schDlHqProcCb SchDlHqProcCb;
 typedef struct schUlHqEnt SchUlHqEnt;
@@ -87,7 +87,8 @@ typedef struct schUeCb SchUeCb;
 
 typedef enum
 {
-   SCH_FCFS
+   SCH_FCFS,
+   SCH_SLICE_BASED
 }SchType;
 
 typedef enum
index 26cc887..01119bb 100644 (file)
@@ -748,7 +748,7 @@ void schFcfsRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
  *
  * @details
  *
- *    Function :  schCalculateUlTbs
+ *    Function :  schFcfsCalculateUlTbs
  *
  *    Functionality: Function will note the required TBS for each LCGIDX and use
  *    the Priority LCG List and RRM policy to allocate the TBS size
@@ -766,7 +766,7 @@ void schFcfsRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
  *                   RFAILED > vice versa
  *
  * ****************************************************************/
-uint8_t schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
+uint8_t schFcfsCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
                           uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchFcfsHqProcCb *fcfsHqP)
 {
    uint16_t mcsIdx = 0;
@@ -912,7 +912,7 @@ uint8_t schFcfsScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, ui
    cell = (*hqP)->hqEnt->cell;
    ueCb = (*hqP)->hqEnt->ue;
    fcfsHqProcCb = (SchFcfsHqProcCb *)(*hqP)->schSpcUlHqProcCb;
-   ret = schCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, fcfsHqProcCb);
+   ret = schFcfsCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, fcfsHqProcCb);
 
    if(totDataReq > 0 && ret == ROK)
    {
diff --git a/src/5gnrsch/sch_slice_based.c b/src/5gnrsch/sch_slice_based.c
new file mode 100644 (file)
index 0000000..2ed18e2
--- /dev/null
@@ -0,0 +1,1385 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+
+/************************************************************************
+
+Name:     5G NR SCH layer
+
+Type:     C source file
+
+Desc:     C source code for Slice based scheduling algorithm
+
+File:     sch_slice_based.c
+
+ **********************************************************************/
+
+/** @file sch_slot_ind.c
+  @brief This module processes slot indications
+ */
+#include "common_def.h"
+#include "tfu.h"
+#include "lrg.h"
+#include "tfu.x"
+#include "lrg.x"
+#include "du_log.h"
+#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "sch.h"
+#include "sch_utils.h"
+#include "sch_slice_based.h"
+#ifdef NR_DRX 
+#include "sch_drx.h"
+#endif
+
+/*******************************************************************
+ *
+ * @brief Function to handle Cell configuration request
+ *
+ * @details
+ *
+ *    Function : schSliceBasedCellCfgReq
+ *
+ *    Functionality: This function configures cell paremeters
+ *       required for Slice Based scheduling
+ *
+ * @params[in] SchCellCb *cellCb, Cell control block
+ * @return ROK
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint8_t schSliceBasedCellCfgReq(SchCellCb *cellCb)
+{
+   SchSliceBasedCellCb *schSpcCellCb = NULLP;
+   
+   SCH_ALLOC(schSpcCellCb, sizeof(SchSliceBasedCellCb));
+   if(!schSpcCellCb)
+   {
+      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedCellCfgReq");
+      return RFAILED;
+   }
+   cmLListInit(&schSpcCellCb->ueToBeScheduled);
+   cellCb->schSpcCell = (void *)schSpcCellCb;
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Function to handle Cell configuration request
+ *
+ * @details
+ *
+ *    Function : schSliceBasedCellDelReq
+ *
+ *    Functionality: This function deletes/frees cell params
+ *       specific to Slice Based scheduling
+ *
+ * @params[in] Pointer to Cell control block
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedCellDelReq(SchCellCb *cellCb)
+{
+   SchSliceBasedCellCb *schSpcCellCb = NULLP;
+   CmLList *node=NULL, *next=NULL;
+
+   schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
+   /* Remove all UE from ueToBeScheduled list and deallocate */
+   node = schSpcCellCb->ueToBeScheduled.first;
+   while(node)
+   {
+      next = node->next;
+      SCH_FREE(node->node, sizeof(uint8_t));
+      cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
+      SCH_FREE(node, sizeof(CmLList));
+      node = next;
+   }
+   SCH_FREE(schSpcCellCb, sizeof(SchSliceBasedCellCb));
+   cellCb->schSpcCell = NULLP;
+}
+
+/*******************************************************************
+ *
+ * @brief Function to handle UE configuration request
+ *
+ * @details
+ *
+ *    Function : SchSliceBasedAddUeConfigReq
+ *
+ *    Functionality: Adds/Configures UE parameters required for
+ *       Slice Based scheduling
+ *
+ * @params[in] Pointer to UE control block
+ * @return ROK
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint8_t SchSliceBasedAddUeConfigReq(SchUeCb *ueCb)
+{
+   SchSliceBasedUeCb *ueSliceBasedCb;
+
+   SCH_ALLOC(ueSliceBasedCb, sizeof(SchSliceBasedHqCb));
+   if(!ueSliceBasedCb)
+   {
+      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in SchSliceBasedAddUeConfigReq");
+      return RFAILED;
+   }
+   
+   cmLListInit(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
+   cmLListInit(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
+   ueCb->schSpcUeCb = (void *)ueSliceBasedCb;
+   
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handles UE reconfiguration request
+ *
+ * @details
+ *
+ *    Function : SchSliceBasedModUeConfigReq
+ *
+ *    Functionality: 
+ *
+ * @params[in] Pointer to UE control block
+ * @return void
+ *
+ * ****************************************************************/
+void SchSliceBasedModUeConfigReq(SchUeCb *ueCb)
+{
+   /*TBD: No action required for Slice Based*/
+   return;
+}
+
+/*******************************************************************
+ *
+ * @brief Handles UE Delete Request
+ *
+ * @details
+ *
+ *    Function : SchSliceBasedUeDeleteReq 
+ *
+ *    Functionality: Deletes/Frees UE parameters specific to 
+ *       Slice Based scheduling
+ *
+ * @params[in] Pointer to UE control block
+ * @return void
+ *
+ * ****************************************************************/
+void SchSliceBasedUeDeleteReq(SchUeCb *ueCb)
+{
+   SchSliceBasedCellCb *schSpcCellCb = NULLP;
+   SchSliceBasedUeCb *ueSliceBasedCb = NULLP;
+   CmLList *node=NULL, *next=NULL;
+   uint8_t ueId = 0;
+
+   schSpcCellCb = (SchSliceBasedCellCb *)ueCb->cellCb->schSpcCell;
+   /* Remove all UE from ueToBeScheduled list and deallocate */
+   node = schSpcCellCb->ueToBeScheduled.first;
+   while(node)
+   {
+      next = node->next;
+      ueId = *(uint8_t *)node->node;
+      if(ueId == ueCb->ueId)
+      {
+        SCH_FREE(node->node, sizeof(uint8_t));
+        cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
+        SCH_FREE(node, sizeof(CmLList));
+        break;
+      }
+      node = next;
+   }
+   
+   ueSliceBasedCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
+   cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
+   cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
+
+   SCH_FREE(ueSliceBasedCb, sizeof(SchSliceBasedUeCb));
+   ueCb->schSpcUeCb = NULLP;
+   return;
+}
+
+/*******************************************************************
+ *
+ * @brief Intializes HARQ Process control block
+ *
+ * @details
+ *
+ *    Function : schSliceBasedInitDlHqProcCb
+ *
+ *    Functionality: Intitialized parameters of HARQ process control
+ *       block specific to Slice Based scheduling in Downlink
+ *
+ * @params[in] Pointer to Downlink HARQ Process control block
+ * @return ROK
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint8_t schSliceBasedInitDlHqProcCb(SchDlHqProcCb *hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqP;
+
+   SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
+   if(!schSpcHqP)
+   {
+      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedInitDlHqProcCb");
+      return RFAILED;
+   }
+
+   cmLListInit(&schSpcHqP->lcCb.dedLcList);
+   cmLListInit(&schSpcHqP->lcCb.defLcList);
+   hqP->schSpcDlHqProcCb = (void *)schSpcHqP;
+
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handles HARQ Process delete request
+ *
+ * @details 
+ *
+ *    Function : schSliceBasedDeleteDlHqProcCb
+ *
+ *    Functionality: Deletes HARQ Process parameters specific to 
+ *       Slice Based scheduling in Downlink
+ *
+ * @params[in] Pointer to Downlink HARQ Process control block
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedDeleteDlHqProcCb(SchDlHqProcCb *hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
+   cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
+   cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
+   SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
+   hqP->schSpcDlHqProcCb = NULLP;
+}
+
+/*******************************************************************
+ *
+ * @brief Intializes HARQ Process control block
+ *
+ * @details
+ *
+ *    Function : schSliceBasedInitUlHqProcCb
+ *
+ *    Functionality: Intitialized parameters of HARQ process control
+ *       block specific to Slice Based scheduling in Uplink
+ *
+ * @params[in] Pointer to Uplink HARQ Process control block
+ * @return ROK
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint8_t schSliceBasedInitUlHqProcCb(SchUlHqProcCb *hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqP;
+
+   SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
+   if(!schSpcHqP)
+   {
+      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedInitUlHqProcCb");
+      return RFAILED;
+   }
+   cmLListInit(&schSpcHqP->lcCb.dedLcList);
+   cmLListInit(&schSpcHqP->lcCb.defLcList);
+   hqP->schSpcUlHqProcCb = (void *)schSpcHqP;
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handled Deletion of HARQ Process control block
+ *
+ * @details
+ *
+ *    Function : schSliceBasedDeleteUlHqProcCb
+ *
+ *    Functionality: Deletes HARQ Process parameters specific to 
+ *       Slice Based scheduling in Uplink
+ *
+ * @params[in] Pointer to Uplink HARQ Process Control block
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedDeleteUlHqProcCb(SchUlHqProcCb *hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
+   cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
+   cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
+   SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
+   hqP->schSpcUlHqProcCb = NULLP;
+}
+
+/*******************************************************************
+ *
+ * @brief Handles freeing of HARQ Process
+ *
+ * @details
+ *
+ *    Function : schSliceBasedFreeDlHqProcCb
+ *
+ *    Functionality: Frees HARQ Process parameters specific to 
+ *       Slice Based scheduling in Downlink when HARQ process becomes free
+ *
+ * @params[in] Pointer to HARQ process control block
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedFreeDlHqProcCb(SchDlHqProcCb *hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
+
+   cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
+   cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
+}
+
+/*******************************************************************
+ *
+ * @brief Handles freeing of HARQ Process
+ *
+ * @details
+ *
+ *    Function : schSliceBasedFreeUlHqProcCb
+ *
+ *    Functionality: Frees HARQ Process parameters specific to 
+ *       Slice Based scheduling in Uplink when HARQ process becomes free
+ *
+ * @params[in] Pointer to HARQ process control block
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedFreeUlHqProcCb(SchUlHqProcCb *hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
+
+   cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
+   cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
+}
+
+/*******************************************************************
+ *
+ * @brief Adds HARQ process to retransmission list
+ *
+ * @details
+ *
+ *    Function : schSliceBasedAddToDlHqRetxList
+ *
+ *    Functionality: Adds HARQ process to retransmission list
+ *
+ * @params[in] Pointer to Downlink HARQ Process 
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedAddToDlHqRetxList(SchDlHqProcCb *hqP)
+{
+   SchSliceBasedUeCb *schSpcUeCb;
+
+   schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
+   cmLListAdd2Tail(&(schSpcUeCb->hqRetxCb.dlRetxHqList),&hqP->dlHqProcLink);  
+#ifdef NR_DRX
+   if(hqP->hqEnt->ue->ueDrxInfoPres == true)
+   {
+      schDrxStrtDlHqRttTmr(hqP);
+   }
+   else
+#endif
+   {
+      schSliceBasedAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Adds HARQ process to retransmission list
+ *
+ * @details
+ *
+ *    Function : schSliceBasedAddToUlHqRetxList
+ *
+ *    Functionality: Adds HARQ process to retransmission list
+ *
+ * @params[in] Pointer to Uplink HARQ Process 
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedAddToUlHqRetxList(SchUlHqProcCb *hqP)
+{
+   SchSliceBasedUeCb *schSpcUeCb;
+
+   schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
+   cmLListAdd2Tail(&(schSpcUeCb->hqRetxCb.ulRetxHqList),&hqP->ulHqProcLink);  
+#ifdef NR_DRX
+   if(hqP->hqEnt->ue->ueDrxInfoPres == true)
+   {
+      schDrxStrtUlHqRttTmr(hqP);
+   }
+   else
+#endif
+   {
+      schSliceBasedAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
+   }   
+}
+
+/*******************************************************************
+ *
+ * @brief Add UE to ueToBeScheduled List
+ *
+ * @details
+ *
+ *    Function : schSliceBasedAddUeToSchedule
+ *
+ *    Functionality:
+ *      Search if UE entry present in the list
+ *      If yes, return.
+ *      If no, add UE to the list
+ *
+ * @params[in] Cell control block
+ *             Ue Id to be added
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t schSliceBasedAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
+{
+   SchSliceBasedCellCb *schSpcCellCb = NULLP;
+   uint8_t *ueId;
+   CmLList *node;
+
+   schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
+   /* Search if UE entry is already present in ueToBeScheduled list.
+    * If yes, another entry for same UE not needed. Hence, return */
+   node = schSpcCellCb->ueToBeScheduled.first;
+   while(node)
+   {
+      ueId = (uint8_t *)node->node;
+      if(*ueId == ueIdToAdd)
+         return ROK;
+      node = node->next;
+   }
+
+   /* If UE entry not present already, add UE to the end of ueToBeScheduled list */
+   SCH_ALLOC(ueId, sizeof(uint8_t));
+   if(!ueId)
+   {
+      DU_LOG("\nERROR  -->  SCH : Memory allocation failure in schSliceBasedAddUeToSchedule");
+      return RFAILED;
+   }
+   *ueId = ueIdToAdd;
+   if(addNodeToLList(&schSpcCellCb->ueToBeScheduled, ueId, NULLP) != ROK)
+   {
+      DU_LOG("\nERROR  --> SCH : Failed to add ueId [%d] to cell->ueToBeScheduled list", *ueId);
+      return RFAILED;
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handled CRC Indication
+ *
+ * @details
+ *
+ *    Function : schSliceBasedProcessCrcInd
+ *
+ *    Functionality: Processes CRC Indication as required for Slice Based
+ *       scheduling
+ *
+ * @params[in] Pointer to Cell control block
+ *             UE Id
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
+{
+   schSliceBasedAddUeToSchedule(cellCb, ueId);   
+}
+
+/*******************************************************************
+ *
+ * @brief Processes Buffer Occupancy report from RLC
+ *
+ * @details
+ *
+ *    Function : schSliceBasedDlRlcBoInfo
+ *
+ *    Functionality: Process buffer occupany report 
+ *
+ * @params[in]
+ * @return
+ *
+ * ****************************************************************/
+void schSliceBasedDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
+{
+   schSliceBasedAddUeToSchedule(cellCb, ueId);   
+}
+
+/*******************************************************************
+ *
+ * @brief Processes BSR request
+ *
+ * @details
+ *
+ *    Function : schSliceBasedBsr
+ *
+ *    Functionality: Processes BSR as per Slice Based scheduling
+ *
+ * @params[in] Pointer to Cell 
+ *             UE ID
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedBsr(SchCellCb *cellCb, uint16_t ueId)
+{
+   schSliceBasedAddUeToSchedule(cellCb, ueId);   
+}
+
+/*******************************************************************
+ *
+ * @brief Processed UCI Indication
+ *
+ * @details
+ *
+ *    Function : schSliceBasedSrUciInd
+ *
+ *    Functionality: Processing of UCI indication specific to 
+ *       Slice Based scheduling
+ *
+ * @params[in] Pointer to Cell
+ *             UE Id
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedSrUciInd(SchCellCb *cellCb, uint16_t ueId)
+{
+   schSliceBasedAddUeToSchedule(cellCb, ueId);   
+}
+
+/*******************************************************************
+ *
+ * @brief Processing of RACH Indication
+ *
+ * @details
+ *
+ *    Function : schSliceBasedProcessRachInd
+ *
+ *    Functionality: Processing of RACH Indication specific to 
+ *       Slice Based scheduling
+ *
+ * @params[in] Pointer to Cell Cb
+ *             UE Id
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
+{
+   schSliceBasedAddUeToSchedule(cellCb, ueId);   
+}
+
+/*******************************************************************
+ *
+ * @brief Processing of DL HARQ Indication
+ *
+ * @details
+ *
+ *    Function : SchSliceBasedDlHarqInd
+ *
+ *    Functionality:
+ *
+ * @params[in] 
+ * @return void
+ *
+ * ****************************************************************/
+void SchSliceBasedDlHarqInd()
+{
+   return;
+}
+
+/*******************************************************************
+ *
+ * @brief Processing of Paging indication
+ *
+ * @details
+ *
+ *    Function : schSliceBasedPagingInd
+ *
+ *    Functionality:
+ *
+ * @params[in]
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedPagingInd()
+{
+   return;
+}
+
+/*******************************************************************
+ *
+ * @brief Processing of RACH Resource Request
+ *
+ * @details
+ *
+ *    Function : schSliceBasedRachRsrcReq
+ *
+ *    Functionality:
+ *
+ * @params[in]
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedRachRsrcReq()
+{
+   return;
+}
+
+/*******************************************************************
+ *
+ * @brief Processing of RACH Resource Release
+ *
+ * @details
+ *
+ *    Function : schSliceBasedRachRsrcRel
+ *
+ *    Functionality:
+ *
+ * @params[in]
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedRachRsrcRel()
+{
+   return;
+}
+
+/*******************************************************************
+ *
+ * @brief Remove entry from HARQ retransmission list
+ *
+ * @details
+ *
+ *    Function : schSliceBasedRemoveFrmDlHqRetxList
+ *
+ *    Functionality: Remove entry from HARQ retransmission list
+ *
+ * @params[in] Pointer to UE
+ *             Node to be deleted
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
+{
+   SchSliceBasedUeCb *schSpcUeCb;
+
+   schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
+   cmLListDelFrm(&schSpcUeCb->hqRetxCb.dlRetxHqList, node);
+}
+
+/*******************************************************************
+ *
+ * @brief Remove entry from HARQ retransmission list
+ *
+ * @details
+ *
+ *    Function : schSliceBasedRemoveFrmUlHqRetxList
+ *
+ *    Functionality: Remove entry from HARQ retransmission list
+ *
+ * @params[in] Pointer to UE
+ *             Node to be deleted
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
+{
+   SchSliceBasedUeCb *schSpcUeCb;
+
+   schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
+   cmLListDelFrm(&schSpcUeCb->hqRetxCb.ulRetxHqList, node);
+}
+
+/*******************************************************************
+ *
+ * @brief Remove UE from Scheduling List
+ *
+ * @details
+ *
+ *    Function : schSliceBasedRemoveUeFrmScheduleLst
+ *
+ *    Functionality: Remove UE from Scheduling List
+ *
+ * @params[in] Pointer to Cell
+ *             Node to be removed
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
+{
+   SchSliceBasedCellCb *schSpcCell;
+
+   schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
+   SCH_FREE(node->node, sizeof(uint8_t));
+   deleteNodeFromLList(&schSpcCell->ueToBeScheduled, node);
+}
+
+/*******************************************************************
+ *
+ * @brief  Handler to calculate TBS size for BSR requested
+ *
+ * @details
+ *
+ *    Function :  schSliceBasedCalculateUlTbs
+ *
+ *    Functionality: Function will note the required TBS for each LCGIDX and use
+ *    the Priority LCG List and RRM policy to allocate the TBS size
+ *
+ * @params [in] ueCb (Pointer to UE CB)
+ *         [in] puschTime (Time slot where PUSCH will be sent)
+ *         [in] symbLen (No of Symbols used for PUSCH transmission)
+ *         [out] startPrb(Pointer to startPRB which will be calculated while
+ *         finding the best Free Block)
+ *         [out] totTBS(Pointer to total TBS size)
+ *         [in] isRetx (to indicate retransmission)
+ *         [in] hqP (UL Harq process pointer)
+ *
+ * @return uint8_t : ROK > Scheduling of UL grant is successful
+ *                   RFAILED > vice versa
+ *
+ * ****************************************************************/
+uint8_t schSliceBasedCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
+                          uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchSliceBasedHqProcCb *schSpcHqP)
+{
+   uint16_t mcsIdx = 0;
+   CmLListCp *lcLL = NULLP;
+   uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
+   uint16_t rsvdDedicatedPRB;
+   *startPrb = 0;
+   *totTBS = 0;
+
+   /* check for BSR */
+   for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
+   {
+      if(ueCb->bsrInfo[lcgIdx].dataVol == 0)
+      {
+         continue;
+      }
+
+      /*TODO: lcgIdx and LCID has been implemented as one to one mapping.
+       * Need to check the mapping to figure out the LCID and lcgIdx once L2
+       * spec specifies any logic*/
+      lcId = lcgIdx;
+      if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
+      {
+         lcLL = &(schSpcHqP->lcCb.dedLcList);
+         rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
+      }
+      else
+      {
+         lcLL = &(schSpcHqP->lcCb.defLcList);
+      }
+
+      /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
+      if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
+      {
+         DU_LOG("\nERROR  --> SCH: LcgId:%d updation failed",lcId);         
+         return RFAILED;
+      }
+   }
+
+   if ((schSpcHqP->lcCb.defLcList.count == 0) && (schSpcHqP->lcCb.dedLcList.count == 0))
+   {
+      if( (ueCb->srRcvd) || (isRetx) )
+      {
+         *startPrb = MAX_NUM_RB;
+         *totTBS = schCalcTbSize(UL_GRANT_SIZE);
+      }
+      /*Returning true when NO Grant is there for UE as this is not scheduling
+       * error*/      
+      return ROK;
+   }
+
+   maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
+
+   /*[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)
+   {
+      mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
+      if((schSpcHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
+      {
+         schSpcHqP->lcCb.sharedNumPrb = maxFreePRB;
+         DU_LOG("\nDEBUG  -->  SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
+               schSpcHqP->lcCb.sharedNumPrb);
+
+         /*PRB Alloc for Default LCs*/
+         prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
+               &(schSpcHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
+      }
+      else
+      {
+         schSpcHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
+
+         /*PRB Alloc for Dedicated LCs*/
+         prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
+               &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
+               NULLP, &(ueCb->srRcvd));
+
+         /*PRB Alloc for Default LCs*/
+         prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
+               &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
+               NULLP,&(ueCb->srRcvd));
+      }
+   }
+   /*[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(schSpcHqP->lcCb.dedLcList.count != 0)
+      updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
+
+   updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.defLcList), NULLP, ueCb->bsrInfo, totTBS);
+
+   /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
+   if (*totTBS == 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");
+      }      
+      return RFAILED;
+   }   
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Grants resources to LC in uplink
+ *
+ * @details
+ *
+ *    Function : schProcessSrOrBsrReq
+ *
+ *    Functionality:
+ *       Grants resources to LC in uplink
+ *
+ * @params[in] PDCCH Time
+ *             PUSCH Time
+ *             Start Symbol
+ *             Number of symbols
+ *             Is retransmission
+ *             HARQ process
+ * @return ROK
+ *         RFAILED
+ *
+ *******************************************************************/
+uint8_t schSliceBasedScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
+{
+   SchCellCb *cell;
+   SchSliceBasedHqProcCb *schSpcHqProcCb;
+   uint8_t ret = RFAILED;
+   uint16_t startPrb = 0;
+   uint32_t totDataReq = 0; /* in bytes */
+   SchUeCb *ueCb;
+   SchPuschInfo *puschInfo;
+   DciInfo  *dciInfo = NULLP;
+
+   cell = (*hqP)->hqEnt->cell;
+   ueCb = (*hqP)->hqEnt->ue;
+   schSpcHqProcCb = (SchSliceBasedHqProcCb *)(*hqP)->schSpcUlHqProcCb;
+   ret = schSliceBasedCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, schSpcHqProcCb);
+
+   if(totDataReq > 0 && ret == ROK)
+   {
+      SCH_ALLOC(dciInfo, sizeof(DciInfo));
+      if(!dciInfo)
+      {
+         DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciInfo alloc");
+         if(isRetx != TRUE)
+         {
+            if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
+               updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
+
+            updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
+         }
+         return RFAILED;
+      }
+      cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
+      memset(dciInfo,0,sizeof(DciInfo));
+
+      /* Update PUSCH allocation */
+      if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
+      {
+         if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo)
+         {
+            puschInfo = cell->schUlSlotInfo[puschTime.slot]->schPuschInfo;
+            if(puschInfo != NULLP)
+            {
+               /* Fill DCI for UL grant */
+               schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
+               memcpy(&dciInfo->slotIndInfo, &dciTime, sizeof(SlotTimingInfo));
+               ueCb->srRcvd = false;
+               ueCb->bsrRcvd = false;
+               cell->schUlSlotInfo[puschTime.slot]->puschUe = ueCb->ueId;
+               if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
+                  updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
+               updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
+               cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);                  
+               return ROK;
+            }
+         }
+      }
+      if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
+         updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
+      updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Grants resources to LC in downlink 
+ *
+ * @details
+ *
+ *    Function : schSliceBasedScheduleDlLc 
+ *
+ *    Functionality: Grants resources to LC in uplink
+ *
+ * @params[in] PDCCH Time
+ *
+ * @return ROK
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint32_t schSliceBasedScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb **hqP)
+{
+   SchSliceBasedHqProcCb *schSpcHqProcCb;
+   SchUeCb *ueCb;
+   uint8_t lcIdx = 0;
+   uint16_t startPrb = 0, maxFreePRB = 0;
+   uint16_t mcsIdx = 0;
+   uint32_t accumalatedSize = 0;
+   CmLListCp *lcLL = NULLP;
+   uint16_t rsvdDedicatedPRB = 0;
+   DlMsgAlloc *dciSlotAlloc;
+
+   /* 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.
+    * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead
+    * else if only Default list is present then first node in this List will add this overhead len*/
+   bool isTxPayloadLenAdded = FALSE;
+
+   ueCb = (*hqP)->hqEnt->ue;
+   dciSlotAlloc = (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1];
+   schSpcHqProcCb = (SchSliceBasedHqProcCb *)((*hqP)->schSpcDlHqProcCb);
+
+   if (isRetx == FALSE)
+   {
+      /*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++)
+      {
+         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)
+            {
+               lcLL = &(schSpcHqProcCb->lcCb.dedLcList);
+               rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
+            }
+            else
+            {
+               lcLL = &(schSpcHqProcCb->lcCb.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)
+            {
+               DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
+               /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+               if(dciSlotAlloc->numSchedInfo == 0)
+               {
+                  SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+                  (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
+               }
+               else
+                  memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+               return false;
+            }
+         }
+         ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
+      }//End of for loop
+
+      if ((schSpcHqProcCb->lcCb.defLcList.count == 0) && (schSpcHqProcCb->lcCb.dedLcList.count == 0))
+      {
+         DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
+         UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
+
+         /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+         if(dciSlotAlloc->numSchedInfo == 0)
+         {
+            SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+            (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
+         }
+         else
+            memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+
+         /*TRUE because this UE has nothing to be scheduled*/
+         return true;
+      }
+   }
+
+   /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
+   maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->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*/
+
+   /*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(isRetx == FALSE)
+   {
+      if(maxFreePRB != 0)
+      {
+         mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
+
+         if((schSpcHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
+         { 
+            schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
+            DU_LOG("\nDEBUG  --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
+                  schSpcHqProcCb->lcCb.sharedNumPrb);
+
+            /*PRB Alloc for Default LCs*/
+            prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
+                  &(schSpcHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
+         }
+         else
+         {
+            schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
+            /*PRB Alloc for Dedicated LCs*/
+            prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
+                  &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
+
+            /*PRB Alloc for Default LCs*/
+            prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
+                  &(schSpcHqProcCb->lcCb.sharedNumPrb), &(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 (isRetx == FALSE)
+   {
+      if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
+         updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
+
+      updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
+   }
+   else
+   {
+      accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
+   }
+
+   /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
+   if (!accumalatedSize)
+   {
+      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*/
+      accumalatedSize = 0;
+   }
+
+   return accumalatedSize;
+}
+
+/*******************************************************************
+ *
+ * @brief Scheduling of Slots in UL And DL 
+ *
+ * @details
+ *
+ *    Function : schSliceBasedScheduleSlot
+ *
+ *    Functionality: Scheduling of slots in UL and DL specific to 
+ *       Slice Based scheduling
+ *
+ * @params[in] Pointer to Cell
+ *             Slot timing info
+ *             Scheduler instance
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
+{
+   SchSliceBasedCellCb  *schSpcCell;
+   SchSliceBasedUeCb    *schSpcUeCb;
+   SchDlHqProcCb  *hqP = NULLP;
+   SchUlHqProcCb  *ulHqP = NULLP;
+   CmLList        *pendingUeNode;
+   CmLList        *node;
+   uint8_t        ueId;
+   bool           isRarPending = false, isRarScheduled = false;
+   bool           isMsg4Pending = false, isMsg4Scheduled = false;
+   bool           isDlMsgPending = false, isDlMsgScheduled = false;
+   bool           isUlGrantPending = false, isUlGrantScheduled = false;
+
+   schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
+   
+   /* Select first UE in the linked list to be scheduled next */
+   pendingUeNode = schSpcCell->ueToBeScheduled.first;
+   if(pendingUeNode)
+   {
+      if(pendingUeNode->node)
+      {
+         ueId = *(uint8_t *)(pendingUeNode->node);
+         schSpcUeCb = (SchSliceBasedUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
+
+         /* 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);
+         }
+
+         /*MSG3 retransmisson*/
+         if(cell->raCb[ueId-1].retxMsg3HqProc)
+         {            
+            schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
+         }
+
+         /* 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->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
+         {
+            /* Retransmission of MSG4 */
+            isMsg4Pending = true;
+            if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
+               isMsg4Scheduled = true;
+         }
+         else
+         {
+            /* First transmission of MSG4 */
+            if(cell->raCb[ueId-1].msg4recvd)
+            {
+               isMsg4Pending = true;
+               if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
+                  isMsg4Scheduled = true;
+
+               /* If MSG4 scheduling failed, free the newly assigned HARQ process */
+               if(!isMsg4Scheduled)
+                  schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
+            }
+         }
+
+         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)
+            {
+               schSliceBasedRemoveUeFrmScheduleLst(cell, 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(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
+            }
+         }
+
+#ifdef NR_DRX 
+         if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
+         {
+            if(pendingUeNode->node)
+            {
+               cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
+            }
+         }
+         else 
+#endif
+         {
+
+            /* DL Data */
+            node = NULLP;
+            if(schSpcUeCb)
+               node = schSpcUeCb->hqRetxCb.dlRetxHqList.first;
+            if(node != NULLP)
+            {
+               /* DL Data ReTransmisson */
+               isDlMsgPending = true;
+               isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
+               if(isDlMsgScheduled)
+               {
+#ifdef NR_DRX 
+                  schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
+#endif
+                  schSliceBasedRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
+               }
+            }
+            else
+            {
+               /* DL Data new transmission */
+               if((cell->boIndBitMap) & (1<<ueId))
+               {
+                  isDlMsgPending = true;               
+                  isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
+
+                  /* If DL scheduling failed, free the newly assigned HARQ process */
+                  if(!isDlMsgScheduled)
+                     schDlReleaseHqProcess(hqP);
+                  else
+                  {
+#ifdef NR_DRX
+                     schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
+#endif
+                  }
+               }
+            }
+
+            /* Scheduling of UL grant */
+            node = NULLP;
+            if(schSpcUeCb)
+               node = schSpcUeCb->hqRetxCb.ulRetxHqList.first;
+            if(node != NULLP)
+            {
+               /* UL Data ReTransmisson */
+               isUlGrantPending = true;
+               isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
+               if(isUlGrantScheduled)
+               {
+#ifdef NR_DRX 
+                  schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
+#endif
+                  schSliceBasedRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
+               }
+            }
+            else
+            {
+               /* UL Data new transmission */
+               if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
+               {
+                  isUlGrantPending = true;
+                  isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
+                  if(!isUlGrantScheduled)
+                     schUlReleaseHqProcess(ulHqP, FALSE);
+                  else
+                  {
+#ifdef NR_DRX
+                     schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
+#endif
+                  }
+               }
+            }
+
+            if(!isUlGrantPending && !isDlMsgPending)
+            {
+               /* No action required */  
+            }
+            else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
+            {
+               cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
+            }
+            else
+            {
+               schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
+            }
+         }
+      }
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Initializes all function pointers to Slice Based function handler
+ *
+ * @details
+ *
+ *    Function : schSliceBasedAllApisInit
+ *
+ *    Functionality: Initializes all function pointers to Slice Based 
+ *       function handler
+ *
+ * @params[in] Function pointer array
+ * @return void
+ *
+ * ****************************************************************/
+void schSliceBasedAllApisInit(SchAllApis *allSliceBasedApi)
+{
+    /* Interface API function pointers */
+    allSliceBasedApi->SchCellCfgReq = schSliceBasedCellCfgReq;
+    allSliceBasedApi->SchCellDeleteReq = schSliceBasedCellDelReq;
+    allSliceBasedApi->SchAddUeConfigReq = SchSliceBasedAddUeConfigReq;
+    allSliceBasedApi->SchModUeConfigReq = SchSliceBasedModUeConfigReq;
+    allSliceBasedApi->SchUeDeleteReq = SchSliceBasedUeDeleteReq; 
+    allSliceBasedApi->SchDlHarqInd = SchSliceBasedDlHarqInd; 
+    allSliceBasedApi->SchCrcInd = schSliceBasedProcessCrcInd;
+    allSliceBasedApi->SchRachInd = schSliceBasedProcessRachInd;
+    allSliceBasedApi->SchPagingInd = schSliceBasedPagingInd;
+    allSliceBasedApi->SchRachRsrcReq = schSliceBasedRachRsrcReq; 
+    allSliceBasedApi->SchRachRsrcRel = schSliceBasedRachRsrcRel;
+    allSliceBasedApi->SchDlRlcBoInfo = schSliceBasedDlRlcBoInfo;
+    allSliceBasedApi->SchSrUciInd = schSliceBasedSrUciInd;
+    allSliceBasedApi->SchBsr = schSliceBasedBsr;
+
+    /* Internal API function pointers */
+    allSliceBasedApi->SchAddToDlHqRetxList = schSliceBasedAddToDlHqRetxList;
+    allSliceBasedApi->SchAddToUlHqRetxList = schSliceBasedAddToUlHqRetxList;
+    allSliceBasedApi->SchRemoveFrmDlHqRetxList = schSliceBasedRemoveFrmDlHqRetxList;
+    allSliceBasedApi->SchRemoveFrmUlHqRetxList = schSliceBasedRemoveFrmUlHqRetxList;
+    allSliceBasedApi->SchAddUeToSchedule = schSliceBasedAddUeToSchedule;
+    allSliceBasedApi->SchRemoveUeFrmScheduleLst = schSliceBasedRemoveUeFrmScheduleLst;
+    allSliceBasedApi->SchInitDlHqProcCb = schSliceBasedInitDlHqProcCb;
+    allSliceBasedApi->SchInitUlHqProcCb = schSliceBasedInitUlHqProcCb;
+    allSliceBasedApi->SchFreeDlHqProcCb = schSliceBasedFreeDlHqProcCb;
+    allSliceBasedApi->SchFreeUlHqProcCb = schSliceBasedFreeUlHqProcCb;
+    allSliceBasedApi->SchDeleteDlHqProcCb = schSliceBasedDeleteDlHqProcCb;
+    allSliceBasedApi->SchDeleteUlHqProcCb = schSliceBasedDeleteUlHqProcCb;
+    allSliceBasedApi->SchScheduleSlot = schSliceBasedScheduleSlot;
+    allSliceBasedApi->SchScheduleDlLc = schSliceBasedScheduleDlLc;
+    allSliceBasedApi->SchScheduleUlLc = schSliceBasedScheduleUlLc;
+}
+/**********************************************************************
+    End of file
+**********************************************************************/
+
diff --git a/src/5gnrsch/sch_slice_based.h b/src/5gnrsch/sch_slice_based.h
new file mode 100644 (file)
index 0000000..2763aba
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+*******************************************************************************/
+
+typedef struct schSliceBasedCellCb
+{
+   CmLListCp     ueToBeScheduled;                   /*!< Linked list to store UEs pending to be scheduled, */
+}SchSliceBasedCellCb;
+
+typedef struct schSliceBasedLcCb
+{
+   /* TODO: For Multiple RRMPolicies, Make DedicatedLcInfo as array/Double Pointer 
+    * and have separate DedLCInfo for each RRMPolcyMemberList*/
+   /* Dedicated LC List will be allocated, if any available*/
+   CmLListCp dedLcList;        /*Contain LCInfo per RRMPolicy*/
+   CmLListCp defLcList; /*Linklist of LC assoc with Default S-NSSAI(s)*/
+   /* SharedPRB number can be used by any LC.
+    * Need to calculate in every Slot based on PRB availability*/
+   uint16_t sharedNumPrb;
+}SchSliceBasedLcCb;
+
+typedef struct schSliceBasedHqProcCb
+{
+   SchSliceBasedLcCb lcCb; 
+}SchSliceBasedHqProcCb;
+
+typedef struct schSliceBasedHqCb
+{
+   CmLListCp  ulRetxHqList;
+   CmLListCp  dlRetxHqList;
+}SchSliceBasedHqCb;
+
+typedef struct schSliceBasedUeCb
+{
+   SchSliceBasedHqCb   hqRetxCb;
+}SchSliceBasedUeCb;
+
+uint8_t schSliceBasedAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd);
+void schSliceBasedAllApisInit(SchAllApis *allSliceBasedApi);
+
+/**********************************************************************
+    End of file
+ *********************************************************************/
+