[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-528] RIC Subscription Request 91/11791/8
authorlal.harshita <Harshita.Lal@radisys.com>
Thu, 14 Sep 2023 09:43:53 +0000 (15:13 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Thu, 21 Sep 2023 14:24:53 +0000 (19:54 +0530)
Change-Id: Ib89e09a0bac4f9b03f915bf0174cc7a1170eb108
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
src/du_app/du_e2ap_mgr.h
src/du_app/du_e2ap_msg_hdl.c
src/du_app/du_e2ap_msg_hdl.h
src/du_app/du_msg_hdl.c
src/ric_stub/ric_e2ap_msg_hdl.c
src/ric_stub/ric_e2ap_msg_hdl.h
src/ric_stub/ric_stub.h

index e59e646..e337f80 100644 (file)
@@ -80,8 +80,8 @@ typedef enum
 /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.2.11 */
 typedef enum
 {
-   INSERT,
    REPORT,
+   INSERT,
    POLICY
 }ActionType;
 
@@ -261,7 +261,7 @@ typedef struct
 /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.1.1 */
 typedef struct
 {
-   uint32_t reportingPeriod;
+   uint32_t reportingPeriod; /* In milliseconds */
 }EventTriggerFormat1;
 
 /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.1 */
@@ -285,16 +285,13 @@ typedef struct
 /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.2.1 */
 typedef struct
 {
-   union
-   {
-      char     measurementTypeName[STRING_SIZE_150_BYTES];
-      uint16_t measurementTypeId;
-   }choice;
+   char     measurementTypeName[STRING_SIZE_150_BYTES];
+   uint16_t measurementTypeId;
 
    /* As of now Labels are not used, hence it is not implemented completely */
    //uint32_t    numOfLabels;
    //LabelInfo   LabelInfoList[MAX_LABEL_INFO];
-   
+
    CmLListCp   measuredValue;  /* To be filled when numOfLabels is 0, else values are calculated per Label */
 }MeasurementInfo;
 
@@ -333,6 +330,7 @@ typedef struct
 typedef struct
 {
    uint8_t     styleType;
+   uint8_t     formatType;
    union
    {
       ActionDefFormat1  format1;
index d7a98bd..f13282f 100644 (file)
 #include "RIC-EventTriggerStyle-Item.h"
 #include "RIC-ReportStyle-Item.h"
 #include "MeasurementInfo-Action-Item.h"
+#include "E2SM-KPM-EventTriggerDefinition.h"
+#include "E2SM-KPM-EventTriggerDefinition-Format1.h"
+#include "E2SM-KPM-ActionDefinition.h"
+#include "E2SM-KPM-ActionDefinition-Format1.h"
+#include "MeasurementInfoItem.h"
 
 /*******************************************************************
  *
@@ -1623,6 +1628,528 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Free RIC Subscription Request
+ *
+ * @details
+ *
+ *    Function : freeAperDecodingOfRicSubsReq
+ *
+ * Functionality : Free RIC Subscription Request
+ *
+ * @return void
+ *
+ ******************************************************************/
+void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
+{
+   uint8_t idx = 0;
+   uint8_t elementIdx = 0;
+   RICsubscriptionDetails_t *subsDetails = NULLP;
+   RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
+
+   if(ricSubscriptionReq->protocolIEs.list.array)
+   {
+      for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
+      {
+         switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
+         {
+            case ProtocolIE_IDE2_id_RICsubscriptionDetails:
+               {
+                  subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
+                  free(subsDetails->ricEventTriggerDefinition.buf);
+
+                  if(subsDetails->ricAction_ToBeSetup_List.list.array)
+                  {
+                     for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
+                     {
+                        if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
+                        {
+                           actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.\
+                              list.array[elementIdx];
+                           if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
+                           {
+                              free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
+                              free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
+                           }
+                           free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
+                        }
+                     }
+                     free(subsDetails->ricAction_ToBeSetup_List.list.array);
+                  }
+                  break;
+               }
+         }
+         free(ricSubscriptionReq->protocolIEs.list.array[idx]);
+      }
+      free(ricSubscriptionReq->protocolIEs.list.array);
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Free Event Trigger Definition
+ *
+ * @details
+ *
+ *    Function : freeAperDecodingOfEventTriggerDef
+ *
+ *    Functionality: Free Event Trigger Definition
+ *
+ * @params[in] E2SM-KPM Event Trigger Definition
+ * @return void
+ *
+ * ****************************************************************/
+void  freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
+{
+   if(eventTiggerDef)
+   {
+      switch(eventTiggerDef->eventDefinition_formats.present)
+      {
+         case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
+            break;
+
+         case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
+            free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
+            break;
+      }
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Extract E2SM-KPM Event trigger definition
+ *
+ * @details
+ *
+ *    Function : extractEventTriggerDef
+ *
+ * Functionality : This function :
+ *     - Decodes E2SM-KPM Event Trigger Definition
+ *     - Validates that even trigger style is supported by E2 node
+ *     - Stores event trigger details in local DB
+ *
+ * @params[in] RAN Function Database structure
+ *             RIC Subscription Info to be added to RAN function
+ *             RIC Event Trigger Definition buffer received from RIC
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, RICeventTriggerDefinition_t *ricEventTriggerDef)
+{
+   uint8_t ret = RFAILED;
+   uint8_t eventIdx = 0;
+   asn_dec_rval_t rval ={0};
+   E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
+
+   /* Decoding E2SM-KPM Even Trigger Definition */
+   eventTiggerDefPtr = &eventTiggerDef;
+   memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
+
+   rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
+         ricEventTriggerDef->size, 0, 0);
+   if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+   {
+      DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition");
+      return RFAILED;
+   }
+   printf("\n");
+   xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr);
+
+   /* Validating the received event trigger definition format */
+   for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
+   {
+      if((eventTiggerDefPtr->eventDefinition_formats.present != \
+         E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
+         (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
+      {
+         ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
+         ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
+            eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
+
+         ret = ROK;
+         break;
+      }
+   }
+
+   /* Free E2SM_KPM_EventTriggerDefinition_t */
+   freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
+   return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Free RIC Action Definition
+ *
+ * @details
+ *
+ *    Function :  freeAperDecodingOfRicActionDefinition
+ *
+ *    Functionality: Free RIC Action Definition
+ *
+ * @params[in] E2SM-KPM Action definition
+ * @return void
+ *
+ * ****************************************************************/
+void  freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
+{
+   uint8_t  elementIdx = 0;
+   E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
+   MeasurementInfoItem_t *measItem = NULLP;
+
+   switch(actionDef->actionDefinition_formats.present)
+   {
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
+         {
+            if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
+            {
+               actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
+               if(actionFormat1->measInfoList.list.array)
+               {
+                  for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
+                  {
+                     if(actionFormat1->measInfoList.list.array[elementIdx])
+                     {
+                        measItem = actionFormat1->measInfoList.list.array[elementIdx];
+                        switch(measItem->measType.present)
+                        {
+                           case MeasurementType_PR_NOTHING:
+                              break;
+
+                           case MeasurementType_PR_measName:
+                           {
+                              free(measItem->measType.choice.measName.buf);
+                              break;
+                           }
+
+                           case MeasurementType_PR_measID:
+                              break;
+                        }
+                        free(measItem);
+                     }
+                  }
+                  free(actionFormat1->measInfoList.list.array);
+               }
+               free(actionFormat1);
+            }
+            break;
+         }
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
+      default:
+         break;   
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Extract Measurement Info list from action definition
+ *
+ * @details
+ *
+ *    Function : extractMeasInfoList
+ *
+ * Functionality : This function :
+ *     - Traverses Measurement-to-be-subscribed list
+ *     - Validates that each measurement in Measurement-to-be-subscribed
+ *       list is supported in RAN-Function->Measurement-supported list.
+ *     - If all measurements in an action is supported by RAN function,
+ *       it is added to measurement-subscribed list in local DB
+ *
+ * @params[in] Measurement Info supported list by RAN function
+ *             Measurement Info to be subscribed as requested by RIC
+ *             Measurement Info finally subscribed
+ *             Memory failure indicator
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
+   CmLListCp *measInfoSubscribedList, bool *memFailure)
+{
+   uint8_t elementIdx = 0;
+   MeasurementInfoForAction *measInfoSupportedDb = NULLP;
+   MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP;
+   CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;;
+   MeasurementInfoItem_t *measItem = NULLP;
+
+   /* Validate Measurement list is supported by E2 node. 
+    *
+    * Traverse and compare the Measurement-Supported List in E2
+    * node with Measurement-to-be-subscribed list received from RIC.
+    * If a match is found, add it to measurement-subscription list.
+    */
+   for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
+   {
+      measInfoSubscribedDb = NULLP;
+      measToAddNode = NULLP;
+      measItem = measInfoToBeSubscribedList->list.array[elementIdx];
+
+      CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
+      while(supportedMeasNode)
+      {
+         measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
+         switch(measItem->measType.present)
+         {
+            case MeasurementType_PR_measName:
+               {
+                  if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
+                  {
+                     DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
+                  }
+                  break;
+               }
+
+            case MeasurementType_PR_measID:
+               {
+                  if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
+                  {
+                     DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
+                  }
+                  break;
+               }
+
+            default:
+               {
+                  DU_LOG("\nERROR  ->  DUAPP: Invalid Measurement-type identifier in \
+                        E2SM-KPM Action Definition Format");
+                  break;
+               }
+         } /* End of switch, for measurement type identifier */
+
+         /* If measurement type is supported, add to measurement-subscription list */
+         if(measInfoSubscribedDb)
+         {
+            measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
+            memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
+                  strlen(measInfoSupportedDb->measurementTypeName));
+
+            DU_ALLOC(measToAddNode, sizeof(CmLList));
+            if(measToAddNode)
+            {
+               measToAddNode->node = (PTR) measInfoSubscribedDb;
+               cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
+
+               /* Break out of while loop if measurement info is found in measurement-supported list  */
+               break;
+            }
+            else
+            {
+               DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
+               measInfoSubscribedDb = NULLP;
+               *memFailure = true;
+               break;
+            }
+         }
+
+         supportedMeasNode = supportedMeasNode->next;  
+
+      } /* End of while for traversing measurement-supported list in a report style */
+
+      /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
+       * Then :
+       * Delete all entries from measurement-subscription list and
+       * 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));
+         }
+         break;
+      }
+
+   } /* End of for loop , traversing measurement-to-be-subscribed list */
+
+   /* If all measurement-to-be-subscribed was found in measurement-supported list and 
+    * was added to measurement-subscription list successfully, return from here */
+   if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
+      return ROK;
+
+   return RFAILED;
+}
+
+/*******************************************************************
+ *
+ * @brief Extract E2SM-KPM Action definition
+ *
+ * @details
+ *
+ *    Function : extractRicActionDef
+ *
+ * Functionality : This function :
+ *     - Decodes E2SM-KPM Action Definition
+ *     - Validates that action is supported by E2 node
+ *     - Stores action details in local DB
+ *
+ * @params[in] RAN Function Database structure
+ *             RIC subscription's Action definition to be added to 
+ *                RAN function
+ *             RIC Action Definition buffer received from RIC
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef)
+{
+   bool memFailure = false;
+   uint8_t styleIdx = 0;
+   asn_dec_rval_t rval ={0};
+
+   E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
+   E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
+   CmLListCp *measInfoSupportedList = NULLP;
+   CmLListCp *measInfoSubscribedList = NULLP;
+
+   /* Decoding E2SM-KPM Action Definition */
+   actionDefPtr = &actionDef;
+   memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
+
+   rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
+         ricActionDef->size, 0, 0);
+   if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+   {
+      DU_LOG("\nERROR  -->  E2AP : ASN decode failed for E2SM-KPM Action Definition");
+      return RFAILED;
+   }
+   printf("\n");
+   xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
+
+
+   /* Validate if Report style to subscribe is supported by E2 Node */
+   for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
+   {
+      /* Validate Report style type and report style format type is supported by E2 Node */
+      if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
+            (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
+      {
+         /* Fetch Report stype type and format type */
+         actionDefDb->styleType = actionDefPtr->ric_Style_Type;
+         actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
+
+         switch(actionDefPtr->actionDefinition_formats.present)
+         {
+            case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
+               {
+                  actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; 
+
+                  /* Fetch granularity period */
+                  actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
+
+                  /* Validate and add the Measurement to subscription list */
+                  measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
+                  measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
+                  if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
+                     measInfoSubscribedList, &memFailure) == ROK)
+                  {
+                     if(!memFailure)
+                     {
+                        /* Free E2SM_KPM_ActionDefinition_t */
+                        freeAperDecodingOfRicActionDefinition(actionDefPtr);
+                        return ROK;
+                     }
+                  }
+
+                  break;  /* End of E2SM-KPM Action definition format 1 case */
+               }
+
+            default :
+               {
+                  DU_LOG("\nERROR  ->  DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
+                  break;
+               }
+         } /* End of switch for E2SM-KPM Action definition formats */
+      }
+
+      if(memFailure)
+         break;
+   } /* End of for loop, traversing Report-styles-supported list in E2 node */
+
+   /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
+   memset(actionDefDb, 0, sizeof(ActionDefinition));
+   freeAperDecodingOfRicActionDefinition(actionDefPtr);
+   return RFAILED;
+}
+
+/*******************************************************************
+ *
+ * @brief Extract RIC Action to be setup
+ *
+ * @details
+ *
+ *    Function : extractRicActionToBeSetup
+ *
+ * Functionality : This function :
+ *     - Validates that each action-to-be-setup is supported by E2 node
+ *     - Stores event trigger details in local DB
+ *
+ * @params[in] RAN Function Database structure
+ *             RIC Subscription Info to be added to RAN function
+ *             RIC Action To Be Setup List received from RIC
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, RICactions_ToBeSetup_List_t *actionList)
+{
+   uint8_t actionIdx = 0;
+   uint8_t ricActionId = 0;
+   RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
+
+   if(actionList->list.array)
+   {
+      for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
+      {
+         actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
+         switch(actionItem->id)
+         {
+            case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
+               {
+                  /* If Action type is REPORT and 
+                   * If RIC action definition's extraction and validation passes, 
+                   * Then : 
+                   * This action is added to action sequence list of subscription info */
+                  if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
+                  {
+                     ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
+                     ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId;
+                     ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT;
+
+                     if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \
+                        actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) == ROK)
+                     {
+                        ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD;
+                        ricSubscriptionInfo->numOfActions++;
+                     }
+                     else
+                     {
+                        memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo));
+                        /* TODO : Since this action addition failed, add to
+                         * reject-action-list in subscription response */
+                     }
+                  }
+                  break;
+               }
+            default:
+               DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
+               break;
+         }
+      }
+   }
+
+   /* If there is even 1 action that can be added, return ROK */
+   if(ricSubscriptionInfo->numOfActions)
+      return ROK;
+
+   return RFAILED;
+}
+
 /******************************************************************
  *
  * @brief Processes RIC Subscription Req sent by RIC
@@ -1641,13 +2168,14 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg)
 
 uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
 {
-   uint8_t idx; 
-   uint8_t ied; 
+   uint8_t idx = 0; 
    uint8_t ret = ROK;
+   uint16_t ranFuncId = 0;
    CmLList  *ricSubscriptionNode = NULLP;
-   RICsubscriptionRequest_t *ricSubsReq;
-   RicSubscription *ricSubscriptionInfo;
-   RICaction_ToBeSetup_ItemIEs_t *actionItem;
+   RanFunction *ranFuncDb = NULLP;
+   RICsubscriptionRequest_t *ricSubsReq = NULLP;
+   RICsubscriptionDetails_t *subsDetails = NULLP;
+   RicSubscription *ricSubscriptionInfo = NULLP;
 
    DU_LOG("\nINFO   -->  E2AP : RIC Subscription request received"); 
    ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
@@ -1660,84 +2188,93 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
          {
             case ProtocolIE_IDE2_id_RICrequestID:
                {
-                  /* TODO :- ricSubscriptionInfo details will be stored based on
-                   * RAN function id, so first we need to search RAN function and then add
-                   * subscription details to that ran function */
                   DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
                   if(!ricSubscriptionInfo)
                   {
                      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for ricSubscriptionInfo");
-                     return RFAILED;
+                     ret = RFAILED;
+                     break;
                   }
                   ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
                   ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
