<JIRA ID: ODUHIGH-389: DL Thproughput Per SNSSAI>
[o-du/l2.git] / src / 5gnrrlc / rlc_tmr.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /********************************************************************20**
20   
21         Name:    RLC - TMR module file
22     
23         Type:    C source file
24   
25         Desc:    Source code for timer functions such as, 
26
27                  - rlcStartTmr
28                  - rlcStopTmr
29                  - rlcTmrExpiry
30                  - rlcBndTmrExpiry  
31                   
32         File:    rlc_tmr.c
33   
34 *********************************************************************21*/
35
36 /* header (.h) include files */
37 #include "common_def.h"
38 #include "lkw.h"           /* LKW defines */
39 #include "ckw.h"           /* CKW defines */
40 #include "kwu.h"           /* KWU defines */
41 #include "rgu.h"           /* RGU defines */
42 #include "rlc_env.h"        /* RLC environment options */
43 #include "rlc_err.h"        /* Error defines */
44
45 /* extern (.x) include files */
46 #include "lkw.x"           /* LKW */
47 #include "ckw.x"           /* CKW */
48 #include "kwu.x"           /* KWU */
49 #include "rgu.x"           /* RGU */
50
51 #include "du_app_rlc_inf.h"
52 #include "rlc_utils.h"            /* RLC defines */
53 #include "rlc_dl_ul_inf.h"
54 #include "rlc_dl.h"
55 #include "rlc_ul.h"
56 #include "rlc_mgr.h"
57
58 /** 
59  * @file gp_tmr.c
60  * @brief RLC Timer Module
61 */
62
63 /**
64  * @def RLC_TMR_CALCUATE_WAIT
65  *
66  *    This macro calculates and assigns wait time based on the value of the 
67  *    timer and the timer resolution. Timer value of 0 signifies that the
68  *    timer is not configured
69  *
70  * @param[out] _wait   Time for which to arm the timer changed to proper 
71  *                     value according to the resolution
72  * @param[in] _tmrVal   Value of the timer
73  * @param[in] _timerRes   Resolution of the timer
74  *
75 */
76 #define RLC_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes)       \
77 {                                                             \
78    (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \
79    if((0 != (_tmrVal)) && (0 == (_wait)))                     \
80    {                                                          \
81       (_wait) = 1;                                            \
82    }                                                          \
83 }
84
85 /* private function declarations */
86 static Void rlcBndTmrExpiry(PTR cb);
87
88 /**
89  * @brief Handler to start timer
90  *       
91  * @param[in] gCb       Pointer to the RLC instance control block
92  * @param[in] cb        Control block depending on the type of the timer event. 
93  *                      It can be uplink/downlink rbCb or rgu sap control block
94  * @param[in] tmrEvnt   Timer event to be started
95  *
96  * @return  Void
97 */
98 void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
99 {
100 /* kw005.201 added support for L2 Measurement */
101 #ifdef LTE_L2_MEAS
102    RlcL2MeasEvtCb *measEvtCb = NULLP;
103 #endif
104
105    CmTmrArg arg;
106    arg.wait = 0;
107
108    /* kw002.201 Adjusting the wait time as per timeRes configured by layer manager */
109    switch (tmrEvnt)
110    {
111       case EVENT_RLC_UMUL_REASSEMBLE_TMR:
112       {
113          RlcUmUl* umUl = &(((RlcUlRbCb *)cb)->m.umUl);
114          /* kw005.201 Changed wait calculation ccpu00117634*/ 
115          RLC_TMR_CALCUATE_WAIT(arg.wait, umUl->reAsmblTmrInt, gCb->genCfg.timeRes);
116
117          arg.timers = &umUl->reAsmblTmr;
118          arg.max = RLC_MAX_UM_TMR;
119          break;
120       }
121       case EVENT_RLC_AMUL_REASSEMBLE_TMR:
122       {
123          RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl);
124          /* kw005.201 Changed wait calculation ccpu00117634*/ 
125          RLC_TMR_CALCUATE_WAIT(arg.wait, amUl->reAsmblTmrInt, gCb->genCfg.timeRes);         
126
127          arg.timers = &amUl->reAsmblTmr;
128          arg.max = RLC_MAX_AM_TMR;
129          break;
130       }
131       case EVENT_RLC_AMUL_STA_PROH_TMR:
132       {
133          RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl);
134          /* kw005.201 Changed wait calculation ccpu00117634*/ 
135          RLC_TMR_CALCUATE_WAIT(arg.wait,
136                               amUl->staProhTmrInt,
137                               gCb->genCfg.timeRes);                  
138
139          arg.timers = &amUl->staProhTmr;
140          arg.max = RLC_MAX_AM_TMR;
141          break;
142       } 
143       case EVENT_RLC_AMDL_POLL_RETX_TMR:
144       {
145          RlcAmDl* amDl = &(((RlcDlRbCb *)cb)->m.amDl);
146          /* kw005.201 Changed wait calculation ccpu00117634*/ 
147          RLC_TMR_CALCUATE_WAIT(arg.wait, 
148                               amDl->pollRetxTmrInt, 
149                               gCb->genCfg.timeRes);                  
150
151          arg.timers = &amDl->pollRetxTmr;
152          arg.max = RLC_MAX_AM_TMR;
153          break;
154       } 
155       case EVENT_RLC_WAIT_BNDCFM:
156       {
157          RlcRguSapCb* rguSap = (RlcRguSapCb *)cb;
158          /* kw005.201 Changed wait calculation ccpu00117634*/ 
159          RLC_TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes);                  
160
161          arg.timers = &rguSap->bndTmr;
162          arg.max = RLC_MAX_RGUSAP_TMR;
163          break;
164       }
165 /* kw005.201 added support for L2 Measurement */
166 #ifdef LTE_L2_MEAS
167       case EVENT_RLC_L2_TMR:
168       {
169          measEvtCb = (RlcL2MeasEvtCb *)cb;
170          /* kw005.201 Changed wait calculation ccpu00117634*/ 
171          RLC_TMR_CALCUATE_WAIT(arg.wait, 
172                               measEvtCb->l2TmrCfg.val, 
173                               gCb->genCfg.timeRes);                  
174
175          arg.timers = &measEvtCb->l2Tmr;
176          arg.max = RLC_L2_MAX_TIMERS;
177          break;
178       }
179 #endif
180       case EVENT_RLC_UE_THROUGHPUT_TMR:
181       {
182          RlcThpt *thptCb = (RlcThpt *)cb;
183          RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes);
184          arg.timers = &thptCb->ueTputInfo.ueThptTmr;
185          arg.max = RLC_MAX_THPT_TMR; 
186          break;
187       }
188       case EVENT_RLC_UE_DELETE_TMR:
189       {
190          RlcUlUeCb *ulUeCb = (RlcUlUeCb*)cb;
191          RLC_TMR_CALCUATE_WAIT(arg.wait, RLC_UE_DELETE_WAIT_TIME, gCb->genCfg.timeRes);
192          arg.timers = &ulUeCb->ueDeleteInfo.ueDelTmr;
193          arg.max = RLC_MAX_UE_TMR;
194          break;
195       }
196       case EVENT_RLC_SNSSAI_THROUGHPUT_TMR:
197       {
198          RlcThpt *thptCb = (RlcThpt *)cb;
199          RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes);
200          arg.timers = &thptCb->snssaiTputInfo.snssaiThptTmr;
201          arg.max = RLC_MAX_THPT_TMR; 
202          break;
203       }
204       default:
205       {
206          DU_LOG("\nERROR  -->  RLC : rlcStartTmr: Invalid tmr Evnt [%d]", tmrEvnt);
207       }
208    } 
209
210    if(arg.wait != 0)
211    {
212       arg.tqCp   = &gCb->rlcTqCp;
213       arg.tq     = gCb->rlcTq;
214       arg.cb     = cb;
215       arg.evnt   = tmrEvnt;
216       arg.tNum   = 0;
217
218       cmPlcCbTq(&arg);
219    }
220
221    return;
222 }
223
224 /**
225  * @brief Handler to stop a timer
226  *       
227  * @param[in] gCb       Pointer to the RLC instance control block
228  * @param[in] cb        Control block depending on the type of the timer event. 
229  *                      It can be uplink/downlink rbCb or rgu sap control block
230  * @param[in] tmrType   Timer event to be started
231  *
232  * @return  Void
233 */
234 void rlcStopTmr(RlcCb *gCb, PTR cb, uint8_t tmrType)
235 {
236    CmTmrArg   arg;
237 /* kw005.201 added support for L2 Measurement */
238 #ifdef LTE_L2_MEAS
239    RlcL2MeasEvtCb *measEvtCb = NULLP;
240 #endif
241
242    arg.timers = NULLP;
243
244    switch (tmrType)
245    {
246       case EVENT_RLC_UMUL_REASSEMBLE_TMR:
247       {
248          arg.timers  = &((RlcUlRbCb *)cb)->m.umUl.reAsmblTmr;
249          arg.max = RLC_MAX_UM_TMR;
250          break;
251       }
252       case EVENT_RLC_AMUL_REASSEMBLE_TMR:
253       {
254          arg.timers = &((RlcUlRbCb *)cb)->m.amUl.reAsmblTmr;
255          arg.max = RLC_MAX_AM_TMR;
256          break;
257       }
258       case EVENT_RLC_AMUL_STA_PROH_TMR:
259       {
260          arg.timers = &((RlcUlRbCb *)cb)->m.amUl.staProhTmr;
261          arg.max = RLC_MAX_AM_TMR;
262          break;
263       } 
264       case EVENT_RLC_AMDL_POLL_RETX_TMR:
265       {
266          arg.timers = &((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr;
267          arg.max = RLC_MAX_AM_TMR;
268          break;
269       } 
270       case EVENT_RLC_WAIT_BNDCFM:
271       {
272          arg.timers = &((RlcRguSapCb *)cb)->bndTmr;
273          arg.max = RLC_MAX_RGUSAP_TMR;
274          break;
275       }
276 /* kw005.201 added support for L2 Measurement */
277 #ifdef LTE_L2_MEAS
278       case EVENT_RLC_L2_TMR:
279       {
280          measEvtCb = (RlcL2MeasEvtCb *)cb;
281          arg.timers   = &measEvtCb->l2Tmr;
282          arg.max  = RLC_L2_MAX_TIMERS;
283          break;
284       }
285 #endif
286       case EVENT_RLC_UE_THROUGHPUT_TMR:
287       {
288          arg.timers   = &((RlcThpt *)cb)->ueTputInfo.ueThptTmr;
289          arg.max  = RLC_MAX_THPT_TMR;
290          break;
291       }
292       case EVENT_RLC_UE_DELETE_TMR:
293       {
294          arg.timers   = &((RlcUlUeCb*)cb)->ueDeleteInfo.ueDelTmr;
295          arg.max  = EVENT_RLC_UE_DELETE_TMR;
296          break;
297       }
298       case EVENT_RLC_SNSSAI_THROUGHPUT_TMR:
299       {
300          arg.timers   = &((RlcThpt *)cb)->snssaiTputInfo.snssaiThptTmr;
301          arg.max  = RLC_MAX_THPT_TMR;
302          break;
303       }
304       default:
305       {
306          DU_LOG("\nERROR  -->  RLC : rlcStopTmr: Invalid tmr Evnt[%d]", tmrType);
307          break;
308       }
309    } 
310    if (tmrType != TMR0)
311    {
312       arg.tqCp   = &gCb->rlcTqCp;
313       arg.tq     = gCb->rlcTq;
314       arg.cb     = cb;
315       arg.evnt   = tmrType;
316       arg.wait   = 0;
317       arg.tNum   = 0;
318       cmRmvCbTq(&arg);
319    }
320    
321    return;
322 }
323
324 /**
325  * @brief Handler to invoke events on expiry of timer.
326  *
327  * @details
328  *    This function is used to handle expiry of timer,it invokes relevant 
329  *    functions.
330  *       
331  * @param[in] cb        Control block depending on the type of the timer event. 
332  *                      It can be uplink/downlink rbCb or rgu sap control block
333  * @param[in] tmrEvnt   Timer event to be started
334  *
335  * @return  Void
336 */
337 Void rlcTmrExpiry(PTR cb,S16 tmrEvnt)
338 {
339 /* kw005.201 added support for L2 Measurement */
340
341    switch (tmrEvnt)
342    {
343       case EVENT_RLC_UMUL_REASSEMBLE_TMR:
344       {
345          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
346          rlcUmmReAsmblTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
347
348          break;
349       }
350       case EVENT_RLC_AMUL_REASSEMBLE_TMR:
351       {
352          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
353          rlcAmmReAsmblTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
354          break;
355       }
356       case EVENT_RLC_AMUL_STA_PROH_TMR:
357       {
358          RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
359          rlcAmmStaProTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
360
361          break;
362       }
363       case EVENT_RLC_AMDL_POLL_RETX_TMR:
364       {
365          RlcDlRbCb *dlRbCb = (RlcDlRbCb *)cb;
366          RlcCb *gCb = RLC_GET_RLCCB(dlRbCb->inst);
367          
368          rlcAmmPollRetxTmrExp(gCb, dlRbCb);
369
370          gCb->genSts.protTimeOut++;
371          break;
372       }
373       case EVENT_RLC_WAIT_BNDCFM:
374       {
375          rlcBndTmrExpiry(cb);
376          break;
377       }
378       case EVENT_RLC_UE_THROUGHPUT_TMR:
379       {
380          rlcUeThptTmrExpiry(cb);
381          break;
382       }
383       case EVENT_RLC_UE_DELETE_TMR:
384       {
385          rlcUeDeleteTmrExpiry(cb);
386          break;
387       }
388       case EVENT_RLC_SNSSAI_THROUGHPUT_TMR:
389       {
390          rlcSnssaiThptTmrExpiry(cb);
391          break;
392       }
393       default:
394       {
395          break;
396       }
397    }
398
399    return;
400 }
401
402 /**
403  * @brief Handler to check if the timer is running
404  *       
405  * @param[in] gCb       Pointer to the RLC instance control block
406  * @param[in] cb        Control block depending on the type of the timer event. 
407  *                      It can be uplink/downlink rbCb or rgu sap control block
408  * @param[in] tmrEvnt   Timer event to be started
409  *
410  * @return  Bool indicating whether the timer is running or not
411  *      -# ROK 
412  *      -# RFAILED 
413 */
414 bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
415 {
416    switch (tmrEvnt)
417    {
418       case EVENT_RLC_UMUL_REASSEMBLE_TMR:
419       {
420          return (((RlcUlRbCb *)cb)->m.umUl.reAsmblTmr.tmrEvnt == 
421                   EVENT_RLC_UMUL_REASSEMBLE_TMR);
422       }
423       case EVENT_RLC_AMUL_REASSEMBLE_TMR:
424       {
425          return (((RlcUlRbCb *)cb)->m.amUl.reAsmblTmr.tmrEvnt == 
426                   EVENT_RLC_AMUL_REASSEMBLE_TMR);
427       }
428       case EVENT_RLC_AMUL_STA_PROH_TMR:
429       {
430          return (((RlcUlRbCb *)cb)->m.amUl.staProhTmr.tmrEvnt == 
431                   EVENT_RLC_AMUL_STA_PROH_TMR);
432       } 
433       case EVENT_RLC_AMDL_POLL_RETX_TMR:
434       {
435          return (((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr.tmrEvnt == 
436                   EVENT_RLC_AMDL_POLL_RETX_TMR);
437       } 
438       case EVENT_RLC_WAIT_BNDCFM:
439       {
440          return (((RlcRguSapCb *)cb)->bndTmr.tmrEvnt == EVENT_RLC_WAIT_BNDCFM);
441       }
442       case EVENT_RLC_UE_THROUGHPUT_TMR:
443       {
444          return (((RlcThpt *)cb)->ueTputInfo.ueThptTmr.tmrEvnt == EVENT_RLC_UE_THROUGHPUT_TMR);
445       }
446       case EVENT_RLC_UE_DELETE_TMR:
447       {
448          return (((RlcUlUeCb *)cb)->ueDeleteInfo.ueDelTmr.tmrEvnt == EVENT_RLC_UE_DELETE_TMR);
449       }
450       case EVENT_RLC_SNSSAI_THROUGHPUT_TMR:
451       {
452          return (((RlcThpt *)cb)->snssaiTputInfo.snssaiThptTmr.tmrEvnt == EVENT_RLC_SNSSAI_THROUGHPUT_TMR);
453       }
454       default:
455       {
456          DU_LOG("\nERROR  -->  RLC : rlcChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
457       }
458    } 
459
460    return FALSE;
461 }
462
463 /**
464  * @brief Handler to do processing on expiry of the bind timer
465  *
466  * @details
467  *    This function processes the RLC bind timer expiry. If the number of
468  *    retries is less than the maximum retry counter, bind request is sent
469  *    again, else an alarm is raised to the layer manager.
470  *
471  * @param[in] cb  Pointer to the Rgu sap
472  *
473  * @return  Void
474 */
475 static Void rlcBndTmrExpiry(PTR cb)
476 {
477    RlcRguSapCb *rguSapCb;
478
479    rguSapCb = (RlcRguSapCb *) cb;
480
481    if (rguSapCb->state == RLC_SAP_BINDING)
482    {
483       if (rguSapCb->retryCnt < RLC_MAX_SAP_BND_RETRY)
484       {
485          /* start timer to wait for bind confirm */
486          rlcStartTmr(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
487                     (PTR)rguSapCb,
488                     EVENT_RLC_WAIT_BNDCFM);
489
490          /* Send bind request */
491          rguSapCb->retryCnt++;
492          RlcLiRguBndReq (&rguSapCb->pst, rguSapCb->suId, rguSapCb->spId);
493       }
494       else
495       {
496          rguSapCb->retryCnt = 0;
497          rguSapCb->state = RLC_SAP_CFG;
498
499          /* Send alarm to the layer manager */
500 #ifdef LTE_L2_MEAS
501          rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
502                         LCM_CATEGORY_INTERFACE,
503                         LCM_EVENT_BND_FAIL,
504                         LCM_CAUSE_TMR_EXPIRED,
505                         0,
506                         0,
507                         0);
508 #else
509          rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
510                         LCM_CATEGORY_INTERFACE,
511                         LCM_EVENT_BND_FAIL,
512                         LCM_CAUSE_TMR_EXPIRED,
513                         0, /* suId */
514                         0 /* ueId */);
515 #endif
516       }
517    }
518
519    return;
520 }
521
522 /**
523  * @brief Handler to do processing on expiry of UE throughput timer
524  *
525  * @details
526  *    This function processes the RLC UE throughput timer expiry.
527  *
528  * @param[in] cb  Pointer to the RLC throughput struct
529  *
530  * @return  Void
531  */
532 void rlcUeThptTmrExpiry(PTR cb)
533 {
534    uint16_t  ueIdx;
535    long double tpt;
536    RlcThpt *rlcThptCb = (RlcThpt*)cb; 
537    
538    /* If cell is not up, throughput details cannot be printed */
539    if(gCellStatus != CELL_UP)
540    {
541       /* Restart timer */
542       rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)(rlcThptCb), EVENT_RLC_UE_THROUGHPUT_TMR);
543       return;
544    }
545
546    /* If cell is up, print throughout for each UE attached to the cell */
547    DU_LOG("\n===================== DL Throughput Per UE==============================");
548    DU_LOG("\nNumber of UEs : %d", rlcThptCb->ueTputInfo.numActvUe);
549    if(rlcThptCb->ueTputInfo.numActvUe)
550    {
551       for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
552       {
553          if(rlcThptCb->ueTputInfo.thptPerUe[ueIdx].ueId)
554          {
555             /* Spec 28.552, section 5.1.1.3 : 
556              * Throughput in kilobits/sec = (dataVol in kiloBits * 1000)/time in milligseconds
557              * 
558              * Since our dataVol is in bytes, multiplying 0.008 to covert into kilobits i.e. 
559              * Throughput[kbits/sec] = (dataVol * 0.008 * 1000)/time in ms
560              */
561              tpt = (double)(rlcThptCb->ueTputInfo.thptPerUe[ueIdx].dataVol * 8)/(double)ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL;
562       
563              DU_LOG("\nUE Id : %d   DL Tpt : %.2Lf", rlcThptCb->ueTputInfo.thptPerUe[ueIdx].ueId, tpt);
564              rlcThptCb->ueTputInfo.thptPerUe[ueIdx].dataVol = 0;
565          }
566       }
567    }
568    DU_LOG("\n==================================================================");
569
570    /* Restart timer */
571    rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_UE_THROUGHPUT_TMR);
572
573    return;
574 }
575
576 /**
577  * @brief Handler to do processing on expiry of the SNSSAI throughput timer
578  *
579  * @details
580  *    This function processes the RLC SNSSAI throughput timer expiry.
581  *
582  * @param[in] cb  Pointer to the RLC throughput struct
583  *
584  * @return  Void
585  */
586 void rlcSnssaiThptTmrExpiry(PTR cb)
587 {
588    long double tpt;
589    RlcThpt *rlcThptCb = (RlcThpt*)cb; 
590    
591    /* If cell is not up, throughput details cannot be printed */
592    if(gCellStatus != CELL_UP)
593    {
594       /* Restart timer */
595       rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)(rlcThptCb), EVENT_RLC_SNSSAI_THROUGHPUT_TMR);
596       return;
597    }
598
599    DU_LOG("\n==================================================================");
600    if(rlcThptCb->snssaiTputInfo.tputPerSnssaiList != NULLP)
601    {
602       DU_LOG("\n===================== DL Throughput Per SNSSAI ==============================");
603   
604       rlcCalculateTputPerSnssai(rlcThptCb->snssaiTputInfo.tputPerSnssaiList);
605       DU_LOG("\n==================================================================");
606    }
607    /* Restart timer */
608    rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_SNSSAI_THROUGHPUT_TMR);
609    return;
610 }
611 /**
612 *
613 * @brief filling RLC UE delete configuration
614 *
615 * @details
616 *    filling RLC UE delete configuration
617 *
618 * @params[in] RlcUlUeCb *ueCb, RlcCfgInfo *rlcUeCfg
619 *
620 * @return void
621 *
622 */
623
624 void fillRlcUeDelInfo(RlcUlUeCb *ueCb, RlcCfgInfo *rlcUeCfg)
625 {
626    uint8_t lcIdx;
627
628    rlcUeCfg->ueId    = ueCb->ueId;
629    rlcUeCfg->cellId  = ueCb->cellId;
630    rlcUeCfg->numEnt = 0;
631    for(lcIdx=0; lcIdx<RLC_MAX_LCH_PER_UE && rlcUeCfg->numEnt < 1; lcIdx++)
632    {
633       if(ueCb->lCh[lcIdx].ulRbCb != NULLP)
634       {
635          rlcUeCfg->entCfg[rlcUeCfg->numEnt].rbId    = 0;
636          rlcUeCfg->entCfg[rlcUeCfg->numEnt].rbType  = 0;
637          rlcUeCfg->entCfg[rlcUeCfg->numEnt].cfgType = CKW_CFG_DELETE_UE;
638          rlcUeCfg->numEnt++;
639       }
640    }
641 }
642
643 /**
644 * @brief Handler to do processing on expiry of the UE delete timer
645 *
646 * @details
647 *    This function processes the RLC UE delete timer expiry.
648 *
649 * @param[in] cb  Pointer to the RlcUlUeCb  
650 *
651 * @return  uint8_t
652 */
653
654 uint8_t rlcUeDeleteTmrExpiry(PTR cb)
655 {
656    RlcCb *gRlcCb = NULLP;
657    RlcCfgInfo *rlcUeCfg = NULLP;
658    RlcUlUeCb *ueCb = (RlcUlUeCb*)cb;
659
660    gRlcCb = RLC_GET_RLCCB(ueCb->ueDeleteInfo.pst.dstInst);
661    RLC_ALLOC(gRlcCb, rlcUeCfg, sizeof(RlcCfgInfo));
662    if(rlcUeCfg == NULLP)
663    {
664       DU_LOG("\nERROR  -->  RLC: rlcUeDeleteTmrExpiry(): Failed to allocate memory");
665       return RFAILED;
666    }
667    memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
668    fillRlcUeDelInfo(ueCb, rlcUeCfg);
669    if(RlcProcCfgReq(&ueCb->ueDeleteInfo.pst, rlcUeCfg) != ROK)
670    {
671       DU_LOG("\nERROR  -->  RLC: rlcUeDeleteTmrExpiry(): Failed to delete UE");
672       if(sendRlcUeDeleteRspToDu(rlcUeCfg->cellId, rlcUeCfg->ueId, INVALID_UEID) != ROK)
673       {
674          DU_LOG("ERROR  --> RLC: rlcUeDeleteTmrExpiry(): Failed to send UE delete response ");
675          return RFAILED;
676       }
677    }
678    return ROK;
679 }
680 \f  
681 /********************************************************************30**
682   
683          End of file
684 **********************************************************************/