[Epic-ID: ODUHIGH-488][Task-ID: ODUHIGH-501] WG8 Alignment | Ue reset req and rsp
[o-du/l2.git] / src / 5gnrrlc / rlc_tmr.c
index d7ecd63..0c7234e 100755 (executable)
 #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
@@ -81,7 +84,7 @@
 
 /* private function declarations */
 static Void rlcBndTmrExpiry(PTR cb);
-void rlcThptTmrExpiry(PTR cb);
+
 
 /**
  * @brief Handler to start timer
@@ -175,11 +178,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;
+         RLC_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;
+         RLC_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;
+         RLC_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 +284,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)->thptTmr;
+         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)->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 +376,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:
+      {
+         rlcUeDeleteTmrExpiry(cb);
+         break;
+      }
+      case EVENT_RLC_SNSSAI_THROUGHPUT_TMR:
       {
-         rlcThptTmrExpiry(cb);
+         rlcSnssaiThptTmrExpiry(cb);
          break;
       }
       default:
@@ -397,9 +440,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)->ueTputInfo.ueThptTmr.tmrEvnt == EVENT_RLC_UE_THROUGHPUT_TMR);
+      }
+      case EVENT_RLC_UE_DELETE_TMR:
       {
-         return (((RlcThpt *)cb)->thptTmr.tmrEvnt == EVENT_RLC_THROUGHPUT_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 +465,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 +485,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 +500,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 +521,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; 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**