+/******************************************************************
+ *
+ * @brief Free RIC Subscription Failure
+ *
+ * @details
+ *
+ * Function : FreeRicSubscriptionFailure
+ *
+ * Functionality: Free RIC Subscription Failure
+ *
+ * @params[in] E2AP PDU
+ * @return void
+ *
+ * ****************************************************************/
+void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg)
+{
+ uint8_t elemIdx = 0;
+ RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
+
+ if(e2apMsg)
+ {
+ if(e2apMsg->choice.unsuccessfulOutcome)
+ {
+ ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
+ if(ricSubscriptionFailure->protocolIEs.list.array)
+ {
+ for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++)
+ {
+ DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
+ }
+ DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
+ }
+ DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
+ }
+ DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+ }
+}
+
+/******************************************************************
+ *
+ * @brief Fill and Send RIC Subscription Failure to RIC
+ *
+ * @details
+ *
+ * Function : BuildAndSendRicSubscriptionFailure
+ *
+ * Functionality: Fill and Send RIC Subscription Failure to RIC
+ *
+ * @params[in] RIC Request ID
+ * RAN Function ID
+ * Cause of Failure
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause)
+{
+ uint8_t ret = RFAILED;
+ uint8_t elementCnt = 0, elemIdx = 0;
+ E2AP_PDU_t *e2apMsg = NULLP;
+ asn_enc_rval_t encRetVal; /* Encoder return value */
+ RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP;
+ RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
+
+ while(true)
+ {
+ DU_LOG("\nINFO --> E2AP : Building RIC Subscription Failure\n");
+
+ DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+ if(e2apMsg == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : 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 at [%s] : Line [%d]", __func__, __LINE__);
+ break;
+ }
+ e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription;
+ e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
+ e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure;
+
+ ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure;
+
+ elementCnt = 3;
+ ricSubscriptionFailure->protocolIEs.list.count = elementCnt;
+ ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *);
+ DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size);
+ if(!ricSubscriptionFailure->protocolIEs.list.array)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__);
+ break;
+ }
+
+ for(elemIdx = 0; elemIdx < elementCnt; elemIdx++)
+ {
+ DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t));
+ if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx])
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \
+ __func__, __LINE__, elemIdx);
+ break;
+ }
+ }
+ if(elemIdx < elementCnt)
+ break;
+
+ elemIdx = 0;
+
+ /* RIC Request ID */
+ ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
+ ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID;
+ ricSubsFailIe->criticality = CriticalityE2_reject;
+ ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
+ ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
+ ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
+
+ /* RAN Function ID */
+ ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
+ ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID;
+ ricSubsFailIe->criticality = CriticalityE2_reject;
+ ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
+ ricSubsFailIe->value.choice.RANfunctionID = ranFuncId;
+
+ /* Cause */
+ ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++];
+ ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2;
+ ricSubsFailIe->criticality = CriticalityE2_reject;
+ ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2;
+ fillE2Cause(&ricSubsFailIe->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 RIC Subscription Failure Message (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
+ }
+ else
+ {
+ DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Failure 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 RIC Subscription Failure");
+
+ }
+ ret = ROK;
+ break;
+ }
+ FreeRicSubscriptionFailure(e2apMsg);
+ return ret;
+}
+