[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-532] RIC Subscription Delete Req/Rsp API...
[o-du/l2.git] / src / du_app / du_e2ap_msg_hdl.c
index 83be943..7660a54 100644 (file)
@@ -26,6 +26,7 @@
 #include "du_e2ap_mgr.h"
 #include "du_e2ap_msg_hdl.h"
 #include "du_cfg.h"
+#include "du_sctp.h"
 #include "du_mgr.h"
 #include "du_mgr_main.h"
 #include "du_utils.h"
@@ -232,7 +233,7 @@ void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
  *
  * ****************************************************************/
 
-uint8_t BuildAndSendRemovalFailure(uint8_t transId, E2FailureCause failureCause)
+uint8_t BuildAndSendRemovalFailure(uint16_t transId, E2FailureCause failureCause)
 {
    uint8_t           ieIdx = 0, elementCnt = 0;
    uint8_t           ret = RFAILED;
@@ -391,7 +392,7 @@ void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t BuildAndSendRemovalResponse(uint8_t transId)
+uint8_t BuildAndSendRemovalResponse(uint16_t transId)
 {
    uint8_t           ieIdx = 0, elementCnt = 0;
    uint8_t           ret = RFAILED;
@@ -482,7 +483,6 @@ uint8_t BuildAndSendRemovalResponse(uint8_t transId)
    }while(true);
 
    FreeE2RemovalResponse(e2apMsg);
-   removeE2NodeInformation();
    return ret;
 }
 
@@ -538,7 +538,8 @@ void freeAperDecodingOfE2RemovalReq(E2RemovalRequest_t *removalReq)
 
 void procE2RemovalRequest(E2AP_PDU_t  *e2apMsg)
 {
-   uint8_t arrIdx =0, transId =0;
+   uint8_t arrIdx =0;
+   uint16_t transId =0;
    E2FailureCause failureCause;
    E2RemovalRequest_t *removalReq=NULLP;
 
@@ -7639,7 +7640,10 @@ void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
                      break;
                   }
 
-                  //TODO : Send statistics delete request to MAC 
+                  if(BuildAndSendStatsDeleteReq(ricSubsDb) != ROK)
+                  {
+                     DU_LOG("\nERROR  -->  E2AP : Failed to build and send ric subscription delete req to du layers");
+                  }
                   break;
                }
 
@@ -7882,105 +7886,1327 @@ void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
 
 /*******************************************************************
  *
- * @brief Handles received E2AP message and sends back response  
+ * @brief Deallocate the memory allocated for RemovalRequest msg
  *
  * @details
  *
- *    Function : E2APMsgHdlr
+ *    Function : FreeRemovalRequest
  *
  *    Functionality:
- *         - Decodes received E2AP control message
- *         - Prepares response message, encodes and sends to SCTP
+ *       - freeing the memory allocated for RemovalRequest
  *
- * @params[in] 
+ * @params[in] E2AP_PDU_t *e2apMsg
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
-void E2APMsgHdlr(Buffer *mBuf)
+void FreeRemovalRequest(E2AP_PDU_t *e2apMsg)
 {
-   int i =0;
-   char *recvBuf = NULLP;
-   MsgLen copyCnt =0;
-   MsgLen recvBufLen =0;
-   E2AP_PDU_t *e2apMsg = NULLP;
-   asn_dec_rval_t rval ={0}; /* Decoder return value */
-   E2AP_PDU_t e2apasnmsg={0} ;
-
-   DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
-   ODU_PRINT_MSG(mBuf, 0,0);
-
-   /* Copy mBuf into char array to decode it */
-   ODU_GET_MSG_LEN(mBuf, &recvBufLen);
-   DU_ALLOC(recvBuf, (Size)recvBufLen);
+   uint8_t ieIdx =0;
+   E2RemovalRequest_t  *removalReq = NULLP;
 
-   if(recvBuf == NULLP)
+   if(e2apMsg != NULLP)
    {
-      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
-      return;
+      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++)
+            {
+               DU_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
+            }
+            DU_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
+         }
+         DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
    }
