[Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Implementation of drx timer 24/9424/7
authorlal.harshita <Harshita.Lal@radisys.com>
Thu, 27 Oct 2022 18:07:14 +0000 (23:37 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Tue, 8 Nov 2022 05:25:30 +0000 (10:55 +0530)
[Onduration timer, short cycle timer, in active drx timer]

Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
Change-Id: Id2c5b1bb4bdd290a91f57f2d7233f925891270c4
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
18 files changed:
src/5gnrmac/mac_ue_mgr.c
src/5gnrsch/sch.c
src/5gnrsch/sch.h
src/5gnrsch/sch_common.c
src/5gnrsch/sch_crc.c
src/5gnrsch/sch_drx.c [new file with mode: 0644]
src/5gnrsch/sch_drx.h [new file with mode: 0644]
src/5gnrsch/sch_slot_ind.c
src/5gnrsch/sch_ue_mgr.c
src/cm/du_app_mac_inf.h
src/cm/mac_sch_interface.h
src/cu_stub/cu_f1ap_msg_hdl.c
src/cu_stub/cu_stub.h
src/du_app/du_f1ap_msg_hdl.c
src/du_app/du_mgr.h
src/du_app/du_mgr_main.c
src/du_app/du_ue_mgr.c
src/phy_stub/phy_stub_msg_hdl.c

index b83130e..2e7e9d6 100644 (file)
@@ -138,7 +138,7 @@ uint8_t fillMacCellGroupCfg(MacCellGrpCfg macCellGrp, SchMacCellGrpCfg  *macCell
 
 #ifdef NR_DRX
    /* Copy Drx configuration */
-
+   macCellGrpCfg->drxCfgPresent = true;
    macCellGrpCfg->drxCfg.drxOnDurationTimer.onDurationTimerValInMs = macCellGrp.drxCfg.drxOnDurationTimer.onDurationTimerValInMs;
    if(!macCellGrp.drxCfg.drxOnDurationTimer.onDurationTimerValInMs)
       macCellGrpCfg->drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = \
@@ -1710,6 +1710,12 @@ uint8_t fillSchUeCfg(Pst *pst, SchUeCfg *schUeCfg, MacUeCfg *ueCfg)
       DU_LOG("\nERROR  -->  MAC : Failed to copy LCs at fillSchUeCfg()");
       return ret;
    }
+#ifdef NR_DRX
+   if(ueCfg->drxConfigIndicatorRelease)
+   {
+      schUeCfg->drxConfigIndicatorRelease = true;
+   }
+#endif
    return ret;
 }
 
index 3e485c4..2e9a16c 100644 (file)
@@ -666,6 +666,10 @@ uint8_t schInitCellCb(Inst inst, SchCellCfg *schCellCfg)
    cell->firstSib1Transmitted = false;
    fillSsbStartSymb(cell);
    cmLListInit(&cell->ueToBeScheduled);
+
+#ifdef NR_DRX
+   memset(cell->drxCb, 0, MAX_DRX_SIZE*sizeof(SchDrxCb));
+#endif   
    schCb[inst].cells[inst] = cell;
 
    DU_LOG("\nINFO  -->  SCH : Cell init completed for cellId:%d", cell->cellId);
@@ -1114,6 +1118,13 @@ uint8_t MacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd)
       DU_LOG("\nINFO --> SCH: UL Data transmission not allowed for UE %d", ueCb->ueCfg.ueId);
       return ROK;
    }
+#ifdef NR_DRX
+   if(ueCb->ueDrxInfoPres)
+   {
+      if(!ueCb->drxUeCb.drxUlUeActiveStatus)
+         ueCb->drxUeCb.drxUlUeActiveStatus = true;
+   }
+#endif
    if(uciInd->numSrBits)
    {
       ueCb->srRcvd = true;      
index 4281ef8..11248c1 100644 (file)
 #define HQ_NACK 1
 #define HQ_DTX 2
 
+#ifdef NR_DRX
+/* As per 38.331 the largest offset which can be used in of size 10240.
+ * But using this much size of array can cause memory related issue so thats why
+ * taking this size which are a multiple of the larger size */
+#define MAX_DRX_SIZE 512
+#endif
+
 typedef struct schDlHqProcCb SchDlHqProcCb;
 typedef struct schUlHqEnt SchUlHqEnt;
 typedef struct schRaReq SchRaReq;
@@ -92,6 +99,7 @@ typedef enum
    SCH_UE_HANDIN_IN_PROGRESS
 }SchUeState;
 
+
 typedef enum
 {
    SCH_RA_STATE_MSG2_HANDLE,
@@ -178,6 +186,17 @@ typedef struct schDlHqTbCb
    uint8_t                statsBitmap;
 }SchDlHqTbCb;
 
+#ifdef NR_DRX
+typedef struct schDrxHarqCb
+{
+   uint32_t     retxStrtIndex;     
+   uint32_t     rttIndex;                  
+   uint32_t     retxIndex;        
+   int16_t      retxExpDistance; 
+   uint8_t      retxTmrReduction;     
+}SchDrxHarqCb;
+#endif
+
 typedef struct schUlHqProcCb
 {
    uint8_t           procId;       /*!< HARQ Process ID */
@@ -196,6 +215,9 @@ typedef struct schUlHqProcCb
    uint8_t           dmrsMappingType;
    uint8_t           nrOfDmrsSymbols;
    uint8_t           dmrsAddPos;
+#ifdef NR_DRX
+   SchDrxHarqCb      drxHarqCb;
+#endif
 }SchUlHqProcCb;
 
 struct schDlHqProcCb
@@ -209,6 +231,9 @@ struct schDlHqProcCb
    uint8_t           k1;
    SchLcPrbEstimate  dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/
    CmLList           dlHqProcLink;
+#ifdef NR_DRX
+   SchDrxHarqCb      drxHarqCb;
+#endif
 };
 struct schUlHqEnt
 {
@@ -385,6 +410,38 @@ typedef struct schHqUlMap
    CmLListCp hqList;
 }SchHqUlMap;
 
+#ifdef NR_DRX
+typedef struct  schDrxUeCb
+{
+   bool      drxDlUeActiveStatus;    /* This variable is used to store the status about downlink active status */
+   bool      drxUlUeActiveStatus;    /* This variable is used to store the status about uplink active status */
+   uint32_t  onDurationLen;          /* on duration value recived from ue cfg/recfg */
+   uint32_t  inActvTimerLen;         /* inActvTimer value recived from ue cfg/recfg */
+   uint8_t   harqRttDlTimerLen;      /* harqRttDlTimer value recived from ue cfg/recfg */
+   uint8_t   harqRttUlTimerLen;      /* harqRttUlTimer value recived from ue cfg/recfg */
+   uint32_t  retransDlTimerLen;      /* retransDlTimer value recived from ue cfg/recfg */
+   uint32_t  retransUlTimerLen;      /* retransUlTimer  value recived from ue cfg/recfg */
+   uint32_t  longCycleLen;           /* long Cycle value recived from ue cfg/recfg */
+   bool      longCycleToBeUsed;      /* long cycle should be used once the short cycle gets expires */
+   uint32_t  drxStartOffset;         /* drxStartOffset value recived from ue cfg/recfg */
+   bool      shortCyclePresent;      /* shortCyclePresent value recived from ue cfg/recfg */
+   uint32_t  shortCycleLen;          /* short Cycle value recived from ue cfg/recfg */
+   uint32_t  shortCycleTmrLen;       /* shortCycleTmr value recived from ue cfg/recfg */
+   uint32_t  drxSlotOffset;          /* drxSlotOffset value recived from ue cfg/recfg */
+   uint32_t  onDurationStartIndex;   /* Index at which UE is stored in onDuration starts list */
+   uint32_t  onDurationExpiryIndex;  /* Index at which UE is stored in onDuration expires in the list */ 
+   uint32_t  inActvExpiryIndex;      /* Index at which UE is stored in inActvTimer expires in the list */
+   uint32_t  shortCycleExpiryIndex;  /* Index at which UE is stored in shortCycle expires in the list */
+   int32_t   shortCycleDistance;     /* Distance after how many slot short cycle tmr gets expire */ 
+   int32_t   onDurationStartDistance;/* Distance after how many slot on Duration Start tmr gets expire */
+   int32_t   onDurationExpiryDistance;/* Distance after how many slot on Duration tmr gets expire */
+   int32_t   inActiveTmrExpiryDistance;/* Distance after how many slot inActive tmr gets expire */
+   CmLList   *onDurationStartNodeInfo;
+   CmLList   *onDurationExpiryNodeInfo;
+   CmLList   *inActvTimerExpiryNodeInfo;
+   CmLList   *shortCycleTmrExpiryNodeInfo;
+}SchDrxUeCb;
+#endif
 /**
  * @brief
  * UE control block
@@ -410,6 +467,10 @@ typedef struct schUeCb
    SchHqUlMap   **hqUlmap;
    CmLListCp  ulRetxHqList;
    CmLListCp  dlRetxHqList;
+#ifdef NR_DRX
+   bool           ueDrxInfoPres;
+   SchDrxUeCb     drxUeCb;
+#endif
 }SchUeCb;
 
 /**
@@ -448,6 +509,22 @@ typedef struct schPageCb
    SchPagingOcc pagMonOcc[MAX_PO_PER_PF];   /*Paging Occasion Slot/FrameOffset are stored*/ 
 }SchPageCb;
 
+#ifdef NR_DRX
+typedef struct schDrxCb
+{
+   CmLListCp   onDurationStartList;   /*!< Tracks the start of onDuration Timer. */
+   CmLListCp   onDurationExpiryList;   /*!< Tracks the Expiry of onDuration Timer. */
+   CmLListCp   inActvTmrExpiryList;   /*!< Tracks the Expiry of drx-InactivityTimer. */
+   CmLListCp   shortCycleExpiryList;   /*!< Tracks the Expiry of DRX Short Cycle. */
+   CmLListCp   dlHarqRttExpiryList;   /*!< Tracks the Expiry of DL HARQ RTT timer. */
+   CmLListCp   dlRetransExpiryList;   /*!< Tracks the Expiry of DL Re-Transmission timer. */
+   CmLListCp   ulHarqRttExpiryList;   /*!< Tracks the Expiry of UL HARQ RTT timer. */
+   CmLListCp   ulRetransExpiryList;   /*!< Tracks the Expiry of UL Re-Transmission timer. */
+   CmLListCp   dlRetransTmrStartList; /*!< It has list of DL harq procs for */
+   CmLListCp   ulRetransTmrStartList; /*!< It has list of UL harq procs for */
+}SchDrxCb;
+#endif
+
 /**
  * @brief
  * Cell Control block per cell.
@@ -479,6 +556,9 @@ typedef struct schCellCb
    uint32_t      slotFrmtBitMap;                    /*!< 2 bits must be read together to determine D/U/S slots. 00-D, 01-U, 10-S */
    uint32_t      symbFrmtBitMap;                    /*!< 2 bits must be read together to determine D/U/S symbols. 00-D, 01-U, 10-S */
 #endif
