[Epic-ID: ODUHIGH-516][Task-ID: 536] Implementation of Error indication Procedure 36/11836/4
authorpborla <pborla@radisys.com>
Fri, 29 Sep 2023 05:14:37 +0000 (10:44 +0530)
committerpborla <pborla@radisys.com>
Fri, 29 Sep 2023 07:57:12 +0000 (13:27 +0530)
Change-Id: Iae376620e157e43353cf90b5d72ccb9726d6ee4d
Signed-off-by: pborla <pborla@radisys.com>
src/du_app/du_e2ap_msg_hdl.c
src/ric_stub/ric_e2ap_msg_hdl.c

index 8838d71..1c8843a 100644 (file)
 #include "MeasurementInfoItem.h"
 #include "RANfunctionsIDcause-List.h"
 
+/*******************************************************************
+ *
+ * @brief Fill E2 Failure Cause
+ *
+ * @details
+ *
+ *    Function : fillE2Cause
+ *
+ *    Functionality: Fill E2 Failure Cause
+ *
+ * @params[in] E2 Cause pointer to be filled in
+ *             E2 Cause to be filled from 
+ * @return void
+ *
+ ******************************************************************/
+void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause)
+{
+   e2Cause->present = failureCause.causeType;
+   switch(e2Cause->present)
+   {
+      case CauseE2_PR_ricRequest:
+         {
+            e2Cause->choice.ricRequest = failureCause.cause;
+            break;
+         }
+      case CauseE2_PR_ricService:
+         {
+            e2Cause->choice.ricService = failureCause.cause;
+            break;
+         }
+      case CauseE2_PR_e2Node:
+         {
+            e2Cause->choice.e2Node = failureCause.cause;
+            break;
+         }
+      case CauseE2_PR_transport:
+         {
+            e2Cause->choice.transport = failureCause.cause;
+            break;
+         }
+      case CauseE2_PR_protocol:
+         {
+            e2Cause->choice.protocol = failureCause.cause;
+            break;
+         }
+      case CauseE2_PR_misc:
+         {
+            e2Cause->choice.misc = failureCause.cause;
+            break;
+         }
+      case CauseE2_PR_NOTHING:
+      default:
+         break;
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Free the ErrorIndication Message
+ *
+ * @details
+ *
+ *    Function : FreeRicIndication
+ *
+ * Functionality: Free the ErrorIndication Message
+ *
+ * @params[in] 
+ *    E2AP_PDU is to freed
+ * @return void
+ *
+ ******************************************************************/
+void FreeErrorIndication(E2AP_PDU_t  *e2apMsg) 
+{
+   uint8_t arrIdx = 0;
+   ErrorIndicationE2_t *errorIndicationMsg= NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.initiatingMessage != NULLP)
+      {
+         errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
+         if(errorIndicationMsg!= NULLP)
+         {
+            if(errorIndicationMsg->protocolIEs.list.array != NULLP)
+            {
+               for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
+               {
+                  DU_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
+               }
+               DU_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
+            }
+         }
+         DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Builds and Send the ErrorIndication Message
+ *
+ * @details
+ *
+ *    Function : BuildAndSendErrorIndication
+ *
+ * Functionality:Fills the ErrorIndication Message
+ *
+ * @params[in] 
+ *    Trans id
+ *    Ric req id
+ *    Ran function id
+ *    Cause of failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+
+uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId,  E2FailureCause failureCause)
+{
+   uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
+   E2AP_PDU_t         *e2apMsg = NULLP;
+   ErrorIndicationE2_t *errorIndicationMsg=NULLP;
+   asn_enc_rval_t     encRetVal;        /* Encoder return value */
+
+   while(true)
+   {
+      DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
+
+      DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU 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 for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
+         break;
+      }
+      e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
+      e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+      e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
+
+      errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
+      
+      /* Element count is 2 for TransactionID/RICrequestID and Cause.
+       * If the RAN function id is present, the count will be increased.*/
+      elementCnt = 2;
+      if(ranFuncId>0)
+      {
+         elementCnt++;
+      }
+      
+      errorIndicationMsg->protocolIEs.list.count = elementCnt;
+      errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
+
+      /* Initialize the E2Setup members */
+      DU_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
+      if(errorIndicationMsg->protocolIEs.list.array == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
+         break;
+      }
+      
+      for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
+      {
+         DU_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
+         if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array [%d] elements in %s at line %d", arrIdx, __func__, __LINE__);
+            break;
+         }
+      }
+      if(arrIdx < elementCnt)
+         break;
+
+      arrIdx = 0;
+
+      if(transId >=0 && transId<=255)
+      {
+         /* TransactionID */
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
+      }
+      else
+      {
+         /* RICrequestID */
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
+      }
+      
+      if(ranFuncId>0)
+      {
+         /* RAN Function ID */
+         arrIdx++;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
+      }
+
+      /* Cause */
+      arrIdx++;
+      errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
+      errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
+      errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
+      fillE2Cause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, failureCause);
+
+      /* 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 Error Indication Message (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \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("\nINFO   -->  E2AP : Sending Error Indication Message");      
+
+      }
+      ret = ROK;
+      break;
+   }
+   FreeErrorIndication(e2apMsg);       
+   return ret;
+}
+
 /******************************************************************
  *
  * @brief Deallocation of memory allocated by aper decoder for e2 
@@ -150,62 +402,6 @@ void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg)
    freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail);
 }
 
-/*******************************************************************
- *
- * @brief Fill E2 Failure Cause
- *
- * @details
- *
- *    Function : fillE2Cause
- *
- *    Functionality: Fill E2 Failure Cause
- *
- * @params[in] E2 Cause pointer to be filled in
- *             E2 Cause to be filled from 
- * @return void
- *
- ******************************************************************/
-void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause)
-{
-   e2Cause->present = failureCause.causeType;
-   switch(e2Cause->present)
-   {
-      case CauseE2_PR_ricRequest:
-         {
-            e2Cause->choice.ricRequest = failureCause.cause;
-            break;
-         }
-      case CauseE2_PR_ricService:
-         {
-            e2Cause->choice.ricService = failureCause.cause;
-            break;
-         }
-      case CauseE2_PR_e2Node:
-         {
-            e2Cause->choice.e2Node = failureCause.cause;
-            break;
-         }
-      case CauseE2_PR_transport:
-         {
-            e2Cause->choice.transport = failureCause.cause;
-            break;
-         }
-      case CauseE2_PR_protocol:
-         {
-            e2Cause->choice.protocol = failureCause.cause;
-            break;
-         }
-      case CauseE2_PR_misc:
-         {
-            e2Cause->choice.misc = failureCause.cause;
-            break;
-         }
-      case CauseE2_PR_NOTHING:
-      default:
-         break;
-   }
-}
-
 /*******************************************************************
  *
  * @brief Builds Global gNodeB Params
@@ -4836,6 +5032,11 @@ void E2APMsgHdlr(Buffer *mBuf)
                      procRicServiceQuery(e2apMsg);
                      break;
                   }
+               case InitiatingMessageE2__value_PR_ErrorIndicationE2:
+                  {
+                     DU_LOG("\nINFO  -->  E2AP : Error indication received");
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\
index 0e49543..0d8555c 100644 (file)
@@ -3015,6 +3015,201 @@ uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricS
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Free the ErrorIndication Message
+ *
+ * @details
+ *
+ *    Function : FreeRicIndication
+ *
+ * Functionality: Free the ErrorIndication Message
+ *
+ * @return void
+ *
+ *
+ ******************************************************************/
+void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
+{
+   uint8_t arrIdx = 0;
+   ErrorIndicationE2_t *errorIndicationMsg= NULLP;
+
+   if(e2apMsg != NULLP)
+   {
+      if(e2apMsg->choice.initiatingMessage != NULLP)
+      {
+         errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
+         if(errorIndicationMsg!= NULLP)
+         {
+            if(errorIndicationMsg->protocolIEs.list.array != NULLP)
+            {
+               for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
+               {
+                  RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
+               }
+               RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
+            }
+         }
+         RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+      }
+      RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+   }
+}
+
+
+/*******************************************************************
+ *
+ * @brief Builds and Send the ErrorIndication Message
+ *
+ * @details
+ *
+ *    Function : BuildAndSendErrorIndication
+ *
+ * Functionality:Fills the ErrorIndication Message
+ *
+ * @params[in] 
+ *    DU id
+ *    Trans id
+ *    Ric req id
+ *    Ran function id
+ *    Reason of failure
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+
+uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
+{
+   uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
+   E2AP_PDU_t         *e2apMsg = NULLP;
+   ErrorIndicationE2_t *errorIndicationMsg=NULLP;
+   asn_enc_rval_t     encRetVal;        /* Encoder return value */
+
+   while(true)
+   {
+      DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
+
+      RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+      if(e2apMsg == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU 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 for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
+         break;
+      }
+      e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
+      e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+      e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
+
+      errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
+
+      /* Element count is 2 for TransactionID/RICrequestID and Cause.
+       * If the RAN function id is present, the count will be increased.*/
+      elementCnt = 2;
+      if(ranFuncId>0)
+         elementCnt++;
+
+      errorIndicationMsg->protocolIEs.list.count = elementCnt;
+      errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
+
+      /* Initialize the E2Setup members */
+      RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
+      if(errorIndicationMsg->protocolIEs.list.array == NULLP)
+      {
+         DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
+         break;
+      }
+      for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
+      {
+         RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
+         if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
+         {
+            DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
+            break;
+         }
+      }
+      if(arrIdx < elementCnt)
+         break;
+
+      arrIdx = 0;
+
+      if(transId >=0 && transId<=255)
+      {
+         /* TransactionID */
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
+      }
+      else
+      {
+         /* RICrequestID */
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
+      }
+      
+      if(ranFuncId>0)
+      {
+         /* RAN Function ID */
+         arrIdx++;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
+         errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
+      }
+     
+      /* Cause */
+      arrIdx++;
+      errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
+      errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
+      errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
+      fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, 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 Error Indication Message (at %s)\n",\
+               encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+         break;
+      }
+      else
+      {
+         DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication 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("\nINFO   -->  E2AP : Sending Error Indication Message");
+
+      }
+      ret = ROK;
+      break;
+   }
+   FreeErrorIndication(e2apMsg);
+   return ret;
+}
+
 /*******************************************************************
 *
 * @brief Handles received E2AP message and sends back response  
@@ -3116,7 +3311,11 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
                      break;
                   }
-
+               case InitiatingMessageE2__value_PR_ErrorIndicationE2:
+                  {
+                     DU_LOG("\nINFO  -->  E2AP : Error indication received");
+                     break;
+                  }
                default:
                   {
                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \