<JIRA ID: ODUHIGH-390 : Ul throughput per SNSSAI (KPI)> 84/7084/7
authorbarveankit <anbarve@radisys.com>
Thu, 2 Dec 2021 13:27:55 +0000 (18:57 +0530)
committerbarveankit <anbarve@radisys.com>
Fri, 3 Dec 2021 06:04:05 +0000 (11:34 +0530)
Change-Id: Iadbd185ae80418d5b7fac106c43c69f8eb72740a
Signed-off-by: barveankit <anbarve@radisys.com>
19 files changed:
src/5gnrrlc/rlc_amm_ul.c
src/5gnrrlc/rlc_cfg_dl.c
src/5gnrrlc/rlc_cfg_ul.c
src/5gnrrlc/rlc_layer_mgr.c
src/5gnrrlc/rlc_msg_hdl.c
src/5gnrrlc/rlc_tmr.c
src/5gnrrlc/rlc_umm_ul.c
src/5gnrrlc/rlc_upr_inf_api.c
src/5gnrrlc/rlc_upr_inf_api.h
src/5gnrrlc/rlc_upr_inf_mgr.c
src/5gnrrlc/rlc_utils.h
src/5gnrrlc/rlc_utl_dl.c
src/5gnrsch/sch.h
src/5gnrsch/sch_rach.c
src/cm/common_def.h
src/cm/du_app_rlc_inf.c
src/cm/du_app_rlc_inf.h
src/du_app/du_mgr_msg_router.c
src/du_app/du_msg_hdl.c

index dee5625..d8a053a 100755 (executable)
@@ -494,26 +494,25 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
    RlcSn      mSn;
    uint8_t    fByte;
    bool      discFlg;
-#ifdef LTE_L2_MEAS_RLC
-   MsgLen              rlcSduSz;  /*Holds length of Rlc Sdu*/
-#endif /* LTE_L2_MEAS */
+   RlcTptPerSnssai *snssaiTputNode = NULLP;
+   MsgLen     pduSz = 0;  /*Holds length of Rlc Sdu*/
 
    amUl = &RLC_AMUL;
 
    numPduToProcess = RLC_MIN(pduInfo->numPdu, RGU_MAX_PDU);
    DU_LOG("\nDEBUG  -->  RLC_UL : rlcAmmProcessPdus: numPdu[%d],numPduToProcess[%d] UEID:%d CELLID:%d",
-            numPdu, numPduToProcess, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+         numPdu, numPduToProcess, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
 
    while (numPdu < numPduToProcess)
    {
       discFlg = FALSE;
       pdu = pduInfo->mBuf[numPdu++];
-
+      snssaiTputNode = NULLP;
       if (! pdu)
       {
 
          DU_LOG("\nERROR  -->  RLC_UL : rlcAmmProcessPdus: Null Pdu UEID:%d CELLID:%d",
-            rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+               rbCb->rlcId.ueId, rbCb->rlcId.cellId);
          gCb->genSts.errorPdusRecv++;
          break;
       }
@@ -533,7 +532,7 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
       if (rlcAmmExtractHdr(gCb, rbCb, pdu, &amHdr, &fByte) != ROK)
       {
          DU_LOG("\nERROR  -->  RLC_UL : rlcAmmProcessPdus: Header Extraction Failed UEID:%d CELLID:%d",
-            rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+               rbCb->rlcId.ueId, rbCb->rlcId.cellId);
          ODU_PUT_MSG_BUF(pdu);
          gCb->genSts.errorPdusRecv++;
          continue;
@@ -548,8 +547,8 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
       if((amHdr.si == RLC_SI_LAST_SEG) && (!amHdr.so))
       {
          DU_LOG("\nERROR  -->  RLC_UL : rlcAmmProcessPdus: Dropping PDU because SO can't be zero\
-           for last segment sn:%u UEID:%d CELLID:%d", amHdr.sn, rbCb->rlcId.ueId,
-            rbCb->rlcId.cellId);
+               for last segment sn:%u UEID:%d CELLID:%d", amHdr.sn, rbCb->rlcId.ueId,
+               rbCb->rlcId.cellId);
          ODU_PUT_MSG_BUF(pdu);
          continue;
       }
@@ -558,13 +557,13 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
 #ifndef TENB_ACC
 #ifndef TENB_T2K3K_SPECIFIC_CHANGES
 #ifndef LTE_PAL_ENB
-    /* Changed the condition to TRUE from ROK  */
+      /* Changed the condition to TRUE from ROK  */
       if(isMemThreshReached(rlcCb[0]->init.region) == TRUE)
       {
          uint32_t rlculdrop;
-        rlculdrop++;
-        ODU_PUT_MSG_BUF(pdu);
-        continue;
+         rlculdrop++;
+         ODU_PUT_MSG_BUF(pdu);
+         continue;
       }
 #endif
 #else
@@ -607,6 +606,17 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
          rlcUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt);
 #endif /* LTE_L2_MEAS */
 
+         if(rbCb->snssai)
+         {
+            snssaiTputNode = rlcHandleSnssaiTputlist(gCb, rbCb->snssai, SEARCH, DIR_UL);
+            if(snssaiTputNode != NULLP)
+            {
+               ODU_GET_MSG_LEN(pdu, &pduSz);
+               snssaiTputNode->dataVol += (uint64_t)pduSz;
+               DU_LOG("\nINFO   -->  RLC_UL: SNSSAI AMM_UL List PduLen:%d, lcId:%d, total :%ld",\
+                     pduSz, rbCb->lch.lChId, snssaiTputNode->dataVol);
+            }
+         }
          /* Update rxNextHighestRcvd */
          MODAMR(sn, mSn, amUl->rxNext, amUl->snModMask);
          MODAMR(amUl->rxNextHighestRcvd, mrxNextHighestRcvd, amUl->rxNext, amUl->snModMask);
@@ -615,19 +625,19 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
             amUl->rxNextHighestRcvd = ((sn + 1) & (amUl->snModMask)); 
 
             DU_LOG("\nDEBUG  -->  RLC_UL : rlcAmmProcessPdus: Updated rxNextHighestRcvd = %d UEID:%d CELLID:%d",
-               amUl->rxNextHighestRcvd, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+                  amUl->rxNextHighestRcvd, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
          }
-         
+
          recBuf = rlcUtlGetRecBuf(amUl->recBufLst, sn);
          if ((NULLP != recBuf) && ( recBuf->allRcvd))
          {
             /* deliver the reassembled RLC SDU to upper layer, 
-              But not removed from the table */
+               But not removed from the table */
             rlcAmmUlReassembleSdus(gCb, rbCb, recBuf);
             recBuf->isDelvUpperLayer = TRUE;
 
             MODAMR(amUl->vrMr, tVrMr, amUl->rxNext, amUl->snModMask);
-            
+
             /* Update rxHighestStatus */
             if (sn == amUl->rxHighestStatus)
             {
@@ -666,12 +676,12 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
                while (mSn <= tVrMr)
                {
                   if ((NULLP != recBuf) && (recBuf->allRcvd) &&
-                     (TRUE == recBuf->isDelvUpperLayer))
-                 {
-                    /* RecBuf should remove from table 
-                       since PDU is already sent to upper layer */
-                     recBuf->isDelvUpperLayer = FALSE;
-                      rlcUtlDelRecBuf(amUl->recBufLst, recBuf, gCb);
+                        (TRUE == recBuf->isDelvUpperLayer))
+                  {
+                     /* RecBuf should remove from table 
+                        since PDU is already sent to upper layer */
+                     recBuf->isDelvUpperLayer = FALSE;
+                     rlcUtlDelRecBuf(amUl->recBufLst, recBuf, gCb);
                   }
                   else
                   {
@@ -693,13 +703,13 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
             Bool snInWin = RLC_AM_CHK_SN_WITHIN_RECV_WINDOW(amUl->rxNextStatusTrig, amUl);
             /* spec 38.322v15.3.0 - 5.2.3.2.3 */
             if((amUl->rxNextStatusTrig == amUl->rxNext) || ( (!snInWin) &&
-                                             (amUl->rxNextStatusTrig != amUl->vrMr) )||
-              (amUl->rxNextStatusTrig == amUl->rxNext && recBuf &&recBuf->noMissingSeg))
+                     (amUl->rxNextStatusTrig != amUl->vrMr) )||
+                  (amUl->rxNextStatusTrig == amUl->rxNext && recBuf &&recBuf->noMissingSeg))
             {
                rlcStopTmr(gCb,(PTR)rbCb, EVENT_RLC_AMUL_REASSEMBLE_TMR);
                tmrRunning = FALSE;
                DU_LOG("\nINFO  --> RLC_UL: rlcAmmProcessPdus: Stopped ReAssembly Timer rxNextStatusTigger = %d"
-                "rxNextReassembly = %d", amUl->rxNextStatusTrig, amUl->rxNext);
+                     "rxNextReassembly = %d", amUl->rxNextStatusTrig, amUl->rxNext);
             }
          }
 
@@ -707,14 +717,14 @@ void rlcAmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
          {
             /* spec 38.322v15.3.0 - 5.2.3.2.3 */
             if((amUl->rxNextHighestRcvd > amUl->rxNext) || ((amUl->rxNextHighestRcvd == amUl->rxNext) &&
-              (recBuf && (!recBuf->noMissingSeg))))
+                     (recBuf && (!recBuf->noMissingSeg))))
             {
                rlcStartTmr(gCb,(PTR)rbCb, EVENT_RLC_AMUL_REASSEMBLE_TMR);
                amUl->rxNextStatusTrig = amUl->rxNextHighestRcvd;
 
                DU_LOG("\nDEBUG  -->  RLC_UL : rlcAmmProcessPdus: Updated rxNextStatusTrig = %d" 
-                 "UEID:%d CELLID:%d", amUl->rxNextStatusTrig, rbCb->rlcId.ueId,
-                  rbCb->rlcId.cellId);
+                     "UEID:%d CELLID:%d", amUl->rxNextStatusTrig, rbCb->rlcId.ueId,
+                     rbCb->rlcId.cellId);
             }
          }
       }