-                  DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
-                  if(ricSubscriptionNode)
-                  {
-                     ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
-                     cmLListAdd2Tail(&duCb.e2apDb.ranFunction[0].subscriptionList,ricSubscriptionNode);
-                  }
+
                   break;
                }
+
             case ProtocolIE_IDE2_id_RANfunctionID:
                {
-                  duCb.e2apDb.ranFunction[0].id = ricSubsReq->protocolIEs.list.array[idx]-> \
-                                          value.choice.RANfunctionID; 
+                  ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; 
+
+                  /* Validating RAN Function id */
+                  if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
+                  {
+                     ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
+                  }
+                  else
+                  {
+                     /* TODO : Send RAN Subcription Failure */
+                     ret = RFAILED;
+                  }
                   break;
                }
+
             case ProtocolIE_IDE2_id_RICsubscriptionDetails:
                {
-                  if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
-                        list.array)
+                  subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
+
+                  /* Decode, Validate and record Event Trigger Definition */
+                  if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition) != ROK)
                   {
-                     actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\
-                                 .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\
-                                 .list.array[0];
+                     /* TODO : Send RAN Subcription Failure */
+                     ret = RFAILED;
+                     break;
+                  }
 
-                     for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\
-                           RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++)
-                     {
-                        switch(actionItem->id)
-                        {
-                           case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
-                              {
-                                 ricSubscriptionInfo->actionSequence[0].id  = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
-                                 ricSubscriptionInfo->actionSequence[0].type = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType;
-                                 break;
-                              }
-                           default:
-                              DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
-                              break;
-                        }
-                        free(actionItem);
-                     }
-                     free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\
-                           list.array);
-
-#ifdef KPI_CALCULATION 
-                     /* This is a dummy trigger for statistics request. It will
-                      * be removed in next gerrit and actual statistics request
-                      * will be sent when RIC subscription request is received
-                      * from RIC */
-                     ricSubscriptionInfo->actionSequence[0].definition.styleType = 1;
-                     BuildAndSendStatsReq(ricSubscriptionInfo->actionSequence[0].definition);
-#endif
+                  /* Decode, Validate and record RIC actions */
+                  if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List) != ROK)
+                  {
+                     /* TODO : Send RAN Subcription Failure */
+                     ret = RFAILED;
+                     break;
                   }
