[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-535] Implementation of E2 Removal Procedure...
[o-du/l2.git] / src / ric_stub / ric_e2ap_msg_hdl.c
index e648cf6..b8b4888 100644 (file)
 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
 #include "E2SM-KPM-EventTriggerDefinition.h"
 
+/*******************************************************************
+ *
+ * @brief Printing Type and Cause of failure
+ *
+ * @details
+ *
+ *    Function : printE2ErrorCause
+ *
+ *    Functionality: Printing Type and Cause of failure
+ *
+ * @params[in] E2 Cause
+ * @return void
+ *
+ ******************************************************************/
+
+void printE2ErrorCause(CauseE2_t *cause)
+{
+   switch(cause->present)
+   {
+      case CauseE2_PR_ricRequest:
+         {
+            DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Request", cause->choice.ricRequest);
+            break;
+         }
+      case CauseE2_PR_ricService:
+         {
+            DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Service", cause->choice.ricService);
+            break;
+         }
+      case CauseE2_PR_e2Node:
+         {
+            DU_LOG("Failure_Type [%s] Cause [%ld]", "E2_Node", cause->choice.e2Node);
+            break;
+         }
+      case CauseE2_PR_transport:
+         {
+            DU_LOG("Failure_Type [%s] Cause [%ld]", "Transport", cause->choice.transport);
+            break;
+         }
+      case CauseE2_PR_protocol:
+         {
+            DU_LOG("Failure_Type [%s] Cause [%ld]", "Protocol", cause->choice.protocol);
+            break;
+         }
+      case CauseE2_PR_misc:
+         {
+            DU_LOG("Failure_Type [%s] Cause [%ld]", "Miscellaneous", cause->choice.misc);
+            break;
+         }
+      default:
+         {
+            DU_LOG("Failure_Type and Cause unknown");
+            break;
+         }
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief fill E2 failure cause 
+ *
+ * @details
+ *
+ *    Function : fillE2FailureCause
+ *
+ * Functionality: fill E2 failure cause
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+
+void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
+{
+   cause->present = causePresent;
+
+   switch(cause->present)
+   {
+      case CauseE2_PR_ricRequest:
+         cause->choice.ricRequest = reason;
+         break;
+      case CauseE2_PR_ricService:
+         cause->choice.ricService = reason;
+         break;
+      case CauseE2_PR_e2Node:
+         cause->choice.e2Node = reason;
+         break;
+      case CauseE2_PR_transport:
+         cause->choice.transport = reason;
+         break;
+      case CauseE2_PR_protocol:
+         cause->choice.protocol = reason;
+         break;
+      case CauseE2_PR_misc:
+         cause->choice.misc = reason;
+         break;
+      default:
+         cause->choice.misc = CauseE2Misc_unspecified;
+         break;
+   }
+}
 
 /*******************************************************************
  *
@@ -125,6 +225,168 @@ uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
    return ROK;
 } /* SendE2APMsg */
 
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for RemovalRequest msg
+ *
+ * @details
+ *
+ *    Function : FreeRemovalRequest
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for RemovalRequest
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void FreeRemovalRequest(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0;
+   E2RemovalRequest_t  *removalReq = NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.initiatingMessage != NULLP)
+      {
+         removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
+         if(removalReq->protocolIEs.list.array)
+         {
+            for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++)
+            {
+               RIC_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
+            }
+            RIC_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Build and send the removal request msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendRemovalRequest
+ *
+ *    Functionality:
+ *         - Buld and send the removal request msg to E2 node
+ *
+ * @params[in]
+ *    DU database
+ *    Type of failure
+ *    Cause of failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendRemovalRequest(DuDb *duDb)
+{
+   uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
+   uint8_t ret = RFAILED;
+   E2AP_PDU_t        *e2apMsg = NULLP;
+   E2RemovalRequest_t  *removalReq = NULLP;
+   asn_enc_rval_t     encRetVal;       /* Encoder return value */
+
+   DU_LOG("\nINFO   -->  E2AP : Building Removal Request\n");
+
+   do
+   {
+      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
+      RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      if(e2apMsg->choice.initiatingMessage == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal;
+      e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+      e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest;
+      removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
+
+      elementCnt = 1;
+      removalReq->protocolIEs.list.count = elementCnt;
+      removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *);
+
+      RIC_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
+      if(!removalReq->protocolIEs.list.array)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
+      {
+         RIC_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
+         if(!removalReq->protocolIEs.list.array[ieIdx])
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+            break;
+         }
+      }
+
+      /* In case of failure */
+      if(ieIdx < elementCnt)
+         break;
+
+      ieIdx = 0;
+      removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+      removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID;
+      transId = assignTransactionId(duDb);
+      removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      /* Prints the Msg formed */
+      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 removal request structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for removal request\n");
+#ifdef DEBUG_ASN_PRINT
+         for(int i=0; i< encBufSize; i++)
+         {
+            printf("%x",encBuf[i]);
+         }
+#endif
+      }
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Sending removal request failed");
+         break;
+      }
+
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   /* Free all memory */
+   FreeRemovalRequest(e2apMsg);
+   return ret;
+}
+
 /*******************************************************************
  *
  * @brief Fetches RAN Function DB
@@ -176,20 +438,30 @@ RanFunction *fetchRanFuncFromRanFuncId(DuDb *duDb, uint16_t ranFuncId)
  *         NULL, in case of failure
  *
  * ****************************************************************/
-RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb)
+RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb, CmLList **ricSubscriptionNode)
 {
-   uint8_t subsIdx = 0;
    RicSubscription *ricSubscriptionInfo = NULLP;
 
-   for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++)
+   /* Fetch subscription detail in RAN Function DB */
+   CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, *ricSubscriptionNode);
+   while(*ricSubscriptionNode)
    {
-      if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) &&
-            (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId))
+      ricSubscriptionInfo = (RicSubscription *)((*ricSubscriptionNode)->node);
+      if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
+            (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
       {
-         ricSubscriptionInfo = &ranFuncDb->subscriptionList[subsIdx];
          break;
       }
+      *ricSubscriptionNode = (*ricSubscriptionNode)->next;
+      ricSubscriptionInfo = NULLP;
    }
+
+   if(!ricSubscriptionInfo)
+   {
+      DU_LOG("\nERROR  -->  E2AP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
+         Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id);
+   }
+
    return ricSubscriptionInfo;
 }
 
@@ -227,74 +499,295 @@ ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSu
    return actionInfoDb;
 }
 
-/*******************************************************************
+/******************************************************************
  *
- * @brief deallocate memory allocated in E2 Node Config Update Failure
+ * @brief Search E2 node component with the help of interface type
+ * and component Id
  *
  * @details
  *
- *    Function : FreeE2ConfigUpdateFail
+ *    Function : fetchE2NodeComponentInfo
  *
- *    Functionality: deallocate memory allocated in E2 Node Config Update Failure
+ *    Functionality: Search E2 node component 
  *
- * @params[in] E2AP_PDU_t *e2apMsg
+ * @params[in]
+ *       DU databse
+ *       Type of interface
+ *       Pointer to E2 component node to be searched
+ * @return CmLList
  *
- * @return void
  * ****************************************************************/
 
-void FreeE2ConfigUpdateFail(E2AP_PDU_t *e2apMsg)
+E2NodeComponent *fetchE2NodeComponentInfo(DuDb *duDb, InterfaceType interfaceType,CmLList **e2ComponentNode)
 {
-   uint8_t arrIdx = 0;
-   E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
+   E2NodeComponent *e2NodeComponentInfo=NULLP;
 
-   if(e2apMsg)
+   if(duDb->e2NodeComponent.count)
    {
-      if(e2apMsg->choice.unsuccessfulOutcome)
+      CM_LLIST_FIRST_NODE(&duDb->e2NodeComponent, *e2ComponentNode);
+      while(*e2ComponentNode)
       {
-         e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
-         if(e2NodeCfgUpdFail->protocolIEs.list.array)
+         e2NodeComponentInfo = (E2NodeComponent*)((*e2ComponentNode)->node);
+         if((e2NodeComponentInfo->interfaceType == interfaceType))
          {
-            for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
-            {
-               RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateFailure_IEs_t));
-            }
-            RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array, e2NodeCfgUpdFail->protocolIEs.list.size);
+            break;
          }
-         RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+
+         *e2ComponentNode = (*e2ComponentNode)->next;
+         e2NodeComponentInfo = NULLP;
       }
-      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
    }