index 878c2e4..a42e44d 100755 (executable)
@@ -412,7 +412,7 @@ static S16 rlcCfgFillDlRbCb(RlcCb *gCb,RlcDlRbCb *rbCb,RlcDlUeCb *ueCb,RlcEntCfg
       memcpy(rbCb->snssai, entCfg->snssai, sizeof(Snssai));
 
       /*Create the entry of this SNSSAI if not exist in Snssai Tput list*/
-      if(rlcHandleSnssaiTputlist(gCb, rbCb->snssai, CREATE) == NULLP)
+      if(rlcHandleSnssaiTputlist(gCb, rbCb->snssai, CREATE, DIR_DL) == NULLP)
       {
          DU_LOG("\nERROR  --> RLC_DL : rlcCfgFillDlRbCb(): SNSSAI insertion in Tput list failed");
       }
index 2da5c58..bfd0c77 100755 (executable)
@@ -388,6 +388,12 @@ static S16 rlcCfgFillUlRbCb(RlcCb *gCb,RlcUlRbCb *rbCb,RlcUlUeCb *ueCb,RlcEntCfg
          }
       }
       memcpy(rbCb->snssai, entCfg->snssai, sizeof(Snssai));
+
+      /*Create the entry of this SNSSAI if not exist in Snssai Tput list*/
+      if(rlcHandleSnssaiTputlist(gCb, rbCb->snssai, CREATE, DIR_UL) == NULLP)
+      {
+         DU_LOG("\nERROR  --> RLC_UL : rlcCfgFillUlRbCb(): SNSSAI insertion in Tput list failed");
+      }
    }
    rbCb->mode = entCfg->entMode;
    
index 03458f1..eb36b21 100755 (executable)
@@ -401,13 +401,13 @@ static S16 rlcLmmGenCfg(RlcCb  *gCb,RlcGenCfg *cfg)
          DU_LOG("\nINFO   --> RLC_DL : Starting UE Throughput timer");
          rlcStartTmr(gCb, (PTR)(&gCb->rlcThpt), EVENT_RLC_UE_THROUGHPUT_TMR);
       }
+   }
       /* Starting timer to print throughput */
       if((rlcChkTmr(gCb, (PTR)(&gCb->rlcThpt), EVENT_RLC_SNSSAI_THROUGHPUT_TMR)) == FALSE)
       {
          DU_LOG("\nINFO   --> RLC_DL : Starting SNSSAI Throughput timer");
          rlcStartTmr(gCb, (PTR)(&gCb->rlcThpt), EVENT_RLC_SNSSAI_THROUGHPUT_TMR);
       }
-   }
 
    
    return (LCM_REASON_NOT_APPL);
@@ -1615,17 +1615,18 @@ static S16 rlcLmmShutdown(RlcCb *gCb)
          }
       }
    }
-   
+
    if(gCb->genCfg.rlcMode == LKW_RLC_MODE_DL)
    {
       rlcDbmDlShutdown(gCb); 
+      rlcDelTputSnssaiList(gCb, DIR_DL);
    }
    else
    {
       rlcDbmUlShutdown(gCb);
+      rlcDelTputSnssaiList(gCb, DIR_UL);
    }
 
-   rlcDelTputSnssaiList(gCb);
    rlcLmmCleanGblRsrcs(gCb);
 
    RLC_MEM_SET (&(gCb->genSts), 0, sizeof (RlcGenSts));
index 90cfcd2..0495a44 100644 (file)
@@ -912,6 +912,170 @@ uint8_t RlcProcUeDeleteReq(Pst *pst, RlcUeDelete *ueDelete)
    return ret;
 }
 