-                  break;
                }
+               break;
 
             default:
                DU_LOG("\nERROR  -->  E2AP : Invalid IE received in RIC SubsReq:%ld",
                      ricSubsReq->protocolIEs.list.array[idx]->id);
                break;
          }
-         free(ricSubsReq->protocolIEs.list.array[idx]);
+
+         if(ret == RFAILED)
+            break;
       }
    }
-   free(ricSubsReq->protocolIEs.list.array);
-   ret = BuildAndSendRicSubscriptionRsp();
+
+   freeAperDecodingOfRicSubsReq(ricSubsReq);
+
+   if(ret == ROK)
    {
-      BuildAndSendRicIndication(ricSubscriptionInfo);
+      /* Add RAN subcription detail to RAN function */
+      DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
+      if(ricSubscriptionNode)
+      {
+         ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
+         cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
+      }
+
+#ifdef KPI_CALCULATION
+      /* Send statistics request to other DU entities */
+      BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo);
+#endif      
+
+      /* TODO : Trigger RIC subscription response once statistics response is
+       * received from MAC . 
+       * TBD in next gerrit */
+      ret = BuildAndSendRicSubscriptionRsp();
+      {
+         BuildAndSendRicIndication(ricSubscriptionInfo);
+      }
    }
 
    return ret;
@@ -1759,63 +2296,63 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg)
  ******************************************************************/
 void FreeRicIndication(E2AP_PDU_t  *e2apMsg) 
 {
-   uint8_t idx=0;
+   uint8_t idx = 0;
    RICindication_t *ricIndicationMsg= NULLP;
 
-
    if(e2apMsg != NULLP)
    {
       if(e2apMsg->choice.initiatingMessage != NULLP)
       {
-        ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
-        if(ricIndicationMsg!= NULLP)
-        {
-           if(ricIndicationMsg->protocolIEs.list.array != NULLP)
-           {
-              for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
-              {
-                 if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
-                 {
-                    switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
-                    {
-                       case ProtocolIE_IDE2_id_RICrequestID:
-                          break;
+         ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
+         if(ricIndicationMsg!= NULLP)
+         {
+            if(ricIndicationMsg->protocolIEs.list.array != NULLP)
+            {
+               for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
+               {
+                  if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
+                  {
+                     switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
+                     {
+                        case ProtocolIE_IDE2_id_RICrequestID:
+                           break;
 
-                       case ProtocolIE_IDE2_id_RANfunctionID:
-                          break;
+                        case ProtocolIE_IDE2_id_RANfunctionID:
+                           break;
 
-                       case ProtocolIE_IDE2_id_RICactionID:
-                          break;
+                        case ProtocolIE_IDE2_id_RICactionID:
+                           break;
 
-                       case ProtocolIE_IDE2_id_RICindicationType:
-                          break;
+                        case ProtocolIE_IDE2_id_RICindicationType:
+                           break;
 
-                       case ProtocolIE_IDE2_id_RICindicationHeader:
-                          {
-                             DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
-                                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
-                             break;
-                          }
-                       case ProtocolIE_IDE2_id_RICindicationMessage:
-                          {
-                             DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
-                                   ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
-                             break;
-                          }
-                       default:
-                          break;
-                    }
-                    DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
-                 }
-              }
-              DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
-           }
-        }
-        DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+                        case ProtocolIE_IDE2_id_RICindicationHeader:
+                           {
+                              DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
+                                    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
+                              break;
+                           }
+                        case ProtocolIE_IDE2_id_RICindicationMessage:
+                           {
+                              DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
+                                    ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
+                              break;
+                           }
+                        default:
+                           break;
+                     }
+                     DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
+                  }
+               }
+               DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
+            }
+         }
+         DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
       }
       DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
    }
 }
+
 /*******************************************************************
  *
  * brief Fill the RicIndication Message
index 18edc27..47f1b7a 100644 (file)
@@ -25,7 +25,8 @@ uint8_t  BuildAndSendE2NodeConfigUpdate();
 uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause);
 void     E2APMsgHdlr(Buffer *mBuf);
 uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo);
-uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction);
+
+uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo);
 /**********************************************************************
   End of file
  **********************************************************************/
index 6444943..6502840 100644 (file)
@@ -2093,34 +2093,93 @@ uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t BuildAndSendStatsReqToMac(MacStatsReq duMacStatsReq)
+uint8_t BuildAndSendStatsReqToMac(uint64_t subscriptionId, RicSubscription *ricSubscriptionInfo)
 {
    Pst pst;
+   uint8_t    actionIdx = 0, grpIdx = 0, statsIdx = 0;
+   ActionInfo *actionDb = NULLP;
+   ActionDefFormat1 *format1Action = NULLP;
    MacStatsReq *macStatsReq = NULLP;
-   
-   DU_LOG("\nINFO  --> DU_APP : Builds Statistics Request to send to MAC");
 
+   /* Fill MAC statistics request */
    DU_ALLOC_SHRABL_BUF(macStatsReq, sizeof(MacStatsReq));
    if(macStatsReq == NULLP)
    {
       DU_LOG("\nERROR  -->  DU_APP : Memory allocation failed for macStatsReq in BuildAndSendStatsReqToMac");
       return RFAILED;
    }
-   else
+
+   macStatsReq->subscriptionId = subscriptionId;
+   for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
    {
-      memcpy(macStatsReq, &duMacStatsReq, sizeof(MacStatsReq));
+      if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
+      {
+         actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
+         macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
+         switch(actionDb->definition.formatType)
+         {
+            case 1:
+               {
+                  format1Action = &actionDb->definition.choice.format1;
+                  macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
+
+                  CmLList *node = NULLP;
+                  MeasurementInfo *measInfo = NULLP;
+                  statsIdx = 0;
+                  /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
+                  node = cmLListFirst(&format1Action->measurementInfoList);
+                  while(node)
+                  {
+                     measInfo = (MeasurementInfo *)(node->node);
+                     switch(measInfo->measurementTypeId)
+                     {
+                        case 1:
+                           {
+                              macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
+                              break;
+                           }
+                        case 2:
+                           {
+                              macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
+                              break;
+                           }
+                        default:
+                           {
+                              DU_LOG("\nERROR  -->  DU_APP : Invalid measurement name BuildAndSendStatsReqToMac");
+                              break;
+                           }
+                     }
+                     node = node->next;
+                  }
+                  macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
+                  break;
+               }
+            default:
+               {
+                  DU_LOG("\nERROR  -->  DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
+                  break;
+               }
+         }
+         if(macStatsReq->statsGrpList[grpIdx].numStats)
+            grpIdx++;
+      }
+   }
+   macStatsReq->numStatsGroup = grpIdx;
 
+   if(macStatsReq->numStatsGroup)
+   {
+      DU_LOG("\nDEBUG  -->  DU_APP: Sending Statistics Request to MAC ");
       FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_REQ);
 
-      DU_LOG("\nDEBUG  -->  DU_APP: Sending Statistics Request to MAC ");
-      if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == RFAILED)
-      {
-         DU_LOG("\nERROR  -->  DU_APP: Failed to send Statistics Request to MAC");
-         DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq));
-         return RFAILED;
-      }
+      if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == ROK)
+         return ROK;
+
+      DU_LOG("\nERROR  -->  DU_APP: Failed to send Statistics Request to MAC");
    }