+   return e2NodeComponentInfo;
 }
 
 /*******************************************************************
  *
- * @brief Buld and send the E2 Node Config Update failure
+ * @brief update E2 node config list
  *
  * @details
  *
- *    Function : BuildAndSendE2NodeConfigUpdateFailure
+ *    Function : updateE2NodeConfigList
  *
  *    Functionality:
- *         - Buld and send the E2 Node Config Update failure
+ *         - update E2 node config list
+ * @params[in]
+ *    DU databse
+ *    Protocol Id
+ *    Configuration which need to update in Database
+ *
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
-
-uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, uint8_t causeInfo, uint8_t causeReason)
+uint8_t updateE2NodeConfigList(DuDb **duDb, uint8_t protocolId, E2NodeConfigItem *tmpCfg)
 {
-   E2AP_PDU_t         *e2apMsg = NULL;
-   asn_enc_rval_t     encRetVal;
-   uint8_t            arrIdx=0;
-   uint8_t            elementCnt=0;
-   bool  memAllocFailed = false;
-   E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdateFail=NULL;
+   CmLList *node;
+   E2NodeComponent * e2NodeComponentInfo;
+   bool configFound= false;
 
-   DU_LOG("\nINFO   -->  E2AP : Building E2 Node Config Update failure\n");
-   while(true)
+   switch(protocolId)
    {
-      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
-      if(e2apMsg == NULLP)
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
+         {
+            /* Adding the new e2 node component in DB*/
+            RIC_ALLOC(e2NodeComponentInfo, sizeof(E2NodeComponent));
+            e2NodeComponentInfo->interfaceType = tmpCfg->componentInfo.interfaceType;
+            e2NodeComponentInfo->componentId =tmpCfg->componentInfo.componentId;
+            RIC_ALLOC(node, sizeof(CmLList));
+            if(node)
+            {
+               node->node = (PTR) e2NodeComponentInfo;
+               cmLListAdd2Tail(&(*duDb)->e2NodeComponent, node);
+               configFound =true;
+            }
+            else
+            {
+               DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for e2NodeComponentList node");
+               RIC_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
+               return RFAILED;
+            }
+            break;
+         }
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
+         {
+            /* searching for information in a database */
+            e2NodeComponentInfo = fetchE2NodeComponentInfo((*duDb),tmpCfg->componentInfo.interfaceType,  &node);
+            if(!e2NodeComponentInfo)
+            {
+               DU_LOG("\nERROR  -->  E2AP : Failed to find the e2 component node");
+               return RFAILED;
+            }
+            /* If the node is present then update the value */
+            e2NodeComponentInfo->componentId =tmpCfg->componentInfo.componentId;
+            configFound =true;
+            break;
+         }
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
+         {
+            /* searching for information in a database */
+            e2NodeComponentInfo = fetchE2NodeComponentInfo((*duDb),tmpCfg->componentInfo.interfaceType, &node);
+            if(!e2NodeComponentInfo)
+            {
+               DU_LOG("\nERROR  -->  E2AP : Failed to find the e2 component node");
+               return RFAILED;
+            }
+            /* Delete the node from the list  */
+            e2NodeComponentInfo->componentId = tmpCfg->componentInfo.componentId;
+            cmLListDelFrm(&(*duDb)->e2NodeComponent, node);
+            RIC_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
+            configFound =true;
+            break;
+         }
+   }
+
+   /* If the configuration update was successful, then mark the isSuccessful as
+    * true; otherwise, mark it as false. */ 
+   if(configFound == true)
+      tmpCfg->isSuccessful = true;
+   else
+      tmpCfg->isSuccessful = false;
+
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handling the E2 node configuration depending on the add, 
+ * update, or remove configuration type
+ *
+ * @details
+ *
+ *    Function : handleE2NodeComponentAction
+ *
+ *    Functionality:
+ *         - Handling the E2 node configuration depending on the add,
+ *         update, or remove configuration type
+ * @params[in] 
+ *    DU database
+ *    Pointer to e2NodeCfg which has info 
+ *    ProtocolId
+ *    E2NodeConfigItem to be filled
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t handleE2NodeComponentAction(DuDb *duDb, PTR e2NodeCfg, uint8_t protocolId, E2NodeConfigItem *storeCfg)
+{
+   uint8_t configFound = ROK;
+   E2NodeConfigItem tmpCfg;
+   E2nodeComponentID_t componentId;
+   E2nodeComponentInterfaceType_t interface;
+   E2nodeComponentConfigAddition_Item_t *addCfg=NULL;
+   E2nodeComponentConfigUpdate_Item_t *updateCfg=NULL;
+   E2nodeComponentConfigRemoval_Item_t *removeCfg=NULL;
+   
+   /* fetching the interface and component id information from the e2NodeCfg */
+   memset(storeCfg, 0, sizeof(E2NodeConfigItem));
+   storeCfg->isSuccessful=false;
+   memset(&tmpCfg, 0, sizeof(E2NodeConfigItem));
+
+   switch(protocolId)
+   {
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
+         {
+            addCfg = (E2nodeComponentConfigAddition_Item_t *)e2NodeCfg;
+            interface = addCfg->e2nodeComponentInterfaceType;
+            componentId = addCfg->e2nodeComponentID;
+            break;
+         }
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
+         {
+            updateCfg = (E2nodeComponentConfigUpdate_Item_t *)e2NodeCfg;
+            interface = updateCfg->e2nodeComponentInterfaceType;
+            componentId = updateCfg->e2nodeComponentID;
+            break;
+         }
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
+         {
+            removeCfg = (E2nodeComponentConfigRemoval_Item_t*)e2NodeCfg;
+            interface = removeCfg->e2nodeComponentInterfaceType;
+            componentId = removeCfg->e2nodeComponentID;
+            break;
+         }
+   }
+   
+   /* Storing the information in temporary structure */
+   tmpCfg.componentInfo.interfaceType = interface;
+
+   switch(componentId.present)
+   {
+      case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
+         {
+            if(componentId.choice.e2nodeComponentInterfaceTypeF1)
+            {
+               tmpCfg.componentInfo.componentId = componentId.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0];
+            }
+            break;
+         }
+      default:
+         {
+            break;
+         }
+   }
+
+   /* Updating the database configuration  */ 
+   configFound = updateE2NodeConfigList(&duDb, protocolId, &tmpCfg);
+
+   memcpy(storeCfg, &tmpCfg,sizeof(E2NodeConfigItem));  
+   return configFound;
+
+}
+
+/*******************************************************************
+ *
+ * @brief deallocate memory allocated in E2 Node Config Update Failure
+ *
+ * @details
+ *
+ *    Function : FreeE2ConfigUpdateFail
+ *
+ *    Functionality: deallocate memory allocated in E2 Node Config Update Failure
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ *
+ * @return void
+ * ****************************************************************/
+
+void FreeE2ConfigUpdateFail(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t arrIdx = 0;
+   E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
+
+   if(e2apMsg)
+   {
+      if(e2apMsg->choice.unsuccessfulOutcome)
+      {
+         e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
+         if(e2NodeCfgUpdFail->protocolIEs.list.array)
+         {
+            for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
+            {
+               RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateFailure_IEs_t));
+            }
+            RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array, e2NodeCfgUpdFail->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Node Config Update failure
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2NodeConfigUpdateFailure
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Node Config Update failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, uint8_t causeInfo, uint8_t causeReason)
+{
+   E2AP_PDU_t         *e2apMsg = NULL;
+   asn_enc_rval_t     encRetVal;
+   uint8_t            arrIdx=0;
+   uint8_t            elementCnt=0;
+   bool  memAllocFailed = false;
+   E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdateFail=NULL;
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Node Config Update failure\n");
+   while(true)
+   {
+      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
       {
          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
          break;
@@ -405,45 +898,158 @@ uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, ui
  *
  * Functionality: Process E2 node configuration update
  *
- * @return ROK     - success
- *         RFAILED - failure
+ * @params[in]
+ *    DU id
+ *    Pointer to E2nodeConfigurationUpdate
+ * @return Void
  *
  ******************************************************************/
 
 void ProcE2NodeConfigUpdate(uint32_t duId, E2nodeConfigurationUpdate_t *e2NodeConfigUpdate)
 {
-   uint8_t ieIdx = 0;
-   uint8_t transId = 0, e2NodeUpdateListIdx=0;
+   DuDb    *duDb = NULLP;
+   E2NodeConfigList tmpE2NodeList;
+   uint16_t arrIdx=0;
+   uint8_t ieIdx = 0, duIdx = 0, elementCnt=0, transId = 0; 
+   E2nodeComponentConfigAddition_List_t *e2NodeAddList=NULL;
+   E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe=NULL;
+   E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList=NULLP;
    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe=NULLP;
    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULLP;
+   E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList=NULL;
+   E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL;
+   E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
 
-   if(e2NodeConfigUpdate)
+   SEARCH_DU_DB(duIdx, duId, duDb);
+   if(duDb == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
+      return;
+   }
+   
+   memset(&tmpE2NodeList, 0, sizeof(E2NodeConfigList));
+   if(!e2NodeConfigUpdate)
    {
-      if(e2NodeConfigUpdate->protocolIEs.list.array)
+      DU_LOG("\nERROR  -->  E2AP : e2NodeConfigUpdate pointer is null");
+      return;
+   }
+   if(!e2NodeConfigUpdate->protocolIEs.list.array)
+   {
+       DU_LOG("\nERROR  -->  E2AP : e2NodeConfigUpdate array pointer is null");
+      return;
+   }
+   
+   elementCnt = e2NodeConfigUpdate->protocolIEs.list.count;
+   for(ieIdx=0; ieIdx < e2NodeConfigUpdate->protocolIEs.list.count; ieIdx++)
+   {
+      if(!e2NodeConfigUpdate->protocolIEs.list.array[ieIdx])
       {
-         for(ieIdx=0; ieIdx < e2NodeConfigUpdate->protocolIEs.list.count; ieIdx++)
-         {
-            if(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx])
+         DU_LOG("\nERROR  -->  E2AP : e2NodeConfigUpdate array idx %d pointer is null",arrIdx);
+         break;
+      }
+      
+      switch(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->id)
+      {
+         case ProtocolIE_IDE2_id_TransactionID:
             {
-               switch(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->id)
+               transId = e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
+               if(transId < 0 || transId > 255)
                {
-                  case ProtocolIE_IDE2_id_TransactionID:
-                     transId = e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
-                     break;
-                  
-                  default:
+                  DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
+                  return;
+               }
+               break;
+            }
+
+         case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
+            {
+               e2NodeAddList =&e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2nodeComponentConfigAddition_List;
+               if(e2NodeAddList->list.array)
+               {
+                  for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
                   {
-                     /*TODO - Other IEs will be handling in next gerrit*/
-                     break;
+                     e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
+                     e2NodeAddItem =  &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
+                     /* Storing the E2 node information in DB */
+                     if(handleE2NodeComponentAction(duDb, (PTR)e2NodeAddItem, ProtocolIE_IDE2_id_E2nodeComponentConfigAddition,\
+                     &tmpE2NodeList.addedE2Node[tmpE2NodeList.addedE2NodeCount++]) != ROK)
+                     {
+                        DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",arrIdx);
+                     }
                   }
                }
+               break;
+            }
+
+         case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
+            {
+               e2NodeUpdateList =&e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2nodeComponentConfigUpdate_List;
+               if(e2NodeUpdateList->list.array)
+               {
+                  for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++)
+                  {
+                     e2NodeUpdateItemIe = (E2nodeComponentConfigUpdate_ItemIEs_t*) e2NodeUpdateList->list.array[arrIdx];
+                     e2NodeUpdateItem =  &e2NodeUpdateItemIe->value.choice.E2nodeComponentConfigUpdate_Item;
+
+                     /* Updating the E2 node information in DB */
+                     if(handleE2NodeComponentAction(duDb, (PTR)e2NodeUpdateItem, ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate,\
+                              &tmpE2NodeList.updatedE2Node[tmpE2NodeList.updatedE2NodeCount++]) != ROK)
+                     {
+                        DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",arrIdx);
+                     }
+                  }
+               }
+               break;
+            }
+
+         case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
+            {
+               e2NodeRemoveList = &e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2nodeComponentConfigRemoval_List;
+               if(e2NodeRemoveList->list.array)
+               {
+                  for(arrIdx = 0; arrIdx< e2NodeRemoveList->list.count; arrIdx++)
+                  {
+                     e2NodeRemovalItemIe = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemoveList->list.array[arrIdx];
+                     e2NodeRemovalItem =  &e2NodeRemovalItemIe->value.choice.E2nodeComponentConfigRemoval_Item;
+
+                     /* Removing the E2 node information in DB */
+                     if(handleE2NodeComponentAction(duDb, (PTR)e2NodeRemovalItem, ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval,\
+                              &tmpE2NodeList.removedE2Node[tmpE2NodeList.removedE2NodeCount++]) != ROK)
+                     {
+                        DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",arrIdx);
+                     }
+                  }
+               }
+               break;
+            }
+
+         default:
+            {
+               break;
             }
-         }
+      }
+   }
+   /* If all of the IEs are processed successfully, we will send an e2 node
+    * config update ack message. 
+    * else we will be sendinf e2 node config update failure */
+   if(elementCnt == ieIdx)
+   {
+     if(BuildAndSendE2NodeConfigUpdateAck(duDb, transId, &tmpE2NodeList) !=ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 node config ack");
+         return;
+      }
+   }
+   else
+   {
+      if(BuildAndSendE2NodeConfigUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 node config Failure");
+         return;
       }
    }
 }
-
 /*******************************************************************
  *
  * @brief Builds Global RIC Id Params
@@ -564,74 +1170,175 @@ void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
 
 /*******************************************************************
  *
- * @brief Build E2node Component config addition ack list
+ * @brief fill e2 node configuration for ack msg 
  *
  * @details
  *
- *    Function :  BuildE2nodeComponentConfigAdditionAck
- *
- *    Functionality: deallocate the memory allocated in E2SetupResponse 
+ *    Function : fillE2NodeConfigAck
  *
- * @params[in] E2nodeComponentConfigAdditionAck_List_t
- * *e2NodeConfigAdditionAckList
+ *    Functionality:
+ *       - fill e2 node configuration for ack msg
  *
- * @return ROK - success
+ * @params[in] 
+ *    Pointer to e2NodeCfg to be filled
+ *    procedure Code
+ *    E2 Node Component information
+ *    Is successful or failure response
+ * @return ROK     - success
  *         RFAILED - failure
+ *
  * ****************************************************************/
 
-uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, DuDb *duDb)
+uint8_t fillE2NodeConfigAck(PTR e2NodeCfg, uint8_t procedureCode, E2NodeComponent *componentInfo, bool isSuccessful)
 {
-   uint8_t arrIdx = 0;
-   E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem;
+   E2nodeComponentID_t *e2nodeComponentID=NULLP;
+   E2nodeComponentInterfaceType_t *e2nodeComponentInterfaceType=NULLP;
+   E2nodeComponentConfigurationAck_t *e2nodeComponentConfigurationAck=NULLP;
+   E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP;
+   E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP;
+   E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP;
    
-   e2NodeConfigAdditionAckList->list.count = 1;
-   e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
-   RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
-   if(e2NodeConfigAdditionAckList->list.array == NULLP)
+   /* filling the interface type, component id, configuration ack based on the
+    * e2 node configuration add, update, delete type  */
+   switch(procedureCode)
    {
-      DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
-      return RFAILED;
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
+         {
+            additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg;
+            e2nodeComponentInterfaceType = &((E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg)->e2nodeComponentInterfaceType;
+            e2nodeComponentID = &additionAckItem->e2nodeComponentID;
+            e2nodeComponentConfigurationAck = &additionAckItem->e2nodeComponentConfigurationAck;
+            break;
+         }
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
+         {
+            updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg;
+            e2nodeComponentInterfaceType = &updateAckItem->e2nodeComponentInterfaceType;
+            e2nodeComponentID = &updateAckItem->e2nodeComponentID;
+            e2nodeComponentConfigurationAck = &updateAckItem->e2nodeComponentConfigurationAck;
+            break;
+         }
+      case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
+         {
+            removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
+            e2nodeComponentInterfaceType = &removalAckItem->e2nodeComponentInterfaceType;
+            e2nodeComponentID = &removalAckItem->e2nodeComponentID;
+            e2nodeComponentConfigurationAck = &removalAckItem->e2nodeComponentConfigurationAck;
+            break;
+         }
    }
 
-   for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
+   /* >E2 Node Component interface type */
+   if(componentInfo->interfaceType>=NG && componentInfo->interfaceType<=X2)
    {
-      RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
-      if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
-      {
-         DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
-         return RFAILED;
-      }
+      *e2nodeComponentInterfaceType = componentInfo->interfaceType;
    }
-   e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[0];
-   e2NodeAddAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
-   e2NodeAddAckItem->criticality = CriticalityE2_reject;
-   e2NodeAddAckItem->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
-   e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentInterfaceType = duDb->e2NodeComponent.interfaceType;
-
-   /* >E2 Node Component ID */
-   e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
-   RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\
-         sizeof(E2nodeComponentInterfaceF1_t));
-   if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP)
+   else
    {
-      DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
+      DU_LOG("\nERROR  --> E2AP: Received an invalid interface value %d",componentInfo->interfaceType);
       return RFAILED;
    }
-   e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
-   RIC_ALLOC(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\
-         e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
 
-   if(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
+   if(*e2nodeComponentInterfaceType == E2nodeComponentInterfaceType_f1)
    {
-      DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
-      return RFAILED;
-   }
-   e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = duDb->e2NodeComponent.componentId;
-   
-   /* >E2 Node Component Configuration Acknowledge*/
-   e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentConfigurationAck.updateOutcome = \
-   E2nodeComponentConfigurationAck__updateOutcome_success;
+      /* >E2 Node Component ID */
+      e2nodeComponentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
+      RIC_ALLOC(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
+      if(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP)
+      {
+         DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
+         return RFAILED;
+      }
+      e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
+      RIC_ALLOC(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
+
+      if(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
+      {
+         DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
+         return RFAILED;
+      }
+      e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = componentInfo->componentId;
+   }
+
+   if(isSuccessful)
+   {
+      /* >E2 Node Component Configuration Acknowledge*/
+      e2nodeComponentConfigurationAck->updateOutcome = E2nodeComponentConfigurationAck__updateOutcome_success;
+   }
+   else
+   {
+      /* >E2 Node Component Configuration Acknowledge*/
+      e2nodeComponentConfigurationAck->updateOutcome = E2nodeComponentConfigurationAck__updateOutcome_failure;
+      RIC_ALLOC(e2nodeComponentConfigurationAck->failureCauseE2, sizeof(struct CauseE2));
+      if(e2nodeComponentConfigurationAck->failureCauseE2)
+      {
+         fillE2FailureCause(e2nodeComponentConfigurationAck->failureCauseE2, CauseE2_PR_e2Node, CauseE2node_e2node_component_unknown);
+      }
+      else
+      {
+         DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
+         return RFAILED;
+      }
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Build E2node Component config addition ack list
+ *
+ * @details
+ *
+ *    Function :  BuildE2nodeComponentConfigAdditionAck
+ *
+ *    Functionality:  Build E2node Component config addition ack list 
+ *
+ * @params[in] 
+ *    E2nodeComponentConfigAdditionAck_List to be filled
+ *    Count of e2 node to be added
+ *    list of e2 node cfg to be added
+ *
+ * @return ROK - success
+ *         RFAILED - failure
+ * ****************************************************************/
+
+uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, \
+uint16_t addedE2NodeCount, E2NodeConfigItem *addedE2Node)
+{
+   E2NodeComponent *e2NodeComponentInfo=NULLP;
+   CmLList *node=NULLP;
+   uint16_t arrIdx = 0;
+   E2nodeComponentConfigAdditionAck_Item_t *e2NodeAddAckItem=NULLP;
+   E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULLP;
+  
+   e2NodeConfigAdditionAckList->list.count = addedE2NodeCount;
    
+   e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
+   RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
+   if(e2NodeConfigAdditionAckList->list.array == NULLP)
+   {
+      DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
+      return RFAILED;
+   }
+
+   for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
+   {
+      RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
+      if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
+      {
+         DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
+         return RFAILED;
+      }
+      e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[arrIdx];
+      e2NodeAddAckItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
+      e2NodeAddAckItemIe->criticality = CriticalityE2_reject;
+      e2NodeAddAckItemIe->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
+      e2NodeAddAckItem = &e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item;
+
+      /* Filling the e2 node config addition ack item */
+      fillE2NodeConfigAck((PTR)&e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck,\
+      &addedE2Node[arrIdx].componentInfo, addedE2Node[arrIdx].isSuccessful);
+   }
    return ROK;  
 }
 
@@ -662,7 +1369,7 @@ uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_L
 
 uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ranFunAcceptedList, RANfunctionsID_List_t *ranFuncAcceptedList, uint8_t procedureCode)
 {
-   uint8_t ranFuncIdx = 0;
+   uint16_t ranFuncIdx = 0;
    RANfunctionID_ItemIEs_t *ranFuncAcceptedItemIe=NULL;
    
    /* For ProcedureCodeE2_id_E2setup and ProcedureCodeE2_id_RICserviceQuery, 
@@ -722,18 +1429,19 @@ uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ran
  *
  *    Function : BuildAndSendE2SetupRsp
  *
- *    Functionality: Constructs the F1SetupResponse message and sends
- *                   it back to the DU through SCTP.
+ *    Functionality: Builds and sends the E2SetupResponse
  *
- * @params[in] void **buf,Buffer to which encoded pattern is written into
- * @params[in] int *size,size of buffer
+ * @params[in] 
+ *      Du datbase
+ *      Trans id
+ *      List of E2node cofniguration which needs to be send
  *
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
 
-uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
+uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId, E2NodeConfigList e2NodeList)
 {
    E2AP_PDU_t         *e2apMsg = NULL;
    E2setupResponse_t  *e2SetupRsp;
@@ -836,7 +1544,7 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId)
       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)
+         value.choice.E2nodeComponentConfigAdditionAck_List, e2NodeList.addedE2NodeCount, e2NodeList.addedE2Node) != ROK)
       {
          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
          break;
@@ -1354,9 +2062,8 @@ uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
  *
  * ****************************************************************/
 
-uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsDb)
+uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsInfo)
 {
-   uint8_t actionIdx = 0;
    uint8_t elementCnt = 0;
    uint8_t elementIdx = 0;
 
@@ -1398,14 +2105,10 @@ uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscripti
       if(elementIdx < elementCnt)
          break;
 
-      for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
-      {
-         ricSubsDb->actionSequence[actionIdx].actionId = -1;
-      }
 
       elementIdx = 0;
       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
-         ricSubsDb) != ROK)
+         ricSubsInfo) != ROK)
       {
          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
          break;
@@ -1433,15 +2136,30 @@ uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscripti
 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
 {
    uint8_t         ret = RFAILED;
+   uint8_t         elementCnt = 0;
+   uint8_t         idx = 0;
+   uint8_t         actionIdx = 0;
+   asn_enc_rval_t  encRetVal;        /* Encoder return value */
    E2AP_PDU_t                 *e2apRicMsg = NULL;
    RICsubscriptionRequest_t   *ricSubscriptionReq;
-   uint8_t         elementCnt;
-   uint8_t         idx;
-   asn_enc_rval_t  encRetVal;        /* Encoder return value */
-   RanFunction     *ranFuncDb = &duDb->ranFunction[0];
+   RanFunction  *ranFuncDb = &duDb->ranFunction[0];
+   CmLList *ricSubsNode = NULLP;
+   RicSubscription *ricSubsInfo = NULLP;
 
    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
 
+   /* Allocate memory to store RIC subscription info in RIC DB */
+   RIC_ALLOC(ricSubsInfo, sizeof(RicSubscription));
+   if(!ricSubsInfo)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+      return RFAILED;
+   }
+   for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
+   {
+      ricSubsInfo->actionSequence[actionIdx].actionId = -1;
+   }
+
    while(true)
    {
       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
@@ -1495,7 +2213,7 @@ uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
       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)
+         &ricSubsInfo->requestId) != ROK)
       {
          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
          break;
@@ -1509,6 +2227,7 @@ uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
+      ricSubsInfo->ranFuncId = ranFuncDb->id;
 
       /* Filling RIC Subscription Details */
       idx++;
@@ -1517,7 +2236,7 @@ uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
       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)