+/*******************************************************************
+*
+* @brief Send the Slice Metrics to  DU APP
+*
+* @details
+*
+*    Function : sendSlicePmToDu
+*
+*    Functionality:
+*      Handles the sending of Slice Metrics to  DU APP
+*
+* @params[in] Post structure pointer
+*             SlicePmList *sliceStats pointer
+*
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+uint8_t sendSlicePmToDu(SlicePmList *sliceStats)
+{
+   Pst pst;  
+   
+   FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_SLICE_PM_TO_DU);
+
+   if(!sliceStats)
+   {
+      DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu(): Memory allocation failed ");
+      return RFAILED;
+   }
+   else
+   {
+      if(rlcSendSlicePmToDu(&pst, sliceStats) == ROK)
+      {
+         DU_LOG("\nDEBUG  -->  RLC: Slice PM send successfully");
+      }
+      else
+      {
+         DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu():Failed to send Slice PM to DU");
+         RLC_FREE_SHRABL_BUF(pst.region, pst.pool, sliceStats, sizeof(SlicePmList));
+         return RFAILED;
+      }
+   }
+   return ROK;
+}
+
+/**
+ * @brief 
+ *    Handler for searching the Slice Entry in Slice Metrics structure
+ *
+ * @details
+ *    This func finds the slice entry in the SliceMetric record structure and
+ *    return the index of the slice sot hat Tput entries can be done
+ *
+ * @param[in] snssaiVal : Snssai Val to be searched
+ *            *snssaiIdx : O/P : Index of the Slice in Slice Metrics record
+ *            sliceStats : Pointer of Slice metrics record list
+ *
+ * @return bool: True: If slice found in the record
+ *               False: If Slice not found; thus parent function will create the
+ *               recpord of this snssai
+ *   
+ */
+bool rlcFindSliceEntry(uint32_t snssaiVal, uint8_t *snssaiIdx, SlicePmList *sliceStats)
+{
+   uint8_t cntSlices = sliceStats->numSlice;
+
+   for(*snssaiIdx = 0;(*snssaiIdx) < cntSlices; (*snssaiIdx)++)
+   {
+      if(snssaiVal == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier)
+      {
+         return TRUE;
+      }
+   }
+   DU_LOG("\nERROR  -->  RLC: Total no of Slice exhausted!");
+   return FALSE;
+}
+
+
+/*******************************************************************
+*
+* @brief Builds the Slice Performance Metrics structure to be sent to DU
+*
+* @details
+*
+*    Function : BuildSliceReportToDu
+*
+*    Functionality:
+*      Builds the Slice Performance Metrics structure to be sent to DU
+*
+* @params[in] uint8_t snssaiCnt
+*             
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+uint8_t BuildSliceReportToDu(uint8_t snssaiCnt)
+{
+   CmLList  *node = NULLP;
+   RlcTptPerSnssai *snssaiNode = NULLP;
+   Direction dir = DIR_UL;
+   SlicePmList *sliceStats = NULLP;   /*Slice metric */
+   uint32_t snssaiVal = 0;
+   uint8_t snssaiIdx = 0;
+
+   if(snssaiCnt == 0)
+   {
+      DU_LOG("\nERROR  -->  RLC: No SNSSAI to send the SLice PM");
+      return RFAILED;
+   }
+
+   RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
+   if(sliceStats == NULLP)
+   {
+      DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
+      return RFAILED;
+   }
+   RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, snssaiCnt * (sizeof(SlicePm)));
+
+   if(sliceStats->sliceRecord == NULLP)
+   {
+      DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
+      RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
+      return RFAILED;
+   }
+   while(dir < DIR_BOTH)
+   {
+      node = arrTputPerSnssai[dir]->first;
+      if(node == NULLP)
+      {
+         DU_LOG("\nERROR  -->  RLC: No SNSSAI in list");
+         RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
+         RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, (snssaiCnt * (sizeof(SlicePm))));
+         return RFAILED;
+      }
+
+      while(node)
+      {
+         snssaiVal = 0;
+         snssaiIdx = 0;
+         snssaiNode = (RlcTptPerSnssai *)node->node;
+
+         memcpy(&snssaiVal, snssaiNode->snssai, sizeof(Snssai));
+
+         if(rlcFindSliceEntry(snssaiVal, &snssaiIdx, sliceStats) == FALSE)
+         {
+            sliceStats->sliceRecord[snssaiIdx].networkSliceIdentifier = snssaiVal;
+            sliceStats->numSlice++;
+         }
+         if(dir == DIR_UL)
+         {
+            sliceStats->sliceRecord[snssaiIdx].ThpUl = snssaiNode->tpt;
+         }
+         else
+         {
+            sliceStats->sliceRecord[snssaiIdx].ThpDl = snssaiNode->tpt;
+         }
+         node = node->next;
+      }
+      dir++;
+   }
+
+   sendSlicePmToDu(sliceStats);
+   return ROK;
+}
 /**********************************************************************
          End of file
 **********************************************************************/
index 0e1f789..fc8ae66 100755 (executable)
@@ -85,6 +85,7 @@
 /* private function declarations */
 static Void rlcBndTmrExpiry(PTR cb);
 
+
 /**
  * @brief Handler to start timer
  *       
@@ -585,9 +586,12 @@ void rlcUeThptTmrExpiry(PTR cb)
  */
 void rlcSnssaiThptTmrExpiry(PTR cb)
 {
-   long double tpt;
    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)
    {
@@ -595,14 +599,24 @@ void rlcSnssaiThptTmrExpiry(PTR cb)
       rlcStartTmr(RLC_GET_RLCCB(rlcThptCb->inst), (PTR)(rlcThptCb), EVENT_RLC_SNSSAI_THROUGHPUT_TMR);
       return;
    }
-
-   DU_LOG("\n==================================================================");
-   if(rlcThptCb->snssaiTputInfo.tputPerSnssaiList != NULLP)
+   
+   if(rlcThptCb->snssaiTputInfo.dlTputPerSnssaiList != NULLP)
    {
-      DU_LOG("\n===================== DL Throughput Per SNSSAI ==============================");
-  
-      rlcCalculateTputPerSnssai(rlcThptCb->snssaiTputInfo.tputPerSnssaiList);
-      DU_LOG("\n==================================================================");
+      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);
index 06119f1..4495f61 100755 (executable)
@@ -507,12 +507,13 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
    RlcSn         tRxNextReassembly;
    RlcSn         tRxNextReassemblyNxt;
    RlcSn         tRxNextHighest;
+   RlcTptPerSnssai *snssaiTputNode = NULLP;
 
    count = 0;
 
    /* pduCount should be the min of RGU_MAX_PDU and pduInfo->numPdu */
    pduCount = (pduInfo->numPdu < RGU_MAX_PDU)? pduInfo->numPdu : RGU_MAX_PDU;