-   return ROK;  
+
+   DU_LOG("\nERROR  -->  DU_APP: No Statistics group found valid. Hence statistics request is not sent to MAC");
+   DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq));
+   return RFAILED;
 }
 
 /*******************************************************************
@@ -2173,29 +2232,28 @@ Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1)
  *       reporting configuration. If so, send the update to 
  *       respective layer.
  *
- * @params[in]
+ * @params[in] Subscription Info
  *             
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction)
+uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo)
 {
-   Statistics stats;
-
-   switch(subscribedAction.styleType)
-   {
-      case 1:
-         stats = FetchStatsFromActionDefFormat1(subscribedAction.choice.format1);
-      case 2:
-      case 3:
-      case 4:
-      case 5:
-      default:
-         break;
-   }
-
-   if(BuildAndSendStatsReqToMac(stats.macStatsReq) != ROK)
+   uint64_t   subscriptionId = 0; 
+
+   /* Calculate 64 bit subscription-ID :
+    *  First 16 MSB is unused
+    *  Next 16 MSB = RAN-Function-ID
+    *  Next 16 MSB = Requestor-ID in RIC-Request-ID
+    *  Last 16 LSB = Instance-ID in RIC-Request-ID
+    */
+   subscriptionId = ricSubscriptionInfo->requestId.instanceId;
+   subscriptionId |= ((uint64_t)ricSubscriptionInfo->requestId.requestorId << 16);
+   subscriptionId |= ((uint64_t)ranFuncId << 32);
+
+   /* Build and sent subscription information to MAC in Statistics Request */
+   if(BuildAndSendStatsReqToMac(subscriptionId, ricSubscriptionInfo) != ROK)
    {
       DU_LOG("\nERROR  -->  DU_APP : Failed at BuildAndSendStatsReqToMac()");
       return RFAILED;   
@@ -2204,18 +2262,13 @@ uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction)
 /* TODO : When KPI collection from RLC will be supported, this function will be 
  * called to configure KPIs to be colled */
 #if 0
-   if(BuildAndSendStatsReqToRlc(macStatsReq->rlcStatsReq) != ROK)
+   if(BuildAndSendStatsReqToRlc() != ROK)
    {
-       DU_LOG("\nERROR  -->  DU_APP : Failed at BuildAndSendStatsReqToRlc()");
-       return RFAILED;
+      DU_LOG("\nERROR  -->  DU_APP : Failed at BuildAndSendStatsReqToRlc()");
+      return RFAILED;
    }
 #endif
 
-   /* TODO : In the caller of this function, change ActionDefinition->action
-    * from CONFIG_ADD to CONFIG_UNKNOWN once configuration is sent 
-    * To be done in next gerrit*/
-    
-
    return ROK;
 }
 
@@ -2240,13 +2293,12 @@ uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction)
  * ****************************************************************/
 uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp)
 {
-   uint8_t idx = 0;
-
    DU_LOG("\nINFO  -->  DU_APP : DuProcMacStatsRsp: Received Statistics Response from MAC");
 
    if(statsRsp)
    {
 #ifdef DEBUG_PRINT   
+      uint8_t idx = 0;
       DU_LOG("\n  Subscription Id [%ld]", statsRsp->subscriptionId);
 
       DU_LOG("\n  Number of Accepted Groups [%d]", statsRsp->numGrpAccepted);
@@ -2261,6 +2313,20 @@ uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp)
          DU_LOG("\n    Group Id [%d]", statsRsp->statsGrpRejectedList[idx]);
       }
 #endif      
+     
+      /* TODO :
+       * For accepted groups:
+       *    Mark scubscrbed-action's -> action = CONFIG_UNKNOWN
+       *    Add action ID to accpeted-action-list in Subscription response
+       *
+       * For rejected groups:
+       *    Remove entry from DU's RAN Function->subscription->actionList
+       *    Add Rejected action Id to reject-action-list created by DU APP while
+       *     processing of subscription request.
+       *
+       * Send subscription response with accepted and rejected action lists to
+       * RIC
+       */
 
       DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
       return ROK;
index 18b9876..9b4ce41 100644 (file)
 #include "RIC-EventTriggerStyle-Item.h"
 #include "RIC-ReportStyle-Item.h"
 #include "MeasurementInfo-Action-Item.h"
