DL throughput calculation for UM [Issue-ID: ODUHIGH-319] 91/5791/2
authorlal.harshita <Harshita.Lal@radisys.com>
Wed, 24 Mar 2021 14:15:24 +0000 (19:45 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Wed, 28 Apr 2021 09:31:00 +0000 (15:01 +0530)
Change-Id: Ib9c3b91dc4ec87ee3307db80afe6c233c879471c
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
src/5gnrrlc/kw.h
src/5gnrrlc/kw.x
src/5gnrrlc/kw_cfg_dl.c
src/5gnrrlc/kw_lmm.c
src/5gnrrlc/kw_tmr.c
src/5gnrrlc/kw_utl_dl.c
src/5gnrrlc/rlc_msg_hdl.c
src/cm/common_def.h
src/cm/lkw.x
src/du_app/du_ue_mgr.c

index f23f1de..52d4237 100755 (executable)
 #define RLC_TMR_LEN                     10
 #define RLC_MAX_UM_TMR                  1
 #define RLC_MAX_AM_TMR                  3
+#define RLC_MAX_THPT_TMR                1
 
 /* Timer events */
 #define EVENT_RLC_UMUL_REASSEMBLE_TMR     1
 #ifdef LTE_L2_MEAS
 #define EVENT_RLC_L2_TMR                  6
 #endif /* LTE_L2_MEAS */
+#define EVENT_RLC_THROUGHPUT_TMR          7
 
 /*******************************************************************************
  *                              DBM Defines 
index 7c6f62b..1c7feae 100755 (executable)
@@ -578,6 +578,23 @@ typedef struct rlcUlCb
 #endif /* LTE_L2_MEAS */
 }RlcUlCb;
 
+typedef struct rlcThptPerUe
+{
+   uint16_t ueIdx;
+   uint64_t dataVol;
+}RlcThptPerUe;
+
+/**
+ * @brief  Structure to hold information about throughput at  RLC
+ * 
+ */
+typedef struct rlcThpt
+{
+   Inst          inst;                      /* RLC instance */
+   CmTimer       thptTmr;                   /* Throughput Timer */
+   uint8_t       numActvUe;                 /* Number of Active UEs */
+   RlcThptPerUe  thptPerUe[MAX_NUM_UE];     /* Throughput calculated per UE */
+}RlcThpt;
 
 /** 
  * @brief  Structure to hold an information about a RLC instance
@@ -609,6 +626,7 @@ typedef struct rlcCb
       RlcDlCb   *dlCb;   /*!< Dl Control Block */
    } u;
    uint8_t    dlSduId;   /*!< Downlink SDU ID */
+   RlcThpt    rlcThpt;   /*!< Throughput at RLC*/
 }RlcCb;
 
 RlcCb *rlcCb[MAX_RLC_INSTANCES];   /*!< RLC global control block */
index 8c9da76..22a6a21 100755 (executable)
@@ -723,6 +723,16 @@ RlcEntCfgCfmInfo   *entCfm
                         entCfg->rbId);
                return RFAILED;
             }
+            /* Start throughput calculation for this UE */
+            gCb->rlcThpt.thptPerUe[gCb->rlcThpt.numActvUe].ueIdx = ueId;
+            gCb->rlcThpt.thptPerUe[gCb->rlcThpt.numActvUe].dataVol = 0;
+            gCb->rlcThpt.numActvUe++;
+            
+            if((rlcChkTmr(gCb, (PTR)(&gCb->rlcThpt), EVENT_RLC_THROUGHPUT_TMR)) == FALSE)
+            {
+               printf("\nHLAL Starting Throughput timer");
+               rlcStartTmr(gCb, (PTR)(&gCb->rlcThpt), EVENT_RLC_THROUGHPUT_TMR);
+            }
          }
 
          /* Validate LChId for UM and AM modes */
index 5500bec..efae6b2 100755 (executable)
@@ -179,6 +179,11 @@ static S16 rlcLmmGenCfg(RlcCb  *gCb,RlcGenCfg *cfg)
    rlcTqCp->tmrLen = RLC_TMR_LEN;
    rlcTqCp->nxtEnt = 0;
 
+   gCb->rlcThpt.inst = gCb->init.inst;
+   gCb->rlcThpt.thptTmr.tmrEvnt = TMR_NONE;
+   gCb->rlcThpt.numActvUe = 0;
+   memset(gCb->rlcThpt.thptPerUe, 0, MAX_NUM_UE * sizeof(RlcThptPerUe));
+
    if(gCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
    {
       RLC_ALLOC(gCb,gCb->u.dlCb, sizeof (RlcDlCb));
index dc5c794..ae6333b 100755 (executable)
@@ -87,6 +87,7 @@
 
 /* private function declarations */
 static Void rlcBndTmrExpiry(PTR cb);
+void rlcThptTmrExpiry(PTR cb);
 
 /**
  * @brief Handler to start timer
@@ -180,6 +181,14 @@ void rlcStartTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
          break;
       }
 #endif
+      case EVENT_RLC_THROUGHPUT_TMR:
+      {
+         RlcThpt *thptCb = (RlcThpt *)cb;
+         RLC_TMR_CALCUATE_WAIT(arg.wait, ODU_THROUGHPUT_PRINT_TIME_INTERVAL, gCb->genCfg.timeRes);
+         arg.timers = &thptCb->thptTmr;
+         arg.max = RLC_MAX_THPT_TMR; 
+         break;
+      }
       default:
       {
          DU_LOG("\nERROR  -->  RLC : rlcStartTmr: Invalid tmr Evnt [%d]", tmrEvnt);
@@ -262,6 +271,11 @@ void rlcStopTmr(RlcCb *gCb, PTR cb, uint8_t tmrType)
          break;
       }
 #endif
+      case EVENT_RLC_THROUGHPUT_TMR:
+      {
+         arg.timers   = &((RlcThpt *)cb)->thptTmr;
+         arg.max  = RLC_MAX_THPT_TMR;
+      }
       default:
       {
          DU_LOG("\nERROR  -->  RLC : rlcStopTmr: Invalid tmr Evnt[%d]", tmrType);
@@ -335,7 +349,11 @@ Void rlcTmrExpiry(PTR cb,S16 tmrEvnt)
          rlcBndTmrExpiry(cb);
          break;
       }
-      /* kw005.201 L2 Measurement support */
+      case EVENT_RLC_THROUGHPUT_TMR:
+      {
+         rlcThptTmrExpiry(cb);
+         break;
+      }
       default:
       {
          break;
@@ -385,6 +403,10 @@ bool rlcChkTmr(RlcCb *gCb, PTR cb, int16_t tmrEvnt)
       {
          return (((RlcRguSapCb *)cb)->bndTmr.tmrEvnt == EVENT_RLC_WAIT_BNDCFM);
       }
+      case EVENT_RLC_THROUGHPUT_TMR:
+      {
+         return (((RlcThpt *)cb)->thptTmr.tmrEvnt == EVENT_RLC_THROUGHPUT_TMR);
+      }
       default:
       {
          DU_LOG("\nERROR  -->  RLC : rlcChkTmr: Invalid tmr Evnt [%d]", tmrEvnt);
@@ -453,6 +475,45 @@ static Void rlcBndTmrExpiry(PTR cb)
    return;
 }
 
+/**
+ * @brief Handler to do processing on expiry of the throughput timer
+ *
+ * @details
+ *    This function processes the RLC throughput timer expiry.
+ *
+ * @param[in] cb  Pointer to the RLC throughput struct
+ *
+ * @return  Void
+ */
+void rlcThptTmrExpiry(PTR cb)
+{
+   uint16_t  ueIdx;
+   long double tpt;
+   RlcThpt *rlcThptCb = (RlcThpt*)cb; 
+
+   /* Print throughput */
+   DU_LOG("\n===================== DL Throughput ==============================");
+   DU_LOG("\nNumber of UEs : %d", rlcThptCb->numActvUe);
+   for(ueIdx = 0; ueIdx < rlcThptCb->numActvUe; ueIdx++)
+   {
+      /* 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;
+      
+      DU_LOG("\nUE Id : %d   DL Tpt : %.2Lf", rlcThptCb->thptPerUe[ueIdx].ueIdx, tpt);
+      rlcThptCb->thptPerUe[ueIdx].dataVol = 0;
+   }
+   DU_LOG("\n==================================================================");
+
+   /* Restart timer */
+   rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)rlcThptCb, EVENT_RLC_THROUGHPUT_TMR);
+
+   return;
+}
 
 \f  
 /********************************************************************30**
index 7a21f27..e47af06 100755 (executable)
@@ -385,6 +385,7 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
 {
    uint8_t           numPdu = 0;
    uint16_t          ueIdx;
+   uint16_t          actvUeIdx;
    RlcDlUeCb         *ueCb;         /* UE control block */
    uint32_t          count;         /* Loop Counter */
    uint32_t          numTb;         /* Number of Tbs */
@@ -432,6 +433,14 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
          /* If ueCb is not found for current rnti then continue to look for next rnti*/
          continue; 
       }
+      
+      /* Find ueIdx for throughput calculation */
+      for(actvUeIdx = 0; actvUeIdx < gCb->rlcThpt.numActvUe; actvUeIdx++)
+      {
+         if(gCb->rlcThpt.thptPerUe[actvUeIdx].ueIdx == ueIdx)
+            break;
+      }
+
       /* kw002.201 Removed the allocation of RlcDatReq */
       /* kw004.201 Used SSI function to initialize the variable */
       memset(&datReq, 0, sizeof(RlcDatReq) ); 
@@ -462,7 +471,9 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
 
             if (rbCb && (!rlcDlUtlIsReestInProgress(rbCb)))
             { 
-//Debug
+               /* Cosider buffer size for throughput calculation */
+               gCb->rlcThpt.thptPerUe[actvUeIdx].dataVol += staIndTb->lchStaInd[count].totBufSize;
+
                staIndSz += staIndTb->lchStaInd[count].totBufSize;
                datReq.pduSz = staIndTb->lchStaInd[count].totBufSize;
 #ifdef LTE_L2_MEAS            
index 3f2badd..e77e9f4 100644 (file)
@@ -699,7 +699,7 @@ uint8_t RlcProcDlUserDataTransfer(Pst *pst, RlcDlUserDataInfo *dlDataMsgInfo)
    if(!datReqInfo)
    {
       DU_LOG("\nERROR  -->  RLC_DL : Memory allocation failed for DatReq in RlcProcDlUserDataTransfer()");
-      RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo->dlMsg, dlDataMsgInfo->msgLen);
+      ODU_PUT_MSG_BUF(dlDataMsgInfo->dlMsg);
       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
       return RFAILED;
    }
index ca7a908..5a52ed3 100644 (file)
@@ -94,6 +94,8 @@
 #define TOTAL_PRB_20MHZ_MU0 106
 #define TOTAL_PRB_100MHZ_MU1 273
 
+#define ODU_THROUGHPUT_PRINT_TIME_INTERVAL  5 /* in milliseconds */
+
 /* Defining macros for common utility functions */
 #define ODU_GET_MSG_BUF SGetMsg
 #define ODU_PUT_MSG_BUF SPutMsg
index a7199c7..bc519f9 100755 (executable)
@@ -49,7 +49,7 @@ typedef struct rlcGenCfg
 /* Supported by SPLIT Architecture */
    uint16_t               maxUdxSaps;    /*!< Maximum Udx SAPs. */
 /* Supported by SPLIT Architecture ends */
-   Ticks             timeRes;       /*!< Time resolution. */
+   Ticks                  timeRes;       /*!< Time resolution. */
 /* Supported by SPLIT Architecture */
    uint8_t                rlcMode;       /*!< RLC_DL or RLC_UL */
 /* Supported by SPLIT Architecture ends */
index 53037ee..4986c68 100644 (file)
@@ -176,7 +176,7 @@ uint8_t duBuildAndSendDlUserDataToRlc(uint16_t msgLen, EgtpMsg *egtpMsg)
    if(ret != ROK)
    {
       DU_LOG("\nERROR  -->  DU_APP : Failed to send User Data to RLC in duHdlEgtpDlData()");
-      DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, dlDataMsgInfo->dlMsg, msgLen);
+      ODU_PUT_MSG_BUF(dlDataMsgInfo->dlMsg);
       DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
    }
    return ret;