-   
+
    vrUh   = &(rbCb->m.umUl.vrUh);
    vrUr   = &(rbCb->m.umUl.vrUr);
    vrUx   = &(rbCb->m.umUl.vrUx);
@@ -523,6 +524,9 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
       RlcSn   seqNum;
       Buffer  *pdu = pduInfo->mBuf[count];
 
+      pduSz = 0;  /*re-intialize the size*/
+      snssaiTputNode = NULLP;
+
       gCb->genSts.pdusRecv++;
 #ifndef RGL_SPECIFIC_CHANGES
 #ifndef TENB_ACC
@@ -538,16 +542,16 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
 #ifndef RGL_SPECIFIC_CHANGES
 #ifndef TENB_ACC
 #ifndef LTE_PAL_ENB
-    /* Changed the condition to TRUE from ROK  */
+      /* Changed the condition to TRUE from ROK  */
 #ifndef XEON_SPECIFIC_CHANGES    
-     if(isMemThreshReached(rlcCb[0]->init.region) == TRUE)
-     {
-        uint32_t rlculdrop;
-        rlculdrop++;
-        ODU_PUT_MSG_BUF(pdu);
-        count++;
-        continue;
-     }
+      if(isMemThreshReached(rlcCb[0]->init.region) == TRUE)
+      {
+         uint32_t rlculdrop;
+         rlculdrop++;
+         ODU_PUT_MSG_BUF(pdu);
+         count++;
+         continue;
+      }
 #endif     
 #endif
 #endif
@@ -556,20 +560,32 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
       if (rlcUmmExtractHdr(gCb, rbCb, pdu, &umHdr))  
       {
          DU_LOG("\nERROR  --> RLC_UL: rlcUmmProcessPdus: Header Extraction Failed UEID:%d CELLID:%d",\
-             rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+               rbCb->rlcId.ueId, rbCb->rlcId.cellId);
          ODU_PUT_MSG_BUF(pdu);
          count++;
          gCb->genSts.errorPdusRecv++;
          continue;
       }
 
+      if(rbCb->snssai)
+      {
+         snssaiTputNode = rlcHandleSnssaiTputlist(gCb, rbCb->snssai, SEARCH, DIR_UL);
+         if(snssaiTputNode != NULLP)
+         {
+            ODU_GET_MSG_LEN(pdu, &pduSz);
+            snssaiTputNode->dataVol += (uint64_t)pduSz;
+            DU_LOG("\nINFO  -->  RLC_UL: UMM_UL SNSSAI List PduLen:%d, lcId:%d, total :%ld",\
+                  pduSz, rbCb->lch.lChId, snssaiTputNode->dataVol);
+         }
+      }
+
       /* Check if the PDU should be delivered to upper layer */
       if(umHdr.si == 0)
       {
          rlcUtlSendUlDataToDu(gCb, rbCb, pdu);
-        ODU_PUT_MSG_BUF(pdu);
-        count++;
-        continue;
+         ODU_PUT_MSG_BUF(pdu);
+         count++;
+         continue;
       }
 
       curSn = umHdr.sn;