+         ricSubsInfo) != ROK)
       {
          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
          break;
@@ -1551,13 +2270,26 @@ uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
          break;
       }
 
-      ranFuncDb->numOfSubscription++;
+      /* Add RIC Subscription Info to RAN Function's RIC Subscription List */
+      RIC_ALLOC(ricSubsNode , sizeof(CmLList));
+      if(!ricSubsNode)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
+         break;
+      }
+      ricSubsNode->node = (PTR)ricSubsInfo;
+      cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubsNode);
+
       ret = ROK;
       break;
    }
 
    if(ret == RFAILED)
-      memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription));
+   {
+      RIC_FREE(ricSubsInfo, sizeof(RicSubscription));
+      RIC_FREE(ricSubsNode , sizeof(CmLList));
+   }
+
    FreeRicSubscriptionReq(e2apRicMsg);
    return ret;
 }
@@ -1585,6 +2317,7 @@ void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricS
    RicRequestId ricReqId;
    RanFunction  *ranFuncDb = NULLP;
    RicSubscription *ricSubs = NULLP;
+   CmLList *ricSubsNode = NULLP;
    ActionInfo *action = NULLP;
    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
@@ -1645,7 +2378,7 @@ void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricS
                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
 
                            /* Remove action from RAN Function's subscription list */
-                           ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb);
+                           ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
                            if(ricSubs)
                            {
                               action = fetchActionInfoFromActionId(actionId, ricSubs);
@@ -1844,108 +2577,113 @@ uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
  *
  * Functionality: process the e2setup request
  *
- * @return ROK     - success
- *         RFAILED - failure
+ * @return void
  *
  ******************************************************************/
 
-uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
+void ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
 {
-   uint8_t arrIdx = 0, e2NodeAddListIdx =0, duIdx = 0, transId =0, ranFuncIdx;
+   uint8_t arrIdx = 0, duIdx = 0, transId =0;
+   uint16_t ranFuncIdx=0, e2NodeAddListIdx =0;
+   E2NodeConfigList tmpE2NodeList;
    DuDb    *duDb = NULLP;
-   E2nodeComponentConfigAddition_List_t *e2NodeAddList;
-   E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem;
-   RANfunction_ItemIEs_t *ranFuncItemIe;
-   RANfunction_Item_t  *ranFunItem;
-   RANfunctions_List_t *ranFunctionsList;
+   bool ieProcessingFailed = false;
+   E2nodeComponentConfigAddition_List_t *e2NodeAddList=NULLP;
+   E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem=NULLP;
+   RANfunction_ItemIEs_t *ranFuncItemIe=NULLP;
+   RANfunction_Item_t  *ranFunItem=NULLP;
+   RANfunctions_List_t *ranFunctionsList=NULLP;
+
+   memset(&tmpE2NodeList, 0, sizeof(E2NodeConfigList));
+   if(!e2SetupReq)
+   {
+      DU_LOG("\nERROR  -->  E2AP : e2SetupReq pointer is null");
+      return;
+   }
+   if(!e2SetupReq->protocolIEs.list.array)
+   {
+      DU_LOG("\nERROR  -->  E2AP : e2SetupReq array pointer is null");
+      return;
+   }
 
-   if(e2SetupReq)
+   for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
    {
-      if(e2SetupReq->protocolIEs.list.array)      
+      if(e2SetupReq->protocolIEs.list.array[arrIdx])
       {
-         for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
+         switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
          {
-            if(e2SetupReq->protocolIEs.list.array[arrIdx])
-            {
-               switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
+            case ProtocolIE_IDE2_id_TransactionID:
                {
-                  case ProtocolIE_IDE2_id_TransactionID:
-                     {
-                        transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
-                        break;
-                     }
-                  case ProtocolIE_IDE2_id_GlobalE2node_ID:
+                  transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
+                  break;
+               }
+            case ProtocolIE_IDE2_id_GlobalE2node_ID:
+               {
+                  if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
+                  {
+                     *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
+
+                     SEARCH_DU_DB(duIdx, *duId, duDb); 
+                     if(duDb == NULLP)
                      {
-                        if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
-                        {
-                            *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
-
-                            SEARCH_DU_DB(duIdx, *duId, duDb); 
-                            if(duDb == NULLP)
-                            {
-                               duDb = &ricCb.duInfo[ricCb.numDu];
-                               ricCb.numDu++;
-                            }
-                            memset(duDb, 0, sizeof(DuDb));
-                            duDb->duId = *duId;
-                        }
-                        break;
+                        duDb = &ricCb.duInfo[ricCb.numDu];
+                        ricCb.numDu++;
                      }
-                     case ProtocolIE_IDE2_id_RANfunctionsAdded:
-                     {
-                        ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
+                     memset(duDb, 0, sizeof(DuDb));
+                     duDb->duId = *duId;
+                  }
+                  break;
+               }
+            case ProtocolIE_IDE2_id_RANfunctionsAdded:
+               {
+                  ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
 
-                        if(ranFunctionsList->list.array)
-                        {
-                           for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
-                           {
-                              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->numOfRanFunction++;
-                           }
-                        }
-                        break;
+                  if(ranFunctionsList->list.array)
+                  {
+                     for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
+                     {
+                        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; 
+                        cmLListInit(&duDb->ranFunction[ranFunItem->ranFunctionID-1].subscriptionList);
+                        duDb->numOfRanFunction++;
                      }
-                     case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
+                  }
+                  break;
+               }
+            case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
+               {
+                  e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
+                  if(e2NodeAddList->list.array)
+                  {
+                     for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
                      {
-                        e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
-                        if(e2NodeAddList->list.array)
+                        if(e2NodeAddList->list.array[e2NodeAddListIdx])
                         {
-                           for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
+                           /* Storing the E2 node information in DB */
+                           e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
+                           if(handleE2NodeComponentAction(duDb, (PTR)&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item,\
+                                    ProtocolIE_IDE2_id_E2nodeComponentConfigAddition, &tmpE2NodeList.addedE2Node[tmpE2NodeList.addedE2NodeCount++]) != ROK)
                            {
-                              if(e2NodeAddList->list.array[e2NodeAddListIdx])
-                              {
-                                 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]; 
-                                 }
-                              }
+                              DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",e2NodeAddListIdx);
                            }
+
                         }
-                        break;
                      }
-                     default:
-                        break;
                   }
+                  break;
                }
-            }
-        }
+            default:
+               break;
+         }
+      }
    }
    
-   if(BuildAndSendE2SetupRsp(duDb, transId) !=ROK)
+   if(BuildAndSendE2SetupRsp(duDb, transId, tmpE2NodeList) !=ROK)
    {
       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
-      return RFAILED;
    }
-   return ROK;   
 }
 /*******************************************************************
  *
@@ -2338,50 +3076,6 @@ void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
    }
 }
 
-/*******************************************************************
- *
- * @brief fill E2 failure cause 
- *
- * @details
- *
- *    Function : fillE2FailureCause
- *
- * Functionality: fill E2 failure cause
- * @return ROK     - success
- *         RFAILED - failure
- *
- ******************************************************************/
-
-void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
-{
-   cause->present = causePresent;
-
-   switch(cause->present)
-   {
-      case CauseE2_PR_ricRequest:
-         cause->choice.ricRequest = reason;
-         break;
-      case CauseE2_PR_ricService:
-         cause->choice.ricService = reason;
-         break;
-      case CauseE2_PR_e2Node:
-         cause->choice.e2Node = reason;
-         break;
-      case CauseE2_PR_transport:
-         cause->choice.transport = reason;
-         break;
-      case CauseE2_PR_protocol:
-         cause->choice.protocol = reason;
-         break;
-      case CauseE2_PR_misc:
-         cause->choice.misc = reason;
-         break;
-      default:
-         cause->choice.misc = CauseE2Misc_unspecified;
-         break;
-   }
-}
-
 /*******************************************************************
  *
  * @brief build and send the ric service update failure 
@@ -2987,11 +3681,12 @@ void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
  ******************************************************************/
 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
 {
-   uint8_t ieIdx = 0, duIdx = 0, subsIdx = 0;
+   uint8_t ieIdx = 0, duIdx = 0;
    uint8_t ranFuncId = 0;
    DuDb    *duDb = NULLP;
    RanFunction *ranFuncDb = NULLP;
    RicSubscription *ricSubs = NULLP;
+   CmLList *ricSubsNode = NULLP;
    RicRequestId ricReqId;
    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
 
@@ -3034,10 +3729,11 @@ uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricS
                      else
                      {
                         /* Remove subscription entry from RAN Function */
-                        ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb);
+                        ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
                         if(ricSubs)
                         {
-                           memset(&ranFuncDb->subscriptionList[subsIdx], 0, sizeof(RicSubscription));
+                           cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
+                           deleteRicSubscriptionNode(ricSubsNode);
                         }
                      }
                      break; 
@@ -3781,6 +4477,7 @@ uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t
    RicRequestId ricReqId;
    RanFunction *ranFuncDb = NULLP;
    RicSubscription *ricSubs = NULLP;
+   CmLList *ricSubsNode = NULLP;
    ActionInfo *action = NULLP;
    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
@@ -3823,7 +4520,7 @@ uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t
                   return RFAILED;
                }
 
