[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-534] Handling of reset req and Implementation... 60/11860/5
authorlal.harshita <Harshita.Lal@radisys.com>
Thu, 5 Oct 2023 10:45:02 +0000 (16:15 +0530)
committerpborla <pborla@radisys.com>
Fri, 6 Oct 2023 09:05:19 +0000 (14:35 +0530)
Change-Id: Id6d6d88cd3a066a4b98246dab3610fc161f5663d
Signed-off-by: pborla <pborla@radisys.com>
src/du_app/du_e2ap_mgr.c
src/du_app/du_e2ap_mgr.h
src/du_app/du_e2ap_msg_hdl.c
src/du_app/du_tmr.c
src/du_app/du_tmr.h

index e5816fe..6bdbe58 100644 (file)
@@ -574,9 +574,8 @@ uint8_t rejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode
    /* Delete subcription from RAN Function */
    memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId));
    cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode);
-   DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription));
-   DU_FREE(ricSubscriptionNode, sizeof(CmLList));
-
+   deleteRicSubscriptionNode(ricSubscriptionNode);
+   ricSubscriptionNode = NULLP;
    convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause);
 
    /* Send RIC subscription failure to RIC */
@@ -1014,6 +1013,183 @@ uint8_t addOrModifyE2NodeComponent(InterfaceType interfaceType, uint8_t action,
    return ROK;
 }
 
+/******************************************************************
+ *
+ * @brief Delete measured Value list
+ *
+ * @details
+ *
+ *    Function : deleteMeasuredValueList
+ *
+ *    Functionality: Delete measured Value list
+ *
+ * @params[in] List of measured Value
+ *          
+ * @return void 
+ *
+ * ****************************************************************/
+void deleteMeasuredValueList(CmLListCp *measuredValueList)
+{
+   CmLList *measValNode = NULLP;
+
+   CM_LLIST_FIRST_NODE(measuredValueList, measValNode);
+
+   while(measValNode)
+   {
+      cmLListDelFrm(measuredValueList, measValNode);
+      DU_FREE(measValNode->node, sizeof(double));
+      DU_FREE(measValNode, sizeof(CmLList));
+      CM_LLIST_FIRST_NODE(measuredValueList, measValNode);
+   }
+}
+
+/******************************************************************
+ *
+ * @brief Delete Measurement Info List 
+ *
+ * @details
+ *
+ *    Function : deleteMeasurementInfoList
+ *
+ *    Functionality: Delete Measurement Info List 
+ *
+ * @params[in] List of Measurement Info List
+ *          
+ * @return void 
+ *
+ * ****************************************************************/
+
+void deleteMeasurementInfoList(CmLListCp *measInfoList)
+{
+   CmLList *measInfoNode = NULLP;
+   MeasurementInfo *measInfo = NULLP;
+
+   CM_LLIST_FIRST_NODE(measInfoList, measInfoNode);
+   while(measInfoNode)
+   {
+      measInfo = (MeasurementInfo *)measInfoNode->node;
+      cmLListDelFrm(measInfoList, measInfoNode);
+      deleteMeasuredValueList(&measInfo->measuredValue);
+      DU_FREE(measInfo, sizeof(MeasurementInfo));
+      DU_FREE(measInfoNode, sizeof(CmLList));
+      CM_LLIST_FIRST_NODE(measInfoList, measInfoNode);
+   }
+}
+
+/******************************************************************
+ *
+ * @brief Delete Ric subscription action 
+ *
+ * @details
+ *
+ *    Function : deleteActionSequence
+ *
+ *    Functionality: Delete Ric subscription action 
+ *
+ * @params[in] Action info 
+ *          
+ * @return void 
+ *
+ * ****************************************************************/
+void deleteActionSequence(ActionInfo *action)
+{
+   ActionDefinition *definition=NULLP;
+   definition= &action->definition;       
+   
+   switch(definition->formatType)
+   {
+      case 1:
+         {
+            deleteMeasurementInfoList(&definition->choice.format1.measurementInfoList);
+            break;
+         }
+
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+      default:
+      {
+         DU_LOG("\nERROR  -->  E2AP : Format %d does not supported", definition->formatType);
+         break;
+      }
+   }
+   memset(action, 0, sizeof(ActionInfo));
+   action->actionId = -1;
+}
+/******************************************************************
+ *
+ * @brief Delete Ric subscription node 
+ *
+ * @details
+ *
+ *    Function : deleteRicSubscriptionNode
+ *
+ *    Functionality: Delete Ric subscription node 
+ *
+ * @params[in] Ric subscription info 
+ *          
+ * @return void 
+ *
+ * ****************************************************************/
+
+void deleteRicSubscriptionNode(CmLList *subscriptionNode)
+{
+   uint8_t actionIdx=0;
+   RicSubscription *ricSubscriptionInfo = NULLP;
+
+   ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;    
+
+   for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
+   {
+      if(ricSubscriptionInfo->actionSequence[actionIdx].actionId > -1)
+      {
+         deleteActionSequence(&ricSubscriptionInfo->actionSequence[actionIdx]);
+      }
+   }
+
+   if(duChkTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) == TRUE)
+   {
+      duStopTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR);
+   }
+
+   memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
+   DU_FREE(subscriptionNode->node, sizeof(RicSubscription));
+   DU_FREE(subscriptionNode, sizeof(CmLList));
+}
+
+/******************************************************************
+ *
+ * @brief Delete ric subscription list from the database
+ *
+ * @details
+ *
+ *    Function : deleteRicSubscriptionList
+ *
+ *    Functionality: Delete ric subscription list 
+ *
+ * @params[in]
+ *    Subscription List to be deleted 
+
+ * @return void 
+ *
+ * ****************************************************************/
+
+
+void deleteRicSubscriptionList(CmLListCp *subscriptionList)
+{
+   CmLList *subscriptionNode=NULLP;
+   
+   CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
+   while(subscriptionNode)
+   {
+      /* TODO - Remove subscription information from MAC and SCH as well */ 
+      cmLListDelFrm(subscriptionList, subscriptionNode);
+      deleteRicSubscriptionNode(subscriptionNode);
+      CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
+   }
+}
+
 /**********************************************************************
   End of file
  **********************************************************************/