@@ -1660,7 +1660,8 @@ uint8_t duBuildAndSendUeCreateReqToMac(uint16_t cellId, uint8_t ueIdx,\
  * ****************************************************************/
 uint8_t duUpdateMacCfg(MacUeCfg *macUeCfg, F1UeContextSetupDb *f1UeDb) 
 {
-   uint8_t ret, lcIdx, dbIdx, numLcs, lcDelIdx;
+   uint8_t ret, lcIdx, dbIdx, numLcs, lcDelIdx, cellIdx;
+   MacUeCfg *oldMacUeCfg;
    ret = ROK;
 
    /*Filling Cell Group Cfg*/
@@ -1678,7 +1679,12 @@ uint8_t duUpdateMacCfg(MacUeCfg *macUeCfg, F1UeContextSetupDb *f1UeDb)
               NULL, &macUeCfg->spCellCfg.servCellCfg.initUlBwp.puschCfg);
       }
       ret = fillAmbr(&macUeCfg->ambrCfg, f1UeDb->duUeCfg.ambrCfg);
+
+      GET_CELL_IDX(macUeCfg->cellId, cellIdx);
+      oldMacUeCfg = &duCb.actvCellLst[cellIdx]->ueCb[macUeCfg->ueIdx-1].macUeCfg;
+      duFillModulationDetails(macUeCfg, oldMacUeCfg, f1UeDb->duUeCfg.ueNrCapability);
    }
+
    /* Filling LC Context */
    for(dbIdx = 0; (dbIdx < f1UeDb->duUeCfg.numMacLcs && ret == ROK); dbIdx++)
    {