+#ifdef NR_DRX
+   SchDrxCb      drxCb[MAX_DRX_SIZE];                           /*!< Drx cb*/
+#endif
 }SchCellCb;
 
 
index bc5ca0f..204affa 100644 (file)
@@ -470,6 +470,7 @@ uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst, SlotTiming
 uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
 {
    int ret = ROK;
+   SchUeCb   *ueCb;
    UlSchedInfo ulSchedInfo;
    SchUlSlotInfo  *schUlSlotInfo = NULLP;
    SlotTimingInfo ulTimingInfo;
@@ -491,6 +492,15 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
    if(schUlSlotInfo->schPuschInfo)
    {
       ulSchedInfo.crnti = schUlSlotInfo->schPuschInfo->crnti;
+      /* Check the ue drx status if the UE is active for uplink scheduling or not  */
+#ifdef NR_DRX 
+      ueCb = schGetUeCb(cell, ulSchedInfo.crnti);
+      if(ueCb->ueDrxInfoPres)
+      {
+         if(ueCb->drxUeCb.drxUlUeActiveStatus)
+            return RFAILED;
+      }
+#endif
       ulSchedInfo.dataType |= SCH_DATATYPE_PUSCH;
       memcpy(&ulSchedInfo.schPuschInfo, schUlSlotInfo->schPuschInfo,
            sizeof(SchPuschInfo));
index 4aa9f81..406d67f 100644 (file)
@@ -76,35 +76,38 @@ uint8_t schProcessCrcInd(CrcIndInfo *crcInd, Inst schInst)
       }
       else
       {
-         if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.count == 0)
+         if(cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot])
          {
-            DU_LOG("\n ERROR no harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId);
-            continue;
-         }
-         if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first == 0)
-         {
-            DU_LOG("\n ERROR NULL harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId);
-            continue;
-         }
-         hqP = (SchUlHqProcCb*) cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first->node;
-         if(hqP == NULLP)
-         {
-            continue;
-         }
-         else
-         {
-            if (crcInd->crcInd[count])
-            {             
-               /* failure case*/
-               schUlHqProcessNack(hqP);
+            if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.count == 0)
+            {
+               DU_LOG("\n ERROR no harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId);
+               continue;
+            }
+            if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first == 0)
+            {
+               DU_LOG("\n ERROR NULL harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId);
+               continue;
+            }
+            hqP = (SchUlHqProcCb*) cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first->node;
+            if(hqP == NULLP)
+            {
+               continue;
             }
             else
             {
-               /* pass case*/
-               schUlHqProcessAck(hqP);
+               if (crcInd->crcInd[count])
+               {             
+                  /* failure case*/
+                  schUlHqProcessNack(hqP);
+               }
+               else
+               {
+                  /* pass case*/
+                  schUlHqProcessAck(hqP);
+               }
             }
+            cmLListDelFrm(&(cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList), &hqP->ulSlotLnk);
          }
-         cmLListDelFrm(&(cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList), &hqP->ulSlotLnk);
       }
       count++;
    }