-               ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb);
+               ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
                if(!ricSubs)
                {
                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
@@ -4111,122 +4808,1083 @@ uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId
  *         RFAILED - failure
  *
  * ****************************************************************/
-void FreeResetRequest(E2AP_PDU_t *e2apMsg)
+void FreeResetRequest(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0;
+   ResetRequestE2_t  *resetReq = NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.initiatingMessage != NULLP)
+      {
+         resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
+         if(resetReq->protocolIEs.list.array)
+         {
+            for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
+            {
+               RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
+            }
+            RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Build and send the reset request msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendResetRequest
+ *
+ *    Functionality:
+ *         - Buld and send the reset request msg to E2 node
+ *
+ * @params[in]
+ *    DU database
+ *    Type of failure 
+ *    Cause of failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
+{
+   uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
+   uint8_t ret = RFAILED;
+   E2AP_PDU_t        *e2apMsg = NULLP;
+   ResetRequestE2_t  *resetReq = NULLP;
+   asn_enc_rval_t     encRetVal;       /* Encoder return value */
+
+   DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
+
+   do
+   {
+      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
+         break;
+      }
+
+      e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
+      RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      if(e2apMsg->choice.initiatingMessage == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
+         break;
+      }
+
+      e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
+      e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+      e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
+      resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
+
+      elementCnt = 2;
+      resetReq->protocolIEs.list.count = elementCnt;
+      resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
+
+      RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
+      if(!resetReq->protocolIEs.list.array)
+      {
+         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
+               Reset Request IE array");
+         break;
+      }
+
+      for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
+      {
+         RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
+         if(!resetReq->protocolIEs.list.array[ieIdx])
+         {
+            DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
+                  Reset Request IE array element");
+            break;
+         }
+      }
+
+      /* In case of failure */
+      if(ieIdx < elementCnt)
+         break;
+
+      ieIdx = 0;
+      resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+      resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
+      transId = assignTransactionId(duDb);
+      resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      ieIdx++;
+      resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
+      resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
+      resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
+      fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
+
+      /* Prints the Msg formed */
+      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 reset request structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
+#ifdef DEBUG_ASN_PRINT
+         for(int i=0; i< encBufSize; i++)
+         {
+            printf("%x",encBuf[i]);
+         }
+#endif
+      }
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
+         break;
+      }
+
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   /* Free all memory */
+   FreeResetRequest(e2apMsg);
+   return ret;
+}
+
+/******************************************************************
+ *
+ * @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)
+      {
+         memset(&ricSubscriptionInfo->actionSequence[actionIdx], 0, sizeof(ActionInfo));
+      }
+   }
+   memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
+   RIC_FREE(subscriptionNode->node, sizeof(RicSubscription));
+   RIC_FREE(subscriptionNode, sizeof(CmLList));
+}
+
+/*******************************************************************
+ *
+ * @brief Delete RIC subscription List
+ *
+ * @details
+ *
+ *    Function : deleteRicSubscriptionList 
+ *
+ * Functionality: Delete RIC subscription list
+ *
+ * @params[in] RIC Subscription list
+ * @return void
+
+ *
+ ******************************************************************/
+void deleteRicSubscriptionList(CmLListCp *subscriptionList)
+{
+   CmLList *subscriptionNode = NULLP;
+
+   CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
+   while(subscriptionNode)
+   {
+      cmLListDelFrm(subscriptionList, subscriptionNode);
+      deleteRicSubscriptionNode(subscriptionNode);
+      CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief process the E2 Reset Response
+ *
+ * @details
+ *
+ *    Function : ProcResetResponse 
+ *
+ * Functionality: Process E2 Reset Response 
+ *
+ * @params[in] 
+ *       du Id
+ *       Pointer to reset response 
+ * @return void
+ *
+ ******************************************************************/
+
+void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
+{
+   uint8_t ieIdx = 0, duIdx =0;
+   DuDb *duDb = NULLP;
+   RanFunction *ranFuncDb = NULLP;
+   uint16_t ranFuncIdx = 0;
+
+   SEARCH_DU_DB(duIdx, duId, duDb); 
+   if(duDb == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
+      return;
+   }
+   
+   if(!resetRsp)
+   {
+      DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
+      return;
+   }
+
+   if(!resetRsp->protocolIEs.list.array)      
+   {
+      DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
+      return;
+   }
+   
+   for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
+   {
+      if(resetRsp->protocolIEs.list.array[ieIdx])
+      {
+         switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
+         {
+            case ProtocolIE_IDE2_id_TransactionID:
+               {
+                  for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
+                  {
+                     ranFuncDb = &duDb->ranFunction[ranFuncIdx];
+                     if(ranFuncDb->id > 0)
+                     {
+                        deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
+                     }
+                  }
+                  break;
+               }
+            case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
+               {
+                  break;
+               }
+         }
+      }
+   }
+}
+
+
+/*******************************************************************
+ *
+ * @brief process the E2 Reset Request
+ *
+ * @details
+ *
+ *    Function : ProcResetRequest 
+ *
+ * Functionality: Process E2 Reset Request 
+ *
+ * @params[in] 
+ *       du Id
+ *       Pointer to reset response 
+ * @return void
+ *
+ ******************************************************************/
+
+void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
+{
+   uint8_t ieIdx = 0, duIdx =0, transId=0;
+   DuDb *duDb = NULLP;
+   RanFunction *ranFuncDb = NULLP;
+   uint16_t ranFuncIdx = 0;
+
+   SEARCH_DU_DB(duIdx, duId, duDb); 
+   if(duDb == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
+      return;
+   }
+   
+   if(!resetReq)
+   {
+      DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
+      return;
+   }
+
+   if(!resetReq->protocolIEs.list.array)      
+   {
+      DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
+      return;
+   }
+   
+   for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
+   {
+      if(resetReq->protocolIEs.list.array[ieIdx])
+      {
+         switch(resetReq->protocolIEs.list.array[ieIdx]->id)
+         {
+            case ProtocolIE_IDE2_id_TransactionID:
+               {
+                  transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
+                  break;
+               }
+            case ProtocolIE_IDE2_id_CauseE2:
+               {
+                  for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
+                  {
+                     ranFuncDb = &duDb->ranFunction[ranFuncIdx];
+                     if(ranFuncDb->id > 0)
+                     {
+                        deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
+                     }
+                  }
+                  break;
+               }
+         }
+      }
+   }
+
+   if(BuildAndSendResetResponse(duId, transId) !=ROK)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Free RIC Subscription Delete Request Message
+ *
+ * @details
+ *
+ *    Function : FreeRicSubscriptionDeleteRequest
+ *
+ * Functionality:  Free RIC Subscription Delete Request
+ *
+ * @param  E2AP Message PDU
+ * @return void
+ *
+ ******************************************************************/
+void FreeRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx = 0, arrIdx = 0;
+   RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
+
+   if(e2apMsg)
+   {
+      if(e2apMsg->choice.initiatingMessage)
+      {
+         ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
+         if(ricSubsDelReq->protocolIEs.list.array)
+         {
+            for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
+            {
+               RIC_FREE(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
+            }
+            RIC_FREE(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Builds and Send RIC Subscription delete request
+ *
+ * @details
+ *
+ *    Function : BuildAndSendRicSubscriptionDeleteRequest
+ *
+ * Functionality: Build and send RIC subscription delete request.
+ *
+ * @params[in] DU ID
+ *             RIC subscription info to be deleted
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t BuildAndSendRicSubscriptionDeleteRequest(uint32_t duId, RicSubscription *ricSubsDb)
+{
+   uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
+   E2AP_PDU_t         *e2apMsg = NULLP;
+   RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
+   RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
+   asn_enc_rval_t     encRetVal;        /* Encoder return value */
+
+   while(true)
+   {
+      DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Request Message\n");
+
+      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
+         break;
+      }
+
+      e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
+      RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      if(e2apMsg->choice.initiatingMessage == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
+         break;
+      }
+      e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
+      e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+      e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest;
+
+      ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
+
+      elementCnt = 2;
+      ricSubsDelReq->protocolIEs.list.count = elementCnt;
+      ricSubsDelReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequest_IEs_t *);
+
+      RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
+      if(ricSubsDelReq->protocolIEs.list.array == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
+         break;
+      }
+
+      for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
+      {
+         RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequest_IEs_t));
+         if(ricSubsDelReq->protocolIEs.list.array[ieIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
+                  __func__, ieIdx, __LINE__);
+            break;
+         }
+      }
+      if(ieIdx < elementCnt)
+         break;
+      
+      /* RIC Request ID */
+      ieIdx = 0;
+      ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
+      ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RICrequestID;
+      ricSubsDelReqIe->criticality = CriticalityE2_reject;
+      ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
+      ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID = ricSubsDb->requestId.requestorId;
+      ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID = ricSubsDb->requestId.instanceId;
+
+      /* RAN Function ID */
+      ieIdx++;
+      ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
+      ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RANfunctionID;
+      ricSubsDelReqIe->criticality = CriticalityE2_reject;
+      ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
+      ricSubsDelReqIe->value.choice.RANfunctionID = ricSubsDb->ranFuncId;
+
+      /* Prints the Msg formed */
+      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 RIC Subscription Delete Request Message (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Request Message \n");
+#ifdef DEBUG_ASN_PRINT
+         for(int i=0; i< encBufSize; i++)
+         {
+            printf("%x",encBuf[i]);
+         } 
+#endif
+      }
+
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
+      {
+         DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Request Message");      
+         break;
+      }
+
+      ret = ROK;
+      break;
+   }
+
+   FreeRicSubscriptionDeleteRequest(e2apMsg);  
+   return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Processing of RIC Subscription Delete Required
+ *
+ * @details
+ *
+ *    Function : ProcRicSubsDeleteReqd
+ *
+ * Functionality: Processing of RIC Subscription Delete Required
+ *    When received, RIC stub will initiate the RIC subscription
+ *    deletion procedure towards DU
+ *
+ * @param  DU ID
+ *         RIC Subscription Delete Required IEs
+ * @return ROK-success
+ *         RFAILED-failure
+ *
+ ******************************************************************/
+uint8_t ProcRicSubsDeleteReqd(uint32_t duId, RICsubscriptionDeleteRequired_t *ricSubsDelRqd)
+{
+   uint8_t ieIdx = 0, duIdx = 0;
+   uint16_t arrIdx = 0;
+   DuDb *duDb = NULLP;
+   RicRequestId ricReqId;
+   RanFunction *ranFuncDb = NULLP;
+   RicSubscription *subsDb = NULLP;
+   CmLList *ricSubsNode = NULLP;
+
+   RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
+   RICsubscription_List_withCause_t *ricSubsList = NULLP;
+   RICsubscription_withCause_Item_t *subsItem = NULLP;
+
+   memset(&ricReqId, 0, sizeof(RicRequestId));
+
+   if(!ricSubsDelRqd)
+   {
+      DU_LOG("\nERROR  -->  E2AP : %s: Received NULL message", __func__);
+      return RFAILED;
+   }
+
+   SEARCH_DU_DB(duIdx, duId, duDb);
+   if(duDb == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
+      return RFAILED;
+   }
+
+   for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
+   {
+      ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
+      switch(ricSubsDelRqdIe->id)
+      {
+         case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
+         {
+            ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
+            for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
+            {
+               subsItem = &(((RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[arrIdx])->\
+                  value.choice.RICsubscription_withCause_Item);
+               ranFuncDb = fetchRanFuncFromRanFuncId(duDb, subsItem->ranFunctionID);
+               if(!ranFuncDb)
+               {
+                  DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%ld] not found", __func__, subsItem->ranFunctionID);
+                  return RFAILED;
+               }
+               
+               ricReqId.requestorId = subsItem->ricRequestID.ricRequestorID;
+               ricReqId.instanceId = subsItem->ricRequestID.ricInstanceID;
+               subsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
+               if(!subsDb)
+               {
+                  DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%ld] Instance_ID [%ld]", \
+                     __func__, subsItem->ricRequestID.ricRequestorID, subsItem->ricRequestID.ricInstanceID);
+                  return RFAILED;
+               }
+
+               /* Delete RIC Subcription from RAN Function */
+               cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
+               
+               /* Send RIC Subscription delete request and then free any memory
+                * allocated to store subscription info at RIC */
+               BuildAndSendRicSubscriptionDeleteRequest(duId, (RicSubscription *)ricSubsNode->node);
+               deleteRicSubscriptionNode(ricSubsNode);
+            }
+            
+            break;
+         }
+         default:
+            break;
+      }
+   }  
+   
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocate memory allocated for E2nodeConfigurationUpdate 
+ *
+ * @details
+ *
+ *    Function : freeE2NodeConfigItem 
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for E2nodeConfigurationUpdate
+ *
+ * @params[in]
+ *       uint8_t protocolIe
+ *       PTR to e2NodeCfg which is to be freed
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+void freeE2NodeConfigItem(uint8_t protocolIe, PTR e2NodeCfg)
+{
+   E2nodeComponentConfigurationAck_t *cfgAck =NULLP;
+   E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
+   E2nodeComponentConfigAdditionAck_Item_t *e2NodeAdditionAckItemIe=NULLP;
+   E2nodeComponentConfigRemovalAck_Item_t *e2NodeRemovalAckItemIe=NULLP;
+   E2nodeComponentConfigUpdateAck_Item_t *e2NodeUpdateAckItemIe=NULLP;
+   
+    /* Extracting the component interface and configuration ack information from
+     * e2NodeCfg based on the protocol id */
+   switch(protocolIe)
+   {
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
+      {
+         e2NodeAdditionAckItemIe= (E2nodeComponentConfigAdditionAck_Item_t*)e2NodeCfg;
+         switch(e2NodeAdditionAckItemIe->e2nodeComponentInterfaceType)
+         {
+            case E2nodeComponentInterfaceType_f1:
+               {
+                  f1InterfaceInfo = e2NodeAdditionAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
+                  break;
+               }
+            default:
+               {
+                  break;
+               }
+
+         }
+         cfgAck = &e2NodeAdditionAckItemIe->e2nodeComponentConfigurationAck;
+      }
+
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
+      {
+         e2NodeUpdateAckItemIe = (E2nodeComponentConfigUpdateAck_Item_t*)e2NodeCfg;
+         switch(e2NodeUpdateAckItemIe->e2nodeComponentInterfaceType)
+         {
+            case E2nodeComponentInterfaceType_f1:
+               {
+                  f1InterfaceInfo = e2NodeUpdateAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
+                  break;
+               }
+            default:
+               {
+                  break;
+               }
+         }
+         cfgAck = &e2NodeUpdateAckItemIe->e2nodeComponentConfigurationAck;
+      }
+
+      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
+      {
+         e2NodeRemovalAckItemIe= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
+         switch(e2NodeRemovalAckItemIe->e2nodeComponentInterfaceType)
+         {
+            case E2nodeComponentInterfaceType_f1:
+               {
+                  f1InterfaceInfo = e2NodeRemovalAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
+                  break;
+               }
+            default:
+               {
+                  break;
+               }
+         }
+         cfgAck = &e2NodeRemovalAckItemIe->e2nodeComponentConfigurationAck;
+      }
+   }
+   
+   /* Freeing the memory allocated to component interface and configuration ack */
+   if(f1InterfaceInfo)
+   {
+      RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
+      RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
+   }
+
+   switch(cfgAck->updateOutcome)
+   {
+      case E2nodeComponentConfigurationAck__updateOutcome_success:
+         break;
+      case E2nodeComponentConfigurationAck__updateOutcome_failure:
+         {
+            RIC_FREE(cfgAck->failureCauseE2, sizeof(CauseE2_t));
+            break;
+         }
+   }
+
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
+ *
+ * @details
+ *
+ *    Function : FreeE2NodeConfigUpdate 
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for E2nodeConfigurationUpdate
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t arrIdx =0, e2NodeConfigIdx=0;
+   E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg=NULL;
+   E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
+   E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
+   E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
+   E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
+   E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
+   E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.successfulOutcome != NULLP)
+      {
+         updateAckMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
+         if(updateAckMsg->protocolIEs.list.array != NULLP)
+         {
+            for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
+            {
+               if(updateAckMsg->protocolIEs.list.array[arrIdx])
+               {
+                  switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
+                  {
+                     case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
+                        {
+                           additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
+                           if(additionAckList->list.array)
+                           {
+                              for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
+                              {
+                                 additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
+                                 if(additionAckItemIte)
+                                 {
+                                    freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck,\
+                                    (PTR)&additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item);
+                                    RIC_FREE(additionAckItemIte, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
+                                 }
+                              }
+                              RIC_FREE(additionAckList->list.array, additionAckList->list.size);
+                           }
+                           break;
+                        }
+                     case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
+                        {
+                           updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
+                           if(updateAckList->list.array)
+                           {
+                              for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
+                              {
+                                 updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
+                                 if(updateAckItemIe)
+                                 {
+                                    freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck,\
+                                    (PTR)&updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item);
+                                    RIC_FREE(updateAckItemIe, sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t));
+                                 }
+                              }
+                              RIC_FREE(updateAckList->list.array, updateAckList->list.size);
+                           }
+                           break;
+                        }
+                     case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
+                        {
+                           removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
+                           if(removalAckList->list.array)
+                           {
+                              for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
+                              {
+                                 removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
+                                 if(removalAckItemIe)
+                                 {
+                                    freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck,\
+                                    (PTR)&removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item);
+                                    RIC_FREE(removalAckItemIe, sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t));
+                                 }
+                              }
+                              RIC_FREE(removalAckList->list.array, removalAckList->list.size);
+                           }
+                           break;
+                        }
+                  }
+                  RIC_FREE(updateAckMsg->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
+               }
+            }
+            RIC_FREE(updateAckMsg->protocolIEs.list.array, updateAckMsg->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Build E2node Component config Removal ack list
+ *
+ * @details
+ *
+ *    Function :  BuildE2nodeComponentConfigRemovalAck
+ *
+ *    Functionality: Build the e2 node remove ack 
+ *
+ * @params[in] 
+ *    E2nodeComponentConfigRemovalAck_List_t to be filled
+ *    Count of e2 node to be removed
+ *    list of e2 node cfg to be removed
+ *
+ * @return ROK - success
+ *         RFAILED - failure
+ * ****************************************************************/
+
+uint8_t BuildE2nodeComponentConfigRemovalAck(E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList,\
+uint16_t removalE2NodeCount, E2NodeConfigItem *removaldE2Node)
+{
+   uint8_t arrIdx = 0;
+   E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULL;
+   
+   /* Filling the e2 node config removal ack list */
+   e2NodeConfigRemovalAckList->list.count = removalE2NodeCount;
+   e2NodeConfigRemovalAckList->list.size = e2NodeConfigRemovalAckList->list.count * sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t*);
+   RIC_ALLOC(e2NodeConfigRemovalAckList->list.array, e2NodeConfigRemovalAckList->list.size);
+   if(e2NodeConfigRemovalAckList->list.array == NULLP)
+   {
+      DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigRemovalAck %d",__LINE__);
+      return RFAILED;
+   }
+
+   for(arrIdx = 0; arrIdx< e2NodeConfigRemovalAckList->list.count; arrIdx++)
+   {
+      RIC_ALLOC(e2NodeConfigRemovalAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t));
+      if(e2NodeConfigRemovalAckList->list.array[arrIdx] == NULLP)
+      {
+         DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigRemovalAck %d",__LINE__);
+         return RFAILED;
+      }
+      e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[arrIdx];
+      e2NodeRemovalAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck_Item;
+      e2NodeRemovalAckItem->criticality = CriticalityE2_reject;
+      e2NodeRemovalAckItem->value.present = E2nodeComponentConfigRemovalAck_ItemIEs__value_PR_E2nodeComponentConfigRemovalAck_Item;
+      
+      /* Filling the e2 node config removal ack item */
+      fillE2NodeConfigAck((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck,\
+      &removaldE2Node[arrIdx].componentInfo, removaldE2Node[arrIdx].isSuccessful);
+   }
+   return ROK;  
+}
+
+/*******************************************************************
+ *
+ * @brief Build E2node Component config update ack list
+ *
+ * @details
+ *
+ *    Function :  BuildE2nodeComponentConfigUpdateAck
+ *
+ *    Functionality: Build E2node Component config update ack list 
+ *
+ * @params[in] 
+ *    E2nodeComponentConfigUpdateAck_List to be filled
+ *    Count of e2 node to be update
+ *    list of e2 node cfg to be update
+ *
+ * @return ROK - success
+ *         RFAILED - failure
+ * ****************************************************************/
+
+uint8_t BuildE2nodeComponentConfigUpdateAck(E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList,\
+uint16_t updatedE2NodeCount, E2NodeConfigItem *updatedE2Node)
 {
-   uint8_t ieIdx =0;
-   ResetRequestE2_t  *resetReq = NULLP;
+   uint8_t arrIdx = 0;
+   E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULL;
+   
+   /* Filling the e2 node config update ack list */
+   e2NodeConfigUpdateAckList->list.count = updatedE2NodeCount;
+   e2NodeConfigUpdateAckList->list.size = e2NodeConfigUpdateAckList->list.count * sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t*);
+   RIC_ALLOC(e2NodeConfigUpdateAckList->list.array, e2NodeConfigUpdateAckList->list.size);
+   if(e2NodeConfigUpdateAckList->list.array == NULLP)
+   {
+      DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
+      return RFAILED;
+   }
 
-   if(e2apMsg != NULLP)
+   for(arrIdx = 0; arrIdx< e2NodeConfigUpdateAckList->list.count; arrIdx++)
    {
-      if(e2apMsg->choice.initiatingMessage != NULLP)
+      RIC_ALLOC(e2NodeConfigUpdateAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t));
+      if(e2NodeConfigUpdateAckList->list.array[arrIdx] == NULLP)
       {
-         resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
-         if(resetReq->protocolIEs.list.array)
-         {
-            for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
-            {
-               RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
-            }
-            RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
-         }
-         RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+         DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
+         return RFAILED;
       }
-      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+      e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[arrIdx];
+      e2NodeUpdateAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck_Item;
+      e2NodeUpdateAckItem->criticality = CriticalityE2_reject;
+      e2NodeUpdateAckItem->value.present = E2nodeComponentConfigUpdateAck_ItemIEs__value_PR_E2nodeComponentConfigUpdateAck_Item;
+      
+      /* Filling the e2 node config update ack item */
+      fillE2NodeConfigAck((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck,\
+      &updatedE2Node[arrIdx].componentInfo, updatedE2Node[arrIdx].isSuccessful);
+
    }
+   return ROK;  
 }
 
 /*******************************************************************
  *
- * @brief Build and send the reset request msg
+ * @brief Buld and send the E2 node config update ack msg 
  *
  * @details
  *
- *    Function : BuildAndSendResetRequest
+ *    Function : BuildAndSendE2NodeConfigUpdateAck 
  *
  *    Functionality:
- *         - Buld and send the reset request msg to E2 node
- *
- * @params[in]
- *    DU database
- *    Type of failure 
- *    Cause of failure
+ *         - Buld and send the E2 node config update ack msg
+ * @params[in] 
+ *    DU databse 
+ *    transId 
+ *    list of E2 node cfg which needs to fill in IEs
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
+
+uint8_t BuildAndSendE2NodeConfigUpdateAck(DuDb *duDb, uint8_t transId,  E2NodeConfigList *e2NodeList)
 {
-   uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
    uint8_t ret = RFAILED;
+   uint8_t arrIdx = 0,elementCnt = 0;
    E2AP_PDU_t        *e2apMsg = NULLP;
-   ResetRequestE2_t  *resetReq = NULLP;
-   asn_enc_rval_t     encRetVal;       /* Encoder return value */
-
-   DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
+   asn_enc_rval_t     encRetVal;       
+   E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
 
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
    do
    {
       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
       if(e2apMsg == NULLP)
       {
-         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
          break;
       }
-
-      e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
-      RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
-      if(e2apMsg->choice.initiatingMessage == NULLP)
+      e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
+      RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      if(e2apMsg->choice.successfulOutcome == NULLP)
       {
-         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
          break;
       }
+      
+      e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
+      e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
+      e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
+      
+      elementCnt =1;
+      if(e2NodeList->addedE2NodeCount)
+         elementCnt++;
+      if(e2NodeList->updatedE2NodeCount)
+         elementCnt++;
+      if(e2NodeList->removedE2NodeCount)
+         elementCnt++;
 
-      e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
-      e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
-      e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
-      resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
-
-      elementCnt = 2;
-      resetReq->protocolIEs.list.count = elementCnt;
-      resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
-
-      RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
-      if(!resetReq->protocolIEs.list.array)
+      e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
+      e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
+      RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
+      if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
       {
-         DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
-               Reset Request IE array");
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
          break;
       }
-
-      for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
+      
+      for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
       {
-         RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
-         if(!resetReq->protocolIEs.list.array[ieIdx])
+         RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
+         if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
          {
-            DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
-                  Reset Request IE array element");
+            
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
             break;
          }
       }
-
-      /* In case of failure */
-      if(ieIdx < elementCnt)
+      
+      if(arrIdx<elementCnt)
          break;
 
-      ieIdx = 0;
-      resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
-      resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
-      resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
-      transId = assignTransactionId(duDb);
-      resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+      arrIdx = 0;
+      e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+      e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+      e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
+      e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
+      
+      if(e2NodeList->addedE2NodeCount)
+      {
+         arrIdx++;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigAdditionAck_List;
+         if(BuildE2nodeComponentConfigAdditionAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List,\
+                  e2NodeList->addedE2NodeCount, e2NodeList->addedE2Node)!=ROK)
 
-      ieIdx++;
-      resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
-      resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
-      resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
-      fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
+            break;
+         }
+      }
+      if(e2NodeList->updatedE2NodeCount)
+      {
+         arrIdx++;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigUpdateAck_List;
+         if(BuildE2nodeComponentConfigUpdateAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List,\
+                  e2NodeList->updatedE2NodeCount, e2NodeList->updatedE2Node)!=ROK)
 
-      /* Prints the Msg formed */
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config update ack list");
+            break;
+         }
+      }
+      if(e2NodeList->removedE2NodeCount)
+      {
+         arrIdx++;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigRemovalAck_List;
+         if(BuildE2nodeComponentConfigRemovalAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List,\
+                  e2NodeList->removedE2NodeCount, e2NodeList->removedE2Node)!=ROK)
+
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config removal ack list");
+            break;
+         }
+      }      
       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
 
       memset(encBuf, 0, ENC_BUF_MAX_LEN);