+#include "MeasurementInfoItem.h"
+#include "E2SM-KPM-ActionDefinition-Format1.h"
+#include "E2SM-KPM-ActionDefinition.h"
+#include "E2SM-KPM-EventTriggerDefinition-Format1.h"
+#include "E2SM-KPM-EventTriggerDefinition.h"
+
 
 /*******************************************************************
  *
@@ -482,8 +488,7 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
       idx++;
       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
-      e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
-                                                               E2setupResponseIEs__value_PR_GlobalRIC_ID;
+      e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID;
 
       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
       {
@@ -510,8 +515,9 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
-      E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
-      if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->value.choice.E2nodeComponentConfigAdditionAck_List, duDb)!=ROK)
+         E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
+      if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\
+         value.choice.E2nodeComponentConfigAdditionAck_List, duDb) != ROK)
       {
          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
          break;
@@ -547,89 +553,467 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
    }
 
    FreeE2SetupRsp(e2apMsg);
-   BuildAndSendRicSubscriptionReq(duDb->duId);
+   BuildAndSendRicSubscriptionReq(duDb);
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Free RIC Subscription Details
+ *
+ * @details
+ *
+ *    Function : FreeRicSubsDetails
+ *
+ *    Functionality: Free the RIC Subscription Details
+ *
+ * @params[in] RICsubscriptionDetails_t *subsDetails
+ * @return void
+ *
+ * ****************************************************************/
+void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
+{
+   uint8_t elementIdx = 0;
+   RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
+
+   RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
+
+   if(subsDetails->ricAction_ToBeSetup_List.list.array)
+   {
+      for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
+      {
+         if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
+         {
+            actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
+            if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
+            {
+               RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \
+                  actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size);
+               RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
+            }
+            RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t))
+         }
+      }
+      RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Free RIC Subscription Request
+ *
+ * @details
+ *
+ *    Function : FreeRicSubscriptionReq
+ *
+ * Functionality : Free RIC Subscription Request
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg)
+{
+   uint8_t idx = 0;
+   RICsubscriptionRequest_t   *ricSubscriptionReq;
+
+   if(e2apRicMsg)
+   {
+      if(e2apRicMsg->choice.initiatingMessage)
+      {
+         ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
+         if(ricSubscriptionReq->protocolIEs.list.array)
+         {
+            for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
+            {
+               switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
+               {
+                  case ProtocolIE_IDE2_id_RICsubscriptionDetails:
+                     {
+                        FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
+                        break;
+                     }
+               }               
+               RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
+            }
+            RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
 /*******************************************************************
  *
  * @brief Builds Ric Request Id
  *
  * @details
  *
- *    Function : BuildRicRequestId
+ *    Function : BuildNewRicRequestId
  *
- *    Functionality: Building the Ric Request Id
+ *    Functionality: Assign new Ric Request ID
  *
- * @params[in] RICrequestID_t *ricReqId
+ * @params[in] RIC request ID to be sent
+ *             RIC request ID stored in DB
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
 
-uint8_t BuildRicRequestId(RICrequestID_t *ricReqId)
+uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb)
 {
+   static uint16_t requestorId = 0;
+   static uint16_t instanceId = 0;
 
    if(ricReqId != NULLP)
    {
-      ricReqId->ricRequestorID = 1;
-      ricReqId->ricInstanceID  = 1;
+      ricReqId->ricRequestorID = ++requestorId;
+      ricReqId->ricInstanceID  = ++instanceId;
+
+      reqIdDb->requestorId = ricReqId->ricRequestorID;
+      reqIdDb->instanceId = ricReqId->ricInstanceID;
    }
    return ROK;
 }
 
 /*******************************************************************
  *
- * @brief Fills Ric Action To be Setup Item
+ * @brief Free RIC Action Definition
  *
  * @details
  *
- *    Function : fillSetupItems
+ *    Function : FreeRicActionDefinition
  *
- *    Functionality: Filling ricAction Id, RicActionType
+ *    Functionality: Free RIC Action Definition
  *
- * @params[in] RICaction_ToBeSetup_Item_t *setupItems
- * @return pointer of type RICaction_ToBeSetup_Item_t
+ * @params[in] E2SM-KPM Action definition
+ * @return void
  *
  * ****************************************************************/
+void  FreeRicActionDefinition(E2SM_KPM_ActionDefinition_t actionDef)
+{
+   uint8_t  elementIdx = 0;
+   E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
+   MeasurementInfoItem_t *measItem = NULLP;
+
+   switch(actionDef.actionDefinition_formats.present)
+   {
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
+         {
+            if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1)
+            {
+               actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
+               if(actionFormat1->measInfoList.list.array)
+               {
+                  for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
+                  {
+                     if(actionFormat1->measInfoList.list.array[elementIdx])
+                     {
+                        measItem = actionFormat1->measInfoList.list.array[elementIdx];
+                        switch(measItem->measType.present)
+                        {
+                           case MeasurementType_PR_NOTHING:
+                           case MeasurementType_PR_measID:
+                              break;
+                           case MeasurementType_PR_measName:
+                           {
+                              RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size)
+                              break;
+                           }
+                        }
+                        RIC_FREE(measItem, sizeof(MeasurementInfoItem_t));
+                     }
+                  }
+                  RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
+               }
+               RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t));
+            }
+            break;
+         }
+
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
+      case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING:
+         break;
+   }
+}
 
-RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
+/*******************************************************************
+ *
+ * @brief Fill RIC Action Definition
+ *
+ * @details
+ *
+ *    Function : fillRicActionDef
+ *
+ *    Functionality: Fill RIC Action Definition
+ *
+ * @params[in] RIC Action definition
+ * @return ROK 
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef)
 {
-   if(setupItems != NULLP)
+   uint8_t ret = RFAILED;
+   asn_enc_rval_t  encRetVal;
+   uint8_t elementCnt = 0, elementIdx = 0;
+   char    *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"};
+   E2SM_KPM_ActionDefinition_t actionDef;
+   E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
+   MeasurementInfoItem_t *measItem = NULLP;
+   
+   while(true)
    {
-      setupItems->ricActionID = 0;
-      setupItems->ricActionType = RICactionType_report;
+      /* Fill E2SM-KPM Action Definition Format 1 */
+
+      /* RIC Stype Type */
+      actionDef.ric_Style_Type = RIC_STYLE_TYPE;
+
+      /* RIC Action Definition Format 1 */
+      actionDef.actionDefinition_formats.present = \
+           E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1;
+
+      RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \
+            sizeof(E2SM_KPM_ActionDefinition_Format1_t));
+      if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+      actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
+
+      /* Measurement Info List */
+      elementCnt = 2;
+      actionFormat1->measInfoList.list.count = elementCnt;
+      actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *);
+      RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
+      if(actionFormat1->measInfoList.list.array == NULL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+
+      for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
+      {
+         RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t));
+         if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+            break;
+         }
+
+         measItem = actionFormat1->measInfoList.list.array[elementIdx];
+         measItem->measType.present = MeasurementType_PR_measName;
+
+         measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]);
+         RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size);
+         if(measItem->measType.choice.measName.buf == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+            break;
+         }
+         memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size);
+      }
+      if(elementIdx < elementCnt)
+         break;
+
+      /* Granularity Period */
+      actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD; /* In ms */
+
+      /* Prints the Msg formed */
+      xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef);
+
+      /* Encode E2SM-KPM RIC Action Definition */
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+
+      /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */
+      ricActionDef->size = encBufSize;
+      RIC_ALLOC(ricActionDef->buf, encBufSize);
+      if(ricActionDef->buf == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+      memcpy(ricActionDef->buf, encBuf, encBufSize);
+
+      ret = ROK;
+      break;
    }
 
