2 /*******************************************************************************
3 ################################################################################
4 # Copyright (c) [2017-2019] [Radisys] #
6 # Licensed under the Apache License, Version 2.0 (the "License"); #
7 # you may not use this file except in compliance with the License. #
8 # You may obtain a copy of the License at #
10 # http://www.apache.org/licenses/LICENSE-2.0 #
12 # Unless required by applicable law or agreed to in writing, software #
13 # distributed under the License is distributed on an "AS IS" BASIS, #
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15 # See the License for the specific language governing permissions and #
16 # limitations under the License. #
17 ################################################################################
18 *******************************************************************************/
20 #include "common_def.h"
26 #include "du_app_mac_inf.h"
27 #include "mac_sch_interface.h"
29 #include "sch_utils.h"
33 * @brief intialize the SchDrxHarqCb structre
37 * Function :schInitDrxHarqCb
39 * intialize the SchDrxHarqCb structre
41 * @param[in] SchDrxHarqCb *hqCb
47 void schInitDrxHarqCb(SchDrxHarqCb *hqDrxCb)
49 memset(hqDrxCb, 0, sizeof(SchDrxHarqCb));
50 hqDrxCb->retxExpDistance = SCH_DRX_INVALID_DISTANCE;
51 hqDrxCb->retxStrtIndex = SCH_DRX_INVALID_INDEX;
52 hqDrxCb->rttIndex = SCH_DRX_INVALID_INDEX;
53 hqDrxCb->retxIndex = SCH_DRX_INVALID_INDEX;
57 * @brief intialize the SchDrxUeCb structre
61 * Function : schInitDrxUeCb
63 * intialize the SchDrxUeCb structre
65 * @param[in] SchUeCb *ueCb
71 void schInitDrxUeCb(SchUeCb *ueCb)
73 memset(&ueCb->drxUeCb, 0, sizeof(SchDrxUeCb));
74 ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX;
75 ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
76 ueCb->drxUeCb.inActvExpiryIndex = SCH_DRX_INVALID_INDEX;
77 ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
78 ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE;
79 ueCb->drxUeCb.onDurationExpiryDistance = SCH_DRX_INVALID_DISTANCE;
80 ueCb->drxUeCb.inActiveTmrExpiryDistance = SCH_DRX_INVALID_DISTANCE;
81 ueCb->drxUeCb.drxDlUeActiveStatus = 0;
82 ueCb->drxUeCb.drxUlUeActiveStatus = 0;
85 /* will uncomment this function in next gerrit */
88 * @brief delete Dl harq drx timers and information
92 * Function : schDeleteDlHarqDrxTimer
94 * delete Dl harq drx timers and information
96 * @param[in] SchCellCb *cell, SchUeCb *ueCb
101 void schDeleteDlHarqDrxTimer(SchCellCb *cell, SchDlHqEnt *dlHqEnt)
103 uint8_t idx, numHqPrcs;
105 SchDlHqProcCb *procs;
106 CmLList *node = NULLP;
108 numHqPrcs = dlHqEnt->numHqPrcs;
109 for(idx =0; idx<numHqPrcs; idx++)
111 procs = &dlHqEnt->procs[idx];
112 tmrIdx = procs->dlDrxHarqCb.retxStrtIndex;
113 CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node);
116 cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node);
117 SCH_FREE(node, sizeof(CmLList));
120 tmrIdx = procs->dlDrxHarqCb.rttIndex;
121 CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node);
124 cmLListDelFrm(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node);
125 SCH_FREE(node, sizeof(CmLList));
128 tmrIdx = procs->dlDrxHarqCb.retxIndex;
129 CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransExpiryList, node);
132 cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransExpiryList, node);
133 SCH_FREE(node, sizeof(CmLList));
135 schInitDrxHarqCb(&procs->dlDrxHarqCb);
140 * @brief delete UL harq drx timers and information
144 * Function : schDeleteUlHarqDrxTimer
146 * delete Ul harq drx timers and information
148 * @param[in] SchCellCb *cell, SchUeCb *ueCb
153 void schDeleteUlHarqDrxTimer(SchCellCb *cell, SchUlHqEnt *ulHqEnt)
155 uint8_t idx, numHqPrcs;
157 CmLList *node = NULLP;
158 SchUlHqProcCb *procs;
160 numHqPrcs = ulHqEnt->numHqPrcs;
161 for(idx =0; idx<numHqPrcs; idx++)
163 procs = &ulHqEnt->procs[idx];
164 tmrIdx = procs->ulDrxHarqCb.retxStrtIndex;
165 CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node);
168 cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node);
169 SCH_FREE(node, sizeof(CmLList));
172 tmrIdx = procs->ulDrxHarqCb.rttIndex;
173 CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node);
176 cmLListDelFrm(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node);
177 SCH_FREE(node, sizeof(CmLList));
180 tmrIdx = procs->ulDrxHarqCb.retxIndex;
181 CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransExpiryList, node);
184 cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransExpiryList, node);
185 SCH_FREE(node, sizeof(CmLList));
187 schInitDrxHarqCb(&procs->ulDrxHarqCb);
193 * @brief delete UE drx timers and information
197 * Function : schDeleteUeDrxInfo
199 * delete UE drx timers and information
201 * @param[in] SchCellCb *cell, SchUeCb *ueCb
206 void schDeleteUeDrxInfo(SchCellCb *cell, SchUeCb *ueCb)
210 if(ueCb->ueDrxInfoPres == true)
212 drxUeCb = &ueCb->drxUeCb;
214 /* delete on duration start timer from ueCb */
215 if(drxUeCb->onDurationStartIndex != SCH_DRX_INVALID_INDEX)
217 cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationStartIndex].onDurationStartList, drxUeCb->onDurationStartNodeInfo);
218 SCH_FREE(drxUeCb->onDurationStartNodeInfo, sizeof(CmLList));
221 /* delete on duration expiry timer from ueCb */
222 if(drxUeCb->onDurationExpiryIndex != SCH_DRX_INVALID_INDEX)
224 cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationExpiryIndex].onDurationExpiryList, drxUeCb->onDurationExpiryNodeInfo);
225 SCH_FREE(drxUeCb->onDurationExpiryNodeInfo, sizeof(CmLList));
228 /* delete inActv Expiry Index timer from ueCb */
229 if(drxUeCb->inActvExpiryIndex != SCH_DRX_INVALID_INDEX)
231 cmLListDelFrm(&cell->drxCb[drxUeCb->inActvExpiryIndex].inActvTmrExpiryList, drxUeCb->inActvTimerExpiryNodeInfo);
232 SCH_FREE(drxUeCb->inActvTimerExpiryNodeInfo, sizeof(CmLList));
235 /* delete short cycle expiry timer from ueCb */
236 if(drxUeCb->shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX)
238 cmLListDelFrm(&cell->drxCb[drxUeCb->shortCycleExpiryIndex].shortCycleExpiryList, drxUeCb->shortCycleTmrExpiryNodeInfo);
239 SCH_FREE(drxUeCb->shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
241 /* TODO - will uncomment this function in next gerrit */
242 //schDeleteDlHarqDrxTimer(cell, &ueCb->dlHqEnt);
243 //schDeleteUlHarqDrxTimer(cell, &ueCb->ulHqEnt);
244 schInitDrxUeCb(ueCb);
249 * @brief fill drxUeCb structure with the help of ue cfg/recfg information
253 * Function : schFillDrxUeCb
255 * fill drxUeCb structure with the help of ue cfg/recfg information
257 * @param[in] SchDrxCfg drxCfg ->configuration received from ue cfg/recfg api
258 * SchDrxUeCb *drxUeCb -> structure that need to be fill
264 void schFillDrxUeCb(uint8_t numerology, SchDrxCfg drxCfg, SchDrxUeCb *drxUeCb)
266 if(drxCfg.drxOnDurationTimer.onDurationTimerValInMs)
268 SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.milliSeconds, numerology);
272 SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds, numerology);
273 drxUeCb->onDurationLen = drxUeCb->onDurationLen >> 5;
275 SCH_CNVRT_MS_TO_SLOT(drxUeCb->inActvTimerLen, drxCfg.drxInactivityTimer, numerology);
276 SCH_CNVRT_SYMBL_TO_SLOT(drxUeCb->harqRttDlTimerLen, drxCfg.drxHarqRttTimerDl);
277 SCH_CNVRT_SYMBL_TO_SLOT(drxUeCb->harqRttUlTimerLen, drxCfg.drxHarqRttTimerUl);
278 drxUeCb->retransDlTimerLen = drxCfg.drxRetransmissionTimerDl;
279 drxUeCb->retransUlTimerLen = drxCfg.drxRetransmissionTimerUl;
280 SCH_CNVRT_MS_TO_SLOT(drxUeCb->longCycleLen, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice, numerology);
281 SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxStartOffset, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetVal, numerology);
282 if(drxCfg.shortDrxPres)
284 drxUeCb->shortCyclePresent = true;
285 SCH_CNVRT_MS_TO_SLOT(drxUeCb->shortCycleLen, drxCfg.shortDrx.drxShortCycle, numerology);
286 drxUeCb->shortCycleTmrLen = drxUeCb->shortCycleLen*drxCfg.shortDrx.drxShortCycleTimer;
288 drxUeCb->longCycleToBeUsed = true;
289 SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxSlotOffset, drxCfg.drxSlotOffset, numerology);
290 drxUeCb->drxSlotOffset = drxUeCb->drxSlotOffset>>5;
294 * @brief Add new entry into the drx timer list
298 * Function : schAddDrxTimerIntoList
300 * Add new entry into the drx timer list
302 * @param[in] CmLListCp *drxTimerList -> List in which new entery have to add
303 * void * ueInfo -> ue information which is need to the added into list
309 uint8_t schAddDrxTimerIntoList(CmLListCp *drxTimerList,void * nodeInfo, CmLList *drxNodeInfo)
311 CmLList *currentNodeInfo = NULLP;
313 SCH_ALLOC(currentNodeInfo, sizeof(CmLList));
316 DU_LOG("\nERROR --> SCH : schAddDrxTimerIntoList() : Memory allocation failed");
320 currentNodeInfo->node = (PTR)nodeInfo;
322 cmLListAdd2Tail(drxTimerList, currentNodeInfo);
323 drxNodeInfo = currentNodeInfo;
324 DU_LOG("\nINFO --> SCH : Drx node added into the list");
329 * @brief This function is used to find the next onduration start timing
333 * Function : findNextOndurationOccurance
335 * This function is used to find the next onduration start timing
337 * @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo *nxtOnDur,
344 void findNextOndurationOccurance(SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo *nxtOnDur, uint8_t delta)
346 uint16_t tmpDistance, numOfCycles;
347 uint32_t curTime, cycleLen, nxtDist;
348 SlotTimingInfo tmpTime;
350 if (ueDrxCb->longCycleToBeUsed == true)
352 cycleLen = ueDrxCb->longCycleLen;
356 cycleLen = ueDrxCb->shortCycleLen;
359 /* Add delta to current time */
360 ADD_DELTA_TO_TIME(cell->slotInfo, tmpTime, delta, cell->numSlots);
362 /* Convert tmpTime to number of slots */
363 curTime = ((tmpTime.sfn * cell->numSlots) + tmpTime.slot);
365 /* as per 38.321, if the criterion below is satisfied, then that sfn and
366 * slot are the correct ones for the on-duration timer.
367 * if the Short DRX Cycle is used, and [(SFN × 10) + subframe number] modulo
368 * (drx-ShortCycle) = (drxStartOffset) modulo (drx-ShortCycle); or
369 * if the Long DRX Cycle is used, and [(SFN × 10) + subframe number] modulo
370 * (drx-LongCycle) = drxStartOffset */
371 if ( curTime <= ueDrxCb->drxStartOffset)
373 /* offset is the nextOnDur */
374 nxtDist = ((((ueDrxCb->drxStartOffset / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (ueDrxCb->drxStartOffset % cell->numSlots);
378 tmpDistance = curTime - ueDrxCb->drxStartOffset;
379 numOfCycles = tmpDistance / cycleLen;
381 if (0 == (tmpDistance % cycleLen))
383 /* Perfect match pick up the current time */
384 nxtDist = ((((curTime / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (curTime % cell->numSlots);
388 nxtDist = ueDrxCb->drxStartOffset + (numOfCycles + 1) * cycleLen;
392 /* If slot offset is non-zero then Add slot offset to the calculated onDur
394 if(ueDrxCb->drxSlotOffset)
396 nxtDist = nxtDist + ueDrxCb->drxSlotOffset;
398 /*If next On Duration is less than DL DELTA ahead, we will miss it and
399 * hence need to move to the On-Duration after that.*/
400 if((nxtDist - (curTime - delta)) <= SCH_DRX_MAX_DELTA)
402 nxtDist = nxtDist + cycleLen;
405 nxtOnDur->sfn = ((nxtDist / cell->numSlots) & (MAX_SFN - 1));
406 nxtOnDur->slot = (nxtDist % cell->numSlots);
410 * @brief Add entry into the on duration list and short cycle list
414 * Function : schDrxUeReCfgTimer
416 * This function is used to Add entry into the on duration list and short
419 * @param[in] SchCellCb *cell, SchUeCb *ueCb
425 void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb)
427 uint8_t currentSlotIndx;
428 uint32_t onDurTime, onDurExpSlotTime, currentSlotTime;
430 SlotTimingInfo onDurationOccurance;
432 if(ueCb->drxUeCb.shortCyclePresent == false)
434 /* 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
435 * remove the entry from the list */
436 if(ueCb->drxUeCb.shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX)
438 cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.shortCycleExpiryIndex ].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
439 SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
440 ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
441 ueCb->drxUeCb.shortCycleDistance = SCH_DRX_INVALID_DISTANCE;
444 /* If there is any entry present in on duration start list then remove the
445 * entry from the list and recaluate the nect onduration cucurance */
446 if(ueCb->drxUeCb.onDurationStartIndex != SCH_DRX_INVALID_INDEX)
448 cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
449 SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
450 ueCb->drxUeCb.onDurationStartIndex= SCH_DRX_INVALID_INDEX;
451 ueCb->drxUeCb.onDurationStartDistance= SCH_DRX_INVALID_DISTANCE;
455 findNextOndurationOccurance(cell, &ueCb->drxUeCb, &onDurationOccurance, 0);
456 onDurTime = onDurationOccurance.sfn*cell->numSlots+onDurationOccurance.slot;
458 /* If Onduration timer of old configuration is already running then next onduration
459 * starts once it expires*/
460 if((ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE) && (ueCb->drxUeCb.onDurationExpiryIndex != SCH_DRX_INVALID_INDEX))
462 currentSlotTime = cell->slotInfo.sfn * cell->numSlots + cell->slotInfo.slot;
463 currentSlotIndx = (currentSlotTime + PHY_DELTA_DL + SCHED_DELTA)%MAX_DRX_SIZE;
464 if(currentSlotIndx >= ueCb->drxUeCb.onDurationExpiryIndex )
466 onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance +1) * MAX_DRX_SIZE) +\
467 (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA);
472 onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance) * MAX_DRX_SIZE) +\
473 (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA);
475 if(onDurTime <= onDurExpSlotTime)
477 if(ueCb->drxUeCb.longCycleToBeUsed == true)
478 cycleLen = ueCb->drxUeCb.longCycleLen;
480 cycleLen = ueCb->drxUeCb.shortCycleLen;
482 onDurTime = onDurTime + ((onDurExpSlotTime - onDurTime)/cycleLen + 1) * cycleLen;
485 SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex);
486 ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, cell->numSlots)/MAX_DRX_SIZE;
487 schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
491 * @brief Add entry into the on duration list
495 * Function : schAddUeInOndurationList
497 * This function is used to Add entry into the on duration list
499 * @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo *nxtOnDur,
506 void schAddUeInOndurationList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta)
509 SlotTimingInfo onDurationOccurance;
511 if(ueCb->ueDrxInfoPres)
513 findNextOndurationOccurance(cell, &ueCb->drxUeCb, &onDurationOccurance, delta);
514 onDurTime = onDurationOccurance.sfn*cell->numSlots+onDurationOccurance.slot;
515 SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex);
516 ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, cell->numSlots)/MAX_DRX_SIZE;
517 schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
523 * @brief Handling of On duration drx start timer
527 * Function : schHdlDrxOnDurStrtTimerForDlDirection
529 * Handling of On duration drx start timer
531 * @param[in] SchCellCb *cell
537 void schHdlDrxOnDurStrtTimerForDlDirection(SchCellCb *cell, uint16_t currListIndx)
539 uint16_t onDurationExpiry=0;
540 CmLList *drxCurrNode = NULLP;
541 SchUeCb *ueCb = NULLP;
543 drxCurrNode = cell->drxCb[currListIndx].onDurationStartList.first;
546 /* Handling of dl On duration drx start list */
549 ueCb = (SchUeCb*)drxCurrNode->node;
550 drxCurrNode = drxCurrNode->next;
552 ueCb->drxUeCb.onDurationStartDistance--;
554 if(ueCb->drxUeCb.onDurationStartDistance != SCH_DRX_INVALID_DISTANCE)
560 ueCb->drxUeCb.drxDlUeActiveStatus |= UE_ACTIVE_FOR_ONDURATION;
562 /* If there is any entery present in onDurationExpiry list remove
563 * the entery from the list and recalculate the
564 * onDurationExpiry time and add it to list */
565 if(ueCb->drxUeCb.onDurationExpiryIndex != SCH_DRX_INVALID_INDEX)
567 cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationExpiryIndex].onDurationExpiryList, ueCb->drxUeCb.onDurationExpiryNodeInfo);
568 SCH_FREE(ueCb->drxUeCb.onDurationExpiryNodeInfo, sizeof(CmLList));
569 ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
570 ueCb->drxUeCb.onDurationExpiryDistance = SCH_DRX_INVALID_DISTANCE;
573 /* onDurationExpiry = (current slot + onduration length) % MAX_DRX_SIZE*/
574 onDurationExpiry = (currListIndx + ueCb->drxUeCb.onDurationLen)%MAX_DRX_SIZE;
575 ueCb->drxUeCb.onDurationExpiryDistance = (ueCb->drxUeCb.onDurationLen)/MAX_DRX_SIZE;
576 schAddDrxTimerIntoList(&cell->drxCb[onDurationExpiry].onDurationExpiryList, ueCb, ueCb->drxUeCb.onDurationExpiryNodeInfo);
577 ueCb->drxUeCb.onDurationExpiryIndex = onDurationExpiry;
585 * @brief Handling of On duration drx start timer
589 * Function : schHdlDrxOnDurStrtTimerForUlDirection
591 * Handling of On duration drx start timer
593 * @param[in] SchCellCb *cell
599 void schHdlDrxOnDurStrtTimerForUlDirection(SchCellCb *cell, uint16_t currListIndx)
601 uint16_t onDurTime=0;
602 CmLList *drxCurrNode = NULLP;
603 SchUeCb *ueCb = NULLP;
605 drxCurrNode = cell->drxCb[currListIndx].onDurationStartList.first;
608 /* Handling of dl On duration drx start list */
611 ueCb = (SchUeCb*)drxCurrNode->node;
612 drxCurrNode = drxCurrNode->next;
614 if(ueCb->drxUeCb.onDurationStartDistance != SCH_DRX_INVALID_DISTANCE)
618 ueCb->drxUeCb.drxUlUeActiveStatus |= UE_ACTIVE_FOR_ONDURATION;
621 /* if there short cycle length is used as the cycle length for onduration calculation then based on the short cycle else long cycle is used for calculating next onduration */
622 cmLListDelFrm(&cell->drxCb[currListIndx].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
623 SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
624 ueCb->drxUeCb.onDurationStartIndex= SCH_DRX_INVALID_INDEX;
626 if(ueCb->drxUeCb.longCycleToBeUsed)
628 onDurTime = currListIndx + ueCb->drxUeCb.longCycleLen;
632 onDurTime = currListIndx + ueCb->drxUeCb.shortCycleLen;
634 SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex);
635 ueCb->drxUeCb.onDurationStartDistance = ueCb->drxUeCb.longCycleLen/MAX_DRX_SIZE;
636 schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo);
642 * @brief Handling of On duration drx start timer
646 * Function : schHdlDrxOnDurStrtTimer
648 * Handling of On duration drx start timer
650 * @param[in] SchCellCb *cell
655 void schHdlDrxOnDurStrtTimer(SchCellCb *cell)
657 uint16_t dlIndx = 0, ulIndx=0;
658 SlotTimingInfo dlSlotInfo, ulSlotInfo;
660 ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
661 ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA, cell->numSlots);
663 dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
664 ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
665 schHdlDrxOnDurStrtTimerForDlDirection(cell, dlIndx);
666 schHdlDrxOnDurStrtTimerForUlDirection(cell, ulIndx);
670 * @brief Handling of the DRX in-active start timer
676 * Handling of DRX in-active start timer
678 * @param[in] SchCellCb *cell
684 void schHdlDrxInActvStrtTmr(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta)
686 uint16_t slotIndx = 0;
687 SlotTimingInfo tmpSlotInfo;
689 if(ueCb->drxUeCb.inActvTimerLen == 0)
694 ADD_DELTA_TO_TIME(cell->slotInfo, tmpSlotInfo, delta, cell->numSlots);
695 slotIndx = (tmpSlotInfo.sfn*MAX_SLOTS+tmpSlotInfo.slot)%MAX_DRX_SIZE;
697 /* if there is any entry present in the in-active exp list then remove the entry */
698 if(ueCb->drxUeCb.inActvExpiryIndex != SCH_DRX_INVALID_INDEX)
700 cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.inActvExpiryIndex].inActvTmrExpiryList, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
701 SCH_FREE(ueCb->drxUeCb.inActvTimerExpiryNodeInfo, sizeof(CmLList));
702 ueCb->drxUeCb.inActvExpiryIndex= SCH_DRX_INVALID_INDEX;
703 ueCb->drxUeCb.inActiveTmrExpiryDistance= SCH_DRX_INVALID_DISTANCE;
706 /* Adding the new entry in in-activity timer list */
707 ueCb->drxUeCb.inActvExpiryIndex = (slotIndx + ueCb->drxUeCb.inActvTimerLen) % MAX_DRX_SIZE;
708 ueCb->drxUeCb.inActiveTmrExpiryDistance = (ueCb->drxUeCb.inActvTimerLen) / MAX_DRX_SIZE;
709 schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.inActvExpiryIndex].inActvTmrExpiryList, ueCb, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
711 /* Set the UE active for UL And Dl transfer */
712 ueCb->drxUeCb.drxDlUeActiveStatus |= UE_ACTIVE_FOR_INACTIVE_TIMER;
713 ueCb->drxUeCb.drxUlUeActiveStatus |= UE_ACTIVE_FOR_INACTIVE_TIMER;
717 * @brief Handling of the DRX timers start
721 * Function : schHandleStartDrxTimer
723 * Handling of DRX timers start
725 * @param[in] SchCellCb *cell
730 void schHandleStartDrxTimer(SchCellCb *cell)
732 /* Handling the onduration start timer */
733 schHdlDrxOnDurStrtTimer(cell);
737 * @brief Handling of the expiry onduration timer in dl direction
741 * Function : schHdlDrxOnDurExpiryTimerForDlDirection
743 * Handling of expiry onduration DRX timers in dl direction
745 * @param[in] SchCellCb *cell
750 void schHdlDrxOnDurExpiryTimerForDlDirection(SchCellCb *cell, uint16_t currListIndx)
752 CmLList *drxCurrNode;
753 SchUeCb *ueCb = NULLP;
755 drxCurrNode = cell->drxCb[currListIndx].onDurationExpiryList.first;
758 /* Handling of dl On duration drx start list */
761 ueCb = (SchUeCb*)drxCurrNode->node;
762 drxCurrNode = drxCurrNode->next;
764 ueCb->drxUeCb.onDurationExpiryDistance--;
766 if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
770 ueCb->drxUeCb.drxDlUeActiveStatus &= ~UE_ACTIVE_FOR_ONDURATION;
776 * @brief Handling of the expiry onduration DRX timers for Ul direction
780 * Function schHdlDrxOnDurExpiryTimerForUlDirection:
782 * Handling of expiry onduration DRX timers in Ul direction
784 * @param[in] SchCellCb *cell
789 void schHdlDrxOnDurExpiryTimerForUlDirection(SchCellCb *cell, uint16_t currListIndx)
791 CmLList *drxCurrNode;
792 SchUeCb *ueCb = NULLP;
794 drxCurrNode = cell->drxCb[currListIndx].onDurationExpiryList.first;
797 /* Handling of dl On duration drx start list */
800 ueCb = (SchUeCb*)drxCurrNode->node;
801 drxCurrNode = drxCurrNode->next;
803 if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
808 ueCb->drxUeCb.drxUlUeActiveStatus &= ~UE_ACTIVE_FOR_ONDURATION;
809 cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationExpiryIndex].onDurationExpiryList, ueCb->drxUeCb.onDurationExpiryNodeInfo);
810 SCH_FREE(ueCb->drxUeCb.onDurationExpiryNodeInfo, sizeof(CmLList));
811 ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX;
816 * @brief Handling of the expiry onduration DRX timers
820 * Function : schHdlDrxOnDurExpiryTimer
822 * Handling of expiry onduration DRX timers
824 * @param[in] SchCellCb *cell
829 void schHdlDrxOnDurExpiryTimer(SchCellCb *cell)
831 uint16_t dlIndx = 0, ulIndx = 0;
832 SlotTimingInfo dlSlotInfo, ulSlotInfo;
834 ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
835 ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA, cell->numSlots);
836 dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
837 ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
839 schHdlDrxOnDurExpiryTimerForDlDirection(cell, dlIndx);
840 schHdlDrxOnDurExpiryTimerForUlDirection(cell, ulIndx);
844 * @brief Handling of the expiry of in-active DRX timers in Dl
848 * Function : schHdlDrxInActvExpiryTimerForDlDirection
850 * Handling of expiry of in-active DRX timers at Dl index
852 * @param[in] SchCellCb *cell, uint16_t dlIndx
858 void schHdlDrxInActvExpiryTimerForDlDirection(SchCellCb *cell, uint16_t dlIndx)
861 SchUeCb *ueCb = NULLP;
863 drxNode = cell->drxCb[dlIndx].inActvTmrExpiryList.first;
866 /* Handling of dl On duration drx start list */
869 ueCb = (SchUeCb*)drxNode->node;
870 drxNode = drxNode->next;
871 ueCb->drxUeCb.inActiveTmrExpiryDistance--;
873 if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
878 ueCb->drxUeCb.drxDlUeActiveStatus &= ~UE_ACTIVE_FOR_INACTIVE_TIMER;
884 * @brief Handling of the expiry of in-active DRX timers in Ul
888 * Function : schHdlDrxInActvExpiryTimerForUlDirection
890 * Handling of expiry of in-active DRX timers at Ul index
892 * @param[in] SchCellCb *cell, uint16_t ulIndx
898 void schHdlDrxInActvExpiryTimerForUlDirection(SchCellCb *cell, uint16_t ulIndx)
901 SchUeCb *ueCb = NULLP;
903 drxNode = cell->drxCb[ulIndx].inActvTmrExpiryList.first;
906 /* Handling of dl On duration drx start list */
909 ueCb = (SchUeCb*)drxNode->node;
910 drxNode = drxNode->next;
912 if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
917 ueCb->drxUeCb.drxUlUeActiveStatus &= ~UE_ACTIVE_FOR_INACTIVE_TIMER;
919 /* Remove the entry from the in-active exp timer list */
920 cmLListDelFrm(&cell->drxCb[ulIndx].inActvTmrExpiryList, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
921 SCH_FREE(ueCb->drxUeCb.inActvTimerExpiryNodeInfo, sizeof(CmLList));
922 ueCb->drxUeCb.inActvExpiryIndex = SCH_DRX_INVALID_INDEX;
924 if(ueCb->drxUeCb.shortCyclePresent)
926 /* Start short cycle timer */
927 /* TODO Will implement this in next gerrit */
934 * @brief Handling of the expiry of in-active DRX timers
938 * Function :schHdlDrxInActvExpiryTimer
940 * Handling of expiry of in-active DRX timers
942 * @param[in] SchCellCb *cell
947 void schHdlDrxInActvExpiryTimer(SchCellCb *cell)
949 uint16_t dlIndx = 0, ulIndx = 0;
950 SlotTimingInfo dlSlotInfo, ulSlotInfo;
952 ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
953 ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA, cell->numSlots);
954 dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
955 ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
957 schHdlDrxInActvExpiryTimerForDlDirection(cell, dlIndx);
958 schHdlDrxInActvExpiryTimerForUlDirection(cell, ulIndx);
962 * @brief Handling of the expiry DRX timers
966 * Function : schHandleExpiryDrxTimer
968 * Handling of expiry DRX timers
970 * @param[in] SchCellCb *cell
975 void schHandleExpiryDrxTimer(SchCellCb *cell)
977 /* Handling the onduration start timer */
978 schHdlDrxOnDurExpiryTimer(cell);
979 schHdlDrxInActvExpiryTimer(cell);
983 /**********************************************************************
985 **********************************************************************/