@@ -4235,197 +5893,96 @@ uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t re
             encBuf);
       if(encRetVal.encoded == ENCODE_FAIL)
       {
-         DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
          break;
       }
       else
       {
-         DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
-#ifdef DEBUG_ASN_PRINT
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
          for(int i=0; i< encBufSize; i++)
          {
-            printf("%x",encBuf[i]);
-         }
-#endif
+            DU_LOG("%x",encBuf[i]);
+         } 
       }
+
+
+      /* Sending msg */
       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
       {
-         DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
+         DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
          break;
       }
-
-
       ret = ROK;
       break;
    }while(true);
-
-   /* Free all memory */
-   FreeResetRequest(e2apMsg);
+   
+   FreeE2NodeConfigUpdateAck(e2apMsg);
    return ret;
 }
 
 
-/*******************************************************************
+/******************************************************************
  *
- * @brief delete ric subscription information 
+ * @brief Processes the E2 removal failure msg
  *
  * @details
  *
- *    Function : deleteRicSubscription 
+ *    Function : procE2RemovalFailure
  *
- * Functionality: Process ric subscription information
+ *    Functionality: Processes the E2 removal failure msg
  *
  * @params[in] 
- *       Pointer to DU database 
- * @return void
-
- *
- ******************************************************************/
-void deleteRicSubscription(DuDb **duDb)
-{
-   RanFunction *ranFuncDb = NULLP;
-   uint16_t ranFuncIdx=0;
-   
-   for(ranFuncIdx =0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
-   {
-      ranFuncDb = &(*duDb)->ranFunction[ranFuncIdx];
-      if(ranFuncDb->id > 0)
-      {
-         memset(&ranFuncDb->subscriptionList, 0,MAX_RIC_REQUEST*sizeof(RicSubscription));
-         ranFuncDb->numOfSubscription =0;
-      }
-   }
-}
-
-/*******************************************************************
- *
- * @brief process the E2 Reset Response
- *
- * @details
- *
- *    Function : ProcResetResponse 
- *
- * Functionality: Process E2 Reset Response 
+ *       E2 Removal Failure information
  *
- * @params[in] 
- *       du Id
- *       Pointer to reset response 
  * @return void
  *
- ******************************************************************/
-
-void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
+ * ****************************************************************/
+void ProcE2RemovalFailure(E2RemovalFailure_t *e2RemovalFailure) 
 {
-   uint8_t ieIdx = 0, duIdx =0;
-   DuDb *duDb = NULLP;
+   uint8_t ieIdx = 0, transId=0;
+   CauseE2_t *cause = NULLP;
 
-   SEARCH_DU_DB(duIdx, duId, duDb); 
-   if(duDb == NULLP)
+   if(!e2RemovalFailure)
    {
-      DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
-      return;
-   }
-   
-   if(!resetRsp)
-   {
-      DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
+      DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure pointer is null"); 
       return;
    }
 
-   if(!resetRsp->protocolIEs.list.array)      
+   if(!e2RemovalFailure->protocolIEs.list.array)      
    {
-      DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
+      DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
       return;
    }
    
-   for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
+   for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
    {
-      if(resetRsp->protocolIEs.list.array[ieIdx])
+      if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
       {
-         switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
+         switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
          {
             case ProtocolIE_IDE2_id_TransactionID:
                {
-                  deleteRicSubscription(&duDb);
-                  break;
-               }
-            case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
-               {
+                  transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
+                  DU_LOG("\nERROR  -->  E2AP : Received transID %d", transId);
                   break;
                }
-         }
-      }
-   }
-}
-
-
-/*******************************************************************
- *
- * @brief process the E2 Reset Request
- *
- * @details
- *
- *    Function : ProcResetRequest 
- *
- * Functionality: Process E2 Reset Request 
- *
- * @params[in] 
- *       du Id
- *       Pointer to reset response 
- * @return void
- *
- ******************************************************************/
-
-void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
-{
-   uint8_t ieIdx = 0, duIdx =0, transId=0;
-   DuDb *duDb = NULLP;
-
-   SEARCH_DU_DB(duIdx, duId, duDb); 
-   if(duDb == NULLP)
-   {
-      DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
-      return;
-   }
-   
-   if(!resetReq)
-   {
-      DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
-      return;
-   }
-
-   if(!resetReq->protocolIEs.list.array)      
-   {
-      DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
-      return;
-   }
-   
-   for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
-   {
-      if(resetReq->protocolIEs.list.array[ieIdx])
-      {
-         switch(resetReq->protocolIEs.list.array[ieIdx]->id)
-         {
-            case ProtocolIE_IDE2_id_TransactionID:
+            case ProtocolIE_IDE2_id_CauseE2:
                {
-                  transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
-                  break;
+                   cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
+                   printE2ErrorCause(cause);
+                   break; 
                }
-            case ProtocolIE_IDE2_id_CauseE2:
+            default:
                {
-                  deleteRicSubscription(&duDb);
+                  DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%d]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
                   break;
                }
          }
       }
    }
-
-   if(BuildAndSendResetResponse(duId, transId) !=ROK)
-   {
-      DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
-   }
 }
+
 /*******************************************************************
 *
 * @brief Handles received E2AP message and sends back response  
@@ -4534,6 +6091,13 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
                      break;
                   }
+               case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
+                  {
+                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
+                      ProcRicSubsDeleteReqd(*duId, \
+                         &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
+                      break;
+                  }
 
                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
                   {
@@ -4565,6 +6129,10 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
                      break;
                   }
+               case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
+                  {
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
@@ -4585,6 +6153,11 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
                      break;
                   }
+               case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
+                  {
+                     ProcE2RemovalFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \