+ schHdlDrxOnDurStrtTimer(cell);
+ schHdlDrxDlHqRetxStrtTimer(cell);
+ schHdlDrxUlHqRetxStrtTimer(cell);
+}
+
+/**
+ * @brief Handling of the Dl harq Rtt start DRX timers
+ *
+ * @details
+ *
+ * Function : schDrxStrtDlHqRttTmr
+ *
+ * Handling of the Dl harq Rtt start DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schDrxStrtDlHqRttTmr(SchDlHqProcCb *hqP)
+{
+ uint16_t harqRttExpTimer=0;
+ SchDrxUeCb *drxUeCb;
+
+ drxUeCb = &hqP->hqEnt->ue->drxUeCb;
+
+ harqRttExpTimer = (hqP->pucchTime.sfn * MAX_SLOTS + hqP->pucchTime.slot + drxUeCb->harqRttDlTimerLen)%MAX_DRX_SIZE;
+ hqP->dlDrxHarqCb.rttExpIndex = harqRttExpTimer;
+ schAddDrxNodeIntoHarqTimerList(&hqP->hqEnt->cell->drxCb[harqRttExpTimer].dlHarqRttExpiryList, hqP, &hqP->dlDrxHarqCb.rttExpNode);
+}
+
+/**
+ * @brief Handling of the Ul harq DRX timers start for Dl scheduling
+ *
+ * @details
+ *
+ * Function : schHdlUlHqRetxStrtTimerForDl
+ *
+ * Handling of Ul harq DRX timers start for Dl scheduling
+ *
+ * @param[in] SchCellCb *cell, uint16_t currIdx
+ * @return
+ * void
+**/
+
+void schHdlUlHqRetxStrtTimerForDl(SchCellCb *cell, uint16_t currIndx)
+{
+ uint32_t retxExpIndx;
+ CmLList *currNode;
+ SchUlHqProcCb *hqP;
+ SchUeCb *ueCb;
+
+ currNode = cell->drxCb[currIndx].ulRetransTmrStartList.first;
+
+ while(currNode)
+ {
+ hqP = (SchUlHqProcCb*)currNode->node;
+ currNode = currNode->next;
+ cell->api->SchAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
+ ueCb = hqP->hqEnt->ue;
+
+ /* calculate the retransmission exp index */
+ retxExpIndx = (currIndx + ueCb->drxUeCb.retransUlTimerLen)%MAX_DRX_SIZE;
+ if(hqP->ulDrxHarqCb.retxExpIndex == SCH_DRX_INVALID_INDEX)
+ {
+ hqP->ulDrxHarqCb.retxExpIndex = retxExpIndx;
+ schAddDrxNodeIntoHarqTimerList(&cell->drxCb[retxExpIndx].ulRetransExpiryList, hqP, &hqP->ulDrxHarqCb.retxExpNode);
+ }
+
+ /* Mark the UE active for downlink */
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq |= (SCH_DRX_UL_HARQ_BITMASK << hqP->procId);
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+ }
+}
+
+/**
+ * @brief Handling of the Ul harq DRX timers start for Ul scheduling
+ *
+ * @details
+ *
+ * Function : schHdlUlHqRetxStrtTimerForUl
+ *
+ * Handling of Ul harq DRX timers start for Ul scheduling
+ *
+ * @param[in] SchCellCb *cell, uint16_t currIdx
+ * @return
+ * void
+ **/
+
+void schHdlUlHqRetxStrtTimerForUl(SchCellCb *cell, uint16_t currIndx)
+{
+ CmLList *currNode;
+ SchUlHqProcCb *hqP;
+ SchUeCb *ueCb;
+
+ currNode = cell->drxCb[currIndx].ulRetransTmrStartList.first;
+
+ while(currNode)
+ {
+ hqP = (SchUlHqProcCb*)currNode->node;
+ currNode = currNode->next;
+ ueCb = hqP->hqEnt->ue;
+
+ /* Mark the UE active for uplink */
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq |= (SCH_DRX_UL_HARQ_BITMASK << hqP->procId);
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+
+ /* Delete the node */
+ cmLListDelFrm(&cell->drxCb[currIndx].ulRetransTmrStartList, hqP->ulDrxHarqCb.retxStrtNode);
+ SCH_FREE(hqP->ulDrxHarqCb.retxStrtNode, sizeof(CmLList));
+ hqP->ulDrxHarqCb.retxStrtIndex = SCH_DRX_INVALID_INDEX;
+ }
+}
+
+/**
+ * @brief Handling of the Ul harq DRX timers start
+ *
+ * @details
+ *
+ * Function : schHdlDrxUlHqRetxStrtTimer
+ *
+ * Handling of Ul harq DRX timers start
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxUlHqRetxStrtTimer(SchCellCb *cell)
+{
+ uint16_t dlIndx = 0, ulIndx=0;
+ SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+ ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots);
+ ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, gConfigInfo.gPhyDeltaUl + SCHED_DELTA, cell->numSlots);
+
+ dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+ ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+
+ schHdlUlHqRetxStrtTimerForDl(cell, dlIndx);
+ schHdlUlHqRetxStrtTimerForUl(cell, ulIndx);
+}
+
+/**
+ * @brief Handling of the Ul harq Rtt start DRX timers
+ *
+ * @details
+ *
+ * Function : schDrxStrtUlHqRttTmr
+ *
+ * Handling of the Ul harq Rtt start DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schDrxStrtUlHqRttTmr(SchUlHqProcCb *hqP)
+{
+ uint16_t harqRttExpTimer=0;
+ SchDrxUeCb *drxUeCb;
+
+ drxUeCb = &hqP->hqEnt->ue->drxUeCb;
+
+ harqRttExpTimer = (hqP->puschTime.sfn * MAX_SLOTS + hqP->puschTime.slot + drxUeCb->harqRttUlTimerLen)%MAX_DRX_SIZE;
+ hqP->ulDrxHarqCb.rttExpIndex = harqRttExpTimer;
+ schAddDrxNodeIntoHarqTimerList(&hqP->hqEnt->cell->drxCb[harqRttExpTimer].ulHarqRttExpiryList, hqP, &hqP->ulDrxHarqCb.rttExpNode);
+}
+
+/**
+ * @brief Handling of the expiry onduration timer in dl direction
+ *
+ * @details
+ *
+ * Function : schHdlDrxOnDurExpiryTimerForDlDirection
+ *
+ * Handling of expiry onduration DRX timers in dl direction
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxOnDurExpiryTimerForDlDirection(SchCellCb *cell, uint16_t currListIndx)
+{
+ 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;
+ drxCurrNode = drxCurrNode->next;
+
+ ueCb->drxUeCb.onDurationExpiryDistance--;
+
+ if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
+ {
+ continue;
+ }
+ ueCb->drxUeCb.drxDlUeActiveMask &= ~UE_ACTIVE_FOR_ONDURATION;
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+ }
+ }
+}
+
+/**
+ * @brief Handling of the expiry onduration DRX timers for Ul direction
+ *
+ * @details
+ *
+ * Function schHdlDrxOnDurExpiryTimerForUlDirection:
+ *
+ * Handling of expiry onduration DRX timers in Ul direction
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxOnDurExpiryTimerForUlDirection(SchCellCb *cell, uint16_t currListIndx)
+{
+ 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;
+ drxCurrNode = drxCurrNode->next;
+
+ if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
+ {
+ continue;
+ }
+
+ ueCb->drxUeCb.drxUlUeActiveMask &= ~UE_ACTIVE_FOR_ONDURATION;
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+ cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationExpiryIndex].onDurationExpiryList, ueCb->drxUeCb.onDurationExpiryNodeInfo);
+ SCH_FREE(ueCb->drxUeCb.onDurationExpiryNodeInfo, sizeof(CmLList));
+ ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
+ }
+ }
+}
+
+/**
+ * @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, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots);
+ ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, gConfigInfo.gPhyDeltaUl + SCHED_DELTA, cell->numSlots);
+ dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+ ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+
+ schHdlDrxOnDurExpiryTimerForDlDirection(cell, dlIndx);
+ schHdlDrxOnDurExpiryTimerForUlDirection(cell, ulIndx);
+}
+
+/**
+ * @brief Handling of the expiry of in-active DRX timers in Dl
+ *
+ * @details
+ *
+ * Function : schHdlDrxInActvExpiryTimerForDlDirection
+ *
+ * Handling of expiry of in-active DRX timers at Dl index
+ *
+ * @param[in] SchCellCb *cell, uint16_t dlIndx
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxInActvExpiryTimerForDlDirection(SchCellCb *cell, uint16_t dlIndx)
+{
+ CmLList *drxNode;
+ SchUeCb *ueCb = NULLP;
+
+ drxNode = cell->drxCb[dlIndx].inActvTmrExpiryList.first;
+ if(drxNode)
+ {
+ /* Handling of dl On duration drx start list */
+ while(drxNode)
+ {
+ ueCb = (SchUeCb*)drxNode->node;
+ drxNode = drxNode->next;
+ ueCb->drxUeCb.inActiveTmrExpiryDistance--;
+
+ if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
+ {
+ continue;
+ }
+
+ ueCb->drxUeCb.drxDlUeActiveMask &= ~UE_ACTIVE_FOR_INACTIVE_TIMER;
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+ }
+ }
+}
+
+/**
+ * @brief Handling of the expiry of in-active DRX timers in Ul
+ *
+ * @details
+ *
+ * Function : schHdlDrxInActvExpiryTimerForUlDirection
+ *
+ * Handling of expiry of in-active DRX timers at Ul index
+ *
+ * @param[in] SchCellCb *cell, uint16_t ulIndx
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxInActvExpiryTimerForUlDirection(SchCellCb *cell, uint16_t ulIndx)
+{
+ CmLList *drxNode;
+ SchUeCb *ueCb = NULLP;
+
+ drxNode = cell->drxCb[ulIndx].inActvTmrExpiryList.first;
+ if(drxNode)
+ {
+ /* Handling of dl On duration drx start list */
+ while(drxNode)
+ {
+ ueCb = (SchUeCb*)drxNode->node;
+ drxNode = drxNode->next;
+
+ if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
+ {
+ continue;
+ }
+
+ ueCb->drxUeCb.drxUlUeActiveMask &= ~UE_ACTIVE_FOR_INACTIVE_TIMER;
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+
+ /* Remove the entry from the in-active exp timer list */
+ cmLListDelFrm(&cell->drxCb[ulIndx].inActvTmrExpiryList, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
+ SCH_FREE(ueCb->drxUeCb.inActvTimerExpiryNodeInfo, sizeof(CmLList));
+ ueCb->drxUeCb.inActvExpiryIndex = SCH_DRX_INVALID_INDEX;
+
+ if(ueCb->drxUeCb.shortCyclePresent)
+ {
+ /* Start short cycle timer */
+ schHdlDrxStartShortCycleTimer(cell, ueCb);
+ }
+ }
+ }
+}
+
+/**
+ * @brief Handling of the expiry of in-active DRX timers
+ *
+ * @details
+ *
+ * Function :schHdlDrxInActvExpiryTimer
+ *
+ * Handling of expiry of 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, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots);
+ ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, gConfigInfo.gPhyDeltaUl + SCHED_DELTA, cell->numSlots);
+ dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+ ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+
+ schHdlDrxInActvExpiryTimerForDlDirection(cell, dlIndx);
+ schHdlDrxInActvExpiryTimerForUlDirection(cell, ulIndx);
+}
+
+/**
+ * @brief Handling of the expiry ShortCycle DRX timers in DL
+ *
+ * @details
+ *
+ * Function : schHdlDrxShortCycleExpiryTimerForDlDirection
+ *
+ * Handling of expiry ShortCycle
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxShortCycleExpiryTimerForDlDirection(SchCellCb *cell, uint16_t dlIndx)
+{
+ CmLList *drxCurrNode = NULLP;
+ SchUeCb *ueCb = NULLP;
+
+ drxCurrNode = cell->drxCb[dlIndx].shortCycleExpiryList.first;
+ if(drxCurrNode)
+ {
+ /* Handling of short cycle expiry in Dl */
+ while(drxCurrNode)
+ {
+ ueCb = (SchUeCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+
+ ueCb->drxUeCb.shortCycleDistance--;
+
+ if(ueCb->drxUeCb.shortCycleDistance != SCH_DRX_INVALID_DISTANCE)
+ {
+ continue;
+ }
+
+ /* once short cycle timer gets expire we will recalculate on-duration start with long cycle */
+ ueCb->drxUeCb.longCycleToBeUsed = true;
+
+ /* delete the entry from on-duration start */
+ 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;
+
+ /* Recalculate on-duration with long cycle */
+ schAddUeInOndurationList(cell, ueCb, gConfigInfo.gPhyDeltaDl + SCHED_DELTA);
+ }
+ }
+}
+
+/**
+ * @brief Handling of the expiry ShortCycle DRX timers in UL
+ *
+ * @details
+ *
+ * Function : schHdlDrxShortCycleExpiryTimerForUlDirection
+ *
+ * Handling of expiry ShortCycle
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDrxShortCycleExpiryTimerForUlDirection(SchCellCb *cell, uint16_t ulIndx)
+{
+ CmLList *drxCurrNode = NULLP;
+ SchUeCb *ueCb = NULLP;
+
+ drxCurrNode = cell->drxCb[ulIndx].shortCycleExpiryList.first;
+ if(drxCurrNode)
+ {
+ /* Handling of short cycle expiry in Ul */
+ while(drxCurrNode)
+ {
+ ueCb = (SchUeCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+
+ if(ueCb->drxUeCb.shortCycleDistance != SCH_DRX_INVALID_DISTANCE)
+ {
+ continue;
+ }
+
+ cmLListDelFrm(&cell->drxCb[ulIndx].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
+ SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
+ ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
+
+ }
+ }
+}
+
+/**
+ * @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, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots);
+ ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, gConfigInfo.gPhyDeltaUl + SCHED_DELTA, cell->numSlots);
+ dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+ ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+
+ schHdlDrxShortCycleExpiryTimerForDlDirection(cell, dlIndx);
+ schHdlDrxShortCycleExpiryTimerForUlDirection(cell, ulIndx);
+}
+
+/**
+ * @brief Handling of the expiry Dl harq rrt DRX timers
+ *
+ * @details
+ *
+ * Function : schHdlDlHqRttExpiryTimerForDl
+ *
+ * Handling of expiry Dl harq rrt DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlDlHqRttExpiryTimerForDl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchDlHqProcCb *hqP;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].dlHarqRttExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchDlHqProcCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+
+ /* Add ue to dlRetransTmrStartList list */
+ if(hqP->dlDrxHarqCb.retxStrtIndex == SCH_DRX_INVALID_INDEX)
+ {
+ schAddDrxNodeIntoHarqTimerList(&cell->drxCb[currIdx + 1].dlRetransTmrStartList, hqP, &hqP->dlDrxHarqCb.retxStrtNode);
+ hqP->dlDrxHarqCb.retxStrtIndex = currIdx + 1;
+ }
+ }
+}
+
+/**
+ * @brief Handling of the expiry Dl harq retransmission DRX timers
+ *
+ * @details
+ *
+ * Function : schHdlDlHqRetxExpiryTimerForDl
+ *
+ * Handling of expiry Dl harq retransmission DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+**/
+
+void schHdlDlHqRetxExpiryTimerForDl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchDlHqProcCb *hqP;
+ SchUeCb *ueCb;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].dlRetransExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchDlHqProcCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+ ueCb = hqP->hqEnt->ue;
+
+ ueCb->drxUeCb.drxDlUeActiveMaskForHarq &= ~(SCH_DRX_DL_HARQ_BITMASK << hqP->procId);
+
+ /* Set the Ue status as inactive */
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+ }
+}
+
+/**
+ * @brief Handling of the expiry Dl harq rrt DRX timers for Ul scheduling
+ *
+ * @details
+ *
+ * Function : schHdlDlHqRttExpiryTimerForUl
+ *
+ * Handling of expiry Dl harq rrt DRX timers for Ul scheduling
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+**/
+
+void schHdlDlHqRttExpiryTimerForUl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchDlHqProcCb *hqP;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].dlHarqRttExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchDlHqProcCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+
+ /* Delete the node from list */
+ cmLListDelFrm(&cell->drxCb[currIdx].dlHarqRttExpiryList, hqP->dlDrxHarqCb.rttExpNode);
+ SCH_FREE(hqP->dlDrxHarqCb.rttExpNode, sizeof(CmLList));
+ hqP->dlDrxHarqCb.rttExpIndex = SCH_DRX_INVALID_INDEX;
+ }
+}
+
+/**
+ * @brief Handling of the expiry Dl harq retransmission DRX timers for Ul scheduling
+ *
+ * @details
+ *
+ * Function : schHdlDlHqRetxExpiryTimerForUl
+ *
+ * Handling of expiry Dl harq retransmission DRX timers for Ul scheduling
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+**/
+
+void schHdlDlHqRetxExpiryTimerForUl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchDlHqProcCb *hqP;
+ SchUeCb *ueCb;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].dlRetransExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchDlHqProcCb*)drxCurrNode->node;
+ ueCb = hqP->hqEnt->ue;
+ drxCurrNode = drxCurrNode->next;
+
+ /* Set the Ue status as inactive for uplink */
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq &= ~(SCH_DRX_UL_HARQ_BITMASK << hqP->procId);
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+
+ /* Delete the UE */
+ cmLListDelFrm(&cell->drxCb[currIdx].dlRetransExpiryList, hqP->dlDrxHarqCb.retxExpNode);
+ SCH_FREE(hqP->dlDrxHarqCb.retxExpNode, sizeof(CmLList));
+ hqP->dlDrxHarqCb.retxExpIndex = SCH_DRX_INVALID_INDEX;
+
+ }
+}
+
+/**
+ * @brief Handling of the expiry of Dl harq DRX timers
+ *
+ * @details
+ *
+ * Function : schHdlDrxDlHarqExpireTimer
+ *
+ * Handling of expiry of Dl harq DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# void
+
+ **/
+
+void schHdlDrxDlHarqExpireTimer(SchCellCb *cell)
+{
+ uint16_t dlIndx = 0, ulIndx = 0;
+ SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+ ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots);
+ ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, gConfigInfo.gPhyDeltaUl + SCHED_DELTA, cell->numSlots);
+ dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+ ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+
+ schHdlDlHqRttExpiryTimerForDl(cell, dlIndx);
+ schHdlDlHqRetxExpiryTimerForDl(cell, dlIndx);
+ schHdlDlHqRttExpiryTimerForUl(cell, ulIndx );
+ schHdlDlHqRetxExpiryTimerForUl(cell, ulIndx);
+}
+
+/**
+ * @brief Handling of the expiry of harq DRX timers
+ *
+ * @details
+ *
+ * Function : schDrxStopDlHqRetxTmr
+ *
+ * Handling of expiry DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schDrxStopDlHqRetxTmr(SchCellCb *cell, SchUeCb *ueCb, SchDlHqProcCb **hqP)
+{
+
+ if((*hqP)->dlDrxHarqCb.retxExpIndex != SCH_DRX_INVALID_INDEX)
+ {
+ ueCb->drxUeCb.drxDlUeActiveMaskForHarq &= ~(SCH_DRX_DL_HARQ_BITMASK << (*hqP)->procId);
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq &= ~(SCH_DRX_UL_HARQ_BITMASK << (*hqP)->procId);
+
+ /* Change the UE status to Inactive */
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+
+ /* If there is any node present in rtt list then remove the node from list */
+ if((*hqP)->dlDrxHarqCb.rttExpIndex != SCH_DRX_INVALID_INDEX)
+ {
+ cmLListDelFrm(&cell->drxCb[(*hqP)->dlDrxHarqCb.rttExpIndex].dlHarqRttExpiryList, (*hqP)->dlDrxHarqCb.rttExpNode);
+ SCH_FREE((*hqP)->dlDrxHarqCb.rttExpNode, sizeof(CmLList));
+ (*hqP)->dlDrxHarqCb.rttExpIndex = SCH_DRX_INVALID_INDEX;
+ }
+
+ /* If there is any node present in retx list then remove the node from list */
+ if((*hqP)->dlDrxHarqCb.retxStrtIndex != SCH_DRX_INVALID_INDEX)
+ {
+ cmLListDelFrm(&cell->drxCb[(*hqP)->dlDrxHarqCb.retxStrtIndex].dlRetransTmrStartList, (*hqP)->dlDrxHarqCb.retxStrtNode);
+ SCH_FREE((*hqP)->dlDrxHarqCb.retxStrtNode, sizeof(CmLList));
+ (*hqP)->dlDrxHarqCb.retxStrtIndex = SCH_DRX_INVALID_INDEX;
+ }
+
+ cmLListDelFrm(&cell->drxCb[(*hqP)->dlDrxHarqCb.retxExpIndex].dlRetransExpiryList, (*hqP)->dlDrxHarqCb.retxExpNode);
+ SCH_FREE((*hqP)->dlDrxHarqCb.retxExpNode, sizeof(CmLList));
+ (*hqP)->dlDrxHarqCb.retxExpIndex = SCH_DRX_INVALID_INDEX;
+ }
+}
+
+/**
+ * @brief Handling of the expiry Ul harq rrt DRX timers
+ *
+ * @details
+ *
+ * Function : schHdlUlHqRttExpiryTimerForDl
+ *
+ * Handling of expiry ul harq rrt DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schHdlUlHqRttExpiryTimerForDl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchUlHqProcCb *hqP;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].ulHarqRttExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchUlHqProcCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+
+ /* Add ue to ulRetransTmrStartList list */
+ if(hqP->ulDrxHarqCb.retxStrtIndex == SCH_DRX_INVALID_INDEX)
+ {
+ schAddDrxNodeIntoHarqTimerList(&cell->drxCb[currIdx + 1].ulRetransTmrStartList, hqP, &hqP->ulDrxHarqCb.retxStrtNode);
+ hqP->ulDrxHarqCb.retxStrtIndex = currIdx + 1;
+ }
+ }
+}
+
+/**
+ * @brief Handling of the expiry ul harq retransmission DRX timers
+ *
+ * @details
+ *
+ * Function : schHdlUlHqRetxExpiryTimerForDl
+ *
+ * Handling of expiry Ul harq retransmission DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+**/
+
+void schHdlUlHqRetxExpiryTimerForDl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchUlHqProcCb *hqP;
+ SchUeCb *ueCb;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].ulRetransExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchUlHqProcCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+ ueCb = hqP->hqEnt->ue;
+
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq &= ~(SCH_DRX_UL_HARQ_BITMASK << hqP->procId);
+
+ /* Set the Ue status as inactive */
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+ }
+}
+
+/**
+ * @brief Handling of the expiry ul harq rrt DRX timers for Ul scheduling
+ *
+ * @details
+ *
+ * Function : schHdlUlHqRttExpiryTimerForUl
+ *
+ * Handling of expiry Ul harq rrt DRX timers for Ul scheduling
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+**/
+
+void schHdlUlHqRttExpiryTimerForUl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchUlHqProcCb *hqP;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].ulHarqRttExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchUlHqProcCb*)drxCurrNode->node;
+ drxCurrNode = drxCurrNode->next;
+
+ /* Delete the node from list */
+ cmLListDelFrm(&cell->drxCb[currIdx].ulHarqRttExpiryList, hqP->ulDrxHarqCb.rttExpNode);
+ SCH_FREE(hqP->ulDrxHarqCb.rttExpNode, sizeof(CmLList));
+ hqP->ulDrxHarqCb.rttExpIndex = SCH_DRX_INVALID_INDEX;
+ }
+}
+
+/**
+ * @brief Handling of the expiry Ul harq retransmission DRX timers for Ul scheduling
+ *
+ * @details
+ *
+ * Function : schHdlUlHqRetxExpiryTimerForUl
+ *
+ * Handling of expiry Ul harq retransmission DRX timers for Ul scheduling
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+**/
+
+void schHdlUlHqRetxExpiryTimerForUl(SchCellCb *cell, uint16_t currIdx)
+{
+ SchUlHqProcCb *hqP;
+ SchUeCb *ueCb;
+ CmLList *drxCurrNode;
+
+ drxCurrNode = cell->drxCb[currIdx].ulRetransExpiryList.first;
+
+ while(drxCurrNode)
+ {
+ hqP = (SchUlHqProcCb*)drxCurrNode->node;
+ ueCb = hqP->hqEnt->ue;
+ drxCurrNode = drxCurrNode->next;
+
+ /* Set the Ue status as inactive for uplink */
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq &= ~(SCH_DRX_UL_HARQ_BITMASK << hqP->procId);
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+
+ /* Delete the UE */
+ cmLListDelFrm(&cell->drxCb[currIdx].ulRetransExpiryList, hqP->ulDrxHarqCb.retxExpNode);
+ SCH_FREE(hqP->ulDrxHarqCb.retxExpNode, sizeof(CmLList));
+ hqP->ulDrxHarqCb.retxExpIndex = SCH_DRX_INVALID_INDEX;
+
+ }
+}
+
+/**
+ * @brief Handling of the expiry of Ul harq DRX timers
+ *
+ * @details
+ *
+ * Function : schHdlDrxUlHarqExpireTimer
+ *
+ * Handling of expiry of Ul harq DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# void
+
+ **/
+
+void schHdlDrxUlHarqExpireTimer(SchCellCb *cell)
+{
+ uint16_t dlIndx = 0, ulIndx = 0;
+ SlotTimingInfo dlSlotInfo, ulSlotInfo;
+
+ ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots);
+ ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, gConfigInfo.gPhyDeltaUl + SCHED_DELTA, cell->numSlots);
+ dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
+ ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
+
+ schHdlUlHqRttExpiryTimerForDl(cell, dlIndx);
+ schHdlUlHqRetxExpiryTimerForDl(cell, dlIndx);
+ schHdlUlHqRttExpiryTimerForUl(cell, ulIndx );
+ schHdlUlHqRetxExpiryTimerForUl(cell, ulIndx);
+}
+
+/**
+ * @brief Hanuling of the expiry of harq DRX timers
+ *
+ * @details
+ *
+ * Function : schDrxStopUlHqRetxTmr
+ *
+ * Hanuling of expiry DRX timers
+ *
+ * @param[in] SchCellCb *cell
+ * @return
+ * -# ROK
+ * -# RFAILED
+ **/
+
+void schDrxStopUlHqRetxTmr(SchCellCb *cell, SchUeCb *ueCb, SchUlHqProcCb **hqP)
+{
+
+ if((*hqP)->ulDrxHarqCb.retxExpIndex != SCH_DRX_INVALID_INDEX)
+ {
+ ueCb->drxUeCb.drxDlUeActiveMaskForHarq &= ~(SCH_DRX_DL_HARQ_BITMASK << (*hqP)->procId);
+ ueCb->drxUeCb.drxUlUeActiveMaskForHarq &= ~(SCH_DRX_UL_HARQ_BITMASK << (*hqP)->procId);
+
+ /* Change the UE status to Inactive */
+ setDrxUeStatusForDlandUl(&ueCb->drxUeCb);
+
+ /* If there is any node present in rtt list then remove the node from list */
+ if((*hqP)->ulDrxHarqCb.rttExpIndex != SCH_DRX_INVALID_INDEX)
+ {
+ cmLListDelFrm(&cell->drxCb[(*hqP)->ulDrxHarqCb.rttExpIndex].ulHarqRttExpiryList, (*hqP)->ulDrxHarqCb.rttExpNode);
+ SCH_FREE((*hqP)->ulDrxHarqCb.rttExpNode, sizeof(CmLList));
+ (*hqP)->ulDrxHarqCb.rttExpIndex = SCH_DRX_INVALID_INDEX;
+ }
+
+ /* If there is any node present in retx list then remove the node from list */
+ if((*hqP)->ulDrxHarqCb.retxStrtIndex != SCH_DRX_INVALID_INDEX)
+ {
+ cmLListDelFrm(&cell->drxCb[(*hqP)->ulDrxHarqCb.retxStrtIndex].ulRetransTmrStartList, (*hqP)->ulDrxHarqCb.retxStrtNode);
+ SCH_FREE((*hqP)->ulDrxHarqCb.retxStrtNode, sizeof(CmLList));
+ (*hqP)->ulDrxHarqCb.retxStrtIndex = SCH_DRX_INVALID_INDEX;
+ }
+
+ cmLListDelFrm(&cell->drxCb[(*hqP)->ulDrxHarqCb.retxExpIndex].ulRetransExpiryList, (*hqP)->ulDrxHarqCb.retxExpNode);
+ SCH_FREE((*hqP)->ulDrxHarqCb.retxExpNode, sizeof(CmLList));
+ (*hqP)->ulDrxHarqCb.retxExpIndex = SCH_DRX_INVALID_INDEX;
+ }
+}
+
+/**
+ * @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)
+{
+ schHdlDrxShortCycleExpiryTimer(cell);