-   return (setupItems);
+   FreeRicActionDefinition(actionDef);
+   return ret;
 }
 
 /*******************************************************************
  *
- * @brief Fills RIC Subscription Details Item List
+ * @brief Fills RIC Action To Be Setup Item
  *
  * @details
  *
- *    Function : fillSubsDetails
+ *    Function : fillActionToBeSetup
  *
- *    Functionality: Fill the RIC Subscription Details Items List
+ *    Functionality: Fill the RIC Action To Be Setup Ite,
+ *                   RIC subscription DB
  *
  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
+uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb)
+{
+   static uint8_t ricActionId = 0;
+
+   if(actionItem == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
+      return RFAILED;
+   }
+
+   while(true)
+   {
+      actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
+      actionItem->criticality   =  CriticalityE2_ignore;
+      actionItem->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
+      
+      /* RIC Action ID */
+      actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ++ricActionId;
+      ricSubsDb->actionSequence[ricSubsDb->numOfActions].id = \
+         actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
+
+      /* RIC Action Type */
+      actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
+
+      /* RIC Action Definition */
+      RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
+      if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+      if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+      
+      ricSubsDb->numOfActions++;
+      return ROK;
+   }
+
+   memset(&ricSubsDb->actionSequence[ricSubsDb->numOfActions], 0, sizeof(ActionInfo));
+   return RFAILED;
+}
+
+/*******************************************************************
+ *
+ * @brief Free Event Trigger Definition
+ *
+ * @details
+ *
+ *    Function : FreeEventTriggerDef
+ *
+ *    Functionality: Free Event Trigger Definition
+ *
+ * @params[in] E2SM-KPM Event Trigger Definition
+ * @return void
+ *
+ * ****************************************************************/
+void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
+{
+   if(eventTiggerDef)
+   {
+      switch(eventTiggerDef->eventDefinition_formats.present)
+      {
+         case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
+            break;
+         case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
+            RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
+                  sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
+            break;                  
+      }         
+   }
+}
 
-uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
+/*******************************************************************
+ *
+ * @brief Fill Event Trigger Definition
+ *
+ * @details
+ *
+ *    Function : fillEventTriggerDef
+ *
+ *    Functionality: Fill Event Trigger Definition
+ *
+ * @params[in] RIC Event Trigger Definition
+ * @return ROK
+ *         RFAILED
+ *
+ * ****************************************************************/
+uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
 {
-   if(items != NULLP)
+   uint8_t ret = RFAILED;
+   asn_enc_rval_t  encRetVal;
+   E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
+
+   while(true)
    {
-      items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
-      items->criticality   =  CriticalityE2_ignore;
-      items->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
-      fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
+      /* Fill E2SM-KPM Event Trigger Definition Format 1 */
+      eventTiggerDef.eventDefinition_formats.present = \
+       E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
+
+      RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
+            sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
+      if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+
+      eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
+
+      /* Prints the Msg formed */
+      xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
+
+      /* Encode E2SM-KPM Event Trigger Definition */
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+
+      /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
+      ricEventTriggerDef->size = encBufSize;
+      RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
+      if(ricEventTriggerDef->buf == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+      memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
+
+      ret = ROK;
+      break;
    }
-   return ROK;
+
+   FreeEventTriggerDef(&eventTiggerDef);
+   return ret;
 }
 
 /*******************************************************************
@@ -642,41 +1026,67 @@ uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
  *
  *    Functionality: Builds the RIC Subscription Details
  *
- * @params[in] RICsubscriptionDetails_t *subsDetails
+ * @params[in] RIC Subscription details to be filled
+ *             RIC subscriotion DB
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
 
-uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
+uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsDb)
 {
+   uint8_t elementCnt = 0;
+   uint8_t elementIdx = 0;
 
-   uint8_t elementCnt;
+   if(subsDetails == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
+      return RFAILED;
+   }
 
-   if(subsDetails != NULLP)
+   while(true)
    {
-      /* Octet string to be build here */
-      /* Sending PLMN as Octect string */
-      uint8_t byteSize = 3;
-      subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t);
-      RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf,  subsDetails->ricEventTriggerDefinition.size);
-      buildPlmnId(ricCb.ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
+      /* RIC Event Trigger Definition */
+      if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+
+      /* RIC Actions To Be Setup List */
       elementCnt = 1;
       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
-      subsDetails->ricAction_ToBeSetup_List.list.size = \
-                      elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
-      RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
-                subsDetails->ricAction_ToBeSetup_List.list.size);
+      subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
+      RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
       {
          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
-         return RFAILED;
+         break;
       } 
-      RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
-                   sizeof(RICaction_ToBeSetup_ItemIEs_t));
-      fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
+
+      for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
+      {
+         RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
+         if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+            break;
+         }
+      }
+      if(elementIdx < elementCnt)
+         break;
+
+      elementIdx = 0;
+      if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
+         ricSubsDb) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+
+      return ROK;
    }
-   return ROK;
+   return RFAILED;
 }
 
 /*******************************************************************
@@ -693,137 +1103,137 @@ uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
  *         RFAILED - failure
  *
  ******************************************************************/
-
-uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId)
+uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
 {
-
+   uint8_t         ret = RFAILED;
    E2AP_PDU_t                 *e2apRicMsg = NULL;
    RICsubscriptionRequest_t   *ricSubscriptionReq;
    uint8_t         elementCnt;
    uint8_t         idx;
    uint8_t         ieId;
-   uint8_t         ret; 
    asn_enc_rval_t  encRetVal;        /* Encoder return value */
+   RanFunction     *ranFuncDb = &duDb->ranFunction[0];
 
    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
 
-   RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
-   if(e2apRicMsg == NULLP)
+   while(true)
    {
-      DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
-      return RFAILED;
-   }
+      RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
+      if(e2apRicMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
 
-   e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
-   RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
-   if(e2apRicMsg->choice.initiatingMessage == NULLP)
-   {
-      DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
-      RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
-      return RFAILED;
-   }
-   e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
-   e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
-   e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
-   
-   RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
-   ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
-   
-   elementCnt = 3;
-   ricSubscriptionReq->protocolIEs.list.count = elementCnt;
-   ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
-
-   /* Initialize the subscription members */
-   RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
-              ricSubscriptionReq->protocolIEs.list.size);
-   if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
-   {
-      DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICSubscriptionRequestIEs failed");
-      RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
-      RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
-      return RFAILED;
-   }
-   
-   for(idx=0; idx<elementCnt; idx++)
-   {
-      RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
-            sizeof(RICsubscriptionRequest_IEs_t));
-      if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
+      e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
+      RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      if(e2apRicMsg->choice.initiatingMessage == NULLP)
       {
-         for(ieId=0; ieId<idx; ieId++)
-         {
-            RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
-                  sizeof(RICsubscriptionRequest_IEs_t));
-         }
-         RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
-                  ricSubscriptionReq->protocolIEs.list.size);
-         RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
-               sizeof(InitiatingMessageE2_t));
-         RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
-         return RFAILED;
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
       }