@@ -112,4 +115,4 @@ uint8_t schProcessCrcInd(CrcIndInfo *crcInd, Inst schInst)
 }
 /**********************************************************************
   End of file
- **********************************************************************/
\ No newline at end of file
+ **********************************************************************/
diff --git a/src/5gnrsch/sch_drx.c b/src/5gnrsch/sch_drx.c
new file mode 100644 (file)
index 0000000..66ab9d0
--- /dev/null
@@ -0,0 +1,1007 @@
+
+/*******************************************************************************
+################################################################################
+#   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.                                             #
+################################################################################
+ *******************************************************************************/
+#ifdef NR_DRX
+#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_drx.h"
+
+/**
+ * @brief intialize the SchDrxHarqCb structre 
+ *
+ * @details
+ *
+ *     Function :schInitDrxHarqCb 
+ *      
+ *     intialize the SchDrxHarqCb structre 
+ *           
+ *  @param[in] SchDrxHarqCb *hqCb 
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schInitDrxHarqCb(SchDrxHarqCb *hqDrxCb)
+{
+   memset(hqDrxCb, 0, sizeof(SchDrxHarqCb));
+   hqDrxCb->retxExpDistance  = SCH_DRX_INVALID_DISTANCE;
+   hqDrxCb->retxStrtIndex    = SCH_DRX_INVALID_INDEX;
+   hqDrxCb->rttIndex         = SCH_DRX_INVALID_INDEX;
+   hqDrxCb->retxIndex        = SCH_DRX_INVALID_INDEX;
+}
+
+/**
+ * @brief intialize the SchDrxUeCb structre 
+ *
+ * @details
+ *
+ *     Function : schInitDrxUeCb 
+ *      
+ *     intialize the SchDrxUeCb structre 
+ *           
+ *  @param[in]  SchUeCb *ueCb 
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schInitDrxUeCb(SchUeCb *ueCb)
+{
+   memset(&ueCb->drxUeCb, 0, sizeof(SchDrxUeCb));
+   ueCb->drxUeCb.onDurationStartIndex  = SCH_DRX_INVALID_INDEX;
+   ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
+   ueCb->drxUeCb.inActvExpiryIndex     = SCH_DRX_INVALID_INDEX;
+   ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
+   ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE;
+   ueCb->drxUeCb.onDurationExpiryDistance = SCH_DRX_INVALID_DISTANCE;
+   ueCb->drxUeCb.inActiveTmrExpiryDistance = SCH_DRX_INVALID_DISTANCE;
+   ueCb->drxUeCb.drxDlUeActiveStatus = false; 
+   ueCb->drxUeCb.drxUlUeActiveStatus = false; 
+}
+#if 0
+/* will uncomment this function in next gerrit */
+/**
+ * @brief delete Dl harq drx timers and information 
+ *
+ * @details
+ *
+ *     Function : schDeleteDlHarqDrxTimer
+ *      
+ *     delete Dl harq drx timers and information 
+ *           
+ *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+ void schDeleteDlHarqDrxTimer(SchCellCb  *cell, SchDlHqEnt *dlHqEnt)
+ {
+    uint8_t idx, numHqPrcs;
+    uint16_t tmrIdx = 0;
+    SchDlHqProcCb *procs;
+    CmLList  *node = NULLP;
+   
+    numHqPrcs = dlHqEnt->numHqPrcs;
+    for(idx =0; idx<numHqPrcs; idx++)
+    {
+       procs = &dlHqEnt->procs[idx];
+       tmrIdx = procs->drxHarqCb.retxStrtIndex;
+       CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node);
+       if(node)
+       {
+          cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node);
+          SCH_FREE(node, sizeof(CmLList));
+       }
+
+       tmrIdx = procs->drxHarqCb.rttIndex;
+       CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node);
+       if(node)
+       {
+          cmLListDelFrm(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node);
+          SCH_FREE(node, sizeof(CmLList));
+       }
+
+       tmrIdx = procs->drxHarqCb.retxIndex;
+       CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransExpiryList, node);
+       if(node)
+       {
+          cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransExpiryList, node);
+          SCH_FREE(node, sizeof(CmLList));
+       }
+       schInitDrxHarqCb(&procs->drxHarqCb);
+    }
+ }
+
+/**
+ * @brief delete UL harq drx timers and information 
+ *
+ * @details
+ *
+ *     Function : schDeleteUlHarqDrxTimer
+ *      
+ *     delete Ul harq drx timers and information 
+ *           
+ *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+ void schDeleteUlHarqDrxTimer(SchCellCb  *cell, SchUlHqEnt *ulHqEnt)
+ {
+    uint8_t idx, numHqPrcs;
+    uint16_t tmrIdx = 0;
+    CmLList  *node = NULLP;
+    SchUlHqProcCb *procs;
+
+    numHqPrcs = ulHqEnt->numHqPrcs;
+    for(idx =0; idx<numHqPrcs; idx++)
+    {
+       procs = &ulHqEnt->procs[idx];
+       tmrIdx = procs->drxHarqCb.retxStrtIndex;
+       CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node);
+       if(node)
+       {
+          cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node);
+          SCH_FREE(node, sizeof(CmLList));
+       }
+
+       tmrIdx = procs->drxHarqCb.rttIndex;
+       CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node);
+       if(node)
+       {
+          cmLListDelFrm(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node);
+          SCH_FREE(node, sizeof(CmLList));
+       }
+
+       tmrIdx = procs->drxHarqCb.retxIndex;
+       CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransExpiryList, node);
+       if(node)
+       {
+          cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransExpiryList, node);
+          SCH_FREE(node, sizeof(CmLList));
+       }
+       schInitDrxHarqCb(&procs->drxHarqCb);
+    }
+ }
+#endif
+/**
+ * @brief delete UE drx timers and information 
+ *
+ * @details
+ *
+ *     Function : schDeleteUeDrxInfo
+ *      
+ *     delete UE drx timers and information 
+ *           
+ *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schDeleteUeDrxInfo(SchCellCb  *cell, SchUeCb *ueCb)
+{
+   SchDrxUeCb *drxUeCb;
+
+   if(ueCb->ueDrxInfoPres == true)
+   {
+      drxUeCb = &ueCb->drxUeCb;
+      
+      /* delete on duration start timer from ueCb */
+      if(drxUeCb->onDurationStartIndex != SCH_DRX_INVALID_INDEX)
+      {
+         cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationStartIndex].onDurationStartList, drxUeCb->onDurationStartNodeInfo);
+         SCH_FREE(drxUeCb->onDurationStartNodeInfo, sizeof(CmLList));
+      }
+      
+      /* delete on duration expiry timer from ueCb */
+      if(drxUeCb->onDurationExpiryIndex != SCH_DRX_INVALID_INDEX)
+      {
+         cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationExpiryIndex].onDurationExpiryList, drxUeCb->onDurationExpiryNodeInfo);
+         SCH_FREE(drxUeCb->onDurationExpiryNodeInfo, sizeof(CmLList));
+      }
+      
+      /* delete inActv Expiry Index timer from ueCb */
+      if(drxUeCb->inActvExpiryIndex != SCH_DRX_INVALID_INDEX)
+      {
+         cmLListDelFrm(&cell->drxCb[drxUeCb->inActvExpiryIndex].inActvTmrExpiryList, drxUeCb->inActvTimerExpiryNodeInfo);
+         SCH_FREE(drxUeCb->inActvTimerExpiryNodeInfo, sizeof(CmLList));
+      }
+      
+      /* delete short cycle expiry timer from ueCb */
+      if(drxUeCb->shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX)
+      {
+         cmLListDelFrm(&cell->drxCb[drxUeCb->shortCycleExpiryIndex].shortCycleExpiryList, drxUeCb->shortCycleTmrExpiryNodeInfo);
+         SCH_FREE(drxUeCb->shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
+      }
+      /* TODO - will uncomment this function in next gerrit */
+      //schDeleteDlHarqDrxTimer(cell, &ueCb->dlHqEnt);
+      //schDeleteUlHarqDrxTimer(cell, &ueCb->ulHqEnt);
+      schInitDrxUeCb(ueCb);
+   }
+}
+
+/**
+ * @brief fill drxUeCb structure with the help of ue cfg/recfg information
+ *
+ * @details
+ *
+ *     Function : schFillDrxUeCb
+ *      
+ *      fill drxUeCb structure with the help of ue cfg/recfg information
+ *           
+ *  @param[in] SchDrxCfg drxCfg ->configuration received from ue cfg/recfg api
+ *            SchDrxUeCb *drxUeCb -> structure that need to be fill
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schFillDrxUeCb(uint8_t numerology, SchDrxCfg drxCfg, SchDrxUeCb *drxUeCb)
+{
+   if(drxCfg.drxOnDurationTimer.onDurationTimerValInMs) 
+   {
+      SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.milliSeconds, numerology); 
+   }
+   else
+   {
+      SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds, numerology);
+      drxUeCb->onDurationLen = drxUeCb->onDurationLen >> 5;
+   }   
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->inActvTimerLen, drxCfg.drxInactivityTimer, numerology);
+   SCH_CNVRT_SYMBL_TO_SLOT(drxUeCb->harqRttDlTimerLen, drxCfg.drxHarqRttTimerDl);
+   SCH_CNVRT_SYMBL_TO_SLOT(drxUeCb->harqRttUlTimerLen, drxCfg.drxHarqRttTimerUl);
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->retransDlTimerLen, drxCfg.drxRetransmissionTimerDl, numerology);
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->retransUlTimerLen, drxCfg.drxRetransmissionTimerUl, numerology);
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->longCycleLen, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice, numerology);
+   drxUeCb->drxStartOffset =  drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetVal;
+   if(drxCfg.shortDrxPres)
+   {
+      drxUeCb->shortCyclePresent = true;                  
+      SCH_CNVRT_MS_TO_SLOT(drxUeCb->shortCycleLen, drxCfg.shortDrx.drxShortCycle, numerology);   
+      drxUeCb->shortCycleTmrLen = drxCfg.shortDrx.drxShortCycleTimer;  
+   }
+   else
+      drxUeCb->longCycleToBeUsed = true;
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxSlotOffset, drxCfg.drxSlotOffset, numerology);  
+   drxUeCb->drxSlotOffset = drxUeCb->drxSlotOffset>>5; 
+}
+
+/**
+ * @brief Add new entry into the drx timer list
+ *
+ * @details
+ *
+ *     Function : schAddDrxTimerIntoList 
+ *      
+ *      Add new entry into the drx timer list
+ *           
+ *  @param[in] CmLListCp *drxTimerList -> List in which new entery have to add
+ *            void * ueInfo -> ue information which is need to the added into list
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+uint8_t schAddDrxTimerIntoList(CmLListCp *drxTimerList,void * nodeInfo, CmLList *drxNodeInfo)
+{
+   CmLList  *currentNodeInfo = NULLP;
+
+   SCH_ALLOC(currentNodeInfo, sizeof(CmLList));
+   if(!currentNodeInfo)
+   {
+      DU_LOG("\nERROR  --> SCH : schAddDrxTimerIntoList() : Memory allocation failed");
+      return RFAILED;
+   }
+
+   currentNodeInfo->node = (PTR)nodeInfo;
+   
+   cmLListAdd2Tail(drxTimerList, currentNodeInfo);
+   drxNodeInfo = currentNodeInfo;
+   return ROK;
+}
+
+/**
+ * @brief This function is used to find the next onduration start timing
+ *
+ * @details
+ *
+ *     Function : findNextOndurationOccurance 
+ *      
+ *      This function is used to find the next onduration start timing
+ *           
+ *  @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur,
+ *  uint8_t delta
+ *            
+ *  @return  
+ *      -# void
+ **/
+void findNextOndurationOccurance(SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur, uint8_t delta)
+{
+   uint16_t   resultX, reusltY, idx;
+   uint32_t   curTime, cycleLen, nxtDist;
+   SlotTimingInfo  tmpTime;
+
+   if (ueDrxCb->longCycleToBeUsed == true)
+   {
+      cycleLen = ueDrxCb->longCycleLen;
+   }
+   else
+   {
+      cycleLen = ueDrxCb->shortCycleLen;
+   }
+
+   /* Add delta to current time */
+   ADD_DELTA_TO_TIME(cell->slotInfo, tmpTime, delta);
+   
+   /* Convert tmpTime to number of slots */
+   curTime = ((tmpTime.sfn * MAX_SLOTS) + tmpTime.slot);
+   
+   /* as per 38.321,  if the criterion below is satisfied, then that sfn and
+    * slot are the correct ones for the on-duration timer.
+    * if the Short DRX Cycle is used, and [(SFN Ã— 10) + subframe number] modulo
+    * (drx-ShortCycle) = (drxStartOffset) modulo (drx-ShortCycle); or
+    * if the Long DRX Cycle is used, and [(SFN Ã— 10) + subframe number] modulo
+    * (drx-LongCycle) = drxStartOffset  */
+   for(idx =1; idx<MAX_DRX_SIZE; idx++)
+   {
+      resultX = (tmpTime.sfn *10+tmpTime.slot) % cycleLen;
+      if (TRUE != ueDrxCb->shortCyclePresent)
+         reusltY = ueDrxCb->drxStartOffset;
+      else
+         reusltY = ueDrxCb->drxStartOffset % cycleLen;
+      if(resultX == reusltY)
+      {
+         memcpy(nxtOnDur, &tmpTime, sizeof(SlotTimingInfo));
+         nxtDist = ((nxtOnDur->sfn * MAX_SLOTS) + nxtOnDur->slot);
+         break;
+      }
+      else
+      {
+         ADD_DELTA_TO_TIME(tmpTime, tmpTime, 1);
+      }
+   }
+
+   /* If slot offset is non-zero then Add slot offset to the calculated onDur
+    * distance */
+   if(ueDrxCb->drxSlotOffset)
+   {
+      nxtDist = nxtDist + ueDrxCb->drxSlotOffset;
+      ADD_DELTA_TO_TIME(tmpTime, tmpTime, ueDrxCb->drxSlotOffset);
+      memcpy(nxtOnDur, &tmpTime, sizeof(SlotTimingInfo));
+   }
+   /*If next On Duration is less than DL DELTA ahead, we will miss it and
+    * hence need to move to the On-Duration after that.*/
+   if((nxtDist - (curTime - delta)) <= SCH_DRX_MAX_DELTA)
+   {
+      ADD_DELTA_TO_TIME(tmpTime, tmpTime, cycleLen);
+      memcpy(nxtOnDur, &tmpTime, sizeof(SlotTimingInfo));
+   }
+}
+
+/**
+ * @brief Add entry into  the on duration list and short cycle list
+ *
+ * @details
+ *
+ *     Function : schDrxUeReCfgTimer 
+ *      
+ *      This function is used to Add entry into  the on duration list and short
+ *      cycle list
+ *           
+ *  @param[in] SchCellCb *cell,   SchUeCb *ueCb
+ *  uint8_t delta
+ *            
+ *  @return  
+ **/
+void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb)
+{
+   uint8_t  onDurIndx, currentSlotIndx;
+   uint32_t onDurTime, onDurExpSlotTime, currentSlotTime;
+   uint32_t cycleLen;
+   SlotTimingInfo onDurationOccurance;
+
+   if(ueCb->drxUeCb.shortCyclePresent == false)   
+   {
+      /* if short cycle configuration are not recived as a part of UE Recfg then if there is any entry present in short cycle timer list 
+       * remove the entry from the list */ 
+      if(ueCb->drxUeCb.shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX)
+      {
+         cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.shortCycleExpiryIndex ].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
+         SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
+         ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
+         ueCb->drxUeCb.shortCycleDistance = SCH_DRX_INVALID_DISTANCE;
+      }
+   }
+   /* If there is any entry present in on duration start list then remove the
+    * entry from the list and recaluate the nect onduration cucurance */
+   if(ueCb->drxUeCb.onDurationStartIndex != SCH_DRX_INVALID_INDEX)
+   {
+      cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
+      SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
+      ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX;
+      ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE;
+   }
+
+   findNextOndurationOccurance(cell,  &ueCb->drxUeCb, &onDurationOccurance, 0);
+   onDurTime = onDurationOccurance.sfn*MAX_SLOTS+onDurationOccurance.slot;
+   onDurIndx = onDurTime%MAX_DRX_SIZE;
+   /* If Onduration timer of old configuration is already running then next onduration 
+    * starts once it expires*/
+   if((ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE) && (ueCb->drxUeCb.onDurationExpiryIndex == SCH_DRX_INVALID_INDEX))
+   {
+       currentSlotTime = cell->slotInfo.sfn * MAX_SLOTS + cell->slotInfo.slot;
+       currentSlotIndx = (currentSlotTime + PHY_DELTA_DL + SCHED_DELTA)%MAX_DRX_SIZE;
+       if(currentSlotIndx >= ueCb->drxUeCb.onDurationExpiryIndex )
+       {
+         onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance +1) * MAX_DRX_SIZE) + (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA);
+       }
+       else
+       {
+         
+         onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance) * MAX_DRX_SIZE) + (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA);
+       }
+       if(onDurTime <= onDurExpSlotTime)
+       {
+          if(ueCb->drxUeCb.longCycleToBeUsed == true)
+             cycleLen = ueCb->drxUeCb.longCycleLen;
+          else
+             cycleLen = ueCb->drxUeCb.shortCycleLen;
+
+          onDurTime = onDurTime + ((onDurExpSlotTime - onDurTime)/cycleLen + 1) * cycleLen;
+       }
+   }
+   onDurIndx = onDurTime%MAX_DRX_SIZE;
+   ueCb->drxUeCb.onDurationStartIndex = onDurIndx;
+   ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, MAX_SLOTS)/MAX_DRX_SIZE;
+   schAddDrxTimerIntoList(&cell->drxCb[onDurIndx].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
+   if((TRUE == ueCb->drxUeCb.shortCyclePresent) &&(ueCb->drxUeCb.longCycleToBeUsed == false))
+   {
+      /* Starting Short Cycle Timer */
+      ueCb->drxUeCb.shortCycleDistance = (ueCb->drxUeCb.shortCycleTmrLen * ueCb->drxUeCb.shortCycleLen) / MAX_DRX_SIZE;
+      ueCb->drxUeCb.shortCycleExpiryIndex = (onDurTime + (ueCb->drxUeCb.shortCycleTmrLen * ueCb->drxUeCb.shortCycleLen)) % MAX_DRX_SIZE;
+      schAddDrxTimerIntoList(&cell->drxCb[ ueCb->drxUeCb.shortCycleExpiryIndex].shortCycleExpiryList, ueCb, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
+      DU_LOG("\nPBORLA ShortCycleE Added %d",ueCb->drxUeCb.shortCycleExpiryIndex);
+   }
+}
+/**
+ * @brief Add entry into  the on duration list and short cycle list
+ *
+ * @details
+ *
+ *     Function : schAddUeInOndurationAndShortCycleList
+ *      
+ *      This function is used to Add entry into  the on duration list and short
+ *      cycle list
+ *           
+ *  @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur,
+ *  uint8_t delta
+ *            
+ *  @return  
+ *      -# void
+ **/
+void schAddUeInOndurationAndShortCycleList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta)
+{
+   uint8_t  onDurIndx;
+   uint32_t onDurTime;
+   SlotTimingInfo onDurationOccurance;
+
+   if(ueCb->ueDrxInfoPres)
+   {
+      findNextOndurationOccurance(cell,  &ueCb->drxUeCb, &onDurationOccurance, delta);
+      onDurTime = onDurationOccurance.sfn*MAX_SLOTS+onDurationOccurance.slot;
+      onDurIndx = onDurTime%MAX_DRX_SIZE;
+      ueCb->drxUeCb.onDurationStartIndex = onDurIndx;
+      ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, MAX_SLOTS)/MAX_DRX_SIZE;
+      schAddDrxTimerIntoList(&cell->drxCb[onDurIndx].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
+
+      if((TRUE == ueCb->drxUeCb.shortCyclePresent) &&(ueCb->drxUeCb.longCycleToBeUsed == false))
+      {
+         /* Starting Short Cycle Timer */
+         ueCb->drxUeCb.shortCycleDistance = (ueCb->drxUeCb.shortCycleTmrLen * ueCb->drxUeCb.shortCycleLen) / MAX_DRX_SIZE;
+         ueCb->drxUeCb.shortCycleExpiryIndex = (onDurTime + (ueCb->drxUeCb.shortCycleTmrLen * ueCb->drxUeCb.shortCycleLen)) % MAX_DRX_SIZE;
+         schAddDrxTimerIntoList(&cell->drxCb[ ueCb->drxUeCb.shortCycleExpiryIndex].shortCycleExpiryList, ueCb, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
+         DU_LOG("\nPBORLA ShortCycleE Added %d",ueCb->drxUeCb.shortCycleExpiryIndex);
+      }
+   }
+}
+/**
+ * @brief Handling of On duration drx start timer
+ *
+ * @details
+ *
+ *     Function : schHdlDrxOnDurStrtTimerForUlandDlDirection
+ *
+ *      Handling of On duration drx start timer
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxOnDurStrtTimerForUlandDlDirection(SchCellCb  *cell, uint16_t currListIndx, bool isDlDirection)
+{
+   uint16_t onDurationExpiry=0;
+   CmLList  *drxCurrNode = NULLP;
+   SchUeCb *ueCb = NULLP;
+
+   drxCurrNode = cell->drxCb[currListIndx].onDurationStartList.first;
+   if(drxCurrNode)
+   {
+      /* Handling of dl On duration drx start list */
+      while(drxCurrNode)
+      {
+         ueCb = (SchUeCb*)drxCurrNode->node;
+         ueCb->drxUeCb.onDurationStartDistance--;
+         if(ueCb->drxUeCb.onDurationStartDistance != SCH_DRX_INVALID_DISTANCE)
+         {
+            continue;
+         }
+         else
+         {
+            if(isDlDirection == true)
+               ueCb->drxUeCb.drxDlUeActiveStatus = true;
+            else
+               ueCb->drxUeCb.drxUlUeActiveStatus = true;
+
+            DU_LOG("\nPBORLA drxUeCb.drxUlUeActiveStatus drxUeCb.drxDlUeActiveStatus [%d:%d] line %d",  ueCb->drxUeCb.drxUlUeActiveStatus, ueCb->drxUeCb.drxDlUeActiveStatus,__LINE__);
+               
+            /* If there is any entery present in onDurationExpiry list remove
+             * the entery from the list and recalculate the
+             * onDurationExpiry time and add it to list */
+            if(ueCb->drxUeCb.onDurationExpiryIndex != SCH_DRX_INVALID_INDEX) 
+            {
+               cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationExpiryIndex].onDurationExpiryList, ueCb->drxUeCb.onDurationExpiryNodeInfo);
+               SCH_FREE(ueCb->drxUeCb.onDurationExpiryNodeInfo, sizeof(CmLList));
+               ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
+            }
+
+            /* onDurationExpiry  = (current slot + onduration length) % MAX_DRX_SIZE*/
+            onDurationExpiry = (currListIndx + ueCb->drxUeCb.onDurationLen)%MAX_DRX_SIZE;
+            ueCb->drxUeCb.onDurationExpiryDistance =  (ueCb->drxUeCb.onDurationLen)/MAX_DRX_SIZE;
+            schAddDrxTimerIntoList(&cell->drxCb[onDurationExpiry].onDurationExpiryList, ueCb, ueCb->drxUeCb.onDurationExpiryNodeInfo);
+            ueCb->drxUeCb.onDurationExpiryIndex = onDurationExpiry;
+            
+            /* if there is any entry present in onduration list remove the entry from the list  */
+            DU_LOG("\nPBORLA ONDURATION START HIT %d %d startIndx %d [%d %d]",\
+                  currListIndx, ueCb->drxUeCb.onDurationStartDistance,ueCb->drxUeCb.onDurationStartIndex, cell->slotInfo.sfn,cell->slotInfo.slot);
+            cmLListDelFrm(&cell->drxCb[currListIndx].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
+            SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
+            ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX;
+            /* if there long cycle length is used as the cycle length for  onduration calculation then based on that calculating next onduration occurance 
+             * other wise next onduration is calcuated based on short cycle
+             * timer */
+            if(ueCb->drxUeCb.longCycleToBeUsed)
+            {
+               schAddUeInOndurationAndShortCycleList(cell, ueCb, 0);
+            }
+         }
+         drxCurrNode = drxCurrNode->next;
+      }
+   }
+}
+/**
+ * @brief Handling of On duration drx start timer
+ *
+ * @details
+ *
+ *     Function : schHdlDrxOnDurStrtTimer
+ *
+ *      Handling of On duration drx start timer
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxOnDurStrtTimer(SchCellCb  *cell)
+{
+   uint16_t dlIndx = 0, ulIndx=0;
+   SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+   ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo,  PHY_DELTA_DL + SCHED_DELTA);
+   ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo,  PHY_DELTA_UL + SCHED_DELTA);
+   
+   dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+   ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+   schHdlDrxOnDurStrtTimerForUlandDlDirection(cell, dlIndx, true);
+   schHdlDrxOnDurStrtTimerForUlandDlDirection(cell, ulIndx, false);
+}
+/**
+ * @brief Handling of short cycle drx start timer
+ *
+ * @details
+ *
+ *     Function : schHdlDrxStartShortCycleTimer 
+ *
+ *      Handling of short cycle drx start timer
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+ void schHdlDrxStartShortCycleTimer(SchCellCb  *cell, SchUeCb *ueCb)
+ {
+   ueCb->drxUeCb.longCycleToBeUsed = false; 
+   schAddUeInOndurationAndShortCycleList(cell, ueCb, PHY_DELTA_DL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+ }
+/**
+ * @brief Handling of the  DRX inactv timers start
+ *
+ * @details
+ *
+ *     Function : schHdlDrxInActvStrtTmr  
+ *
+ *      Handling of DRX in active timers start
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+ void schHdlDrxInActvStrtTmr(SchCellCb  *cell,  SchUeCb *ueCb, uint8_t delta)
+ {
+    uint16_t slotIndx = 0;
+    SlotTimingInfo tmpSlotInfo;
+    
+    if(ueCb->drxUeCb.inActvTimerLen == 0)
+    {
+       return;
+    }
+    ADD_DELTA_TO_TIME(cell->slotInfo, tmpSlotInfo,  delta);
+    slotIndx = (tmpSlotInfo.sfn*MAX_SLOTS+tmpSlotInfo.slot)%MAX_DRX_SIZE;
+
+    DU_LOG("\nPBORLA IN ACTV START HIT %d %d", cell->slotInfo.sfn, cell->slotInfo.slot); 
+    /* if there is nay old entry present in the list remove the entry*/
+    if(ueCb->drxUeCb.inActvExpiryIndex != SCH_DRX_INVALID_INDEX)
+    {
+       cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.inActvExpiryIndex].inActvTmrExpiryList, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
+       SCH_FREE(ueCb->drxUeCb.inActvTimerExpiryNodeInfo, sizeof(CmLList));
+       ueCb->drxUeCb.inActvExpiryIndex= SCH_DRX_INVALID_INDEX;
+       ueCb->drxUeCb.inActiveTmrExpiryDistance= SCH_DRX_INVALID_DISTANCE;
+    }
+    /* Adding the new entry in in activity timer list */
+    ueCb->drxUeCb.inActvExpiryIndex = (slotIndx + ueCb->drxUeCb.inActvTimerLen) % MAX_DRX_SIZE;
+    ueCb->drxUeCb.inActiveTmrExpiryDistance = (ueCb->drxUeCb.inActvTimerLen) / MAX_DRX_SIZE;
+    schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.inActvExpiryIndex].inActvTmrExpiryList, ueCb, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
+
+    /* Set the UE active for UL And Dl transfer */
+    ueCb->drxUeCb.drxDlUeActiveStatus = true;
+    ueCb->drxUeCb.drxUlUeActiveStatus = true;
+    DU_LOG("\nPBORLA drxUeCb.drxUlUeActiveStatus drxUeCb.drxDlUeActiveStatus [%d:%d] line %d",  ueCb->drxUeCb.drxUlUeActiveStatus, ueCb->drxUeCb.drxDlUeActiveStatus,__LINE__);
+
+ }
+/**
+ * @brief Handling of the  DRX timers start
+ *
+ * @details
+ *
+ *     Function : schHandleStartDrxTimer
+ *
+ *      Handling of DRX timers start
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHandleStartDrxTimer(SchCellCb  *cell)
+{
+   /* Handling the onduration start timea*/
+   schHdlDrxOnDurStrtTimer(cell);
+}
+
+/**
+ * @brief Handling of the expiry ShortCycle DRX timers
+ *
+ * @details
+ *
+ *     Function : schHdlDrxShortCycleExpiryTimerForUlandDlDirection 
+ *
+ *      Handling of expiry ShortCycle 
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxShortCycleExpiryTimerForUlandDlDirection(SchCellCb  *cell, uint16_t currListIndx, bool isDlDirection)
+{
+   CmLList  *drxCurrNode = NULLP;
+   SchUeCb *ueCb = NULLP;
+   SchUeCb *tempUeCb = NULLP;
+
+   drxCurrNode = cell->drxCb[currListIndx].shortCycleExpiryList.first;
+   if(drxCurrNode)
+   {
+      /* Handling of dl On duration drx start list */
+      while(drxCurrNode)
+      {
+         ueCb = (SchUeCb*)drxCurrNode->node;
+         if(ueCb->ueDrxInfoPres)
+         {
+            if(ueCb->drxUeCb.shortCycleDistance != SCH_DRX_INVALID_DISTANCE)
+               ueCb->drxUeCb.shortCycleDistance--;
+
+            if(ueCb->drxUeCb.shortCycleDistance== SCH_DRX_INVALID_DISTANCE)
+            {
+               DU_LOG("\nPBORLA ShortCycleE EXP HIT %d",currListIndx);
+               ueCb->drxUeCb.longCycleToBeUsed = true;
+               /* Remove Short Cycle timer from the list */
+               cmLListDelFrm(&cell->drxCb[currListIndx].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
+               SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
+               ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
+               
+               /* calculating the next duration event 
+               If another entry is found in the On duration list, it must first be removed 
+               before the next On duration occurrences may be calculated  */
+               if(ueCb->drxUeCb.onDurationStartIndex != SCH_DRX_INVALID_INDEX)
+               {
+                  cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
+                  SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
+                  tempUeCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE;
+                  tempUeCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX;
+               }
+               if(isDlDirection == true)
+                  schAddUeInOndurationAndShortCycleList(cell, ueCb, PHY_DELTA_DL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+               else
+                  schAddUeInOndurationAndShortCycleList(cell, ueCb, PHY_DELTA_UL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+
+            }
+            else
+               continue;
+         }
+         drxCurrNode = drxCurrNode->next;
+      }
+   }
+}
+
+
+/**
+ * @brief Handling of the expiry ShortCycle DRX timers
+ *
+ * @details
+ *
+ *     Function :schHdlDrxShortCycleExpiryTimer 
+ *
+ *      Handling of expiry ShortCycle 
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxShortCycleExpiryTimer(SchCellCb  *cell)
+{
+   uint16_t dlIndx = 0, ulIndx= 0;
+   SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+   ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+   ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+   dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+   ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+   
+   schHdlDrxShortCycleExpiryTimerForUlandDlDirection(cell, dlIndx, true);
+   schHdlDrxShortCycleExpiryTimerForUlandDlDirection(cell, ulIndx, false);
+}
+
+/**
+ * @brief Handling of the expiry onduration DRX timers for specific direction
+ *
+ * @details
+ *
+ *     Function :schHdlDrxOnDurExpiryTimerForUlandDlDirection 
+ *
+ *      Handling of expiry onduration DRX timers
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxOnDurExpiryTimerForUlandDlDirection(SchCellCb  *cell, uint16_t currListIndx, bool isDlDirection)
+{
+   CmLList  *drxCurrNode;
+   SchUeCb *ueCb = NULLP;
+
+   drxCurrNode = cell->drxCb[currListIndx].onDurationExpiryList.first;
+   if(drxCurrNode)
+   {
+      /* Handling of dl On duration drx start list */
+      while(drxCurrNode)
+      {
+         ueCb = (SchUeCb*)drxCurrNode->node;
+         if(ueCb->ueDrxInfoPres)
+         {
+            ueCb->drxUeCb.onDurationExpiryDistance--;
+
+            if(ueCb->drxUeCb.onDurationExpiryDistance== SCH_DRX_INVALID_DISTANCE)
+            {
+
+               DU_LOG("\nPBORLA ONDURATION EXP HIT %d[%d:%d]",currListIndx, cell->slotInfo.sfn, cell->slotInfo.slot);
+
+               /* delete on duration expiry timer from ueCb */
+               if(drxCurrNode->node)
+               {
+                  cmLListDelFrm(&cell->drxCb[currListIndx].onDurationExpiryList, ueCb->drxUeCb.onDurationExpiryNodeInfo);
+                  SCH_FREE(ueCb->drxUeCb.onDurationExpiryNodeInfo, sizeof(CmLList));
+                  ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
+               }
+               if(isDlDirection == true)
+                  ueCb->drxUeCb.drxDlUeActiveStatus = false;
+               else
+                  ueCb->drxUeCb.drxUlUeActiveStatus = false;
+               DU_LOG("\nPBORLA drxUeCb.drxUlUeActiveStatus drxUeCb.drxDlUeActiveStatus [%d:%d] line %d",  ueCb->drxUeCb.drxUlUeActiveStatus, ueCb->drxUeCb.drxDlUeActiveStatus,__LINE__);
+            }
+            else
+               continue;
+         }
+         drxCurrNode = drxCurrNode->next;
+      }
+   }
+}
+
+
+/**
+ * @brief Handling of the expiry onduration DRX timers
+ *
+ * @details
+ *
+ *     Function : schHdlDrxOnDurExpiryTimer 
+ *
+ *      Handling of expiry onduration DRX timers
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxOnDurExpiryTimer(SchCellCb  *cell)
+{
+   uint16_t dlIndx = 0, ulIndx = 0;
+   SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+   ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+   ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+   dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+   ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+   
+   schHdlDrxOnDurExpiryTimerForUlandDlDirection(cell, dlIndx, true);
+   schHdlDrxOnDurExpiryTimerForUlandDlDirection(cell, ulIndx, false);
+}
+/**
+ * @brief Handling of the expiry in active DRX timers in Dl and Ul direction
+ *
+ * @details
+ *
+ *     Function : schHdlDrxInActvExpiryTimerForUlandDlDirection
+ *
+ *      Handling of expiry in active  DRX timers in DLand Ul  direction
+ *
+ *  @param[in] SchCellCb  *cell, uint16_t dlIndx
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxInActvExpiryTimerForUlandDlDirection(SchCellCb  *cell, uint16_t listIndx, bool isDlDirection)
+{
+   CmLList  *drxNode;
+   SchUeCb *ueCb = NULLP;
+
+   drxNode = cell->drxCb[listIndx].inActvTmrExpiryList.first;
+   if(drxNode)
+   {
+      /* Handling of dl On duration drx start list */
+      while(drxNode)
+      {
+         ueCb = (SchUeCb*)drxNode->node;
+         ueCb->drxUeCb.inActiveTmrExpiryDistance--;
+
+         if(ueCb->drxUeCb.onDurationExpiryDistance== SCH_DRX_INVALID_DISTANCE)
+         {
+            DU_LOG("\nPBORLA IN ACTV EXP HIT %d[%d:%d]",listIndx, cell->slotInfo.sfn, cell->slotInfo.slot);
+            /*Delete the current entry from list */
+            if(drxNode->node)
+            {
+               cmLListDelFrm(&cell->drxCb[listIndx].inActvTmrExpiryList, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
+               SCH_FREE(ueCb->drxUeCb.inActvTimerExpiryNodeInfo, sizeof(CmLList));
+               ueCb->drxUeCb.inActvExpiryIndex = SCH_DRX_INVALID_INDEX;
+            }
+
+            /* If short cycle is configured then start the short cycle timer */
+            if(ueCb->drxUeCb.shortCyclePresent)
+            {
+               schHdlDrxStartShortCycleTimer(cell, ueCb);
+            }
+            else
+            {
+               ueCb->drxUeCb.longCycleToBeUsed = true;
+            }
+            /* Set the drx ue status as inactive once the in active timer gets
+             * expire */
+            if(isDlDirection == true)
+               ueCb->drxUeCb.drxDlUeActiveStatus = false;
+            else
+               ueCb->drxUeCb.drxUlUeActiveStatus = false;
+            DU_LOG("\nPBORLA drxUeCb.drxUlUeActiveStatus drxUeCb.drxDlUeActiveStatus [%d:%d] line %d",  ueCb->drxUeCb.drxUlUeActiveStatus, ueCb->drxUeCb.drxDlUeActiveStatus,__LINE__);
+
+         }
+         else
+            continue;
+         drxNode = drxNode->next;
+      }
+   }
+
+}
+/**
+ * @brief Handling of the expiry in active DRX timers
+ *
+ * @details
+ *
+ *     Function :schHdlDrxInActvExpiryTimer 
+ *
+ *      Handling of expiry in active  DRX timers
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHdlDrxInActvExpiryTimer(SchCellCb  *cell)
+{
+   uint16_t dlIndx = 0, ulIndx = 0;
+   SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+   ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+   ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA + SCH_DRX_TMRS_EXP_DELTA);
+   dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+   ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+   
+   schHdlDrxInActvExpiryTimerForUlandDlDirection(cell, dlIndx, true);
+   schHdlDrxInActvExpiryTimerForUlandDlDirection(cell, ulIndx, false);
+}/**
+ * @brief Handling of the expiry  DRX timers
+ *
+ * @details
+ *
+ *     Function : schHandleExpiryDrxTimer
+ *
+ *      Handling of expiry  DRX timers
+ *
+ *  @param[in] SchCellCb  *cell
+ *  @return
+ *      -# ROK
+ *      -# RFAILED
+ **/
+void schHandleExpiryDrxTimer(SchCellCb  *cell)
+{
+   /* Handling the onduration start timer */
+   schHdlDrxShortCycleExpiryTimer(cell);
+   schHdlDrxOnDurExpiryTimer(cell);
+   schHdlDrxInActvExpiryTimer(cell);
+}
+
+
+#endif
+/**********************************************************************
+  End of file
+ **********************************************************************/
diff --git a/src/5gnrsch/sch_drx.h b/src/5gnrsch/sch_drx.h
new file mode 100644 (file)
index 0000000..c4679d1
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************
+################################################################################
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+#define SCH_DRX_INVALID_DISTANCE -1
+#define SCH_DRX_INVALID_INDEX 0xFFFFFF 
+#define SCH_DRX_MAX_DELTA 1
+#define SCH_DRX_TMRS_EXP_DELTA 1
+
+/** @brief Macro to convert milli second to slots */
+#define SCH_CNVRT_MS_TO_SLOT(_numSlot, _numMs, _mu)\
+{\
+   _numSlot = _numMs * (1 << _mu);\
+}
+
+/** @brief Macro to convert number symbols to slots */
+#define SCH_CNVRT_SYMBL_TO_SLOT(_numSlot, _numSymbl)\
+{\
+   _numSlot = _numSymbl/14; \
+}
+
+/**  @brief Macro to find the slot difference */
+#define SCH_CALC_SLOT_DIFF(_newTime, _oldTime, _numOfSlotsPerRadioFrame)\
+((_newTime.sfn*_numOfSlotsPerRadioFrame+_newTime.slot) >= (_oldTime.sfn*_numOfSlotsPerRadioFrame+_oldTime.slot)?\
+(_newTime.sfn*_numOfSlotsPerRadioFrame+_newTime.slot) - (_oldTime.sfn*_numOfSlotsPerRadioFrame+_oldTime.slot) : \
+(_newTime.sfn*_numOfSlotsPerRadioFrame+_newTime.slot) + (1024*_numOfSlotsPerRadioFrame - (_oldTime.sfn*_numOfSlotsPerRadioFrame+_oldTime.slot)))
+
+void schInitDrxUeCb(SchUeCb *ueCb);
+void schFillDrxUeCb(uint8_t numerology, SchDrxCfg drxCfg, SchDrxUeCb *drxUeCb);
+void schDeleteUeDrxInfo(SchCellCb  *cell, SchUeCb *ueCb);
+void schHandleStartDrxTimer(SchCellCb  *cell);
+void schHdlDrxInActvStrtTmr(SchCellCb  *cell,  SchUeCb *ueCb, uint8_t delta);
+void schInitDrxHarqCb(SchDrxHarqCb *hqCb);
+void schAddUeInOndurationAndShortCycleList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta);
+void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb);
+void schHdlDrxShortCycleExpiryTimer(SchCellCb  *cell);
+void schHdlDrxOnDurExpiryTimer(SchCellCb  *cell);
+void schHandleExpiryDrxTimer(SchCellCb  *cell);
+/**********************************************************************
+  End of file
+ **********************************************************************/
index 12a387c..052a930 100644 (file)
@@ -41,6 +41,9 @@ File:     sch_slot_ind.c
 #include "mac_sch_interface.h"
 #include "sch.h"
 #include "sch_utils.h"
