[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-535] Implementation of E2 Removal Procedure... 69/11969/3
authorpborla <pborla@radisys.com>
Wed, 25 Oct 2023 12:06:13 +0000 (17:36 +0530)
committerpborla <pborla@radisys.com>
Fri, 27 Oct 2023 10:29:28 +0000 (15:59 +0530)
Change-Id: Iced6b80c9fbf1d3f4430416f91d55492f7abaf2b
Signed-off-by: pborla <pborla@radisys.com>
src/du_app/du_e2ap_msg_hdl.c
src/ric_stub/ric_e2ap_msg_hdl.c

index 83be943..6dffb51 100644 (file)
@@ -232,7 +232,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 +391,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;
@@ -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;
 
@@ -7880,6 +7881,369 @@ void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
    freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck);
 }
 
+/*******************************************************************
+ *
+ * @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++)
+            {
+               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));
+   }
+}
+
+/*******************************************************************
+ *
+ * @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_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
+         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)
+   {
+      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);
+      }
+   }
+}
+
+/******************************************************************
+ *
+ * @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;
+
+   e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
+
+   if(!e2RemovalFailure->protocolIEs.list.array)      
+   {
+      DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
+      return;
+   }
+   
+   for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
+   {
+      if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
+      {
+         switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
+         {
+            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))
+                  {
+                     memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
+                  }
+                  else
+                  {
+                     DU_LOG("\nERROR  -->  E2AP : Invalid transaction id [%d]", transId);
+                  }
+                  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))
+                  {
+                     removeE2NodeInformation();
+                     memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo));
+                  }
+                  else
+                  {
+                     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 Handles received E2AP message and sends back response  
@@ -7974,6 +8338,11 @@ void E2APMsgHdlr(Buffer *mBuf)
                      procRicSubscriptionModificationRefuse(e2apMsg);
                      break;
                   }
+               case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
+                  {
+                     ProcE2RemovalFailure(e2apMsg);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome  [%d]",\
@@ -8016,6 +8385,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]",\
index 5f8b115..e9bc3f5 100644 (file)
@@ -6023,7 +6023,7 @@ void deleteE2NodeInfo(DuDb *duDb)
  *
  * @details
  *
- *    Function : ProcRemovalResponse 
+ *    Function : ProcE2RemovalResponse 
  *
  * Functionality: Process E2 Removal Response 
  *
@@ -6034,12 +6034,10 @@ void deleteE2NodeInfo(DuDb *duDb)
  *
  ******************************************************************/
 
-void ProcRemovalResponse(uint32_t duId, E2RemovalResponse_t *removalRsp)
+void ProcE2RemovalResponse(uint32_t duId, E2RemovalResponse_t *removalRsp)
 {
    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)
