#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
{
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;
{
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;
{
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);
{
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);
{
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;
{
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);
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;
}
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)
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:
{
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:
{
* @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;
{
/* 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);
/* 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
}
/**
- * @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; lcIdx<RLC_MAX_LCH_PER_UE && rlcUeCfg->numEnt < 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;
+}
\f
/********************************************************************30**