index ef32be4..d7f9de7 100644 (file)
@@ -503,7 +503,11 @@ uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause);
 uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize);
 E2NodeComponent *fetchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType, CmLList **e2ComponentNode);
 uint8_t addOrModifyE2NodeComponent(InterfaceType interfaceType, uint8_t action, bool reqPart, uint8_t bufSize, char *bufString);
-
+void deleteRicSubscriptionList(CmLListCp *subscriptionList);
+void deleteRicSubscriptionNode(CmLList *ricSubscriptionInfo);
+void deleteMeasurementInfoList(CmLListCp *measInfoList);
+void deleteActionSequence(ActionInfo *action);
+void deleteMeasuredValueList(CmLListCp *measuredValueList);
 /**********************************************************************
   End of file
  **********************************************************************/
index 2041f9b..0a5cec5 100644 (file)
@@ -2560,13 +2560,7 @@ uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoLis
        * Break out of for loop to search in next report style */
       if(!measInfoSubscribedDb)
       {
-         while(measInfoSubscribedList->count)
-         {
-            measToDelNode = cmLListDelFrm(measInfoSubscribedList, measInfoSubscribedList->first);
-            measInfoToDel = (MeasurementInfo*)measToDelNode->node;
-            DU_FREE(measInfoToDel, sizeof(MeasurementInfo));
-            DU_FREE(measToDelNode, sizeof(CmLList));
-         }
+         deleteMeasurementInfoList(measInfoSubscribedList);
          break;
       }
 
@@ -2752,8 +2746,7 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu
 
                   /* In case of any failure, action is rejected
                    * Added to rejected-action-list in subscription response */
-                  memset(&ricSubscriptionInfo->actionSequence[ricActionId], 0, sizeof(ActionInfo));
-                  ricSubscriptionInfo->actionSequence[ricActionId].actionId = -1;
+                  deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]);
 
                   subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
                   if(failureCause->causeType == E2_NOTHING)
@@ -3374,16 +3367,11 @@ uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInf
          measRecord->list.array[measRecIdx]->choice.real = measVal;
      }
      measRecIdx++;
-
+     measValNode= measValNode->next;  
      /* Once the measurement record is added to the message, delete it from DB */
-     cmLListDelFrm(&measInfoDb->measuredValue, measValNode);
-     DU_FREE(measValNode->node, sizeof(double));
-     DU_FREE(measValNode, sizeof(CmLList));
-
-     CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
      measVal = 0;
    }
-
+   deleteMeasuredValueList(&measInfoDb->measuredValue);
    return ROK;
 }
 
@@ -6257,8 +6245,8 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
                      }
                      else
                      {
-                        memset(actionDb, 0, sizeof(ActionInfo));
-                        actionDb->actionId = -1;
+                        deleteActionSequence(actionDb);
+                        actionDb =NULLP;
                         ricSubsDb->numOfActions--;
                         /* Further handling can include :
                          * Deletion of this action from all DU layers 
@@ -6305,6 +6293,249 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg)
    return;
 }
 
+/******************************************************************
+* @brief Deallocate the memory allocated for E2 Reset Response
+*
+* @details
+*
+*    Function : FreeE2ResetResponse
+*
+*    Functionality:
+*       - freeing the memory allocated for E2ResetResponse
+*
+* @params[in] E2AP_PDU_t *e2apMsg
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0;
+   ResetResponseE2_t *resetResponse;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.successfulOutcome != NULLP)
+      {
+         resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
+         if(resetResponse->protocolIEs.list.array)
+         {
+            for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
+            {
+               if(resetResponse->protocolIEs.list.array[ieIdx])
+               {
+                  DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
+               }
+            }
+            DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
+         }
+
+         DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      }
+      DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Reset Response msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2ResetResponse
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Reset Response Message
+ *
+ * @params[in] Trans Id
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendResetResponse(uint8_t transId)
+{
+   uint8_t           ieIdx = 0, elementCnt = 0;
+   uint8_t           ret = RFAILED;
+   E2AP_PDU_t        *e2apMsg = NULLP;
+   ResetResponseE2_t *resetResponse;
+   asn_enc_rval_t    encRetVal;       /* Encoder return value */
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
+   do
+   {
+      DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
+         break;
+      }
+      e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
+
+      DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      if(e2apMsg->choice.successfulOutcome == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
+         break;
+      }
+
+      e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
+      e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
+      resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
+
+      elementCnt = 1;
+      resetResponse->protocolIEs.list.count = elementCnt;
+      resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
+      DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
+      if(!resetResponse->protocolIEs.list.array)
+      {
+         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
+         break;
+      }
+
+      for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
+      {
+         DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
+         if(!resetResponse->protocolIEs.list.array[ieIdx])
+         {
+            DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
+            break;
+         }
+      }
+      if(ieIdx < elementCnt)
+         break;
+
+      ieIdx = 0;
+      resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
+      resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
+      resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
+
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         }
+      }
+
+      /* Sending msg */
+      if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
+         break;
+      }
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   FreeE2ResetResponse(e2apMsg);
+   return ret;
+}
+
+/******************************************************************
+ *
+ * @brief Deallocation of memory allocated by aper decoder for reset req
+ *
+ * @details
+ *
+ *    Function : freeAperDecodingOfE2ResetReq
+ *
+ *    Functionality: Deallocation of memory allocated by aper decoder for
+ *    reset req
+ *
+ * @params[in] Pointer to resetReq
+ * @return void
+ *
+ * ****************************************************************/
+void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq)
+{
+   uint8_t arrIdx=0;
+
+   if(resetReq)
+   {
+      if(resetReq->protocolIEs.list.array)
+      {
+         for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
+         {
+            if(resetReq->protocolIEs.list.array[arrIdx])
+            {
+               free(resetReq->protocolIEs.list.array[arrIdx]);
+            }
+         }
+         free(resetReq->protocolIEs.list.array);
+      }
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Process reset req received from RIC
+ *
+ * @details
+ *
+ *    Function : procE2ResetRequest
+ *
+ * Functionality: Process reset req received from RIC
+ *
+ * @param  E2AP_PDU_t  *e2apMsg
+ * @return void
+ *
+ ******************************************************************/
+
+void procE2ResetRequest(E2AP_PDU_t  *e2apMsg)
+{
+   uint16_t ranFuncIdx=0;
+   uint8_t arrIdx =0, transId =0;
+   ResetRequestE2_t *resetReq;
+
+   DU_LOG("\nINFO   -->  E2AP : E2 Reset request received");
+   resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
+
+   for(arrIdx=0; arrIdx<resetReq->protocolIEs.list.count; arrIdx++)
+   {
+      switch(resetReq->protocolIEs.list.array[arrIdx]->id)
+      {
+         case ProtocolIE_IDE2_id_TransactionID:
+            {
+               transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
+               break;
+            }
+
+         case ProtocolIE_IDE2_id_CauseE2:
+            {
+               for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
+               {
+                  if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
+                  {
+                     deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
+                     memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
+                  }
+               }
+               break;
+            }
+      }
+   }
+   if(BuildAndSendResetResponse(transId) != ROK)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
+   }
+   freeAperDecodingOfE2ResetReq(resetReq);
+}
+
 /*******************************************************************
  *
  * @brief Handles received E2AP message and sends back response  
@@ -6467,6 +6698,12 @@ void E2APMsgHdlr(Buffer *mBuf)
                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
                      break;
                   }
+               case InitiatingMessageE2__value_PR_ResetRequestE2:
+                  {
+                     DU_LOG("\nINFO  -->  E2AP : Error indication received");
+                     procE2ResetRequest(e2apMsg);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
index 1ea0d77..3e24888 100644 (file)
@@ -224,6 +224,79 @@ void duTmrExpiry(PTR cb,int16_t tmrEvnt)
    return;
 }
 
+/**
+ * @brief Handler to stop timer
+ *
+ * @param[in] cb        Control block depending on the type of the timer event.
+ * @param[in] tmrEvnt   Timer event to be stopped
+ *
+ * @return  Void
+*/
+
+void duStopTmr(PTR cb, uint8_t tmrType)
+{
+   CmTmrArg   arg;
+   arg.timers = NULLP;
+
+   switch (tmrType)
+   {
+      case EVENT_E2_SETUP_TMR:
+      {
+         CmTimer *e2SetupTimer = NULLP;
+         
+         e2SetupTimer = ((CmTimer *)cb);
+         arg.timers = e2SetupTimer;
+         arg.max = MAX_E2_SETUP_TMR;
+         break;
+      }
+      case EVENT_RIC_SERVICE_UPDATE_TMR:
+      {
+         RicServiceUpdateTimer *ricServiceUpdateTimer = NULLP;
+         
+         ricServiceUpdateTimer= ((RicServiceUpdateTimer*)cb);
+         arg.timers = &ricServiceUpdateTimer->timer;
+         arg.max = MAX_RIC_SERVICE_UPDATE_TMR;
+         break;
+      }
+      case EVENT_E2_NODE_CONFIG_UPDATE_TMR:
+      {
+         E2NodeConfigUpdateTimer *cfgUpdateTimer;
+         
+         cfgUpdateTimer = ((E2NodeConfigUpdateTimer*)cb);
+         arg.timers = &cfgUpdateTimer->timer;
+         arg.max = MAX_E2_NODE_CONFIG_UPDATE_TMR;
+         break;
+      }
+      case EVENT_RIC_SUBSCRIPTION_REPORTING_TMR:
+      {
+         RicSubscription *ricSubscription = NULLP;
+         
+         ricSubscription = ((RicSubscription*)cb);
+         arg.timers = &ricSubscription->ricSubsReportTimer;
+         arg.max = MAX_RIC_SUBSCRIPTION_REPORTING_TMR;
+         break;
+      }
+      default:
+      {
+         DU_LOG("\nERROR  -->  RLC : rlcStopTmr: Invalid tmr Evnt[%d]", tmrType);
+         break;
+      }
+   }
+
+   if (tmrType != TMR0)
+   {
+      arg.tqCp   = &(duCb.duTimersInfo.tmrTqCp);
+      arg.tq     = duCb.duTimersInfo.tmrTq;
+      arg.cb     = cb;
+      arg.evnt   = tmrType;
+      arg.wait   = 0;
+      arg.tNum   = 0;
+      cmRmvCbTq(&arg);
+   }
+
+   return;
+}
+
 /**
  * @brief DU instance timer call back function registered with system services.
  *
index 54aced7..444bc24 100644 (file)
@@ -22,7 +22,7 @@
 short int duActvTmr(Ent ent,Inst inst); 
 bool duChkTmr(PTR cb, int16_t tmrEvnt);
 void duStartTmr(PTR cb, int16_t tmrEvnt, uint32_t timerValue);
-
+void duStopTmr(PTR cb, uint8_t tmrType);
 /**********************************************************************
   End of file
  **********************************************************************/