@@ -6080,6 +6078,388 @@ void ProcRemovalResponse(uint32_t duId, E2RemovalResponse_t *removalRsp)
       }
    }
 }
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for E2 Removal Failure
+ *
+ * @details
+ *
+ *    Function : FreeE2RemovalFailure
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for E2RemovalFailure
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ * @return void
+ *
+ * ****************************************************************/
+void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0;
+   E2RemovalFailure_t *e2RemovalFailure=NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
+      {
+         e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
+         if(e2RemovalFailure->protocolIEs.list.array)
+         {
+            for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
+            {
+               if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
+               {
+                  RIC_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
+               }
+            }
+            RIC_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Removal Failure msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2RemovalFailure
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Removal Failure Message
+ * @params[in] 
+ *    DU Id
+ *    Trans Id 
+ *    Type of failure 
+ *    Cause of failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t BuildAndSendRemovalFailure(uint32_t duId, uint16_t transId,  CauseE2_PR causePresent, uint8_t reason)
+{
+   uint8_t           ieIdx = 0, elementCnt = 0;
+   uint8_t           ret = RFAILED;
+   E2AP_PDU_t        *e2apMsg = NULLP;
+   E2RemovalFailure_t *e2RemovalFailure=NULLP;
+   asn_enc_rval_t    encRetVal;       /* Encoder return value */
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Failure Message\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_unsuccessfulOutcome;
+
+      RIC_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_E2removal;
+      e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure;
+      e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
+
+      elementCnt = 2;
+      e2RemovalFailure->protocolIEs.list.count = elementCnt;
+      e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *);
+      RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
+      if(!e2RemovalFailure->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(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
+         if(!e2RemovalFailure->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;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      /* Cause */
+      ieIdx++;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
+      e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
+      fillE2FailureCause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
+      
+      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 removal 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 Removal Failure \n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         }
+      }
+
+      /* Sending msg */
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Failure");
+         break;
+      }
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   FreeE2RemovalFailure(e2apMsg);
+   return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for E2 Removal Response
+ *
+ * @details
+ *
+ *    Function : FreeE2RemovalResponse
+ *
+ *    Functionality:
+ *       - freeing the memory allocated for E2RemovalResponse
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
+{
+   uint8_t ieIdx =0;
+   E2RemovalResponse_t *e2RemovalResponse=NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.successfulOutcome != NULLP)
+      {
+         e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
+         if(e2RemovalResponse->protocolIEs.list.array)
+         {
+            for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++)
+            {
+               if(e2RemovalResponse->protocolIEs.list.array[ieIdx])
+               {
+                  RIC_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
+               }
+            }
+            RIC_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
+         }
+         RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Buld and send the E2 Removal Response msg
+ *
+ * @details
+ *
+ *    Function : BuildAndSendE2RemovalResponse
+ *
+ *    Functionality:
+ *         - Buld and send the E2 Removal Response Message
+ * @params[in] 
+ *    Du Id
+ *    Trans Id 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendRemovalResponse(uint32_t duId, uint16_t transId)
+{
+   uint8_t ieIdx = 0, elementCnt = 0;
+   uint8_t ret = RFAILED, duIdx =0;
+   E2AP_PDU_t *e2apMsg = NULLP;
+   DuDb *duDb = NULLP;
+   E2RemovalResponse_t *e2RemovalResponse=NULLP;
+   asn_enc_rval_t    encRetVal;       /* Encoder return value */
+
+   DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Response Message\n");
+   do
+   {
+      SEARCH_DU_DB(duIdx, duId, duDb);
+      if(duDb == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
+         return;
+      }
+   
+      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_successfulOutcome;
+
+      RIC_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_E2removal;
+      e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
+      e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse;
+      e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
+
+      elementCnt = 1;
+      e2RemovalResponse->protocolIEs.list.count = elementCnt;
+      e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *);
+      RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
+      if(!e2RemovalResponse->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(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
+         if(!e2RemovalResponse->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;
+      e2RemovalResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
+      e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
+      e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID;
+      e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
+
+      xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
+
+      memset(encBuf, 0, ENC_BUF_MAX_LEN);
+      encBufSize = 0;
+      encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
+      if(encRetVal.encoded == ENCODE_FAIL)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal response structure (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Response \n");
+         for(int i=0; i< encBufSize; i++)
+         {
+            DU_LOG("%x",encBuf[i]);
+         }
+      }
+
+      /* Sending msg */
+      if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Response");
+         break;
+      }
+
+      ret = ROK;
+      break;
+   }while(true);
+
+   FreeE2RemovalResponse(e2apMsg);
+   deleteE2NodeInfo(duDb);
+   return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Process Removal req received from RIC
+ *
+ * @details
+ *
+ *    Function : procE2RemovalRequest
+ *
+ * Functionality: Process Removal req received from RIC
+ *
+ * @param  
+ *    DU id
+ *    E2 Removal Request 
+ * @return void
+ *
+ ******************************************************************/
+
+void procE2RemovalRequest(uint32_t duId, E2RemovalRequest_t *removalReq)
+{
+   uint8_t arrIdx =0;
+   uint16_t transId =0;
+
+   DU_LOG("\nINFO   -->  E2AP : E2 Removal request received");
+   
+   for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
+   {
+      switch(removalReq->protocolIEs.list.array[arrIdx]->id)
+      {
+         case ProtocolIE_IDE2_id_TransactionID:
+            {
+               transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
+               break;
+            }
+         default:
+            {
+               DU_LOG("\nERROR  -->  E2AP : Invalid IE recevied [%d]", transId);
+               break;
+            }
+      }
+   }
+   
+   if(transId>=0 && transId<=255)
+   {
+      if(BuildAndSendRemovalResponse(duId, transId) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
+      }
+   }
+   else
+   {
+      if(BuildAndSendRemovalFailure(duId, transId, CauseE2_PR_protocol, CauseE2Protocol_abstract_syntax_error_falsely_constructed_message) != ROK)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
+      }
+   }
+}
 
 /*******************************************************************
 *
@@ -6202,6 +6582,13 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
                      break;
                   }
+               case InitiatingMessageE2__value_PR_E2RemovalRequest:
+                  {
+                     DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
+                     procE2RemovalRequest(*duId,\
+                     &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest);
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
@@ -6229,7 +6616,7 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                   }
                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
                   {
-                     ProcRemovalResponse(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse);
+                     ProcE2RemovalResponse(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse);
                      break;
                   }
                default: