1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /********************************************************************20**
21 Name: RLC - TMR module file
25 Desc: Source code for timer functions such as,
34 *********************************************************************21*/
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 */
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 */
51 #include "rlc_utils.h" /* RLC defines */
52 #include "rlc_dl_ul_inf.h"
57 * @brief RLC Timer Module
61 * @def RLC_TMR_CALCUATE_WAIT
63 * This macro calculates and assigns wait time based on the value of the
64 * timer and the timer resolution. Timer value of 0 signifies that the
65 * timer is not configured
67 * @param[out] _wait Time for which to arm the timer changed to proper
68 * value according to the resolution
69 * @param[in] _tmrVal Value of the timer
70 * @param[in] _timerRes Resolution of the timer
73 #define RLC_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes) \
75 (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \
76 if((0 != (_tmrVal)) && (0 == (_wait))) \
82 /* private function declarations */
83 static Void rlcBndTmrExpiry(PTR cb);
84 void rlcThptTmrExpiry(PTR cb);
87 * @brief Handler to start timer
89 * @param[in] gCb Pointer to the RLC instance control block
90 * @param[in] cb Control block depending on the type of the timer event.
91 * It can be uplink/downlink rbCb or rgu sap control block
92 * @param[in] tmrEvnt Timer event to be started
96 void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
98 /* kw005.201 added support for L2 Measurement */
100 RlcL2MeasEvtCb *measEvtCb = NULLP;
106 /* kw002.201 Adjusting the wait time as per timeRes configured by layer manager */
109 case EVENT_RLC_UMUL_REASSEMBLE_TMR:
111 RlcUmUl* umUl = &(((RlcUlRbCb *)cb)->m.umUl);
112 /* kw005.201 Changed wait calculation ccpu00117634*/
113 RLC_TMR_CALCUATE_WAIT(arg.wait, umUl->reAsmblTmrInt, gCb->genCfg.timeRes);
115 arg.timers = &umUl->reAsmblTmr;
116 arg.max = RLC_MAX_UM_TMR;
119 case EVENT_RLC_AMUL_REASSEMBLE_TMR:
121 RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl);
122 /* kw005.201 Changed wait calculation ccpu00117634*/
123 RLC_TMR_CALCUATE_WAIT(arg.wait, amUl->reAsmblTmrInt, gCb->genCfg.timeRes);
125 arg.timers = &amUl->reAsmblTmr;
126 arg.max = RLC_MAX_AM_TMR;
129 case EVENT_RLC_AMUL_STA_PROH_TMR:
131 RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl);
132 /* kw005.201 Changed wait calculation ccpu00117634*/
133 RLC_TMR_CALCUATE_WAIT(arg.wait,
135 gCb->genCfg.timeRes);
137 arg.timers = &amUl->staProhTmr;
138 arg.max = RLC_MAX_AM_TMR;
141 case EVENT_RLC_AMDL_POLL_RETX_TMR:
143 RlcAmDl* amDl = &(((RlcDlRbCb *)cb)->m.amDl);
144 /* kw005.201 Changed wait calculation ccpu00117634*/
145 RLC_TMR_CALCUATE_WAIT(arg.wait,
146 amDl->pollRetxTmrInt,
147 gCb->genCfg.timeRes);
149 arg.timers = &amDl->pollRetxTmr;
150 arg.max = RLC_MAX_AM_TMR;
153 case EVENT_RLC_WAIT_BNDCFM:
155 RlcRguSapCb* rguSap = (RlcRguSapCb *)cb;
156 /* kw005.201 Changed wait calculation ccpu00117634*/
157 RLC_TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes);
159 arg.timers = &rguSap->bndTmr;
160 arg.max = RLC_MAX_RGUSAP_TMR;
163 /* kw005.201 added support for L2 Measurement */
165 case EVENT_RLC_L2_TMR:
167 measEvtCb = (RlcL2MeasEvtCb *)cb;
168 /* kw005.201 Changed wait calculation ccpu00117634*/
169 RLC_TMR_CALCUATE_WAIT(arg.wait,
170 measEvtCb->l2TmrCfg.val,
171 gCb->genCfg.timeRes);
173 arg.timers = &measEvtCb->l2Tmr;
174 arg.max = RLC_L2_MAX_TIMERS;
178 case EVENT_RLC_THROUGHPUT_TMR:
180 RlcThpt *thptCb = (RlcThpt *)cb;
181 RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes);
182 arg.timers = &thptCb->thptTmr;
183 arg.max = RLC_MAX_THPT_TMR;
188 DU_LOG("\nERROR --> RLC : rlcStartTmr: Invalid tmr Evnt [%d]", tmrEvnt);
194 arg.tqCp = &gCb->rlcTqCp;
207 * @brief Handler to stop a timer
209 * @param[in] gCb Pointer to the RLC instance control block
210 * @param[in] cb Control block depending on the type of the timer event.
211 * It can be uplink/downlink rbCb or rgu sap control block
212 * @param[in] tmrType Timer event to be started
216 void rlcStopTmr(RlcCb *gCb, PTR cb, uint8_t tmrType)
219 /* kw005.201 added support for L2 Measurement */
221 RlcL2MeasEvtCb *measEvtCb = NULLP;
228 case EVENT_RLC_UMUL_REASSEMBLE_TMR:
230 arg.timers = &((RlcUlRbCb *)cb)->m.umUl.reAsmblTmr;
231 arg.max = RLC_MAX_UM_TMR;
234 case EVENT_RLC_AMUL_REASSEMBLE_TMR:
236 arg.timers = &((RlcUlRbCb *)cb)->m.amUl.reAsmblTmr;
237 arg.max = RLC_MAX_AM_TMR;
240 case EVENT_RLC_AMUL_STA_PROH_TMR:
242 arg.timers = &((RlcUlRbCb *)cb)->m.amUl.staProhTmr;
243 arg.max = RLC_MAX_AM_TMR;
246 case EVENT_RLC_AMDL_POLL_RETX_TMR:
248 arg.timers = &((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr;
249 arg.max = RLC_MAX_AM_TMR;
252 case EVENT_RLC_WAIT_BNDCFM:
254 arg.timers = &((RlcRguSapCb *)cb)->bndTmr;
255 arg.max = RLC_MAX_RGUSAP_TMR;
258 /* kw005.201 added support for L2 Measurement */
260 case EVENT_RLC_L2_TMR:
262 measEvtCb = (RlcL2MeasEvtCb *)cb;
263 arg.timers = &measEvtCb->l2Tmr;
264 arg.max = RLC_L2_MAX_TIMERS;
268 case EVENT_RLC_THROUGHPUT_TMR:
270 arg.timers = &((RlcThpt *)cb)->thptTmr;
271 arg.max = RLC_MAX_THPT_TMR;
275 DU_LOG("\nERROR --> RLC : rlcStopTmr: Invalid tmr Evnt[%d]", tmrType);
280 arg.tqCp = &gCb->rlcTqCp;
293 * @brief Handler to invoke events on expiry of timer.
296 * This function is used to handle expiry of timer,it invokes relevant
299 * @param[in] cb Control block depending on the type of the timer event.
300 * It can be uplink/downlink rbCb or rgu sap control block
301 * @param[in] tmrEvnt Timer event to be started
305 Void rlcTmrExpiry(PTR cb,S16 tmrEvnt)
307 /* kw005.201 added support for L2 Measurement */
311 case EVENT_RLC_UMUL_REASSEMBLE_TMR:
313 RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
314 rlcUmmReAsmblTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
318 case EVENT_RLC_AMUL_REASSEMBLE_TMR:
320 RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
321 rlcAmmReAsmblTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
324 case EVENT_RLC_AMUL_STA_PROH_TMR:
326 RlcUlRbCb *ulRbCb = (RlcUlRbCb *)cb;
327 rlcAmmStaProTmrExp(RLC_GET_RLCCB(ulRbCb->inst), ulRbCb);
331 case EVENT_RLC_AMDL_POLL_RETX_TMR:
333 RlcDlRbCb *dlRbCb = (RlcDlRbCb *)cb;
334 RlcCb *gCb = RLC_GET_RLCCB(dlRbCb->inst);
336 rlcAmmPollRetxTmrExp(gCb, dlRbCb);
338 gCb->genSts.protTimeOut++;
341 case EVENT_RLC_WAIT_BNDCFM:
346 case EVENT_RLC_THROUGHPUT_TMR:
348 rlcThptTmrExpiry(cb);
361 * @brief Handler to check if the timer is running
363 * @param[in] gCb Pointer to the RLC instance control block
364 * @param[in] cb Control block depending on the type of the timer event.
365 * It can be uplink/downlink rbCb or rgu sap control block
366 * @param[in] tmrEvnt Timer event to be started
368 * @return Bool indicating whether the timer is running or not
372 bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
376 case EVENT_RLC_UMUL_REASSEMBLE_TMR:
378 return (((RlcUlRbCb *)cb)->m.umUl.reAsmblTmr.tmrEvnt ==
379 EVENT_RLC_UMUL_REASSEMBLE_TMR);
381 case EVENT_RLC_AMUL_REASSEMBLE_TMR:
383 return (((RlcUlRbCb *)cb)->m.amUl.reAsmblTmr.tmrEvnt ==
384 EVENT_RLC_AMUL_REASSEMBLE_TMR);
386 case EVENT_RLC_AMUL_STA_PROH_TMR:
388 return (((RlcUlRbCb *)cb)->m.amUl.staProhTmr.tmrEvnt ==
389 EVENT_RLC_AMUL_STA_PROH_TMR);
391 case EVENT_RLC_AMDL_POLL_RETX_TMR:
393 return (((RlcDlRbCb *)cb)->m.amDl.pollRetxTmr.tmrEvnt ==
394 EVENT_RLC_AMDL_POLL_RETX_TMR);
396 case EVENT_RLC_WAIT_BNDCFM:
398 return (((RlcRguSapCb *)cb)->bndTmr.tmrEvnt == EVENT_RLC_WAIT_BNDCFM);
400 case EVENT_RLC_THROUGHPUT_TMR:
402 return (((RlcThpt *)cb)->thptTmr.tmrEvnt == EVENT_RLC_THROUGHPUT_TMR);
406 DU_LOG("\nERROR --> RLC : rlcChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
414 * @brief Handler to do processing on expiry of the bind timer
417 * This function processes the RLC bind timer expiry. If the number of
418 * retries is less than the maximum retry counter, bind request is sent
419 * again, else an alarm is raised to the layer manager.
421 * @param[in] cb Pointer to the Rgu sap
425 static Void rlcBndTmrExpiry(PTR cb)
427 RlcRguSapCb *rguSapCb;
429 rguSapCb = (RlcRguSapCb *) cb;
431 if (rguSapCb->state == RLC_SAP_BINDING)
433 if (rguSapCb->retryCnt < RLC_MAX_SAP_BND_RETRY)
435 /* start timer to wait for bind confirm */
436 rlcStartTmr(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
438 EVENT_RLC_WAIT_BNDCFM);
440 /* Send bind request */
441 rguSapCb->retryCnt++;
442 RlcLiRguBndReq (&rguSapCb->pst, rguSapCb->suId, rguSapCb->spId);
446 rguSapCb->retryCnt = 0;
447 rguSapCb->state = RLC_SAP_CFG;
449 /* Send alarm to the layer manager */
451 rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
452 LCM_CATEGORY_INTERFACE,
454 LCM_CAUSE_TMR_EXPIRED,
459 rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst),
460 LCM_CATEGORY_INTERFACE,
462 LCM_CAUSE_TMR_EXPIRED,
473 * @brief Handler to do processing on expiry of the throughput timer
476 * This function processes the RLC throughput timer expiry.
478 * @param[in] cb Pointer to the RLC throughput struct
482 void rlcThptTmrExpiry(PTR cb)
486 RlcThpt *rlcThptCb = (RlcThpt*)cb;
488 /* Print throughput */
489 DU_LOG("\n===================== DL Throughput ==============================");
490 DU_LOG("\nNumber of UEs : %d", rlcThptCb->numActvUe);
491 for(ueIdx = 0; ueIdx < rlcThptCb->numActvUe; ueIdx++)
493 /* Spec 28.552, section 5.1.1.3 :
494 * Throughput in kilobits/sec = (dataVol in kiloBits * 1000)/time in milligseconds
496 * Since our dataVol is in bytes, multiplying 0.008 to covert into kilobits i.e.
497 * Throughput[kbits/sec] = (dataVol * 0.008 * 1000)/time in ms
499 tpt = (double)(rlcThptCb->thptPerUe[ueIdx].dataVol * 8)/(double)ODU_THROUGHPUT_PRINT_TIME_INTERVAL;
501 DU_LOG("\nUE Id : %d DL Tpt : %.2Lf", rlcThptCb->thptPerUe[ueIdx].ueIdx, tpt);
502 rlcThptCb->thptPerUe[ueIdx].dataVol = 0;
504 DU_LOG("\n==================================================================");
507 rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_THROUGHPUT_TMR);
513 /********************************************************************30**
516 **********************************************************************/