@@ -582,7 +598,7 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
       {
          /* PDU needs to be discarded */
          DU_LOG("\nINFO  -->  RLC_UL: rlcUmmProcessPdus: Received an unexpected pdu with sn %d \
-           UEID:%d CELLID:%d", curSn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+               UEID:%d CELLID:%d", curSn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
 
          ODU_PUT_MSG_BUF(pdu);
          count++;
@@ -602,9 +618,9 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
          if (recBuf == NULLP)
          {
             DU_LOG("\nERROR  -->  RLC_UL: rlcUmmProcessPdus: recBuf is NULLP UEID:%d CELLID:%d", \
-               rbCb->rlcId.ueId, rbCb->rlcId.cellId);
-           ODU_PUT_MSG_BUF(pdu);
-           count++;
+                  rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+            ODU_PUT_MSG_BUF(pdu);
+            count++;
             continue;
          }
 
@@ -613,7 +629,7 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
          {
             rlcUmmReAssembleSdus(gCb, rbCb, recBuf);
             DU_LOG("\nDEBUG  -->  RLC_UL: rlcUmmProcessPdus: Assembled the Sdus for  sn = %d UEID:%d CELLID:%d",\
-               umHdr.sn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+                  umHdr.sn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
 
             /* if curSn is same as the RX_NEXT_Reassembly */
             if (seqNum == ur)
@@ -627,9 +643,9 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
          else if (!rlcUmmCheckSnInReassemblyWindow(curSn,&RLC_UMUL))
          {  
             DU_LOG("\nDEBUG  -->  RLC_UL: rlcUmmProcessPdus: curent sn is outSide the re-Assembly window. \
-               sn = %d UEID:%d CELLID:%d", umHdr.sn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+                  sn = %d UEID:%d CELLID:%d", umHdr.sn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
 
-           /* update RX_NEXT_Highest */
+            /* update RX_NEXT_Highest */
             *vrUh  = (curSn + 1) & RLC_UMUL.modBitMask;
 
             /* Discard all pdus outside the modified re-assembly window */
@@ -640,10 +656,10 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
                RlcSn packetCount;
 
                /* Set RX_NEXT_Reassembly to next SN >= (RX_NEXT_Highest - windowSize) that has not been reassembled yet */
-              *vrUr = (*vrUh - RLC_UMUL.umWinSz) &  RLC_UMUL.modBitMask;
-              lowerEdge = *vrUr;
+               *vrUr = (*vrUh - RLC_UMUL.umWinSz) &  RLC_UMUL.modBitMask;
+               lowerEdge = *vrUr;
                packetCount = (lowerEdge - sn) & RLC_UMUL.modBitMask;
-            
+
                while (packetCount)
                {
                   recBuf = rlcUtlGetUmRecBuf(RLC_UMUL.recBufLst, sn);
@@ -655,57 +671,57 @@ void rlcUmmProcessPdus(RlcCb *gCb, RlcUlRbCb *rbCb, KwPduInfo *pduInfo)
                   sn = (sn + 1) & RLC_UMUL.modBitMask;
                   packetCount--;
                }
-              recBuf = rlcUtlGetUmRecBuf(RLC_UMUL.recBufLst, *vrUr);
-              if (recBuf != NULLP && recBuf->allSegRcvd)
-              {
-                 /* set rxNextReassembly to next SN > current rxNextReassembly which is not received */
-                 RlcSn nextRxNextReassembly = (*vrUr + 1) & RLC_UMUL.modBitMask;
-                 rlcUmmFindRxNextReassembly(gCb ,&RLC_UMUL, nextRxNextReassembly);
-              }
+               recBuf = rlcUtlGetUmRecBuf(RLC_UMUL.recBufLst, *vrUr);
+               if (recBuf != NULLP && recBuf->allSegRcvd)
+               {
+                  /* set rxNextReassembly to next SN > current rxNextReassembly which is not received */
+                  RlcSn nextRxNextReassembly = (*vrUr + 1) & RLC_UMUL.modBitMask;
+                  rlcUmmFindRxNextReassembly(gCb ,&RLC_UMUL, nextRxNextReassembly);
+               }
             }
          }
 
-        tmrRunning = rlcChkTmr(gCb,(PTR)rbCb, EVENT_RLC_UMUL_REASSEMBLE_TMR);
+         tmrRunning = rlcChkTmr(gCb,(PTR)rbCb, EVENT_RLC_UMUL_REASSEMBLE_TMR);
          tRxNextReassembly = RLC_UM_GET_VALUE(*vrUr ,RLC_UMUL);
          tRxNextReassemblyNxt = (*vrUr + 1) & rbCb->m.umUl.modBitMask;
          tRxNextHighest = RLC_UM_GET_VALUE(*vrUh, RLC_UMUL);
          tRxNextReassemblyNxt = RLC_UM_GET_VALUE(tRxNextReassemblyNxt ,RLC_UMUL);
 
-        /* If reassemby timer is running */
-        if (tmrRunning) 
-        {
-           RlcSn  tRxTimerTigger = RLC_UM_GET_VALUE(*vrUx, RLC_UMUL);
-           uint8_t ret = rlcUmmCheckSnInReassemblyWindow(*vrUx, &RLC_UMUL);
-           recBuf = rlcUtlGetUmRecBuf(RLC_UMUL.recBufLst,*vrUr);
+         /* If reassemby timer is running */
+         if (tmrRunning) 
+         {
+            RlcSn  tRxTimerTigger = RLC_UM_GET_VALUE(*vrUx, RLC_UMUL);
+            uint8_t ret = rlcUmmCheckSnInReassemblyWindow(*vrUx, &RLC_UMUL);
+            recBuf = rlcUtlGetUmRecBuf(RLC_UMUL.recBufLst,*vrUr);
 
             if ((tRxTimerTigger <= tRxNextReassembly) || ((!ret) && (tRxTimerTigger != tRxNextHighest)) ||
-                (tRxNextHighest ==  tRxNextReassemblyNxt && recBuf && recBuf->noMissingSeg))
+                  (tRxNextHighest ==  tRxNextReassemblyNxt && recBuf && recBuf->noMissingSeg))
             {
                rlcStopTmr(gCb,(PTR)rbCb, EVENT_RLC_UMUL_REASSEMBLE_TMR);             
                tmrRunning = FALSE;
                DU_LOG("\nINFO  --> RLC_UL: rlcUmmProcessPdus: Stopped ReAssembly Timer rxTimerTigger = %d \
-                  rxNextReassembly = %d rxNextHighest = %d ", tRxTimerTigger, tRxNextReassembly, tRxNextHighest);
+                     rxNextReassembly = %d rxNextHighest = %d ", tRxTimerTigger, tRxNextReassembly, tRxNextHighest);
             }
-        }
+         }
 
-        /* If Reassembly timer is not running */
-        if (!tmrRunning)
-        {
+         /* If Reassembly timer is not running */
+         if (!tmrRunning)
+         {
             recBuf = rlcUtlGetUmRecBuf(RLC_UMUL.recBufLst, curSn);
             if ((tRxNextHighest > tRxNextReassemblyNxt) || ((tRxNextHighest == tRxNextReassemblyNxt)
-                 && (recBuf && (!recBuf->noMissingSeg))))
+                     && (recBuf && (!recBuf->noMissingSeg))))
             {
-                DU_LOG("\nDEBUG  -->  RLC_UL: rlcUmmProcessPdus: Start ReAssembly Timer tRxNextReassemblyNxt = %d \
-                   tRxNextHighest %d", tRxNextReassemblyNxt, tRxNextHighest);
-                rlcStartTmr(gCb, (PTR)rbCb, EVENT_RLC_UMUL_REASSEMBLE_TMR); 
-                *vrUx = *vrUh;
+               DU_LOG("\nDEBUG  -->  RLC_UL: rlcUmmProcessPdus: Start ReAssembly Timer tRxNextReassemblyNxt = %d \
+                     tRxNextHighest %d", tRxNextReassemblyNxt, tRxNextHighest);
+               rlcStartTmr(gCb, (PTR)rbCb, EVENT_RLC_UMUL_REASSEMBLE_TMR); 
+               *vrUx = *vrUh;
             }
-        }
+         }
       }
       else
       {
          DU_LOG("\nERROR  -->  RLC_UL: rlcUmmProcessPdus:Failed to assemble the PDU for SN  = %d UEID:%d CELLID:%d",\
-            umHdr.sn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
+               umHdr.sn, rbCb->rlcId.ueId, rbCb->rlcId.cellId);
 
       }
       count++;
index 32ddf36..547f741 100644 (file)
@@ -56,6 +56,12 @@ RlcDuUeDeleteRsp rlcUeDeleteRspOpts[] =
    packRlcDuUeDeleteRsp     /* 2 - LWLC loosely coupled */
 };
 
+RlcSlicePmToDuFunc rlcSlicePmOpts[] =
+{
+   packRlcDuSlicePm,          /* 0 - loosely coupled */
+   DuProcRlcSliceMetrics,     /* 1 - tightly coupled */
+   packRlcDuSlicePm           /* 2 - LWLC loosely coupled */
+};
 /*******************************************************************
  *
  * @brief Sends UL RRC Message Info to DU APP
@@ -160,6 +166,26 @@ uint8_t rlcSendUeDeleteRspToDu(Pst *pst, RlcUeDeleteRsp *ueDeleteRsp)
     return (*rlcUeDeleteRspOpts[pst->selector])(pst, ueDeleteRsp);
 }
 
+/*******************************************************************
+ *
+ * @brief Sends Slice Performance Metrics to DU APP
+ *
+ * @details
+ *
+ *    Function : rlcSendSlicePmToDu 
+ *
+ *    Functionality:  Sends Performace Metrics per slice together to DU APP
+ *
+ * @params[in] Pst *pst, SlicePmList *sliceStats 
+ *             
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t rlcSendSlicePmToDu(Pst *pst, SlicePmList *sliceStats)
+{
+    return (*rlcSlicePmOpts[pst->selector])(pst, sliceStats);
+}
 /**********************************************************************
          End of file
 **********************************************************************/
index 1f9ee1b..4647da3 100644 (file)
@@ -21,6 +21,7 @@ uint8_t rlcSendRrcDeliveryReportToDu(Pst *pst, RrcDeliveryReport *rrcDelivery);
 uint8_t rlcSendDlRrcMsgRspToDu(Pst *pst, RlcDlRrcMsgRsp *dlRrcMsgRsp);
 uint8_t rlcSendUlUserDataToDu(Pst *pst, RlcUlUserDatInfo *ulUserData);
 uint8_t rlcSendUeDeleteRspToDu(Pst *pst, RlcUeDeleteRsp *ueDeleteRsp);
