X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrrlc%2Frlc_tmr.c;h=2f3a1873228684b411e3b171971b4d80cf56aa1a;hb=f73456bd55152c329601f8286ae67fe9875025bc;hp=d7ecd63d60a1247137d202fc77e1694f4aa10c2e;hpb=be872311899d115fdf4565e4811cc8b37226ac53;p=o-du%2Fl2.git diff --git a/src/5gnrrlc/rlc_tmr.c b/src/5gnrrlc/rlc_tmr.c index d7ecd63d6..2f3a18732 100755 --- a/src/5gnrrlc/rlc_tmr.c +++ b/src/5gnrrlc/rlc_tmr.c @@ -48,40 +48,21 @@ #include "kwu.x" /* KWU */ #include "rgu.x" /* RGU */ +#include "du_app_rlc_inf.h" #include "rlc_utils.h" /* RLC defines */ #include "rlc_dl_ul_inf.h" #include "rlc_dl.h" #include "rlc_ul.h" +#include "rlc_mgr.h" + /** * @file gp_tmr.c * @brief RLC Timer Module */ -/** - * @def RLC_TMR_CALCUATE_WAIT - * - * This macro calculates and assigns wait time based on the value of the - * timer and the timer resolution. Timer value of 0 signifies that the - * timer is not configured - * - * @param[out] _wait Time for which to arm the timer changed to proper - * value according to the resolution - * @param[in] _tmrVal Value of the timer - * @param[in] _timerRes Resolution of the timer - * -*/ -#define RLC_TMR_CALCUATE_WAIT(_wait, _tmrVal, _timerRes) \ -{ \ - (_wait) = ((_tmrVal) * SS_TICKS_SEC)/((_timerRes) * 1000); \ - if((0 != (_tmrVal)) && (0 == (_wait))) \ - { \ - (_wait) = 1; \ - } \ -} - /* private function declarations */ static Void rlcBndTmrExpiry(PTR cb); -void rlcThptTmrExpiry(PTR cb); + /** * @brief Handler to start timer @@ -110,7 +91,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcUmUl* umUl = &(((RlcUlRbCb *)cb)->m.umUl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, umUl->reAsmblTmrInt, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, umUl->reAsmblTmrInt, gCb->genCfg.timeRes); arg.timers = &umUl->reAsmblTmr; arg.max = RLC_MAX_UM_TMR; @@ -120,7 +101,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, amUl->reAsmblTmrInt, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, amUl->reAsmblTmrInt, gCb->genCfg.timeRes); arg.timers = &amUl->reAsmblTmr; arg.max = RLC_MAX_AM_TMR; @@ -130,7 +111,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcAmUl* amUl = &(((RlcUlRbCb *)cb)->m.amUl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, + TMR_CALCUATE_WAIT(arg.wait, amUl->staProhTmrInt, gCb->genCfg.timeRes); @@ -142,7 +123,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcAmDl* amDl = &(((RlcDlRbCb *)cb)->m.amDl); /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, + TMR_CALCUATE_WAIT(arg.wait, amDl->pollRetxTmrInt, gCb->genCfg.timeRes); @@ -154,7 +135,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { RlcRguSapCb* rguSap = (RlcRguSapCb *)cb; /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes); + TMR_CALCUATE_WAIT(arg.wait, rguSap->bndTmrInt, gCb->genCfg.timeRes); arg.timers = &rguSap->bndTmr; arg.max = RLC_MAX_RGUSAP_TMR; @@ -166,7 +147,7 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { measEvtCb = (RlcL2MeasEvtCb *)cb; /* kw005.201 Changed wait calculation ccpu00117634*/ - RLC_TMR_CALCUATE_WAIT(arg.wait, + TMR_CALCUATE_WAIT(arg.wait, measEvtCb->l2TmrCfg.val, gCb->genCfg.timeRes); @@ -175,11 +156,27 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) break; } #endif - case EVENT_RLC_THROUGHPUT_TMR: + case EVENT_RLC_UE_THROUGHPUT_TMR: { RlcThpt *thptCb = (RlcThpt *)cb; - RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); - arg.timers = &thptCb->thptTmr; + TMR_CALCUATE_WAIT(arg.wait, ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); + arg.timers = &thptCb->ueTputInfo.ueThptTmr; + arg.max = RLC_MAX_THPT_TMR; + break; + } + case EVENT_RLC_UE_DELETE_TMR: + { + RlcUlUeCb *ulUeCb = (RlcUlUeCb*)cb; + TMR_CALCUATE_WAIT(arg.wait, RLC_UE_DELETE_WAIT_TIME, gCb->genCfg.timeRes); + arg.timers = &ulUeCb->ueDeleteInfo.ueDelTmr; + arg.max = RLC_MAX_UE_TMR; + break; + } + case EVENT_RLC_SNSSAI_THROUGHPUT_TMR: + { + RlcThpt *thptCb = (RlcThpt *)cb; + TMR_CALCUATE_WAIT(arg.wait, ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes); + arg.timers = &thptCb->snssaiTputInfo.snssaiThptTmr; arg.max = RLC_MAX_THPT_TMR; break; } @@ -265,14 +262,28 @@ void rlcStopTmr(RlcCb *gCb, PTR cb, uint8_t tmrType) break; } #endif - case EVENT_RLC_THROUGHPUT_TMR: + case EVENT_RLC_UE_THROUGHPUT_TMR: + { + arg.timers = &((RlcThpt *)cb)->ueTputInfo.ueThptTmr; + arg.max = RLC_MAX_THPT_TMR; + break; + } + case EVENT_RLC_UE_DELETE_TMR: + { + arg.timers = &((RlcUlUeCb*)cb)->ueDeleteInfo.ueDelTmr; + arg.max = EVENT_RLC_UE_DELETE_TMR; + break; + } + case EVENT_RLC_SNSSAI_THROUGHPUT_TMR: { - arg.timers = &((RlcThpt *)cb)->thptTmr; + arg.timers = &((RlcThpt *)cb)->snssaiTputInfo.snssaiThptTmr; arg.max = RLC_MAX_THPT_TMR; + break; } default: { DU_LOG("\nERROR --> RLC : rlcStopTmr: Invalid tmr Evnt[%d]", tmrType); + break; } } if (tmrType != TMR0) @@ -343,9 +354,19 @@ Void rlcTmrExpiry(PTR cb,S16 tmrEvnt) rlcBndTmrExpiry(cb); break; } - case EVENT_RLC_THROUGHPUT_TMR: + case EVENT_RLC_UE_THROUGHPUT_TMR: + { + rlcUeThptTmrExpiry(cb); + break; + } + case EVENT_RLC_UE_DELETE_TMR: { - rlcThptTmrExpiry(cb); + rlcUeDeleteTmrExpiry(cb); + break; + } + case EVENT_RLC_SNSSAI_THROUGHPUT_TMR: + { + rlcSnssaiThptTmrExpiry(cb); break; } default: @@ -397,9 +418,17 @@ bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) { return (((RlcRguSapCb *)cb)->bndTmr.tmrEvnt == EVENT_RLC_WAIT_BNDCFM); } - case EVENT_RLC_THROUGHPUT_TMR: + case EVENT_RLC_UE_THROUGHPUT_TMR: { - return (((RlcThpt *)cb)->thptTmr.tmrEvnt == EVENT_RLC_THROUGHPUT_TMR); + return (((RlcThpt *)cb)->ueTputInfo.ueThptTmr.tmrEvnt == EVENT_RLC_UE_THROUGHPUT_TMR); + } + case EVENT_RLC_UE_DELETE_TMR: + { + return (((RlcUlUeCb *)cb)->ueDeleteInfo.ueDelTmr.tmrEvnt == EVENT_RLC_UE_DELETE_TMR); + } + case EVENT_RLC_SNSSAI_THROUGHPUT_TMR: + { + return (((RlcThpt *)cb)->snssaiTputInfo.snssaiThptTmr.tmrEvnt == EVENT_RLC_SNSSAI_THROUGHPUT_TMR); } default: { @@ -414,17 +443,17 @@ bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt) * @brief Handler to do processing on expiry of the bind timer * * @details - * This function processes the RLC bind timer expiry. If the number of - * retries is less than the maximum retry counter, bind request is sent + * This function processes the RLC bind timer expiry. If the number of + * retries is less than the maximum retry counter, bind request is sent * again, else an alarm is raised to the layer manager. - * + * * @param[in] cb Pointer to the Rgu sap * * @return Void */ static Void rlcBndTmrExpiry(PTR cb) { - RlcRguSapCb *rguSapCb; + RlcRguSapCb *rguSapCb; rguSapCb = (RlcRguSapCb *) cb; @@ -434,9 +463,9 @@ static Void rlcBndTmrExpiry(PTR cb) { /* start timer to wait for bind confirm */ rlcStartTmr(RLC_GET_RLCCB(rguSapCb->pst.srcInst), - (PTR)rguSapCb, + (PTR)rguSapCb, EVENT_RLC_WAIT_BNDCFM); - + /* Send bind request */ rguSapCb->retryCnt++; RlcLiRguBndReq (&rguSapCb->pst, rguSapCb->suId, rguSapCb->spId); @@ -449,17 +478,17 @@ static Void rlcBndTmrExpiry(PTR cb) /* Send alarm to the layer manager */ #ifdef LTE_L2_MEAS rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst), - LCM_CATEGORY_INTERFACE, + LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_FAIL, - LCM_CAUSE_TMR_EXPIRED, - 0, - 0, + LCM_CAUSE_TMR_EXPIRED, + 0, + 0, 0); #else rlcLmmSendAlarm(RLC_GET_RLCCB(rguSapCb->pst.srcInst), - LCM_CATEGORY_INTERFACE, + LCM_CATEGORY_INTERFACE, LCM_EVENT_BND_FAIL, - LCM_CAUSE_TMR_EXPIRED, + LCM_CAUSE_TMR_EXPIRED, 0, /* suId */ 0 /* ueId */); #endif @@ -470,45 +499,176 @@ static Void rlcBndTmrExpiry(PTR cb) } /** - * @brief Handler to do processing on expiry of the throughput timer + * @brief Handler to do processing on expiry of UE throughput timer * * @details - * This function processes the RLC throughput timer expiry. + * This function processes the RLC UE throughput timer expiry. * * @param[in] cb Pointer to the RLC throughput struct * * @return Void */ -void rlcThptTmrExpiry(PTR cb) +void rlcUeThptTmrExpiry(PTR cb) { uint16_t ueIdx; long double tpt; RlcThpt *rlcThptCb = (RlcThpt*)cb; + + /* If cell is not up, throughput details cannot be printed */ + if(gCellStatus != CELL_UP) + { + /* Restart timer */ + rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)(rlcThptCb), EVENT_RLC_UE_THROUGHPUT_TMR); + return; + } - /* Print throughput */ - DU_LOG("\n===================== DL Throughput =============================="); - DU_LOG("\nNumber of UEs : %d", rlcThptCb->numActvUe); - for(ueIdx = 0; ueIdx < rlcThptCb->numActvUe; ueIdx++) + /* If cell is up, print throughout for each UE attached to the cell */ + DU_LOG("\n===================== DL Throughput Per UE=============================="); + DU_LOG("\nNumber of UEs : %d", rlcThptCb->ueTputInfo.numActvUe); + if(rlcThptCb->ueTputInfo.numActvUe) { - /* Spec 28.552, section 5.1.1.3 : - * Throughput in kilobits/sec = (dataVol in kiloBits * 1000)/time in milligseconds - * - * Since our dataVol is in bytes, multiplying 0.008 to covert into kilobits i.e. - * Throughput[kbits/sec] = (dataVol * 0.008 * 1000)/time in ms - */ - tpt = (double)(rlcThptCb->thptPerUe[ueIdx].dataVol * 8)/(double)ODU_THROUGHPUT_PRINT_TIME_INTERVAL; + for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) + { + if(rlcThptCb->ueTputInfo.thptPerUe[ueIdx].ueId) + { + /* Spec 28.552, section 5.1.1.3 : + * Throughput in kilobits/sec = (dataVol in kiloBits * 1000)/time in milligseconds + * + * Since our dataVol is in bytes, multiplying 0.008 to covert into kilobits i.e. + * Throughput[kbits/sec] = (dataVol * 0.008 * 1000)/time in ms + */ + tpt = (double)(rlcThptCb->ueTputInfo.thptPerUe[ueIdx].dataVol * 8)/(double)ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL; - DU_LOG("\nUE Id : %d DL Tpt : %.2Lf", rlcThptCb->thptPerUe[ueIdx].ueIdx, tpt); - rlcThptCb->thptPerUe[ueIdx].dataVol = 0; + DU_LOG("\nUE Id : %d DL Tpt : %.2Lf", rlcThptCb->ueTputInfo.thptPerUe[ueIdx].ueId, tpt); + rlcThptCb->ueTputInfo.thptPerUe[ueIdx].dataVol = 0; + } + } } DU_LOG("\n=================================================================="); /* Restart timer */ - rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_THROUGHPUT_TMR); + rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_UE_THROUGHPUT_TMR); return; } +/** + * @brief Handler to do processing on expiry of the SNSSAI throughput timer + * + * @details + * This function processes the RLC SNSSAI throughput timer expiry. + * + * @param[in] cb Pointer to the RLC throughput struct + * + * @return Void + */ +void rlcSnssaiThptTmrExpiry(PTR cb) +{ + RlcThpt *rlcThptCb = (RlcThpt*)cb; + + static uint8_t snssaiCntDl = 0, snssaiCntUl = 0; + /*Bit map to keep record of reception of DL and UL Snssai Tput expiry*/ + static uint8_t snssaiTputBitmap = DIR_NONE; + + /* If cell is not up, throughput details cannot be printed */ + if(gCellStatus != CELL_UP) + { + /* Restart timer */ + rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)(rlcThptCb), EVENT_RLC_SNSSAI_THROUGHPUT_TMR); + return; + } + + if(rlcThptCb->snssaiTputInfo.dlTputPerSnssaiList != NULLP) + { + snssaiCntDl = rlcCalculateTputPerSnssai(rlcThptCb->snssaiTputInfo.dlTputPerSnssaiList, DIR_DL); + snssaiTputBitmap |= DIR_DL; + arrTputPerSnssai[DIR_DL] = rlcThptCb->snssaiTputInfo.dlTputPerSnssaiList; + } + if(rlcThptCb->snssaiTputInfo.ulTputPerSnssaiList != NULLP) + { + snssaiCntUl = rlcCalculateTputPerSnssai(rlcThptCb->snssaiTputInfo.ulTputPerSnssaiList, DIR_UL); + snssaiTputBitmap |= DIR_UL; + arrTputPerSnssai[DIR_UL] = rlcThptCb->snssaiTputInfo.ulTputPerSnssaiList; + } + if(snssaiTputBitmap == DIR_BOTH) + { + //call the function + BuildSliceReportToDu(MAX(snssaiCntUl, snssaiCntDl)); + snssaiTputBitmap = DIR_NONE; + } + /* Restart timer */ + rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_SNSSAI_THROUGHPUT_TMR); + return; +} +/** +* +* @brief filling RLC UE delete configuration +* +* @details +* filling RLC UE delete configuration +* +* @params[in] RlcUlUeCb *ueCb, RlcCfgInfo *rlcUeCfg +* +* @return void +* +*/ + +void fillRlcUeDelInfo(RlcUlUeCb *ueCb, RlcCfgInfo *rlcUeCfg) +{ + uint8_t lcIdx; + + rlcUeCfg->ueId = ueCb->ueId; + rlcUeCfg->cellId = ueCb->cellId; + rlcUeCfg->numEnt = 0; + for(lcIdx=0; lcIdxnumEnt < 1; lcIdx++) + { + if(ueCb->lCh[lcIdx].ulRbCb != NULLP) + { + rlcUeCfg->entCfg[rlcUeCfg->numEnt].rbId = 0; + rlcUeCfg->entCfg[rlcUeCfg->numEnt].rbType = 0; + rlcUeCfg->entCfg[rlcUeCfg->numEnt].cfgType = CKW_CFG_DELETE_UE; + rlcUeCfg->numEnt++; + } + } +} + +/** +* @brief Handler to do processing on expiry of the UE delete timer +* +* @details +* This function processes the RLC UE delete timer expiry. +* +* @param[in] cb Pointer to the RlcUlUeCb +* +* @return uint8_t +*/ + +uint8_t rlcUeDeleteTmrExpiry(PTR cb) +{ + RlcCb *gRlcCb = NULLP; + RlcCfgInfo *rlcUeCfg = NULLP; + RlcUlUeCb *ueCb = (RlcUlUeCb*)cb; + + gRlcCb = RLC_GET_RLCCB(ueCb->ueDeleteInfo.pst.dstInst); + RLC_ALLOC(gRlcCb, rlcUeCfg, sizeof(RlcCfgInfo)); + if(rlcUeCfg == NULLP) + { + DU_LOG("\nERROR --> RLC: rlcUeDeleteTmrExpiry(): Failed to allocate memory"); + return RFAILED; + } + memset(rlcUeCfg, 0, sizeof(RlcCfgInfo)); + fillRlcUeDelInfo(ueCb, rlcUeCfg); + if(RlcProcCfgReq(&ueCb->ueDeleteInfo.pst, rlcUeCfg) != ROK) + { + DU_LOG("\nERROR --> RLC: rlcUeDeleteTmrExpiry(): Failed to delete UE"); + if(sendRlcUeDeleteRspToDu(rlcUeCfg->cellId, rlcUeCfg->ueId, UEID_INVALID) != ROK) + { + DU_LOG("ERROR --> RLC: rlcUeDeleteTmrExpiry(): Failed to send UE delete response "); + return RFAILED; + } + } + return ROK; +} /********************************************************************30**