-   if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
+}
+
+/*******************************************************************
+ *
+ * @brief Build and send the removal request msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendRemovalRequest
+ *
+ *    Functionality:
+ *         - Buld and send the removal request msg to E2 node
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t BuildAndSendRemovalRequest()
+{
+   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
    {
-      DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
-      return;
-   }
+      DU_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;
+      DU_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 *);
+
+      DU_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++)
+      {
+         DU_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();
+      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
-   printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
-   for(i=0; i< recvBufLen; i++)
+         for(int i=0; i< encBufSize; i++)
+         {
+            printf("%x",encBuf[i]);
+         }
+#endif
+      }
+      if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Sending removal request failed");
+         break;
+      }
+
+
+      ret = ROK;
+      duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId;
+      duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode;
+      break;
+   }while(true);
+
+   /* Free all memory */
+   FreeRemovalRequest(e2apMsg);
+   
+   return ret;
+}
+
+/******************************************************************
+ *
+ * @brief Deallocation of memory allocated by aper decoder
+ *   for Removal failure
+ *
+ * @details
+ *
+ *    Function : freeAperDecodingOfE2RemovalFailure
+ *
+ *    Functionality: Deallocation of memory allocated by aper decoder
+ * for Removal failure
+ *
+ * @params[in] Pointer to removalFailure
+ * @return void
+ *
+ * ****************************************************************/
+void freeAperDecodingOfE2RemovalFailure(E2RemovalFailure_t *removalFailure)
+{
+   uint8_t arrIdx=0;
+
+   if(removalFailure)
    {
-      printf("%x",recvBuf[i]);
+      if(removalFailure->protocolIEs.list.array)
+      {
+         for(arrIdx=0; arrIdx<removalFailure->protocolIEs.list.count; arrIdx++)
+         {
+            if(removalFailure->protocolIEs.list.array[arrIdx])
+            {
+               free(removalFailure->protocolIEs.list.array[arrIdx]);
+            }
+         }
+         free(removalFailure->protocolIEs.list.array);
+      }
    }
-#endif
+}
 