+uint8_t rlcSendSlicePmToDu(Pst *pst, SlicePmList *sliceStats);
 /**********************************************************************
          End of file
 **********************************************************************/
index fba7a56..6c4d0f2 100755 (executable)
@@ -832,29 +832,60 @@ KwuDiscSduInfo   *discSdu
  *    -# Snssai Node
  *   
  */
-RlcTptPerSnssai* rlcHandleSnssaiTputlist(RlcCb *gCb, Snssai *snssai, RlcSnssaiActionType action)
+RlcTptPerSnssai* rlcHandleSnssaiTputlist(RlcCb *gCb, Snssai *snssai, RlcSnssaiActionType action, Direction dir)
 {
    CmLListCp *snssaiList = NULLP;
    CmLList  *node = NULLP;
    RlcTptPerSnssai *snssaiNode = NULLP;
    bool found = FALSE;
 
-   snssaiList = gCb->rlcThpt.snssaiTputInfo.tputPerSnssaiList;
-   if(snssaiList == NULLP)
+   if(dir == DIR_DL)
+   {
+      snssaiList = gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList;
+      if(action == CREATE)
+      {
+         if(snssaiList == NULLP)
+         {
+            RLC_ALLOC(gCb, gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList, sizeof(CmLListCp));
+            snssaiList = gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList;
+            cmLListInit(snssaiList);
+         }
+      }
+      else
+      {
+         if(snssaiList == NULLP)
+         {
+            DU_LOG("\nERROR --> RLC: SNSSAI DL list doesnt exist!");
+            return NULLP;
+         }
+      }
+   }
+   else if(dir == DIR_UL)
    {
+      snssaiList = gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList;
       if(action == CREATE)
       {
-         RLC_ALLOC(gCb, gCb->rlcThpt.snssaiTputInfo.tputPerSnssaiList, sizeof(CmLListCp));
-         snssaiList =  gCb->rlcThpt.snssaiTputInfo.tputPerSnssaiList;
-         cmLListInit(snssaiList);
-         DU_LOG("\nINFO  --> RLC: First SNSSAI to add in this List");
+         if(snssaiList == NULLP)
+         {
+            RLC_ALLOC(gCb, gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList, sizeof(CmLListCp));
+            snssaiList = gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList;
+            cmLListInit(snssaiList);
+         }
       }
       else
       {
-         DU_LOG("\nERROR --> RLC: SNSSAI list doesnt exist!");
-         return NULLP;
+         if(snssaiList == NULLP)
+         {
+            DU_LOG("\nERROR --> RLC: SNSSAI UL list doesnt exist!");
+            return NULLP;
+         }
       }
    }
+   else
+   {
+      DU_LOG("\nERROR  -->  RLC : Direction:%d is invalid", dir);
+      return NULLP;
+   }
 
    node = snssaiList->first;
 
@@ -958,20 +989,31 @@ RlcTptPerSnssai* rlcHandleSnssaiTputlist(RlcCb *gCb, Snssai *snssai, RlcSnssaiAc
  *
  * @param[in] gCb            RlcCb 
  *
- * @return void 
+ * @return uint_8 (ROK/RFAILED)
  *   
  */
-void rlcDelTputSnssaiList(RlcCb *gCb)
+uint8_t rlcDelTputSnssaiList(RlcCb *gCb, Direction dir)
 {
    CmLListCp *snssaiList = NULLP;
    CmLList  *node = NULLP, *next = NULLP;
    RlcTptPerSnssai *snssaiNode = NULLP;
-
-   snssaiList = gCb->rlcThpt.snssaiTputInfo.tputPerSnssaiList;
+   if(dir == DIR_DL)
+   {
+      snssaiList = gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList;
+   }
+   else if(dir == DIR_UL)
+   {
+      snssaiList = gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList;
+   }
+   else
+   {
+      DU_LOG("\nERROR  -->  RLC: Invalid direction:%d",dir);
+      return RFAILED;
+   }
    if(snssaiList == NULLP)
    {
-      DU_LOG("\nERROR --> RLC: SnssaiList not exist");
-      return;
+      DU_LOG("\nERROR -->  RLC: SnssaiList not exist");
+      return RFAILED;
    }
    node = snssaiList->first;
 
@@ -988,8 +1030,9 @@ void rlcDelTputSnssaiList(RlcCb *gCb)
    if(snssaiList->count == 0)
    {
       RLC_FREE(gCb, snssaiList, sizeof(CmLListCp));
-      DU_LOG("\nINFO   --> RLC : This SNSSAI was last in the list thus freeing the list also");
+      DU_LOG("\nDEBUG   -->  RLC : This SNSSAI was last in the list thus freeing the list also");
    }
+   return ROK;
 }
 
 /**
@@ -1005,30 +1048,42 @@ void rlcDelTputSnssaiList(RlcCb *gCb)
  * @return void 
  *   
  */
-void rlcCalculateTputPerSnssai(CmLListCp *snssaiList)
+uint8_t rlcCalculateTputPerSnssai(CmLListCp *snssaiList, Direction dir)
 {
    CmLList  *node = NULLP;
    RlcTptPerSnssai *snssaiNode = NULLP;
-   double long tpt = 0;
+   uint8_t snssaiCnt = 0;
 
    node = snssaiList->first;
    if(node == NULLP)
    {
       DU_LOG("\n No SNSSAI in list");
-      return;
+      return(snssaiCnt);
    }
    /*Traversing the LC LinkList*/
    while(node)
    {
       snssaiNode = (RlcTptPerSnssai *)node->node;
-      tpt =  (double)(snssaiNode->dataVol * 8)/(double)ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL;
-      DU_LOG("\nSNSSAI(sst:%d,sd [%d,%d, %d]), DL Tpt : %.2Lf", snssaiNode->snssai->sst, snssaiNode->snssai->sd[0], \
-            snssaiNode->snssai->sd[1],snssaiNode->snssai->sd[2] , tpt);
+      snssaiNode->tpt =  (double)(snssaiNode->dataVol * 8)/(double)(ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL * 0.001);
+     
+      if(dir == DIR_DL)
+      {
+         DU_LOG("\nDEBUG  -->  RLC_DL: SNSSAI(sst:%d,sd [%d,%d, %d]), DL Tpt : %.5lf", snssaiNode->snssai->sst,\
+               snssaiNode->snssai->sd[0], snssaiNode->snssai->sd[1],snssaiNode->snssai->sd[2] , snssaiNode->tpt);
+      }
+      if(dir == DIR_UL)
+      {
+         DU_LOG("\nDEBUG  -->  RLC_UL: SNSSAI(sst:%d,sd [%d,%d, %d]), UL Tpt : %.5lf", snssaiNode->snssai->sst,\
+               snssaiNode->snssai->sd[0], snssaiNode->snssai->sd[1],snssaiNode->snssai->sd[2] , snssaiNode->tpt);
+      }
+
       snssaiNode->dataVol = 0;
       node = node->next;
+      snssaiCnt++;
    }
-   return;
+   return(snssaiCnt);
 }
+
 /********************************************************************30**
          End of file
 **********************************************************************/
index 092dcd6..2bb5fba 100755 (executable)
@@ -39,6 +39,7 @@ extern "C" {
 #endif /* __cplusplus */
 
 #include "du_log.h"
+#include "du_app_rlc_inf.h"
 \f 
 
 #define EKWxxx 1
@@ -1725,13 +1726,15 @@ typedef struct rlcTptPerSnssai
 {
    Snssai   *snssai;
    uint64_t dataVol;
+   double   tpt;
 }RlcTptPerSnssai;
 
 
 typedef struct rlcSnssaiTputInfo
 {
    CmTimer       snssaiThptTmr;                   /* Throughput Timer */
-   CmLListCp     *tputPerSnssaiList; 
+   CmLListCp     *dlTputPerSnssaiList; 
+   CmLListCp     *ulTputPerSnssaiList;
 }RlcSnssaiTputInfo;
 
 typedef struct rlcUeTputInfo
@@ -1786,6 +1789,7 @@ typedef struct rlcCb
 
 RlcCb *rlcCb[MAX_RLC_INSTANCES];   /*!< RLC global control block */
 
+CmLListCp *arrTputPerSnssai[DIR_BOTH]; /*Stores the address of Througput LL*/
 /****************************************************************************
  *                      Declarations
  ***************************************************************************/
@@ -1807,9 +1811,12 @@ uint8_t  rlcUeDeleteTmrExpiry(PTR cb);
 
 void rlcSnssaiThptTmrExpiry(PTR cb);
 RlcTptPerSnssai* rlcHandleSnssaiTputlist(RlcCb *gCb, Snssai *snssai,\
-                                  RlcSnssaiActionType action);
-void rlcCalculateTputPerSnssai(CmLListCp *snssaiList);
-void rlcDelTputSnssaiList(RlcCb *gCb);
+                                  RlcSnssaiActionType action, Direction dir);
+uint8_t rlcCalculateTputPerSnssai(CmLListCp *snssaiList, Direction dir);
+uint8_t rlcDelTputSnssaiList(RlcCb *gCb, Direction dir);
+uint8_t BuildSliceReportToDu(uint8_t snssaiCnt);
+bool rlcFindSliceEntry(uint32_t snssaiVal, uint8_t *snssaiIdx,\
+                      SlicePmList *sliceStats);
 
 #ifdef LTE_L2_MEAS
 Void rlcLmmSendAlarm ARGS (( RlcCb *gCb,
index 356e44a..444879f 100755 (executable)
@@ -511,11 +511,11 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo)
 
                if(rbCb->snssai)
                {
-                  snssaiTputNode = rlcHandleSnssaiTputlist(gCb, rbCb->snssai, SEARCH);
+                  snssaiTputNode = rlcHandleSnssaiTputlist(gCb, rbCb->snssai, SEARCH, DIR_DL);
                   if(snssaiTputNode != NULLP)
                   {
                      snssaiTputNode->dataVol += staIndTb->lchStaInd[count].totBufSize;
-                     DU_LOG("\nINFO   -->SCH: SNSSAI List Grant:%d, lcId:%d, total :%d",\
+                     DU_LOG("\nINFO   -->SCH: SNSSAI List Grant:%d, lcId:%d, total :%ld",\
                            staIndTb->lchStaInd[count].totBufSize, staIndTb->lchStaInd[count].lcId,\
                            snssaiTputNode->dataVol);
                   }
index 965a7f3..1b262b3 100644 (file)
@@ -97,12 +97,6 @@ typedef enum
    DELETE
 }ActionTypeLcLL;
 
-typedef enum
-{
-   DIR_UL,
-   DIR_DL
-}Direction;
-
 /**
  * @brief
  * Structure holding LTE MAC's General Configuration information.
index becb131..2e0527c 100644 (file)
@@ -151,7 +151,7 @@ void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotTimingInfo
    if(cell == NULLP)
    {
       DU_LOG("\nERROR  --> SCH : schPrachResAlloc(): Received cellCb is null");
-      return RFAILED;
+      return;
    }
 
    /* If this slot is not a PRACH occassion, return */
index 129d91b..1220b2e 100644 (file)
@@ -254,6 +254,15 @@ typedef enum
    CELL_DOWN
 }OduCellStatus;
 
+
+typedef enum
+{
+   DIR_NONE,
+   DIR_UL,
+   DIR_DL,
+   DIR_BOTH
+}Direction;
+
 typedef struct slotTimingInfo
 {
    uint16_t cellId;
index 22bcaf9..dd2aae7 100644 (file)
@@ -859,6 +859,87 @@ uint8_t unpackRlcUeDeleteRsp(RlcDuUeDeleteRsp func, Pst *pst, Buffer *mBuf)
     return RFAILED;
 }
 
+/*******************************************************************
+*
+* @brief Packs and Sends Slice PM from RLC to DUAPP
+*
+* @details
+*
+*    Function : packRlcDuSlicePm
+*
+*    Functionality:
+*       Packs and Sends Slice Performance Metrics from RLC to DUAPP
+*
+*
+* @params[in] Post structure pointer
+*             SlicePmList *sliceStats
+*
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t packRlcDuSlicePm(Pst *pst, SlicePmList *sliceStats)
+{
+   Buffer *mBuf = NULLP;
+
+   if(pst->selector == ODU_SELECTOR_LWLC)
+   {
+      if (ODU_GET_MSG_BUF(pst->region, pst->pool, &mBuf) != ROK)
+      {
+         DU_LOG("\nERROR  --> RLC : Memory allocation failed at packRlcDuSlicePm");
+         return RFAILED;
+      }
+      /* pack the address of the structure */
+      CMCHKPK(oduPackPointer,(PTR)sliceStats, mBuf);
+   }
+   else
+   {
+      DU_LOG("\nERROR  -->  RLC: Only LWLC supported for packRlcDuSlicePm");
+      return RFAILED;
+   }
+
+   return ODU_POST_TASK(pst,mBuf);
+}
+
+/*******************************************************************
+*
+* @brief Unpacks Slice PM received from RLC
+*
+* @details
+*
+*    Function : unpackRlcSlicePm
+*
+*    Functionality:
+*         Unpacks Slice Performance Metrics received from RLC
+*
+* @params[in] Pointer to Handler
+*             Post structure pointer
+*             Message Buffer
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t unpackRlcSlicePm(RlcSlicePmToDuFunc func, Pst *pst, Buffer *mBuf)
+{
+    if(pst->selector == ODU_SELECTOR_LWLC)
+    {
+       SlicePmList *sliceStats = NULLP;
+       /* unpack the address of the structure */
+       CMCHKUNPK(oduUnpackPointer, (PTR *)&sliceStats, mBuf);
+       ODU_PUT_MSG_BUF(mBuf);
+       return (*func)(pst, sliceStats);
+    }
+    else
+    {
+       /* Nothing to do for other selectors */
+       DU_LOG("\nERROR  -->  RLC: Only LWLC supported for Slice Metrics ");
+       ODU_PUT_MSG_BUF(mBuf);
+    }
+
+    return RFAILED;
+}
 /**********************************************************************
          End of file
 ***********************************************************************/
index 34147e0..519862d 100644 (file)
@@ -33,6 +33,7 @@
 #define EVENT_UL_USER_DATA_TRANS_TO_DU 219
 #define EVENT_RLC_UE_DELETE_REQ 220
 #define EVENT_RLC_UE_DELETE_RSP 221
+#define EVENT_RLC_SLICE_PM_TO_DU 222
 
 #define RB_ID_SRB 0
 #define RB_ID_DRB 1
@@ -273,6 +274,20 @@ typedef struct rrcDeliveryStatus
    uint16_t  triggeringMessage;
 }RrcDeliveryStatus;
 
+/*Pm Metric for NW Slicing from RLC to DUAPP*/
+typedef struct slicePm
+{
+  uint32_t networkSliceIdentifier;
+  double ThpDl;
+  double ThpUl;
+}SlicePm;
+
+typedef struct slicePmList
+{
+   uint8_t numSlice;
+   SlicePm *sliceRecord;
+}SlicePmList;
+
 typedef struct rrcDeliveryReportInfo
 {
    uint16_t  cellId;
@@ -347,6 +362,11 @@ typedef uint8_t (*DuRlcDlUserDataToRlcFunc) ARGS((
    Pst           *pst,
    RlcDlUserDataInfo *dlDataMsg));
 
+/* Slice Metrics from RLC to DU APP */
+typedef uint8_t (*RlcSlicePmToDuFunc) ARGS((
+   Pst           *pst,
+   SlicePmList *sliceStats));
+
 /* Pack/Unpack function declarations */
 uint8_t packDuRlcUeCreateReq(Pst *pst, RlcUeCfg *ueCfg);
 uint8_t unpackRlcUeCreateReq(DuRlcUeCreateReq func, Pst *pst, Buffer *mBuf);
@@ -370,6 +390,8 @@ uint8_t packDuRlcUeDeleteReq(Pst *pst, RlcUeDelete *ueDelete);
 uint8_t unpackRlcUeDeleteReq(DuRlcUeDeleteReq func, Pst *pst, Buffer *mBuf);
 uint8_t packRlcDuUeDeleteRsp(Pst *pst, RlcUeDeleteRsp *ueDeleteRsp);
 uint8_t unpackRlcUeDeleteRsp(RlcDuUeDeleteRsp func, Pst *pst, Buffer *mBuf);
+uint8_t packRlcDuSlicePm(Pst *pst, SlicePmList *sliceStats);
+uint8_t unpackRlcSlicePm(RlcSlicePmToDuFunc func, Pst *pst, Buffer *mBuf);
 
 /* Event Handler function declarations */
 uint8_t RlcProcUeCreateReq(Pst *pst, RlcUeCfg *ueCfg);
@@ -383,6 +405,7 @@ uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData);
 uint8_t RlcProcDlUserDataTransfer(Pst *pst, RlcDlUserDataInfo *dlDataMsgInfo);
 uint8_t RlcProcUeDeleteReq(Pst *pst, RlcUeDelete *ueDelete);
 uint8_t DuProcRlcUeDeleteRsp(Pst *pst, RlcUeDeleteRsp *delRsp);
+uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats);
 #endif /* RLC_INF_H */
 
 /**********************************************************************
index 75daa20..f66dae7 100644 (file)
@@ -461,6 +461,11 @@ uint8_t duActvTsk(Pst *pst, Buffer *mBuf)
                      ret = unpackRlcUlUserDataToDu(DuProcRlcUlUserDataTrans, pst, mBuf);
                      break;
                   }
+               case EVENT_RLC_SLICE_PM_TO_DU:
+                  {
+                     ret = unpackRlcSlicePm(DuProcRlcSliceMetrics, pst, mBuf);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  DU_APP : Invalid event %d received at duActvTsk from ENTRLC", \
index f8b909e..97c251c 100644 (file)
 #include "AlarmInterface.h"
 #include "ConfigInterface.h"
 
+/*TODO: Uncomment when PM O1 gerrit gets ready*/
+#if 0
+#include "PmInterface.h"
+#endif
+
 #endif 
 
 uint8_t rlcDlCfg = 0;
@@ -2132,6 +2137,57 @@ uint8_t DuProcMacSliceReCfgRsp(Pst *pst,  MacSliceCfgRsp *reCfgRsp)
    duFreeTempSliceCfg();
    return ROK;
 }
+
+/*******************************************************************
+*
+* @brief Handles received Slice Metrics from RLC and forward it to O1 
+*
+* @details
+*
+*    Function : DuProcRlcSliceMetrics
+*
+*    Functionality:
+*      Handles received Slice Metrics from RLC and forward it to O1
+*
+* @params[in] Post structure pointer
+*              SlicePmList *sliceStats
+*
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats)
+{
+    uint8_t sliceRecord = 0;
+
+    DU_LOG("\nDEBUG  -->  DU APP : Received Slice Metrics");
+    if(sliceStats == NULLP)
+    {
+       DU_LOG("\nERROR  -->  DU APP : Empty Metrics");
+       return RFAILED;
+    }
+    
+    for(sliceRecord = 0; sliceRecord < sliceStats->numSlice; sliceRecord++)
+    {
+       DU_LOG("\nINFO   -->  DU_APP: SliceIndx:%d, DlTput %.5lf, UlTput:%.5lf", sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier,\
+                        sliceStats->sliceRecord[sliceRecord].ThpDl, sliceStats->sliceRecord[sliceRecord].ThpUl);
+    }
+/*TODO: Uncomment when PM O1 gerrit gets ready*/
+#if 0
+#ifdef O1_ENABLE
+    if(sliceStats)
+    {
+       sendSliceMetric(sliceStats);
+    }
+#endif
+#endif
+
+   DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats->sliceRecord, (sliceStats->numSlice) * (sizeof(SlicePm)));
+   DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats, sizeof(SlicePmList));
+
+   return ROK;
+}
+
 /**********************************************************************
   End of file
  **********************************************************************/