[Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Handling of drx timer in SCH [storing...
[o-du/l2.git] / src / 5gnrsch / sch_drx.c
diff --git a/src/5gnrsch/sch_drx.c b/src/5gnrsch/sch_drx.c
new file mode 100644 (file)
index 0000000..ff0844d
--- /dev/null
@@ -0,0 +1,524 @@
+
+/*******************************************************************************
+################################################################################
+#   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; 
+}
+
+/* will uncomment this function in next gerrit */
+#if 0
+/**
+ * @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->dlDrxHarqCb.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->dlDrxHarqCb.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->dlDrxHarqCb.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->dlDrxHarqCb);
+    }
+ }
+
+/**
+ * @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->ulDrxHarqCb.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->ulDrxHarqCb.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->ulDrxHarqCb.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->ulDrxHarqCb);
+    }
+ }
+#endif
+
+/**
+ * @brief delete UE drx timers and information 
+ *
+ * @details
+ *
+ *     Function : schDeleteUeDrxInfo
+ *      
+ *     delete UE drx timers and information 
+ *           
+ *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
+ *  @return  void
+ *
+ **/
+
+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);
+   drxUeCb->retransDlTimerLen = drxCfg.drxRetransmissionTimerDl;
+   drxUeCb->retransUlTimerLen = drxCfg.drxRetransmissionTimerUl;
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->longCycleLen, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice, numerology);
+   SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxStartOffset, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetVal, numerology);
+   if(drxCfg.shortDrxPres)
+   {
+      drxUeCb->shortCyclePresent = true;                  
+      SCH_CNVRT_MS_TO_SLOT(drxUeCb->shortCycleLen, drxCfg.shortDrx.drxShortCycle, numerology);   
+      drxUeCb->shortCycleTmrLen = drxUeCb->shortCycleLen*drxCfg.shortDrx.drxShortCycleTimer;   
+   }
+   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;
+   DU_LOG("\nINFO --> SCH : Drx node added into the list");
+   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   tmpDistance, numOfCycles;
+   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, cell->numSlots);
+   
+   /* Convert tmpTime to number of slots */
+   curTime = ((tmpTime.sfn * cell->numSlots) + 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  */
+   if ( curTime <= ueDrxCb->drxStartOffset)
+   {
+      /* offset is the nextOnDur */
+      nxtDist = ((((ueDrxCb->drxStartOffset / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (ueDrxCb->drxStartOffset % cell->numSlots);
+   }
+   else
+   {
+      tmpDistance = curTime - ueDrxCb->drxStartOffset;
+      numOfCycles = tmpDistance / cycleLen;
+
+      if (0 == (tmpDistance % cycleLen))
+      {
+         /* Perfect match pick up the current time */
+         nxtDist = ((((curTime / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (curTime % cell->numSlots);
+      }
+      else
+      {
+         nxtDist  = ueDrxCb->drxStartOffset + (numOfCycles + 1) * cycleLen;
+      }
+   }
+
+   /* If slot offset is non-zero then Add slot offset to the calculated onDur
+    * distance */
+   if(ueDrxCb->drxSlotOffset)
+   {
+      nxtDist = nxtDist + ueDrxCb->drxSlotOffset;
+   }
+   /*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)
+   {
+      nxtDist = nxtDist + cycleLen;
+   }
+   
+   nxtOnDur->sfn = ((nxtDist / cell->numSlots) & (MAX_SFN - 1));
+   nxtOnDur->slot = (nxtDist % cell->numSlots);
+}
+
+/**
+ * @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 
+ **/
+
+void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb)
+{
+   uint8_t  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*cell->numSlots+onDurationOccurance.slot;
+   
+   /* 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 * cell->numSlots + 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;
+       }
+   }
+   SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex);
+   ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, cell->numSlots)/MAX_DRX_SIZE;
+   schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
+}
+
+/**
+ * @brief Add entry into  the on duration list 
+ *
+ * @details
+ *
+ *     Function : schAddUeInOndurationList
+ *      
+ *      This function is used to Add entry into  the on duration list 
+ *           
+ *  @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur,
+ *  uint8_t delta
+ *            
+ *  @return  
+ *      -# void
+ **/
+
+void schAddUeInOndurationList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta)
+{
+   uint32_t onDurTime;
+   SlotTimingInfo onDurationOccurance;
+
+   if(ueCb->ueDrxInfoPres)
+   {
+      findNextOndurationOccurance(cell,  &ueCb->drxUeCb, &onDurationOccurance, delta);
+      onDurTime = onDurationOccurance.sfn*cell->numSlots+onDurationOccurance.slot;
+      SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex);
+      ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, cell->numSlots)/MAX_DRX_SIZE;
+      schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
+
+   }
+}
+
+#endif
+/**********************************************************************
+  End of file
+ **********************************************************************/