+#ifdef NR_DRX 
+#include "sch_drx.h"
+#endif
 
 SchMacDlAllocFunc schMacDlAllocOpts[] =
 {
@@ -793,6 +796,10 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
    dlSchedInfo.cellId = cell->cellId;
    slot = dlSchedInfo.schSlotValue.broadcastTime.slot;
 
+#ifdef NR_DRX 
+   schHandleStartDrxTimer(cell);
+#endif
+   
    /* Check for SSB occassion */
    dlBrdcstAlloc->ssbTrans = schCheckSsbOcc(cell, dlSchedInfo.schSlotValue.broadcastTime); 
    if(dlBrdcstAlloc->ssbTrans)
@@ -838,6 +845,7 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
       {
          ueNode = (uint8_t *)pendingUeNode->node;
          ueId = *(uint8_t *)(pendingUeNode->node);
+         
          /* 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)
@@ -852,6 +860,14 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
             schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
          }
 
+#ifdef NR_DRX 
+         if(!(cell->ueCb[ueId-1].ueDrxInfoPres) && !(cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus))//&&  !(cell->ueCb[ueId-1].drxUeCb.drxUlUeActiveStatus))
+         {
+            cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
+         }
+         else 
+#endif
+         {
          /* 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
@@ -913,6 +929,13 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
                /* If DL scheduling failed, free the newly assigned HARQ process */
                if(!isDlMsgScheduled)
                   schDlReleaseHqProcess(hqP);
+               else
+               {
+#ifdef NR_DRX 
+                  if(cell->ueCb[ueId-1].ueDrxInfoPres)
+                     schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
+#endif               
+               }
             }
          }
 
@@ -934,6 +957,13 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
                isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
                if(!isUlGrantScheduled)
                   schUlReleaseHqProcess(ulHqP, FALSE);
+               else
+               {
+#ifdef NR_DRX 
+                  if(cell->ueCb[ueId-1].ueDrxInfoPres)
+                     schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
+#endif               
+               }
             }
          }
 
@@ -950,7 +980,7 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
             SCH_FREE(ueNode, sizeof(uint8_t));
             deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
          }
-      }
+      }}
    }
 
    /* Check if any PDU is scheduled at this slot for any UE */
@@ -992,7 +1022,9 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
 
    schInitDlSlot(cell->schDlSlotInfo[slot]);
    schUlResAlloc(cell, schInst);
-
+#ifdef NR_DRX 
+   schHandleExpiryDrxTimer(cell);
+#endif   
    return ret;
 }
 
index aa74c06..db15108 100644 (file)
@@ -28,6 +28,9 @@
 #include "mac_sch_interface.h"
 #include "sch.h"
 #include "sch_utils.h"
+#ifdef NR_DRX 
+#include "sch_drx.h"
+#endif
 
 /* local defines */
 SchUeCfgRspFunc SchUeCfgRspOpts[] =
@@ -256,8 +259,56 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
    {
       memcpy(&ueCb->ueCfg.macCellGrpCfg , &ueCfg->macCellGrpCfg, sizeof(SchMacCellGrpCfg)); 
       ueCb->ueCfg.macCellGrpCfgPres = true;
+#ifdef NR_DRX
+      if(ueCfg->macCellGrpCfg.drxCfgPresent == true)
+      {
+         if(ueCb->ueDrxInfoPres == false)
+         {
+            ueCb->ueDrxInfoPres = true;
+            /* intialize the drxUeCb */
+            schInitDrxUeCb(ueCb);
+            
+            /* intialize the Dl drxHarqCb */
+            for(idx =0; idx<ueCb->dlHqEnt.numHqPrcs; idx++)
+            {
+               schInitDrxHarqCb(&ueCb->dlHqEnt.procs[idx].drxHarqCb);
+            }
+            /* intialize the Ul drxHarqCb */
+            for(idx =0; idx<ueCb->ulHqEnt.numHqPrcs; idx++)
+            {
+               schInitDrxHarqCb(&ueCb->ulHqEnt.procs[idx].drxHarqCb);
+            }
+            /* convert all the drx configuration recived in ms/subms into number of slots and store into the drxUeCb */
+            schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueCfg->macCellGrpCfg.drxCfg, &ueCb->drxUeCb);
+            /* Calculate the onduration timer and short cycle timer (if shortcycle configuration is present) as soon as we 
+             * recived ueCfg request */
+            schAddUeInOndurationAndShortCycleList(ueCb->cellCb, ueCb, 0);
+
+         }
+         else
+         {
+            /* convert all the drx configuration recived in ms/subms into number
+             * of slots and store into the drxUeCb */
+            schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueCfg->macCellGrpCfg.drxCfg, &ueCb->drxUeCb);
+
+            /* Recalculate/Restart timer based on their presence */
+            schDrxUeReCfgTimer(ueCb->cellCb, ueCb);
+         }
+      }
+#endif
    }
 
+#ifdef NR_DRX
+   if(ueCfg->drxConfigIndicatorRelease == true)
+   {
+      if(ueCb->ueDrxInfoPres == true)
+      {
+         schDeleteUeDrxInfo(ueCb->cellCb, ueCb);
+         ueCb->ueDrxInfoPres = false;
+      }
+   }
+#endif
+   
    if(ueCfg->phyCellGrpCfgPres == true)
    {
       memcpy(&ueCb->ueCfg.phyCellGrpCfg ,  &ueCfg->phyCellGrpCfg, sizeof(SchPhyCellGrpCfg));
@@ -1139,7 +1190,14 @@ void deleteSchUeCb(SchUeCb *ueCb)
          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
       }
-
+#ifdef NR_DRX
+      if(ueCb->ueDrxInfoPres)
+      {
+         /* Removing all the calculated drx configuration timer list */ 
+         schDeleteUeDrxInfo(ueCb->cellCb, ueCb);
+         ueCb->ueDrxInfoPres = false;
+      }
+#endif
       memset(ueCb, 0, sizeof(SchUeCb));
    }
 }
index 9020815..cbb8935 100644 (file)
@@ -843,6 +843,7 @@ typedef struct macCellGrpCfg
    bool        phrCfgSetupPres;   /* true/false: phrCfgSetup/phrCfgRelease */
    PhrCfg      phrCfg;
 #ifdef NR_DRX
+   bool        drxCfgPresent;
    DrxCfg      drxCfg;
 #endif
 }MacCellGrpCfg;
@@ -1300,6 +1301,9 @@ typedef struct macUeCfg
    LcCfg lcCfgList[MAX_NUM_LC];
    UeCfgState macUeCfgState;    /* InActive / Completed */
    DataTransmissionAction transmissionAction;
+#ifdef NR_DRX   
+   bool     drxConfigIndicatorRelease;
+#endif
 }MacUeCfg;
 
 typedef struct nrcgi
index 0d1ab67..a38e407 100644 (file)
@@ -1200,6 +1200,7 @@ typedef struct schMacCellGrpCfg
    SchTagCfg        tagCfg;
    SchPhrCfg        phrCfg;             /* To be used only if phrCfgSetupPres is true */      
 #ifdef NR_DRX
+   bool             drxCfgPresent;
    SchDrxCfg        drxCfg;          /* Drx configuration */
 #endif
 }SchMacCellGrpCfg;
@@ -1654,6 +1655,9 @@ typedef struct schUeCfg
    uint8_t            numLcs;
    SchLcCfg           schLcCfg[MAX_NUM_LC];
    SchDataTransmission dataTransmissionInfo;
+#ifdef NR_DRX   
+   bool     drxConfigIndicatorRelease;
+#endif
 }SchUeCfg;
 
 typedef struct schUeCfgRsp
index 4e2e2f5..4920f8b 100644 (file)
@@ -1954,25 +1954,22 @@ void fillLongCycleOffsetValue(DrxLongCycleStartOffset *drxLongCycleStartOffset,
  * ****************************************************************/
 void storeDrxCfgInUeCb(struct DRX_ConfigRrc *drxSetup, DrxCfg *drxCfg)
 {
-   if(drxSetup)
+   switch(drxSetup->drx_onDurationTimer.present)
    {
-      switch(drxSetup->drx_onDurationTimer.present)
-      {
-         case DRX_ConfigRrc__drx_onDurationTimer_PR_NOTHING:
+      case DRX_ConfigRrc__drx_onDurationTimer_PR_NOTHING:
+         break;
+      case DRX_ConfigRrc__drx_onDurationTimer_PR_milliSeconds:
+         {
+            drxCfg->drxOnDurationTimer.onDurationTimerValInMs = true;
+            drxCfg->drxOnDurationTimer.onDurationtimerValue.milliSeconds=drxSetup->drx_onDurationTimer.choice.milliSeconds;
             break;
-         case DRX_ConfigRrc__drx_onDurationTimer_PR_milliSeconds:
-            {
-               drxCfg->drxOnDurationTimer.onDurationTimerValInMs = true;
-               drxCfg->drxOnDurationTimer.onDurationtimerValue.milliSeconds=drxSetup->drx_onDurationTimer.choice.milliSeconds;
-               break;
-            }
-         case DRX_ConfigRrc__drx_onDurationTimer_PR_subMilliSeconds:
-            {
-               drxCfg->drxOnDurationTimer.onDurationTimerValInMs = false;
-               drxCfg->drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = drxSetup->drx_onDurationTimer.choice.subMilliSeconds;
-               break;
-            }
-      }
+         }
+      case DRX_ConfigRrc__drx_onDurationTimer_PR_subMilliSeconds:
+         {
+            drxCfg->drxOnDurationTimer.onDurationTimerValInMs = false;
+            drxCfg->drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = drxSetup->drx_onDurationTimer.choice.subMilliSeconds;
+            break;
+         }
    }
    fillLongCycleOffsetValue(&drxCfg->drxLongCycleStartOffset, &drxSetup->drx_LongCycleStartOffset);
    drxCfg->drxInactivityTimer = drxSetup->drx_InactivityTimer;
@@ -2049,7 +2046,11 @@ uint8_t extractCellGroupConfig(CuUeCb *ueCb, CellGroupConfigRrc_t *cellGrpCfg)
 
             case MAC_CellGroupConfig__drx_ConfigRrc_PR_setup:
             {
-               storeDrxCfgInUeCb(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup, &ueCb->drxCfg);
+               if(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup)
+               {
+                  ueCb->drxCfgPresent = true;  
+                  storeDrxCfgInUeCb(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup, &ueCb->drxCfg);
+               }
                break;
             }
 
@@ -10937,14 +10938,18 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt
       ueContextModifyReq =&f1apMsg->choice.initiatingMessage->value.choice.UEContextModificationRequest;
 
       if(action == MODIFY_UE)
-         elementCnt = 4;
+         elementCnt = 5;
       else if(action == QUERY_CONFIG)
          elementCnt = 3;
       else if(action == RRC_RECONFIG_COMPLETE_IND)
          elementCnt = 3;
       else if((action == STOP_DATA_TX) || (action == RESTART_DATA_TX)) 
          elementCnt = 5;
-
+      
+#ifdef NR_DRX
+      if(DRX_TO_BE_RELEASE)
+         elementCnt++;
+#endif      
       ueContextModifyReq->protocolIEs.list.count = elementCnt;
       ueContextModifyReq->protocolIEs.list.size = elementCnt*sizeof(UEContextModificationRequest_t *);
 
@@ -11070,6 +11075,20 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt
          ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCDeliveryStatusRequest = RRCDeliveryStatusRequest_true;
       }
 
+#ifdef NR_DRX
+      if(DRX_TO_BE_RELEASE)
+      {
+         /* DRX Configuration Indicator */
+         ieIdx++;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRXConfigurationIndicator;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_DRXConfigurationIndicator;
+         ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.DRXConfigurationIndicator = DRXConfigurationIndicator_release;
+         ueCb->drxCfgPresent = false;
+         memset(&ueCb->drxCfg, 0, sizeof(DrxCfg));
+      }
+#endif
+
       xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
 
       /* Encode the F1SetupRequest type as APER */
@@ -11678,7 +11697,7 @@ uint8_t procServedCellPlmnList(ServedPLMNs_List_t *srvPlmn)
  * ****************************************************************/
 uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
 {
-   uint8_t idx=0, duIdx=0;
+   uint8_t idx=0, duIdx=0, countiX =1;
    uint8_t duUeF1apId = 0, cuUeF1apId = 0;
    DuDb *duDb = NULLP;
    CuUeCb *ueCb = NULLP;
@@ -11764,7 +11783,14 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
          }
       }
    }
-   
+#ifdef NR_DRX
+   if(countiX == 1)
+   {
+      countiX++;
+      DU_LOG("\nPBORLA INFO  -->  F1AP: Sending UE Context Modification Request to MODIFY_UE");
+      //BuildAndSendUeContextModificationReq(duId, ueCb, MODIFY_UE);
+   }
+#endif
    return ROK;
 }
 
index fed791c..f6cb5c7 100644 (file)
    }\
 }
 
+#ifdef NR_DRX
+/* Set this parameter true of false as per the need to enable or disable drx of
+ * a particular UE */
+#define DRX_TO_BE_RELEASE true 
+#endif
+
 typedef enum
 {
    CELL_INACTIVE,
@@ -304,6 +310,7 @@ typedef struct cuUeCb
    F1apMsgDb f1apMsgDb;
    UeState   state;
 #ifdef NR_DRX
+   bool      drxCfgPresent;
    DrxCfg    drxCfg;
 #endif
    HandoverInfo hoInfo;
index a44829d..d9151a4 100644 (file)
@@ -13406,62 +13406,72 @@ void freeAperDecodeF1UeContextSetupReq(UEContextSetupRequest_t   *ueSetReq)
    {
       for(ieIdx = 0; ieIdx < ueSetReq->protocolIEs.list.count; ieIdx++)
       {
-        if(ueSetReq->protocolIEs.list.array[ieIdx])
-        {
-           switch(ueSetReq->protocolIEs.list.array[ieIdx]->id)
-           {
-              case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
-                 break;
-              case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
-                 break;
-              case ProtocolIE_ID_id_SpCell_ID:
-                 freeAperDecodeNrcgi(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.NRCGI);
-                 break;
-              case ProtocolIE_ID_id_ServCellIndex:
-                 break;
-              case ProtocolIE_ID_id_SpCellULConfigured:
-                 break;
-              case ProtocolIE_ID_id_CUtoDURRCInformation:
+         if(ueSetReq->protocolIEs.list.array[ieIdx])
+         {
+            switch(ueSetReq->protocolIEs.list.array[ieIdx]->id)
+            {
+               case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+                  break;
+               case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+                  break;
+               case ProtocolIE_ID_id_SpCell_ID:
+                  freeAperDecodeNrcgi(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.NRCGI);
+                  break;
+               case ProtocolIE_ID_id_ServCellIndex:
+                  break;
+               case ProtocolIE_ID_id_SpCellULConfigured:
+                  break;
+               case ProtocolIE_ID_id_CUtoDURRCInformation:
 
-                 freeAperDecodeCuToDuInfo(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation);
-                 break;
-              case ProtocolIE_ID_id_SCell_ToBeSetup_List:
+                  freeAperDecodeCuToDuInfo(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation);
+                  break;
+               case ProtocolIE_ID_id_SCell_ToBeSetup_List:
 
-                 freeAperDecodeSplCellList(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SCell_ToBeSetup_List);
-                 break;
-              case ProtocolIE_ID_id_SRBs_ToBeSetup_List:
+                  freeAperDecodeSplCellList(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SCell_ToBeSetup_List);
+                  break;
+               case ProtocolIE_ID_id_SRBs_ToBeSetup_List:
 
-                 freeAperDecodeSRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SRBs_ToBeSetup_List);
-                 break;
-              case ProtocolIE_ID_id_DRBs_ToBeSetup_List:
+                  freeAperDecodeSRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SRBs_ToBeSetup_List);
+                  break;
+               case ProtocolIE_ID_id_DRBs_ToBeSetup_List:
 
-                 freeAperDecodeDRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRBs_ToBeSetup_List);
-                 break;
-              case ProtocolIE_ID_id_RRCContainer:
-                 {
+                  freeAperDecodeDRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRBs_ToBeSetup_List);
+                  break;
+               case ProtocolIE_ID_id_RRCContainer:
+                  {
 
-                    if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf != NULLP)
-                    {
+                     if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf != NULLP)
+                     {
 
-                       free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf);
-                    }
-                    break;
-                 }
-              case ProtocolIE_ID_id_RRCDeliveryStatusRequest:
-                 break;
-              case ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL:
-                 {
-                    if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf)
-                    {
-                       free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf);
-                    }
-                    break;
-                 }
-              default:
-                 DU_LOG("\nERROR  -->  F1AP: Invalid event type %ld " ,ueSetReq->protocolIEs.list.array[ieIdx]->id);
-           } 
-           free(ueSetReq->protocolIEs.list.array[ieIdx]);
-        }
+                        free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf);
+                     }
+                     break;
+                  }
+               case ProtocolIE_ID_id_RRCDeliveryStatusRequest:
+                  break;
+               case ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL:
+                  {
+                     if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf)
+                     {
+                        free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf);
+                     }
+                     break;
+                  }
+#ifdef NR_DRX
+               case ProtocolIE_ID_id_DRXCycle:
+                  {
+                     if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleLength)
+                        free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleLength);
+                     if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleTimer)
+                        free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleTimer);
+                     break;
+                  }
+#endif             
+                default:
+                  DU_LOG("\nERROR  -->  F1AP: Invalid event type %ld " ,ueSetReq->protocolIEs.list.array[ieIdx]->id);
+            } 
+            free(ueSetReq->protocolIEs.list.array[ieIdx]);
+         }
       }
       free(ueSetReq->protocolIEs.list.array);
    }
@@ -13840,50 +13850,52 @@ void FreeUeContextSetupRsp(F1AP_PDU_t *f1apMsg)
    {
       if(f1apMsg->choice.successfulOutcome)
       {
-        ueSetRsp = &f1apMsg->choice.successfulOutcome->value.choice.\
-                   UEContextSetupResponse;
-        if(ueSetRsp->protocolIEs.list.array)
-        {
-           for(idx = 0; idx < ueSetRsp->protocolIEs.list.count; idx++)
-           {
-              if(ueSetRsp->protocolIEs.list.array[idx])
-              {
-                 switch(ueSetRsp->protocolIEs.list.array[idx]->id)
-                 {
-                    case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
-                       break;
-                    case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
-                       break;
-                    case ProtocolIE_ID_id_DUtoCURRCInformation:
-                       {
-                          CellGroupConfig_t *cellGrpCfg = NULLP;
-                          cellGrpCfg  = &ueSetRsp->protocolIEs.list.array[idx]->value.choice.\
-                                        DUtoCURRCInformation.cellGroupConfig;
-                          if(cellGrpCfg->buf != NULLP)
-                          {
-                             DU_FREE(cellGrpCfg->buf, cellGrpCfg->size);
-                             cellGrpCfg = NULLP;
-                          }
-                          break;
-                       }
-                    case ProtocolIE_ID_id_DRBs_Setup_List:
-                       {
+         ueSetRsp = &f1apMsg->choice.successfulOutcome->value.choice.\
+                    UEContextSetupResponse;
+         if(ueSetRsp->protocolIEs.list.array)
+         {
+            for(idx = 0; idx < ueSetRsp->protocolIEs.list.count; idx++)
+            {
+               if(ueSetRsp->protocolIEs.list.array[idx])
+               {
+                  switch(ueSetRsp->protocolIEs.list.array[idx]->id)
+                  {
+                     case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+                        break;
+                     case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+                        break;
+                     case ProtocolIE_ID_id_C_RNTI:
+                        break;
+                     case ProtocolIE_ID_id_DUtoCURRCInformation:
+                        {
+                           CellGroupConfig_t *cellGrpCfg = NULLP;
+                           cellGrpCfg  = &ueSetRsp->protocolIEs.list.array[idx]->value.choice.\
+                                         DUtoCURRCInformation.cellGroupConfig;
+                           if(cellGrpCfg->buf != NULLP)
+                           {
+                              DU_FREE(cellGrpCfg->buf, cellGrpCfg->size);
+                              cellGrpCfg = NULLP;
+                           }
+                           break;
+                        }
+                     case ProtocolIE_ID_id_DRBs_Setup_List:
+                        {
                            freeDrbSetupList(&ueSetRsp->protocolIEs.list.array[idx]->value.choice.DRBs_Setup_List); 
                            break;
-                       }
-                    default:
-                       DU_LOG("\nERROR  -->  DUAPP: Invalid Id %ld at FreeUeContextSetupRsp()",\
-                       ueSetRsp->protocolIEs.list.array[idx]->id);
-                       break;
-                 }
-                 DU_FREE(ueSetRsp->protocolIEs.list.array[idx],\
-                       sizeof(UEContextSetupResponseIEs_t));
-              }
-           }
-           DU_FREE(ueSetRsp->protocolIEs.list.array, \
-                 ueSetRsp->protocolIEs.list.size);
-        }
-        DU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
+                        }
+                     default:
+                        DU_LOG("\nERROR  -->  DUAPP: Invalid Id %ld at FreeUeContextSetupRsp()",\
+                              ueSetRsp->protocolIEs.list.array[idx]->id);
+                        break;
+                  }
+                  DU_FREE(ueSetRsp->protocolIEs.list.array[idx],\
+                        sizeof(UEContextSetupResponseIEs_t));
+               }
+            }
+            DU_FREE(ueSetRsp->protocolIEs.list.array, \
+                  ueSetRsp->protocolIEs.list.size);
+         }
+         DU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
       }
       DU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
    }
@@ -15940,6 +15952,8 @@ uint8_t BuildAndSendUeContextModRsp(DuUeCb *ueCb)
       break;
    }
    FreeUeContextModResp(f1apMsg);
+   //sleep(5);
+   //BuildAndSendDUConfigUpdate(SERV_CELL_TO_DELETE);
    return ret;
 }
 /*******************************************************************
@@ -16360,6 +16374,13 @@ uint8_t procF1UeContextModificationReq(F1AP_PDU_t *f1apMsg)
                }
                break;
             }
+#ifdef NR_DRX
+         case ProtocolIE_ID_id_DRXConfigurationIndicator:
+            {
+               duUeCb->f1UeDb->duUeCfg.drxConfigIndicatorRelease = true;
+               break;
+            }
+#endif
               
       }
    }
index c260408..e7345f5 100644 (file)
@@ -157,6 +157,7 @@ typedef struct duUeCfg
 #ifdef NR_DRX
    bool     drxCyclePres;
    DrxCycle drxCycle;
+   bool     drxConfigIndicatorRelease;
 #endif
 }DuUeCfg;
 
index ba89f0b..0d171a5 100644 (file)
@@ -548,7 +548,7 @@ uint8_t commonInit()
       DU_LOG("\nERROR  -->  DU_APP : System Task creation for DU APP failed");
       return RFAILED;
    }
-   ODU_SET_THREAD_AFFINITY(&du_app_stsk, SS_AFFINITY_MODE_EXCL, 16, 0);
+   //ODU_SET_THREAD_AFFINITY(&du_app_stsk, SS_AFFINITY_MODE_EXCL, 16, 0);
 
    /* system task for EGTP */
    if(ODU_CREATE_TASK(PRIOR0, &egtp_stsk) != ROK)
@@ -556,7 +556,7 @@ uint8_t commonInit()
       DU_LOG("\nERROR  -->  DU_APP : System Task creation for EGTP failed");
       return RFAILED;
    }
-   ODU_SET_THREAD_AFFINITY(&egtp_stsk, SS_AFFINITY_MODE_EXCL, 27, 0);
+   //ODU_SET_THREAD_AFFINITY(&egtp_stsk, SS_AFFINITY_MODE_EXCL, 27, 0);
 
    /* system task for RLC_DL and MAC */
    if(ODU_CREATE_TASK(PRIOR0, &rlc_mac_cl_stsk) != ROK)
@@ -566,7 +566,7 @@ uint8_t commonInit()
    }
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-   ODU_SET_THREAD_AFFINITY(&rlc_mac_cl_stsk, SS_AFFINITY_MODE_EXCL, 18, 0);
+   //ODU_SET_THREAD_AFFINITY(&rlc_mac_cl_stsk, SS_AFFINITY_MODE_EXCL, 18, 0);
 
    /* system task for RLC UL */
    if(ODU_CREATE_TASK(PRIOR1, &rlc_ul_stsk) != ROK)
@@ -574,7 +574,7 @@ uint8_t commonInit()
       DU_LOG("\nERROR  -->  DU_APP : System Task creation for RLC UL failed");
       return RFAILED;
    }
-   ODU_SET_THREAD_AFFINITY(&rlc_ul_stsk, SS_AFFINITY_MODE_EXCL, 22, 0);
+   //ODU_SET_THREAD_AFFINITY(&rlc_ul_stsk, SS_AFFINITY_MODE_EXCL, 22, 0);
 
    /* system task for SCTP receiver thread */
    if(ODU_CREATE_TASK(PRIOR0, &sctp_stsk) != ROK)
@@ -582,7 +582,7 @@ uint8_t commonInit()
       DU_LOG("\nERROR  -->  DU_APP : System Task creation for SCTP failed");
       return RFAILED;
    }
-   ODU_SET_THREAD_AFFINITY(&sctp_stsk, SS_AFFINITY_MODE_EXCL, 25, 0);
+   //ODU_SET_THREAD_AFFINITY(&sctp_stsk, SS_AFFINITY_MODE_EXCL, 25, 0);
 
    /* system task for lower-mac receiver thread */
    if(ODU_CREATE_TASK(PRIOR0, &lwr_mac_stsk) != ROK)
@@ -590,7 +590,7 @@ uint8_t commonInit()
       DU_LOG("\nERROR  -->  DU_APP : System Task creation for Lower MAC failed");
       return RFAILED;
    }
-   ODU_SET_THREAD_AFFINITY(&lwr_mac_stsk, SS_AFFINITY_MODE_EXCL, 21, 0);
+   //ODU_SET_THREAD_AFFINITY(&lwr_mac_stsk, SS_AFFINITY_MODE_EXCL, 21, 0);
 
 #ifndef INTEL_WLS_MEM
    /* system task for phy stub's slot indication generator thread */
index b77b231..cae946e 100644 (file)
@@ -1283,6 +1283,11 @@ uint8_t fillMacUeCfg(uint16_t cellId, uint8_t gnbDuUef1apId, uint16_t crnti, DuU
       }
 
 #ifdef NR_DRX
+      if(ueCfgDb->drxConfigIndicatorRelease == true)
+     {
+         macUeCfg->drxConfigIndicatorRelease = true;
+      }
+      
       if(ueCfgDb->drxCyclePres)
       {
          macUeCfg->macCellGrpCfg.drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice = ueCfgDb->drxCycle.drxLongCycleLength;
index b88a260..19ecc8c 100644 (file)
@@ -886,7 +886,8 @@ S16 l1HdlDlTtiReq(uint16_t msgLen, void *msg)
       }
       else if(dlTtiReq->pdus[pduCount].pduType == 0)
       {
-         DU_LOG("\nINFO   -->  PHY_STUB: PDCCH PDU");
+         //DU_LOG("\nINFO   -->  PHY_STUB: PDCCH PDU");
+         DU_LOG("\nINFO   -->  PHY_STUB: PDCCH PDU sfn=%d slot=%d",dlTtiReq->sfn,dlTtiReq->slot);
       }
       else if(dlTtiReq->pdus[pduCount].pduType == 1)
       {