-   }
+      e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
+      e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+      e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
 
-   /* Filling RIC Request Id */
-   idx = 0;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
-                                    RICsubscriptionRequest_IEs__value_PR_RICrequestID;
-   BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
+      ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
 
+      elementCnt = 3;
+      ricSubscriptionReq->protocolIEs.list.count = elementCnt;
+      ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
 
-   /* Filling RAN Function Id */
-   idx++;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
-                                    RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
+      /* Initialize the subscription members */
+      RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
+      if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+
+      for(idx=0; idx<elementCnt; idx++)
+      {
+         RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
+         if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+            break;
+         }
+      }
+      if(idx < elementCnt)
+         break;
 
+      /* Filling RIC Request Id */
+      idx = 0;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
+                                                                      RICsubscriptionRequest_IEs__value_PR_RICrequestID;
+      if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
+         &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription].requestId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed at [%d] : Line [%d]", __func__, __LINE__);
+         break;
+      }
 
-   /* Filling RIC Subscription Details */
-   idx++;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
-   ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
-                                    RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
 
-   BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
+      /* Filling RAN Function Id */
+      idx++;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
+                                                                      RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
 
+      /* Filling RIC Subscription Details */
+      idx++;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+      ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
+                                                                      RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
+      if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
+         &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription]) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed at [%d] : Line [%d]", __func__, __LINE__);
+         break;
+      }
 
-   /* Prints the Msg formed */
-   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
+      /* Prints the Msg formed */
+      xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
 
-   memset(encBuf, 0, ENC_BUF_MAX_LEN);
-   encBufSize = 0;
-   encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
-               encBuf);
-   if(encRetVal.encoded == ENCODE_FAIL)
-   {
-      DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
-      encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
-      return RFAILED;
-   }
-   else
-   {
-      DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
-      for(int i=0; i< encBufSize; i++)
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
       {
-          DU_LOG("%x",encBuf[i]);
-      } 
-   }
+         DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;               
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         } 
+      }
 
+      /* Sending msg */
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
+         break;
+      }
 
-   /* Sending msg */
-   if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
-   {
-      DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
-      return RFAILED;
+      ranFuncDb->numOfSubscription++;
+      ret = ROK;
+      break;
    }
 
-   return ROK;
+   if(ret == RFAILED)
+      memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription));
+   FreeRicSubscriptionReq(e2apRicMsg);
+   return ret;
 }
 
 /*******************************************************************
@@ -1075,7 +1485,6 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
                      }
                      case ProtocolIE_IDE2_id_RANfunctionsAdded:
                      {
-                                                               
                         ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
 
                         if(ranFunctionsList->list.array)
@@ -1084,8 +1493,8 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
                            {
                               ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
                               ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
-                              duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID;
-                              duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision;
+                              duDb->ranFunction[duDb->numOfRanFunction].id = ranFunItem->ranFunctionID; 
+                              duDb->ranFunction[duDb->numOfRanFunction].revisionCounter = ranFunItem->ranFunctionRevision; 
                               duDb->numOfRanFunction++;
                            }
                         }
@@ -1100,12 +1509,15 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
                            {
                               if(e2NodeAddList->list.array[e2NodeAddListIdx])
                               {
-                                 e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx];
-                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\
-                                       e2nodeComponentInterfaceTypeF1)
+                                 e2NodeAddItem = \
+                                    (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
+                                 if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
+                                    choice.e2nodeComponentInterfaceTypeF1)
                                  {
                                     duDb->e2NodeComponent.interfaceType = F1; 
-                                    duDb->e2NodeComponent.componentId = e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
+                                    duDb->e2NodeComponent.componentId = \
+                                       e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\
+                                       choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; 
                                  }
                               }
                            }
index aba63d2..e370ed6 100644 (file)
 #define TRANS_ID 1
 #define RRC_SIZE 1
 #define ENC_BUF_MAX_LEN 100
-#define SUL_BAND_COUNT 0
+#define SUL_BAND_COUNT  0
 #define UL_SRBID        1
 #define DL_SRBID        0
 #define DU_ID           1
-#define RIC_ID           1
+#define RIC_ID          1
 #define CRNTI           17017
 #define CELL_INDEX      0
 
+#define RIC_STYLE_TYPE  1
+#define RIC_ACTION_GRANULARITY_PERIOD 100
 /* allocate and zero out a static buffer */
 #define RIC_ALLOC(_datPtr, _size)                                \
 {                                                               \
@@ -53,7 +55,7 @@
 
 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf);
 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId);
-uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId);
+uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb);
 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId);
 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb);
 /**********************************************************************
index 0452820..5213a79 100644 (file)
 #define MAX_RAN_FUNCTION 256        /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.1.2.2 : maxofRANfunctionID */
 #define MAX_NUM_TRANSACTION 256     /* As per, O-RAN WG3 E2AP v3.0, section 9.2.33 */
 
+#define MAX_RIC_ACTION  16          /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.1.1.1 : maxofRICActionID */
+#define MAX_RIC_REQUEST 5           /* As per O-RAN.WG3.E2AP-R003-v03.00 : Section 9.2.7, max request is 65535. \
+                                     * But for our internal testing purpose, keeping it to 5 for now */
+
 /* allocate and zero out a static buffer */
 #define RIC_ALLOC(_datPtr, _size)                                \
 {                                                               \
@@ -90,11 +94,30 @@ typedef enum
    X2
 }InterfaceType;
 
+typedef struct
+{
+   uint16_t requestorId;
+   uint16_t instanceId;
+}RicRequestId;
+
+typedef struct
+{
+   uint8_t           id;
+}ActionInfo;
+
+typedef struct ricSubscription
+{
+   RicRequestId    requestId;
+   uint8_t         numOfActions;
+   ActionInfo      actionSequence[MAX_RIC_ACTION];
+}RicSubscription;
 
 typedef struct
 {
    uint16_t  id;
    uint16_t  revisionCounter;
+   uint8_t   numOfSubscription;
+   RicSubscription subscriptionList[MAX_RIC_REQUEST];
 }RanFunction;
 
 typedef struct