-   /* Decoding flat buffer into E2AP messsage */
-   e2apMsg = &e2apasnmsg;
-   memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
+/******************************************************************
+ *
+ * @brief Processes the E2 removal failure msg
+ *
+ * @details
+ *
+ *    Function : procE2RemovalFailure
+ *
+ *    Functionality: Processes the E2 removal failure msg
+ *
+ * @params[in] 
+ *       E2AP_PDU_t *e2apMsg
+ *
+ * @return void
+ *
+ * ****************************************************************/
+void ProcE2RemovalFailure(E2AP_PDU_t *e2apMsg) 
+{
+   uint8_t ieIdx = 0, transId=0;
+   CauseE2_t *cause = NULLP;
+   E2RemovalFailure_t *e2RemovalFailure=NULLP;
 
-   rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
-   DU_FREE(recvBuf, (Size)recvBufLen);
+   e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
 
-   if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+   if(!e2RemovalFailure->protocolIEs.list.array)      
    {
-      DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
+      DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
       return;
    }
-   printf("\n");
-   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
-
-   switch(e2apMsg->present)
+   
+   for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
    {
-      case E2AP_PDU_PR_unsuccessfulOutcome:
+      if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
+      {
+         switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
          {
-            switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
-            {
-               case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
-                  {
-                     procE2SetupFailure(e2apMsg);
-                     break;
-                  }
-               case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
+            case ProtocolIE_IDE2_id_TransactionID:
+               {
+                  transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
+                  if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
+                        (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
                   {
-                     procE2NodeConfigUpdateFailure(e2apMsg);
-                     break;
+                     memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
                   }
-               case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
+                  else
                   {
-                     procRicServiceUpdateFailure(e2apMsg);
-                     break;
+                     DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
                   }
-               case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
+                  break;
+               }
+            case ProtocolIE_IDE2_id_CauseE2:
+               {
+                   cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
+                   printE2ErrorCause(cause);
+                   break; 
+               }
+            default:
+               {
+                  DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
+                  break;
+               }
+         }
+      }
+   }
+   freeAperDecodingOfE2RemovalFailure(e2RemovalFailure);
+}
+
+ /******************************************************************
+  *
+  * @brief Deallocation of memory allocated by aper decoder
+  *   for Removal failure
+  *
+  * @details
+  *
+  *    Function : freeAperDecodingOfE2RemovalResponse
+  *
+  *    Functionality: Deallocation of memory allocated by aper decoder
+  * for Removal failure
+  *
+  * @params[in] Pointer to removalResponse
+  * @return void
+  *
+  * ****************************************************************/
+ void freeAperDecodingOfE2RemovalResponse(E2RemovalResponse_t *removalResponse)
+ {
+    uint8_t arrIdx=0;
+
+    if(removalResponse)
+    {
+       if(removalResponse->protocolIEs.list.array)
+       {
+          for(arrIdx=0; arrIdx<removalResponse->protocolIEs.list.count; arrIdx++)
+          {
+             if(removalResponse->protocolIEs.list.array[arrIdx])
+             {
+                free(removalResponse->protocolIEs.list.array[arrIdx]);
+             }
+          }
+          free(removalResponse->protocolIEs.list.array);
+       }
+    }
+ }
+
+/*******************************************************************
+ *
+ * @brief process the E2 Removal Response
+ *
+ * @details
+ *
+ *    Function : ProcE2RemovalResponse 
+ *
+ * Functionality: Process E2 Removal Response 
+ *
+ * @params[in] 
+ *      E2AP_PDU_t *e2apMsg
+ * @return void
+ *
+ ******************************************************************/
+
+void ProcE2RemovalResponse(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx = 0, transId=0;
+   E2RemovalResponse_t *removalRsp = NULLP;
+   
+   removalRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
+
+   if(!removalRsp->protocolIEs.list.array)      
+   {
+      DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
+      return;
+   }
+
+   for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
+   {
+      if(removalRsp->protocolIEs.list.array[ieIdx])
+      {
+         switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
+         {
+            case ProtocolIE_IDE2_id_TransactionID:
+               {
+                  transId = removalRsp->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
+                  if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\
+                        (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode))
                   {
-                     procRicSubscriptionModificationRefuse(e2apMsg);
-                     break;
+                     DU_LOG("\nINFO  -->  E2AP : Sending request to close the sctp connection");
+                     cmInetClose(&ricParams.sockFd);
+                     memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
+                     removeE2NodeInformation();
                   }
-               default:
+                  else
                   {
-                     DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
-                           e2apMsg->choice.unsuccessfulOutcome->value.present);
-                     return;
+                     DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
                   }
-            }
+                  break;
+               }
+            default:
+               {
+                  DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
+                  break;
+               }
+         }
+      }
+   }
+   
+   freeAperDecodingOfE2RemovalResponse(removalRsp);
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for E2 Connection Update Failure
+ *
+ * @details
+ *
+ *    Function : FreeE2ConnectionUpdateFailure
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for E2ConnectionUpdateFailure
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void FreeE2ConnectionUpdateFailure(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0;
+   E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
+      {
+         e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure;
+         if(e2ConnectionUpdateFailure->protocolIEs.list.array)
+         {
+            for(ieIdx=0; ieIdx < e2ConnectionUpdateFailure->protocolIEs.list.count; ieIdx++)
+            {
+               DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t));
+            }
+            DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size);
+         }
+         DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+      }
+      DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Connection Update Failure msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2ConnectionUpdateFailure
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Connection Update Failure Message
+ * @params[in] 
+ *    Trans Id 
+ *    Failure Cause
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t BuildAndSendE2ConnectionUpdateFailure(uint16_t transId, E2FailureCause failureCause)
+{
+   uint8_t           ieIdx = 0, elementCnt = 0;
+   uint8_t           ret = RFAILED;
+   E2AP_PDU_t        *e2apMsg = NULLP;
+   E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP;
+   asn_enc_rval_t    encRetVal;       /* Encoder return value */
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Failure Message\n");
+   do
+   {
+      DU_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_unsuccessfulOutcome;
+
+      DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+      if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
+      e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure;
+      e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure;
+
+      elementCnt = 2;
+      e2ConnectionUpdateFailure->protocolIEs.list.count = elementCnt;
+      e2ConnectionUpdateFailure->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateFailure_IEs_t *);
+      DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size);
+      if(!e2ConnectionUpdateFailure->protocolIEs.list.array)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
+      {
+         DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t));
+         if(!e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx])
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+            break;
+         }
+      }
+      if(ieIdx < elementCnt)
+         break;
+
+      ieIdx = 0;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_TransactionID;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      /* Cause */
+      ieIdx++;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
+      e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_CauseE2;
+      fillE2Cause(&e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause);
+      
+      xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
+
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update failure structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update Failure \n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         }
+      }
+
+      /* Sending msg */
+      if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update Failure");
+         break;
+      }
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   FreeE2ConnectionUpdateFailure(e2apMsg);
+   return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief fill E2 connection update item
+ *
+ * @details
+ *
+ *    Function : fillE2connectionUpdateItem
+ *
+ *    Functionality: fill E2 connection update item
+ *
+ * @params[in]
+ *    E2connectionUpdate Item to be filled
+ *    Protocol Id
+ *    IP Address
+ *    Usage
+ * @return ROK - success
+ *         RFAILED - failure
+ * ****************************************************************/
+
+uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId, uint32_t ipAddress, AssocUsage usage)
+{
+   CauseE2_t *cause=NULLP;
+   TNLusage_t  *tnlUsage=NULLP;
+   E2FailureCause failureCause;
+   TNLinformation_t *tnlInformation = NULLP;
+   E2connectionUpdate_Item_t *connectionModifyItem=NULLP;
+   E2connectionSetupFailed_Item_t *connectionRemoveITem=NULLP;
+
+   switch(protocolId)
+   {
+      case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
+      {
+         connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo;
+         tnlInformation = &connectionModifyItem->tnlInformation;
+         tnlUsage = &connectionModifyItem->tnlUsage;
+         break;
+      }
+
+      case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item:
+      {
+         connectionRemoveITem = (E2connectionSetupFailed_Item_t*)connectionInfo;
+         tnlInformation= &connectionRemoveITem->tnlInformation;
+         cause = &connectionRemoveITem->cause;
+         break;
+      }
+      default:
+         return RFAILED;
+   }
+
+   tnlInformation->tnlAddress.size =  4*sizeof(uint8_t);
+   DU_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size);
+   if(!tnlInformation->tnlAddress.buf)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+      return RFAILED;
+   }
+
+   tnlInformation->tnlAddress.buf[3] =  ipAddress & 0xFF;
+   tnlInformation->tnlAddress.buf[2] = (ipAddress>> 8) & 0xFF;
+   tnlInformation->tnlAddress.buf[1] = (ipAddress>> 16) & 0xFF;
+   tnlInformation->tnlAddress.buf[0] = (ipAddress>> 24) & 0xFF;
+   tnlInformation->tnlAddress.bits_unused = 0;
+
+   switch(protocolId)
+   {
+      case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
+         {
+            *tnlUsage = usage;
+            break;
+         }
+      case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item:
+         {
+            failureCause.causeType = E2_TRANSPORT;
+            failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED;
+            fillE2Cause(cause, failureCause);
+            break;
+         }
+      default:
+         return RFAILED;
+   }
+   return ROK;
+}
+
+
+/*******************************************************************
+ *
+ * @brief Build E2 connection modification list
+ *
+ * @details
+ *
+ *    Function :BuildE2ConnectionUpdateList 
+ *
+ *    Functionality: Build E2 connection modification list
+ *
+ * @params[in]
+ *    E2 connection update list to be filled
+ *    Count of E2 connection to be added in the list    
+ *    Received list of E2 connection
+ *
+ * @return ROK - success
+ *         RFAILED - failure
+ * ****************************************************************/
+
+uint8_t BuildE2ConnectionUpdateList(E2connectionUpdate_List_t *connectionSetupList, uint8_t count, E2ConnectionItem *tmpConnectionList)
+{
+   uint8_t arrIdx = 0;
+   E2connectionUpdate_ItemIEs_t *connectionSetupItem=NULLP;
+
+   connectionSetupList->list.count = count;
+
+   connectionSetupList->list.size = connectionSetupList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*);
+   DU_ALLOC(connectionSetupList->list.array, connectionSetupList->list.size);
+   if(connectionSetupList->list.array)
+   {
+      for(arrIdx = 0; arrIdx< connectionSetupList->list.count; arrIdx++)
+      {
+         DU_ALLOC(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
+         if(connectionSetupList->list.array[arrIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+            return RFAILED;
+         }
+         connectionSetupItem = (E2connectionUpdate_ItemIEs_t*)connectionSetupList->list.array[arrIdx];
+         connectionSetupItem->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item;
+         connectionSetupItem->criticality= CriticalityE2_ignore;
+         connectionSetupItem->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item;
+         if(fillE2connectionUpdateItem((PTR)&connectionSetupItem->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item,\
+          tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
+            return RFAILED;
+         }
+
+      }
+   }
+   else
+   {
+      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+      return RFAILED;
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Build E2 connection setup failed list
+ *
+ * @details
+ *
+ *    Function : BuildE2ConnectionSetupFailedList
+ *
+ *    Functionality: Build E2 connection setup failed list
+ *
+ * @params[in]
+ *    E2 connection setup failed list to be filled
+ *    Count of E2 connection to be added in the list    
+ *    Received list of E2 connection
+ *
+ * @return ROK - success
+ *         RFAILED - failure
+ * ****************************************************************/
+
+uint8_t BuildE2ConnectionSetupFailedList(E2connectionSetupFailed_List_t *setupFailedList, uint8_t count, E2ConnectionItem *tmpConnectionList)
+{
+   uint8_t arrIdx = 0;
+   E2connectionSetupFailed_ItemIEs_t *setupFailedItem=NULLP;
+
+   setupFailedList->list.count = 1;
+
+   setupFailedList->list.size = setupFailedList->list.count*sizeof(E2connectionSetupFailed_ItemIEs_t *);
+   DU_ALLOC(setupFailedList->list.array, setupFailedList->list.size);
+   if(setupFailedList->list.array)
+   {
+      for(arrIdx = 0; arrIdx< setupFailedList->list.count; arrIdx++)
+      {
+         DU_ALLOC(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t));
+         if(setupFailedList->list.array[arrIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+            return RFAILED;
+         }
+         setupFailedItem = (E2connectionSetupFailed_ItemIEs_t*)setupFailedList->list.array[arrIdx];
+         setupFailedItem->id = ProtocolIE_IDE2_id_E2connectionSetupFailed_Item;
+         setupFailedItem->criticality= CriticalityE2_ignore;
+         setupFailedItem->value.present = E2connectionSetupFailed_ItemIEs__value_PR_E2connectionSetupFailed_Item;
+         if(fillE2connectionUpdateItem((PTR)&setupFailedItem->value.choice.E2connectionSetupFailed_Item, ProtocolIE_IDE2_id_E2connectionSetupFailed_Item,\
+          tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection failed to update item");
+            return RFAILED;
+         }
+
+      }
+   }
+   else
+   {
+      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+      return RFAILED;
+   }
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for E2 Connection
+ * Update ack msg 
+ *
+ * @details
+ *
+ *    Function :FreeE2ConnectionUpdateAcknowledge 
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for E2 Connection
+ * Update ack msg
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+void FreeE2ConnectionUpdateAcknowledge(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0, arrIdx=0;
+   E2connectionUpdateAcknowledge_t *connectionUpdate = NULLP;
+   E2connectionUpdate_List_t *connectionSetupList = NULLP;
+   E2connectionSetupFailed_List_t *setupFailedList = NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.successfulOutcome != NULLP)
+      {
+         connectionUpdate = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge;
+         if(connectionUpdate->protocolIEs.list.array)
+         {
+            for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
+            {
+               if(connectionUpdate->protocolIEs.list.array[ieIdx])
+               {
+                  switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
+                  {
+                     case ProtocolIE_IDE2_id_TransactionID:
+                        break;
+
+                     case ProtocolIE_IDE2_id_E2connectionSetup:
+                        {
+                           connectionSetupList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
+                           if(connectionSetupList->list.array)
+                           {
+                              for(arrIdx = 0; arrIdx < connectionSetupList->list.count; arrIdx++)
+                              {
+                                 DU_FREE(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
+                              }
+                              DU_FREE(connectionSetupList->list.array, connectionSetupList->list.size);
+                           }
+                           break;
+                        }
+
+                     case ProtocolIE_IDE2_id_E2connectionSetupFailed:
+                        {
+                           setupFailedList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List;
+                           if(setupFailedList->list.array)
+                           {
+                              for(arrIdx = 0; arrIdx < setupFailedList->list.count; arrIdx++)
+                              {
+                                 DU_FREE(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t));
+                              }
+                              DU_FREE(setupFailedList->list.array, setupFailedList->list.size);
+                           }
+                           break;
+                        }
+                  }
+                  DU_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t));
+               }
+            }
+            DU_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size);
+         }
+         DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      }
+      DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Connection Update Acknowledge msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2ConnectionUpdateAcknowledge
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Connection Update Acknowledge Message
+ * @params[in] 
+ *    Trans Id 
+ *    List of E2 connection needs to fill in IE 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t BuildAndSendE2ConnectionUpdateAcknowledge(uint16_t transId,  E2ConnectionList connectionInfoList)
+{
+   uint8_t           ieIdx = 0, elementCnt = 0;
+   uint8_t           ret = RFAILED;
+   E2AP_PDU_t        *e2apMsg = NULLP;
+   asn_enc_rval_t    encRetVal;       
+   E2connectionUpdateAcknowledge_t *e2ConnectionUpdateAcknowledge=NULLP;
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Acknowledge Message\n");
+   do
+   {
+      DU_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_successfulOutcome;
+
+      DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      if(e2apMsg->choice.successfulOutcome == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
+      e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2connectionUpdateAcknowledge;
+      e2ConnectionUpdateAcknowledge = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge;
+
+      elementCnt = 1;
+      if(connectionInfoList.numOfE2ConnectionSetup)
+         elementCnt++;
+      if(connectionInfoList.numOfE2ConnectionFailedToSetup)
+         elementCnt++;
+
+      e2ConnectionUpdateAcknowledge->protocolIEs.list.count = elementCnt;
+      e2ConnectionUpdateAcknowledge->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateAck_IEs_t*);
+      DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array, e2ConnectionUpdateAcknowledge->protocolIEs.list.size);
+      if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+         break;
+      }
+
+      for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
+      {
+         DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t));
+         if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx])
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
+            break;
+         }
+      }
+      if(ieIdx < elementCnt)
+         break;
+
+      ieIdx = 0;
+      e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
+      e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_TransactionID;
+      e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      if(connectionInfoList.numOfE2ConnectionSetup)
+      {
+         ieIdx++;
+         e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionSetup;
+         e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+         e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionUpdate_List;
+         if(BuildE2ConnectionUpdateList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List, \
+                  connectionInfoList.numOfE2ConnectionSetup, connectionInfoList.setupE2Connection) != ROK)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection setup list");
+            break;
+         }
+      }
+      
+      if(connectionInfoList.numOfE2ConnectionFailedToSetup)
+      {
+         ieIdx++;
+         e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionSetupFailed;
+         e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+         e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionSetupFailed_List;
+         if(BuildE2ConnectionSetupFailedList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List, \
+               connectionInfoList.numOfE2ConnectionFailedToSetup, connectionInfoList.failedToSetupE2Connection) != ROK) 
+         {
+            DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection failed to setup list");
+            break;
+         }
+      }
+
+      xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
+
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update acknowledge failure structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update Acknowledge \n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         }
+      }
+
+      /* Sending msg */
+      if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update Acknowledge");
+         break;
+      }
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   FreeE2ConnectionUpdateAcknowledge(e2apMsg);
+   return ret;
+}
+
+/******************************************************************
+ *
+ * @brief Deallocation of memory allocated by aper decoder for 
+ * E2 Connection Update
+ *
+ * @details
+ *
+ *    Function :freeAperDecodingOfE2ConnectionUpdate 
+ *
+ *    Functionality: Deallocation of memory allocated by aper decoder for
+ *    E2 Connection Update
+ *
+ * @params[in] Pointer to connectionUpdate 
+ * @return void
+ *
+ * ****************************************************************/
+
+void freeAperDecodingOfE2ConnectionUpdate(E2connectionUpdate_t *connectionUpdate)
+{
+   uint8_t ieIdx =0, arrIdx=0;
+   E2connectionUpdate_List_t *connectionToBeModifyList = NULLP;
+   E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP;
+
+   if(connectionUpdate->protocolIEs.list.array)
+   {
+      for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
+      {
+         if(connectionUpdate->protocolIEs.list.array[ieIdx])
+         {
+            switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
+            {
+               case ProtocolIE_IDE2_id_TransactionID:
+                  break;
+
+               case ProtocolIE_IDE2_id_E2connectionUpdateModify:
+                  {
+                     connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
+                     if(connectionToBeModifyList->list.array)
+                     {
+                        for(arrIdx= 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++)
+                        {
+                           free(connectionToBeModifyList->list.array[arrIdx]);
+                        }
+                        free(connectionToBeModifyList->list.array);
+                     }
+                     break;
+                  }
+               case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
+                  {
+                     connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List;
+                     if(connectionToBeRemoveList->list.array)
+                     {
+                        for(arrIdx= 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++)
+                        {
+                           free(connectionToBeRemoveList->list.array[arrIdx]);
+                        }
+                        free(connectionToBeRemoveList->list.array);
+                     }
+                     break;
+                  }
+            }
+            free(connectionUpdate->protocolIEs.list.array[ieIdx]);
+         }
+      }
+      free(connectionUpdate->protocolIEs.list.array);
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Handling of E2 connection modification Ie
+ *
+ * @details
+ *
+ *    Function : handleE2ConnectionModification 
+ *
+ * Functionality: Handling of E2 connection modification Ie
+ *
+ * @param 
+ *        E2 Connection update list
+ *        E2 connection list which needs to be filled
+ * @return void
+ *
+ ******************************************************************/
+
+void handleE2ConnectionModification(E2connectionUpdate_List_t *connectionUpdateList, E2ConnectionList *connectionInfoList)
+{
+   uint32_t ipAddress=0;
+   bool infoFound = false;
+   uint8_t arrIdx=0,idx=0, count =0;
+   E2connectionUpdate_ItemIEs_t *connectionModifyItem=NULLP;
+
+   if(connectionUpdateList->list.array)
+   {
+      for(arrIdx = 0; arrIdx < connectionUpdateList->list.count; arrIdx++)
+      {
+         connectionModifyItem= (E2connectionUpdate_ItemIEs_t*)connectionUpdateList->list.array[arrIdx];
+         bitStringToInt(&connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlInformation.tnlAddress, &ipAddress);
+         for(idx=0; idx<duCb.e2apDb.numOfTNLAssoc; idx++)
+         {
+            /* If the TNL information is found in the data base, update the
+             * information in the database */
+            if(duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr == ipAddress)
+            {
+               duCb.e2apDb.tnlAssoc[idx].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage;
+               infoFound = true;
+               break;
+            }
+         }
+         
+         /* If the TNL information is found in the data base, then add the
+          * information in setupE2Connection array else add in failedToSetupE2Connection array */
+         if(infoFound == true)
+         {
+            count =connectionInfoList->numOfE2ConnectionSetup;
+            connectionInfoList->setupE2Connection[count].ipV4Addr =  duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr;
+            connectionInfoList->setupE2Connection[count].usage = duCb.e2apDb.tnlAssoc[idx].usage;
+            connectionInfoList->numOfE2ConnectionSetup++;
+         }
+         else
+         {
+            count = connectionInfoList->numOfE2ConnectionFailedToSetup;
+            connectionInfoList->failedToSetupE2Connection[count].ipV4Addr =  ipAddress;
+            connectionInfoList->failedToSetupE2Connection[count].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage;
+            connectionInfoList->numOfE2ConnectionFailedToSetup++;
+         }
+      }
+
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Handling of E2 connection removal Ie
+ *
+ * @details
+ *
+ *    Function : handleE2ConnectionRemoval 
+ *
+ * Functionality: Handling of E2 connection removal Ie
+ *
+ * @param  
+ *    E2 Connection removal List 
+ * @return void
+ *
+ ******************************************************************/
+
+void handleE2ConnectionRemoval(E2connectionUpdateRemove_List_t *connectionRemovalList)
+{
+   uint32_t ipAddress=0;
+   uint8_t arrIdx=0,idx=0;
+   E2connectionUpdateRemove_ItemIEs_t *connectionRemovalItem=NULLP;
+
+   if(connectionRemovalList->list.array)
+   {
+      for(arrIdx = 0; arrIdx < connectionRemovalList->list.count; arrIdx++)
+      {
+         connectionRemovalItem= (E2connectionUpdateRemove_ItemIEs_t*)connectionRemovalList->list.array[arrIdx];
+         bitStringToInt(&connectionRemovalItem->value.choice.E2connectionUpdateRemove_Item.tnlInformation.tnlAddress, &ipAddress);
+         for(idx=0; idx<duCb.e2apDb.numOfTNLAssoc; idx++)
+         {
+            if(duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr == ipAddress)
+            {
+               cmInetClose(&ricParams.sockFd);
+               removeE2NodeInformation();
+               break;
+            }
+         }
+         
+      }
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Process e2 connection update received from RIC
+ *
+ * @details
+ *
+ *    Function : procE2ConnectionUpdate
+ *
+ * Functionality: Process e2 connection update received from RIC
+ *
+ * @param  E2AP_PDU_t  *e2apMsg
+ * @return void
+ *
+ ******************************************************************/
+
+void procE2ConnectionUpdate(E2AP_PDU_t  *e2apMsg)
+{
+   uint8_t arrIdx =0, transId =0;
+   bool invalidTransId = false, connectionFailedToUpdate=false;
+   E2FailureCause failureCause;
+   E2ConnectionList connectionInfoList;
+   E2connectionUpdate_t *connectionUpdate=NULLP;
+
+   DU_LOG("\nINFO   -->  E2AP : E2 connection update received");
+   connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
+   
+   memset(&connectionInfoList, 0, sizeof(E2ConnectionList));
+   for(arrIdx=0; arrIdx<connectionUpdate->protocolIEs.list.count; arrIdx++)
+   {
+      switch(connectionUpdate->protocolIEs.list.array[arrIdx]->id)
+      {
+         case ProtocolIE_IDE2_id_TransactionID:
+            {
+               transId = connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
+               if(transId>255)
+               {
+                  failureCause.causeType = E2_PROTOCOL;
+                  failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
+                  invalidTransId = true;
+               }
+               break;
+            }
+
+         case ProtocolIE_IDE2_id_E2connectionUpdateModify:
+            {
+               handleE2ConnectionModification(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdate_List,\
+                     &connectionInfoList);
+               if((connectionInfoList.numOfE2ConnectionSetup == 0) && (connectionInfoList.numOfE2ConnectionFailedToSetup > 0))
+               {
+                  failureCause.causeType = E2_TRANSPORT;
+                  failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED;
+                  connectionFailedToUpdate =true;
+               }
+
+               break;
+            }
+
+         case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
+            {
+               handleE2ConnectionRemoval(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdateRemove_List);
+               break;
+            }
+
+         default:
+            {
+               DU_LOG("\nERROR  -->  E2AP : Invalid IE received[%ld]",connectionUpdate->protocolIEs.list.array[arrIdx]->id);
+               break;
+            }
+      }
+
+      if(invalidTransId == true || connectionFailedToUpdate ==true)
+         break;
+   }
+   
+   if(invalidTransId == true || connectionFailedToUpdate == true)
+   {
+      if(BuildAndSendE2ConnectionUpdateFailure(transId, failureCause) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 connection update failure");
+      }
+   }
+   else
+   {
+      if(BuildAndSendE2ConnectionUpdateAcknowledge(transId, connectionInfoList) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 connection update ack");
+      }
+   }
+
+   freeAperDecodingOfE2ConnectionUpdate(connectionUpdate);
+}
+
+/*******************************************************************
+ *
+ * @brief Handles received E2AP message and sends back response  
+ *
+ * @details
+ *
+ *    Function : E2APMsgHdlr
+ *
+ *    Functionality:
+ *         - Decodes received E2AP control message
+ *         - Prepares response message, encodes and sends to SCTP
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void E2APMsgHdlr(Buffer *mBuf)
+{
+   int i =0;
+   char *recvBuf = NULLP;
+   MsgLen copyCnt =0;
+   MsgLen recvBufLen =0;
+   E2AP_PDU_t *e2apMsg = NULLP;
+   asn_dec_rval_t rval ={0}; /* Decoder return value */
+   E2AP_PDU_t e2apasnmsg={0} ;
+
+   DU_LOG("\nDEBUG   -->  E2AP : Received E2AP message buffer");
+   ODU_PRINT_MSG(mBuf, 0,0);
+
+   /* Copy mBuf into char array to decode it */
+   ODU_GET_MSG_LEN(mBuf, &recvBufLen);
+   DU_ALLOC(recvBuf, (Size)recvBufLen);
+
+   if(recvBuf == NULLP)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
+      return;
+   }
+   if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
+   {
+      DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
+      return;
+   }
+
+#ifdef DEBUG_ASN_PRINT
+   printf("\nDEBUG   -->  E2AP : Received flat buffer to be decoded : ");
+   for(i=0; i< recvBufLen; i++)
+   {
+      printf("%x",recvBuf[i]);
+   }
+#endif
+
+   /* Decoding flat buffer into E2AP messsage */
+   e2apMsg = &e2apasnmsg;
+   memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
+
+   rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
+   DU_FREE(recvBuf, (Size)recvBufLen);
+
+   if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+   {
+      DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
+      return;
+   }
+   printf("\n");
+   xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
+
+   switch(e2apMsg->present)
+   {
+      case E2AP_PDU_PR_unsuccessfulOutcome:
+         {
+            switch(e2apMsg->choice.unsuccessfulOutcome->value.present)
+            {
+               case UnsuccessfulOutcomeE2__value_PR_E2setupFailure:
+                  {
+                     procE2SetupFailure(e2apMsg);
+                     break;
+                  }
+               case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure:
+                  {
+                     procE2NodeConfigUpdateFailure(e2apMsg);
+                     break;
+                  }
+               case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure:
+                  {
+                     procRicServiceUpdateFailure(e2apMsg);
+                     break;
+                  }
+               case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse:
+                  {
+                     procRicSubscriptionModificationRefuse(e2apMsg);
+                     break;
+                  }
+               case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
+                  {
+                     ProcE2RemovalFailure(e2apMsg);
+                     break;
+                  }
+               default:
+                  {
+                     DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
+                           e2apMsg->choice.unsuccessfulOutcome->value.present);
+                     return;
+                  }
+            }
             free(e2apMsg->choice.unsuccessfulOutcome);
             break;
          }
@@ -8016,6 +9242,11 @@ void E2APMsgHdlr(Buffer *mBuf)
                      procE2NodeConfigUpdateAck(e2apMsg);
                      break;
                   }
+               case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
+                  {
+                     ProcE2RemovalResponse(e2apMsg);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome  [%d]",\
@@ -8064,6 +9295,12 @@ void E2APMsgHdlr(Buffer *mBuf)
                      procE2RemovalRequest(e2apMsg);
                      break;
                   }
+               case InitiatingMessageE2__value_PR_E2connectionUpdate:
+                  {
+                     DU_LOG("\nINFO  -->  E2AP : E2 coneection update received");
+                     procE2ConnectionUpdate(e2apMsg);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\