[Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Implementation of short cycle timer
[o-du/l2.git] / src / 5gnrsch / sch_drx.c
1
2 /*******************************************************************************
3 ################################################################################
4 #   Copyright (c) [2017-2019] [Radisys]                                        #
5 #                                                                              #
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                                    #
9 #                                                                              #
10 #       http://www.apache.org/licenses/LICENSE-2.0                             #
11 #                                                                              #
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  *******************************************************************************/
19 #ifdef NR_DRX
20 #include "common_def.h"
21 #include "tfu.h"
22 #include "lrg.h"
23 #include "tfu.x"
24 #include "lrg.x"
25 #include "du_log.h"
26 #include "du_app_mac_inf.h"
27 #include "mac_sch_interface.h"
28 #include "sch.h"
29 #include "sch_utils.h"
30 #include "sch_drx.h"
31
32 /**
33  * @brief intialize the SchDrxHarqCb structre 
34  *
35  * @details
36  *
37  *     Function :schInitDrxHarqCb 
38  *      
39  *     intialize the SchDrxHarqCb structre 
40  *           
41  *  @param[in] SchDrxHarqCb *hqCb 
42  *  @return  
43  *      -# ROK
44  *      -# RFAILED
45  **/
46
47 void schInitDrxHarqCb(SchDrxHarqCb *hqDrxCb)
48 {
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;
54 }
55
56 /**
57  * @brief intialize the SchDrxUeCb structre 
58  *
59  * @details
60  *
61  *     Function : schInitDrxUeCb 
62  *      
63  *     intialize the SchDrxUeCb structre 
64  *           
65  *  @param[in]  SchUeCb *ueCb 
66  *  @return  
67  *      -# ROK
68  *      -# RFAILED
69  **/
70
71 void schInitDrxUeCb(SchUeCb *ueCb)
72 {
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; 
83 }
84
85 /* will uncomment this function in next gerrit */
86 #if 0
87 /**
88  * @brief delete Dl harq drx timers and information 
89  *
90  * @details
91  *
92  *     Function : schDeleteDlHarqDrxTimer
93  *      
94  *     delete Dl harq drx timers and information 
95  *           
96  *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
97  *  @return  
98  *      -# ROK
99  *      -# RFAILED
100  **/
101  void schDeleteDlHarqDrxTimer(SchCellCb  *cell, SchDlHqEnt *dlHqEnt)
102  {
103     uint8_t idx, numHqPrcs;
104     uint16_t tmrIdx = 0;
105     SchDlHqProcCb *procs;
106     CmLList  *node = NULLP;
107    
108     numHqPrcs = dlHqEnt->numHqPrcs;
109     for(idx =0; idx<numHqPrcs; idx++)
110     {
111        procs = &dlHqEnt->procs[idx];
112        tmrIdx = procs->dlDrxHarqCb.retxStrtIndex;
113        CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node);
114        if(node)
115        {
116           cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node);
117           SCH_FREE(node, sizeof(CmLList));
118        }
119
120        tmrIdx = procs->dlDrxHarqCb.rttIndex;
121        CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node);
122        if(node)
123        {
124           cmLListDelFrm(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node);
125           SCH_FREE(node, sizeof(CmLList));
126        }
127
128        tmrIdx = procs->dlDrxHarqCb.retxIndex;
129        CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransExpiryList, node);
130        if(node)
131        {
132           cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransExpiryList, node);
133           SCH_FREE(node, sizeof(CmLList));
134        }
135        schInitDrxHarqCb(&procs->dlDrxHarqCb);
136     }
137  }
138
139 /**
140  * @brief delete UL harq drx timers and information 
141  *
142  * @details
143  *
144  *     Function : schDeleteUlHarqDrxTimer
145  *      
146  *     delete Ul harq drx timers and information 
147  *           
148  *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
149  *  @return  
150  *      -# ROK
151  *      -# RFAILED
152  **/
153  void schDeleteUlHarqDrxTimer(SchCellCb  *cell, SchUlHqEnt *ulHqEnt)
154  {
155     uint8_t idx, numHqPrcs;
156     uint16_t tmrIdx = 0;
157     CmLList  *node = NULLP;
158     SchUlHqProcCb *procs;
159
160     numHqPrcs = ulHqEnt->numHqPrcs;
161     for(idx =0; idx<numHqPrcs; idx++)
162     {
163        procs = &ulHqEnt->procs[idx];
164        tmrIdx = procs->ulDrxHarqCb.retxStrtIndex;
165        CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node);
166        if(node)
167        {
168           cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node);
169           SCH_FREE(node, sizeof(CmLList));
170        }
171
172        tmrIdx = procs->ulDrxHarqCb.rttIndex;
173        CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node);
174        if(node)
175        {
176           cmLListDelFrm(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node);
177           SCH_FREE(node, sizeof(CmLList));
178        }
179
180        tmrIdx = procs->ulDrxHarqCb.retxIndex;
181        CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransExpiryList, node);
182        if(node)
183        {
184           cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransExpiryList, node);
185           SCH_FREE(node, sizeof(CmLList));
186        }
187        schInitDrxHarqCb(&procs->ulDrxHarqCb);
188     }
189  }
190 #endif
191
192 /**
193  * @brief delete UE drx timers and information 
194  *
195  * @details
196  *
197  *     Function : schDeleteUeDrxInfo
198  *      
199  *     delete UE drx timers and information 
200  *           
201  *  @param[in] SchCellCb  *cell, SchUeCb *ueCb 
202  *  @return  void
203  *
204  **/
205
206 void schDeleteUeDrxInfo(SchCellCb  *cell, SchUeCb *ueCb)
207 {
208    SchDrxUeCb *drxUeCb;
209
210    if(ueCb->ueDrxInfoPres == true)
211    {
212       drxUeCb = &ueCb->drxUeCb;
213       
214       /* delete on duration start timer from ueCb */
215       if(drxUeCb->onDurationStartIndex != SCH_DRX_INVALID_INDEX)
216       {
217          cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationStartIndex].onDurationStartList, drxUeCb->onDurationStartNodeInfo);
218          SCH_FREE(drxUeCb->onDurationStartNodeInfo, sizeof(CmLList));
219       }
220       
221       /* delete on duration expiry timer from ueCb */
222       if(drxUeCb->onDurationExpiryIndex != SCH_DRX_INVALID_INDEX)
223       {
224          cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationExpiryIndex].onDurationExpiryList, drxUeCb->onDurationExpiryNodeInfo);
225          SCH_FREE(drxUeCb->onDurationExpiryNodeInfo, sizeof(CmLList));
226       }
227       
228       /* delete inActv Expiry Index timer from ueCb */
229       if(drxUeCb->inActvExpiryIndex != SCH_DRX_INVALID_INDEX)
230       {
231          cmLListDelFrm(&cell->drxCb[drxUeCb->inActvExpiryIndex].inActvTmrExpiryList, drxUeCb->inActvTimerExpiryNodeInfo);
232          SCH_FREE(drxUeCb->inActvTimerExpiryNodeInfo, sizeof(CmLList));
233       }
234       
235       /* delete short cycle expiry timer from ueCb */
236       if(drxUeCb->shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX)
237       {
238          cmLListDelFrm(&cell->drxCb[drxUeCb->shortCycleExpiryIndex].shortCycleExpiryList, drxUeCb->shortCycleTmrExpiryNodeInfo);
239          SCH_FREE(drxUeCb->shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
240       }
241       /* TODO - will uncomment this function in next gerrit */
242       //schDeleteDlHarqDrxTimer(cell, &ueCb->dlHqEnt);
243       //schDeleteUlHarqDrxTimer(cell, &ueCb->ulHqEnt);
244       schInitDrxUeCb(ueCb);
245    }
246 }
247
248 /**
249  * @brief fill drxUeCb structure with the help of ue cfg/recfg information
250  *
251  * @details
252  *
253  *     Function : schFillDrxUeCb
254  *      
255  *      fill drxUeCb structure with the help of ue cfg/recfg information
256  *           
257  *  @param[in] SchDrxCfg drxCfg ->configuration received from ue cfg/recfg api
258  *             SchDrxUeCb *drxUeCb -> structure that need to be fill
259  *  @return  
260  *      -# ROK
261  *      -# RFAILED
262  **/
263
264 void schFillDrxUeCb(uint8_t numerology, SchDrxCfg drxCfg, SchDrxUeCb *drxUeCb)
265 {
266    if(drxCfg.drxOnDurationTimer.onDurationTimerValInMs) 
267    {
268       SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.milliSeconds, numerology); 
269    }
270    else
271    {
272       SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds, numerology);
273       drxUeCb->onDurationLen = drxUeCb->onDurationLen >> 5;
274    }   
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)
283    {
284       drxUeCb->shortCyclePresent = true;                   
285       SCH_CNVRT_MS_TO_SLOT(drxUeCb->shortCycleLen, drxCfg.shortDrx.drxShortCycle, numerology);   
286       drxUeCb->shortCycleTmrLen = drxUeCb->shortCycleLen*drxCfg.shortDrx.drxShortCycleTimer;    
287    }
288    drxUeCb->longCycleToBeUsed = true;
289    SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxSlotOffset, drxCfg.drxSlotOffset, numerology);  
290    drxUeCb->drxSlotOffset = drxUeCb->drxSlotOffset>>5; 
291 }
292
293 /**
294  * @brief Add new entry into the drx timer list
295  *
296  * @details
297  *
298  *     Function : schAddDrxTimerIntoList 
299  *      
300  *      Add new entry into the drx timer list
301  *           
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
304  *  @return  
305  *      -# ROK
306  *      -# RFAILED
307  **/
308
309 uint8_t schAddDrxTimerIntoList(CmLListCp *drxTimerList,void * nodeInfo, CmLList *drxNodeInfo)
310 {
311    CmLList  *currentNodeInfo = NULLP;
312
313    SCH_ALLOC(currentNodeInfo, sizeof(CmLList));
314    if(!currentNodeInfo)
315    {
316       DU_LOG("\nERROR  --> SCH : schAddDrxTimerIntoList() : Memory allocation failed");
317       return RFAILED;
318    }
319
320    currentNodeInfo->node = (PTR)nodeInfo;
321    
322    cmLListAdd2Tail(drxTimerList, currentNodeInfo);
323    drxNodeInfo = currentNodeInfo;
324    DU_LOG("\nINFO --> SCH : Drx node added into the list");
325    return ROK;
326 }
327
328 /**
329  * @brief This function is used to find the next onduration start timing
330  *
331  * @details
332  *
333  *     Function : findNextOndurationOccurance 
334  *      
335  *      This function is used to find the next onduration start timing
336  *           
337  *  @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur,
338  *  uint8_t delta
339  *             
340  *  @return  
341  *      -# void
342  **/
343
344 void findNextOndurationOccurance(SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur, uint8_t delta)
345 {
346    uint16_t   tmpDistance, numOfCycles;
347    uint32_t   curTime, cycleLen, nxtDist;
348    SlotTimingInfo  tmpTime;
349    
350    if (ueDrxCb->longCycleToBeUsed == true)
351    {
352       cycleLen = ueDrxCb->longCycleLen;
353    }
354    else
355    {
356       cycleLen = ueDrxCb->shortCycleLen;
357    }
358
359    /* Add delta to current time */
360    ADD_DELTA_TO_TIME(cell->slotInfo, tmpTime, delta, cell->numSlots);
361    
362    /* Convert tmpTime to number of slots */
363    curTime = ((tmpTime.sfn * cell->numSlots) + tmpTime.slot);
364    
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)
372    {
373       /* offset is the nextOnDur */
374       nxtDist = ((((ueDrxCb->drxStartOffset / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (ueDrxCb->drxStartOffset % cell->numSlots);
375    }
376    else
377    {
378       tmpDistance = curTime - ueDrxCb->drxStartOffset;
379       numOfCycles = tmpDistance / cycleLen;
380
381       if (0 == (tmpDistance % cycleLen))
382       {
383          /* Perfect match pick up the current time */
384          nxtDist = ((((curTime / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (curTime % cell->numSlots);
385       }
386       else
387       {
388          nxtDist  = ueDrxCb->drxStartOffset + (numOfCycles + 1) * cycleLen;
389       }
390    }
391
392    /* If slot offset is non-zero then Add slot offset to the calculated onDur
393     * distance */
394    if(ueDrxCb->drxSlotOffset)
395    {
396       nxtDist = nxtDist + ueDrxCb->drxSlotOffset;
397    }
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)
401    {
402       nxtDist = nxtDist + cycleLen;
403    }
404    
405    nxtOnDur->sfn = ((nxtDist / cell->numSlots) & (MAX_SFN - 1));
406    nxtOnDur->slot = (nxtDist % cell->numSlots);
407 }
408
409 /**
410  * @brief Add entry into  the on duration list and short cycle list
411  *
412  * @details
413  *
414  *     Function : schDrxUeReCfgTimer 
415  *      
416  *      This function is used to Add entry into  the on duration list and short
417  *      cycle list
418  *           
419  *  @param[in] SchCellCb *cell,   SchUeCb *ueCb
420  *  uint8_t delta
421  *             
422  *  @return void 
423  **/
424
425 void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb)
426 {
427    uint8_t  currentSlotIndx;
428    uint32_t onDurTime, onDurExpSlotTime, currentSlotTime;
429    uint32_t cycleLen;
430    SlotTimingInfo onDurationOccurance;
431    
432    if(ueCb->drxUeCb.shortCyclePresent == false)   
433    {
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)
437       {
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;
442       }
443    }
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)
447    {
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; 
452       
453    }
454
455    findNextOndurationOccurance(cell,  &ueCb->drxUeCb, &onDurationOccurance, 0);
456    onDurTime = onDurationOccurance.sfn*cell->numSlots+onDurationOccurance.slot;
457    
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))
461    {
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 )
465        {
466          onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance +1) * MAX_DRX_SIZE) +\
467          (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA);
468        }
469        else
470        {
471          
472          onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance) * MAX_DRX_SIZE) +\
473          (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA);
474        }
475        if(onDurTime <= onDurExpSlotTime)
476        {
477           if(ueCb->drxUeCb.longCycleToBeUsed == true)
478              cycleLen = ueCb->drxUeCb.longCycleLen;
479           else
480              cycleLen = ueCb->drxUeCb.shortCycleLen;
481
482           onDurTime = onDurTime + ((onDurExpSlotTime - onDurTime)/cycleLen + 1) * cycleLen;
483        }
484    }
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);
488 }
489
490 /**
491  * @brief Add entry into  the on duration list 
492  *
493  * @details
494  *
495  *     Function : schAddUeInOndurationList
496  *      
497  *      This function is used to Add entry into  the on duration list 
498  *           
499  *  @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo  *nxtOnDur,
500  *  uint8_t delta
501  *             
502  *  @return  
503  *      -# void
504  **/
505
506 void schAddUeInOndurationList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta)
507 {
508    uint32_t onDurTime;
509    SlotTimingInfo onDurationOccurance;
510
511    if(ueCb->ueDrxInfoPres)
512    {
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);
518
519    }
520 }
521
522 /**
523  * @brief Handling of On duration drx start timer
524  *
525  * @details
526  *
527  *     Function : schHdlDrxOnDurStrtTimerForDlDirection
528  *
529  *      Handling of On duration drx start timer
530  *
531  *  @param[in] SchCellCb  *cell
532  *  @return
533  *      -# ROK
534  *      -# RFAILED
535  **/
536
537 void schHdlDrxOnDurStrtTimerForDlDirection(SchCellCb  *cell, uint16_t currListIndx)
538 {
539    uint16_t onDurationExpiry=0;
540    CmLList  *drxCurrNode = NULLP;
541    SchUeCb *ueCb = NULLP;
542
543    drxCurrNode = cell->drxCb[currListIndx].onDurationStartList.first;
544    if(drxCurrNode)
545    {
546       /* Handling of dl On duration drx start list */
547       while(drxCurrNode)
548       {
549          ueCb = (SchUeCb*)drxCurrNode->node;
550          drxCurrNode = drxCurrNode->next;
551          
552          ueCb->drxUeCb.onDurationStartDistance--;
553          
554          if(ueCb->drxUeCb.onDurationStartDistance != SCH_DRX_INVALID_DISTANCE)
555          {
556             continue;
557          }
558          else
559          {
560             ueCb->drxUeCb.drxDlUeActiveStatus |= UE_ACTIVE_FOR_ONDURATION;
561             
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)
566             {
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; 
571             }
572
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;
578
579          }
580       }
581    }
582 }
583
584 /**
585  * @brief Handling of On duration drx start timer
586  *
587  * @details
588  *
589  *     Function : schHdlDrxOnDurStrtTimerForUlDirection
590  *
591  *      Handling of On duration drx start timer
592  *
593  *  @param[in] SchCellCb  *cell
594  *  @return
595  *      -# ROK
596  *      -# RFAILED
597  **/
598
599 void schHdlDrxOnDurStrtTimerForUlDirection(SchCellCb  *cell, uint16_t currListIndx)
600 {
601    uint16_t onDurTime=0;
602    CmLList  *drxCurrNode = NULLP;
603    SchUeCb *ueCb = NULLP;
604
605    drxCurrNode = cell->drxCb[currListIndx].onDurationStartList.first;
606    if(drxCurrNode)
607    {
608       /* Handling of dl On duration drx start list */
609       while(drxCurrNode)
610       {
611          ueCb = (SchUeCb*)drxCurrNode->node;
612          drxCurrNode = drxCurrNode->next;
613          
614          if(ueCb->drxUeCb.onDurationStartDistance != SCH_DRX_INVALID_DISTANCE)
615          {
616             continue;
617          }
618          ueCb->drxUeCb.drxUlUeActiveStatus |= UE_ACTIVE_FOR_ONDURATION;
619
620
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; 
625
626          if(ueCb->drxUeCb.longCycleToBeUsed)
627          {
628             onDurTime = currListIndx +  ueCb->drxUeCb.longCycleLen;
629          }
630          else
631          {
632             onDurTime = currListIndx +  ueCb->drxUeCb.shortCycleLen;
633          }
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);
637       }
638    }
639 }
640
641 /**
642  * @brief Handling of On duration drx start timer
643  *
644  * @details
645  *
646  *     Function : schHdlDrxOnDurStrtTimer
647  *
648  *      Handling of On duration drx start timer
649  *
650  *  @param[in] SchCellCb  *cell
651  *  @return
652  *      -# ROK
653  *      -# RFAILED
654  **/
655 void schHdlDrxOnDurStrtTimer(SchCellCb  *cell)
656 {
657    uint16_t dlIndx = 0, ulIndx=0;
658    SlotTimingInfo dlSlotInfo, ulSlotInfo;
659
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);
662
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);
667 }
668
669 /**
670  * @brief Handling of the DRX in-active start timer
671  *
672  * @details
673  *
674  *     Function : 
675  *
676  *      Handling of DRX in-active start timer
677  *
678  *  @param[in] SchCellCb  *cell
679  *  @return
680  *      -# ROK
681  *      -# RFAILED
682  **/
683
684 void schHdlDrxInActvStrtTmr(SchCellCb  *cell,  SchUeCb *ueCb, uint8_t delta)
685 {
686    uint16_t slotIndx = 0;
687    SlotTimingInfo tmpSlotInfo;
688    
689    if(ueCb->drxUeCb.inActvTimerLen == 0)
690    {
691       return;
692    }
693
694    ADD_DELTA_TO_TIME(cell->slotInfo, tmpSlotInfo,  delta, cell->numSlots);
695    slotIndx = (tmpSlotInfo.sfn*MAX_SLOTS+tmpSlotInfo.slot)%MAX_DRX_SIZE;
696
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)
699    {
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;
704    }
705
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);
710
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;
714 }
715
716 /**
717  * @brief Handling of short cycle drx start timer
718  *
719  * @details
720  *
721  *     Function : schHdlDrxStartShortCycleTimer
722  *
723  *      Handling of short cycle drx start timer
724  *
725  *  @param[in] SchCellCb  *cell
726  *  @return
727  *      -# ROK
728  *      -# RFAILED
729  **/
730
731  void schHdlDrxStartShortCycleTimer(SchCellCb  *cell, SchUeCb *ueCb)
732  {
733     ueCb->drxUeCb.longCycleToBeUsed = false;
734
735     /* if there is any present in on-duration start list, remove the entry from on duration start list */
736     if(ueCb->drxUeCb.onDurationStartIndex != SCH_DRX_INVALID_INDEX)
737     {
738        cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
739        SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
740        ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX; 
741        ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE; 
742     } 
743     
744     /* recalculate the new index of on duration start based on short cycle */
745     schAddUeInOndurationList(cell, ueCb, PHY_DELTA_DL + SCHED_DELTA);
746     
747     /* if any node is present in short cycle exp list then remove the node from list  */
748     if(ueCb->drxUeCb.shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX && ueCb->drxUeCb.shortCycleDistance != SCH_DRX_INVALID_DISTANCE)
749     {
750        cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.shortCycleExpiryIndex].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
751        SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
752        ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
753        ueCb->drxUeCb.shortCycleDistance = SCH_DRX_INVALID_DISTANCE;
754     }
755  
756     /* recalculate the new index for shortCycleExpiryList */
757     ueCb->drxUeCb.shortCycleExpiryIndex = (ueCb->drxUeCb.onDurationStartIndex + ueCb->drxUeCb.shortCycleTmrLen) % MAX_DRX_SIZE;
758     ueCb->drxUeCb.shortCycleDistance = ueCb->drxUeCb.shortCycleTmrLen / MAX_DRX_SIZE;
759     schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.shortCycleExpiryIndex].shortCycleExpiryList, ueCb, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
760  }
761
762 /**
763  * @brief Handling of the  DRX timers start
764  *
765  * @details
766  *
767  *     Function : schHandleStartDrxTimer
768  *
769  *      Handling of DRX timers start
770  *
771  *  @param[in] SchCellCb  *cell
772  *  @return
773  *      -# ROK
774  *      -# RFAILED
775  **/
776 void schHandleStartDrxTimer(SchCellCb  *cell)
777 {
778    /* Handling the onduration start timer */
779    schHdlDrxOnDurStrtTimer(cell);
780 }
781
782 /**
783  * @brief Handling of the expiry onduration timer in dl direction
784  *
785  * @details
786  *
787  *     Function : schHdlDrxOnDurExpiryTimerForDlDirection
788  *
789  *      Handling of expiry onduration DRX timers in dl direction
790  *
791  *  @param[in] SchCellCb  *cell
792  *  @return
793  *      -# ROK
794  *      -# RFAILED
795  **/
796 void schHdlDrxOnDurExpiryTimerForDlDirection(SchCellCb  *cell, uint16_t currListIndx)
797 {
798    CmLList  *drxCurrNode;
799    SchUeCb *ueCb = NULLP;
800
801    drxCurrNode = cell->drxCb[currListIndx].onDurationExpiryList.first;
802    if(drxCurrNode)
803    {
804       /* Handling of dl On duration drx start list */
805       while(drxCurrNode)
806       {
807          ueCb = (SchUeCb*)drxCurrNode->node;
808          drxCurrNode = drxCurrNode->next;
809          
810          ueCb->drxUeCb.onDurationExpiryDistance--;
811
812          if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
813          {
814             continue;
815          }
816          ueCb->drxUeCb.drxDlUeActiveStatus &= ~UE_ACTIVE_FOR_ONDURATION;
817       }
818    }
819 }
820
821 /**
822  * @brief Handling of the expiry onduration DRX timers for Ul direction
823  *
824  * @details
825  *
826  *     Function  schHdlDrxOnDurExpiryTimerForUlDirection:
827  *
828  *      Handling of expiry onduration DRX timers in Ul direction
829  *
830  *  @param[in] SchCellCb  *cell
831  *  @return
832  *      -# ROK
833  *      -# RFAILED
834  **/
835 void schHdlDrxOnDurExpiryTimerForUlDirection(SchCellCb  *cell, uint16_t currListIndx)
836 {
837    CmLList  *drxCurrNode;
838    SchUeCb *ueCb = NULLP;
839
840    drxCurrNode = cell->drxCb[currListIndx].onDurationExpiryList.first;
841    if(drxCurrNode)
842    {
843       /* Handling of dl On duration drx start list */
844       while(drxCurrNode)
845       {
846          ueCb = (SchUeCb*)drxCurrNode->node;
847          drxCurrNode = drxCurrNode->next;
848
849          if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
850          {
851             continue;
852          }
853
854          ueCb->drxUeCb.drxUlUeActiveStatus &= ~UE_ACTIVE_FOR_ONDURATION;
855          cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationExpiryIndex].onDurationExpiryList, ueCb->drxUeCb.onDurationExpiryNodeInfo);
856          SCH_FREE(ueCb->drxUeCb.onDurationExpiryNodeInfo, sizeof(CmLList));
857          ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX; 
858       }
859    }
860 }
861 /**
862  * @brief Handling of the expiry onduration DRX timers
863  *
864  * @details
865  *
866  *     Function : schHdlDrxOnDurExpiryTimer
867  *
868  *      Handling of expiry onduration DRX timers
869  *
870  *  @param[in] SchCellCb  *cell
871  *  @return
872  *      -# ROK
873  *      -# RFAILED
874  **/
875 void schHdlDrxOnDurExpiryTimer(SchCellCb  *cell)
876 {
877    uint16_t dlIndx = 0, ulIndx = 0;
878    SlotTimingInfo dlSlotInfo, ulSlotInfo;
879
880    ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
881    ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA, cell->numSlots);
882    dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
883    ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
884
885    schHdlDrxOnDurExpiryTimerForDlDirection(cell, dlIndx);
886    schHdlDrxOnDurExpiryTimerForUlDirection(cell, ulIndx);
887 }
888
889 /**
890  * @brief Handling of the expiry of in-active DRX timers in Dl
891  *
892  * @details
893  *
894  *     Function : schHdlDrxInActvExpiryTimerForDlDirection
895  *
896  *      Handling of expiry of in-active DRX timers at Dl index
897  *
898  *  @param[in] SchCellCb  *cell,  uint16_t dlIndx
899  *  @return
900  *      -# ROK
901  *      -# RFAILED
902  **/
903
904 void schHdlDrxInActvExpiryTimerForDlDirection(SchCellCb  *cell, uint16_t dlIndx)
905 {
906    CmLList  *drxNode;
907    SchUeCb *ueCb = NULLP;
908
909    drxNode = cell->drxCb[dlIndx].inActvTmrExpiryList.first;
910    if(drxNode)
911    {
912       /* Handling of dl On duration drx start list */
913       while(drxNode)
914       {
915          ueCb = (SchUeCb*)drxNode->node;
916          drxNode = drxNode->next;
917          ueCb->drxUeCb.inActiveTmrExpiryDistance--;
918
919          if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
920          {  
921             continue;
922          }
923          
924          ueCb->drxUeCb.drxDlUeActiveStatus &= ~UE_ACTIVE_FOR_INACTIVE_TIMER;
925       }
926    }
927 }
928
929 /**
930  * @brief Handling of the expiry of in-active DRX timers in Ul
931  *
932  * @details
933  *
934  *     Function : schHdlDrxInActvExpiryTimerForUlDirection
935  *
936  *      Handling of expiry of in-active DRX timers at Ul index
937  *
938  *  @param[in] SchCellCb  *cell,  uint16_t ulIndx
939  *  @return
940  *      -# ROK
941  *      -# RFAILED
942  **/
943
944 void schHdlDrxInActvExpiryTimerForUlDirection(SchCellCb  *cell, uint16_t ulIndx)
945 {
946    CmLList  *drxNode;
947    SchUeCb *ueCb = NULLP;
948
949    drxNode = cell->drxCb[ulIndx].inActvTmrExpiryList.first;
950    if(drxNode)
951    {
952       /* Handling of dl On duration drx start list */
953       while(drxNode)
954       {
955          ueCb = (SchUeCb*)drxNode->node;
956          drxNode = drxNode->next;
957
958          if(ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE)
959          {  
960             continue;
961          }
962          
963          ueCb->drxUeCb.drxUlUeActiveStatus &= ~UE_ACTIVE_FOR_INACTIVE_TIMER;
964          
965          /* Remove the entry from the in-active exp timer list */
966          cmLListDelFrm(&cell->drxCb[ulIndx].inActvTmrExpiryList, ueCb->drxUeCb.inActvTimerExpiryNodeInfo);
967          SCH_FREE(ueCb->drxUeCb.inActvTimerExpiryNodeInfo, sizeof(CmLList));
968          ueCb->drxUeCb.inActvExpiryIndex = SCH_DRX_INVALID_INDEX;
969
970          if(ueCb->drxUeCb.shortCyclePresent)
971          {  
972             /* Start short cycle timer */
973             schHdlDrxStartShortCycleTimer(cell, ueCb);
974          }
975       }
976    }
977 }
978
979 /**
980  * @brief Handling of the expiry of in-active DRX timers
981  *
982  * @details
983  *
984  *     Function :schHdlDrxInActvExpiryTimer
985  *
986  *      Handling of expiry  of in-active DRX timers
987  *
988  *  @param[in] SchCellCb  *cell
989  *  @return
990  *      -# ROK
991  *      -# RFAILED
992  **/
993 void schHdlDrxInActvExpiryTimer(SchCellCb  *cell)
994 {
995    uint16_t dlIndx = 0, ulIndx = 0;
996    SlotTimingInfo dlSlotInfo, ulSlotInfo;
997
998    ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
999    ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA, cell->numSlots);
1000    dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
1001    ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
1002
1003    schHdlDrxInActvExpiryTimerForDlDirection(cell, dlIndx);
1004    schHdlDrxInActvExpiryTimerForUlDirection(cell, ulIndx);
1005 }
1006
1007 /**
1008  * @brief Handling of the expiry ShortCycle DRX timers in DL
1009  *
1010  * @details
1011  *
1012  *     Function : schHdlDrxShortCycleExpiryTimerForDlDirection
1013  *
1014  *      Handling of expiry ShortCycle
1015  *
1016  *  @param[in] SchCellCb  *cell
1017  *  @return
1018  *      -# ROK
1019  *      -# RFAILED
1020  **/
1021
1022 void schHdlDrxShortCycleExpiryTimerForDlDirection(SchCellCb  *cell, uint16_t dlIndx)
1023 {
1024    CmLList  *drxCurrNode = NULLP;
1025    SchUeCb *ueCb = NULLP;
1026
1027    drxCurrNode = cell->drxCb[dlIndx].shortCycleExpiryList.first;
1028    if(drxCurrNode)
1029    {
1030       /* Handling of short cycle expiry in Dl */
1031       while(drxCurrNode)
1032       {
1033          ueCb = (SchUeCb*)drxCurrNode->node;
1034          drxCurrNode = drxCurrNode->next;
1035
1036          ueCb->drxUeCb.shortCycleDistance--;
1037
1038          if(ueCb->drxUeCb.shortCycleDistance != SCH_DRX_INVALID_DISTANCE)
1039          {
1040             continue;
1041          }
1042
1043          /* once short cycle timer gets expire we will recalculate on-duration start with long cycle */ 
1044          ueCb->drxUeCb.longCycleToBeUsed = true;
1045
1046          /* delete the entry from on-duration start */
1047          cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo);
1048          SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList));
1049          ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX; 
1050          ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE; 
1051
1052          /* Recalculate on-duration with  long cycle */
1053          schAddUeInOndurationList(cell, ueCb, PHY_DELTA_DL + SCHED_DELTA);
1054       }
1055    }
1056 }
1057
1058 /**
1059  * @brief Handling of the expiry ShortCycle DRX timers in UL
1060  *
1061  * @details
1062  *
1063  *     Function : schHdlDrxShortCycleExpiryTimerForUlDirection
1064  *
1065  *      Handling of expiry ShortCycle
1066  *
1067  *  @param[in] SchCellCb  *cell
1068  *  @return
1069  *      -# ROK
1070  *      -# RFAILED
1071  **/
1072
1073 void schHdlDrxShortCycleExpiryTimerForUlDirection(SchCellCb  *cell, uint16_t ulIndx)
1074 {
1075    CmLList  *drxCurrNode = NULLP;
1076    SchUeCb *ueCb = NULLP;
1077
1078    drxCurrNode = cell->drxCb[ulIndx].shortCycleExpiryList.first;
1079    if(drxCurrNode)
1080    {
1081       /* Handling of short cycle expiry in Ul */
1082       while(drxCurrNode)
1083       {
1084          ueCb = (SchUeCb*)drxCurrNode->node;
1085          drxCurrNode = drxCurrNode->next;
1086          
1087          if(ueCb->drxUeCb.shortCycleDistance != SCH_DRX_INVALID_DISTANCE)
1088          {
1089             continue;
1090          }
1091          
1092          cmLListDelFrm(&cell->drxCb[ulIndx].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo);
1093          SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList));
1094          ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX;
1095
1096       }
1097    }
1098 }
1099
1100 /**
1101  * @brief Handling of the expiry ShortCycle DRX timers
1102  *
1103  * @details
1104  *
1105  *     Function :schHdlDrxShortCycleExpiryTimer
1106  *
1107  *      Handling of expiry ShortCycle
1108  *
1109  *  @param[in] SchCellCb  *cell
1110  *  @return
1111  *      -# ROK
1112  *      -# RFAILED
1113  **/
1114 void schHdlDrxShortCycleExpiryTimer(SchCellCb  *cell)
1115 {
1116    uint16_t dlIndx = 0, ulIndx= 0;
1117    SlotTimingInfo dlSlotInfo, ulSlotInfo;
1118
1119    ADD_DELTA_TO_TIME(cell->slotInfo, dlSlotInfo, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
1120    ADD_DELTA_TO_TIME(cell->slotInfo, ulSlotInfo, PHY_DELTA_UL + SCHED_DELTA, cell->numSlots);
1121    dlIndx = (dlSlotInfo.sfn*MAX_SLOTS+dlSlotInfo.slot)%MAX_DRX_SIZE;
1122    ulIndx = (ulSlotInfo.sfn*MAX_SLOTS+ulSlotInfo.slot)%MAX_DRX_SIZE;
1123
1124    schHdlDrxShortCycleExpiryTimerForDlDirection(cell, dlIndx);
1125    schHdlDrxShortCycleExpiryTimerForUlDirection(cell, ulIndx);
1126 }
1127
1128 /**
1129  * @brief Handling of the expiry  DRX timers
1130  *
1131  * @details
1132  *
1133  *     Function : schHandleExpiryDrxTimer
1134  *
1135  *      Handling of expiry  DRX timers
1136  *
1137  *  @param[in] SchCellCb  *cell
1138  *  @return
1139  *      -# ROK
1140  *      -# RFAILED
1141  **/
1142 void schHandleExpiryDrxTimer(SchCellCb  *cell)
1143 {
1144    schHdlDrxShortCycleExpiryTimer(cell);
1145    schHdlDrxOnDurExpiryTimer(cell);
1146    schHdlDrxInActvExpiryTimer(cell);
1147 }
1148
1149 #endif
1150 /**********************************************************************
1151   End of file
1152  **********************************************************************/