+
+ } /* End of for loop , traversing measurement-to-be-subscribed list */
+
+ /* If all measurement-to-be-subscribed was found in measurement-supported list and
+ * was added to measurement-subscription list successfully, return from here */
+ if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count)
+ return ROK;
+
+ return RFAILED;
+}
+
+/*******************************************************************
+ *
+ * @brief Extract E2SM-KPM Action definition
+ *
+ * @details
+ *
+ * Function : extractRicActionDef
+ *
+ * Functionality : This function :
+ * - Decodes E2SM-KPM Action Definition
+ * - Validates that action is supported by E2 node
+ * - Stores action details in local DB
+ *
+ * @params[in] RAN Function Database structure
+ * RIC subscription's Action definition to be added to
+ * RAN function
+ * RIC Action Definition buffer received from RIC
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\
+ E2FailureCause *failureCause)
+{
+ bool memFailure = false;
+ uint8_t styleIdx = 0;
+ asn_dec_rval_t rval ={0};
+
+ E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP;
+ E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
+ CmLListCp *measInfoSupportedList = NULLP;
+ CmLListCp *measInfoSubscribedList = NULLP;
+
+ /* Decoding E2SM-KPM Action Definition */
+ actionDefPtr = &actionDef;
+ memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
+
+ rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\
+ ricActionDef->size, 0, 0);
+ if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+ {
+ DU_LOG("\nERROR --> E2AP : ASN decode failed for E2SM-KPM Action Definition");
+ failureCause->causeType = E2_PROTOCOL;
+ failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE;
+ return RFAILED;
+ }
+ printf("\n");
+ xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr);
+
+
+ /* Validate if Report style to subscribe is supported by E2 Node */
+ for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++)
+ {
+ /* Validate Report style type and report style format type is supported by E2 Node */
+ if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) &&
+ (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present))
+ {
+ /* Fetch Report stype type and format type */
+ actionDefDb->styleType = actionDefPtr->ric_Style_Type;
+ actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present;
+
+ switch(actionDefPtr->actionDefinition_formats.present)
+ {
+ case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
+ {
+ actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1;
+
+ /* Fetch granularity period */
+ actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod;
+
+ /* Validate and add the Measurement to subscription list */
+ measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList;
+ measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList;
+ if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \
+ measInfoSubscribedList, &memFailure) == ROK)
+ {
+ if(!memFailure)
+ {
+ /* Free E2SM_KPM_ActionDefinition_t */
+ freeAperDecodingOfRicActionDefinition(actionDefPtr);
+ return ROK;
+ }
+ }
+
+ break; /* End of E2SM-KPM Action definition format 1 case */
+ }
+
+ default :
+ {
+ DU_LOG("\nERROR -> DUAPP: Only E2SM-KPM Action Definition Format 1 is supported");
+ break;
+ }
+ } /* End of switch for E2SM-KPM Action definition formats */
+ }
+
+ if(memFailure)
+ {
+ failureCause->causeType = E2_MISCELLANEOUS;
+ failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
+ break;
+ }
+ } /* End of for loop, traversing Report-styles-supported list in E2 node */
+
+ /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */
+ memset(actionDefDb, 0, sizeof(ActionDefinition));
+ freeAperDecodingOfRicActionDefinition(actionDefPtr);
+
+ if(failureCause->causeType == E2_NOTHING)
+ {
+ failureCause->causeType = E2_RIC_REQUEST;
+ failureCause->cause = E2_ACTION_NOT_SUPPORTED;
+ }
+ return RFAILED;
+}
+
+/*******************************************************************
+ *
+ * @brief Extract RIC Action to be setup
+ *
+ * @details
+ *
+ * Function : extractRicActionToBeSetup
+ *
+ * Functionality : This function :
+ * - Validates that each action-to-be-setup is supported by E2 node
+ * - Stores event trigger details in local DB
+ *
+ * @params[in] RAN Function Database structure
+ * RIC Subscription Info to be added to RAN function
+ * RIC Action To Be Setup List received from RIC
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
+ RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp)
+{
+ uint8_t actionIdx = 0;
+ uint8_t ricActionId = 0;
+ RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
+
+ if(actionList->list.array)
+ {
+ for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++)
+ {
+ actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx];
+ switch(actionItem->id)
+ {
+ case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item:
+ {
+ /* If Action type is REPORT and
+ * If RIC action definition's extraction and validation passes,
+ * Then :
+ * This action is added to action sequence list of subscription info */
+ ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
+
+ if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
+ {
+ ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId;
+ ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT;
+
+ if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \
+ actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
+ {
+ ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD;
+ ricSubscriptionInfo->numOfActions++;
+ break;
+ }
+ }
+
+ /* In case of any failure, action is rejected
+ * Added to rejected-action-list in subscription response */
+ memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo));
+ subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
+ if(failureCause->causeType == E2_NOTHING)
+ {
+ failureCause->causeType = E2_RIC_REQUEST;
+ failureCause->cause = E2_ACTION_NOT_SUPPORTED;
+ }
+ memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \
+ failureCause, sizeof(E2FailureCause));
+ subsRsp->numOfRejectedActions++;
+ break;
+ }
+ default:
+ DU_LOG("\nERROR --> E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id);
+ break;
+ }
+ }
+ }
+
+ /* If there is even 1 action that can be added, return ROK */
+ if(ricSubscriptionInfo->numOfActions)
+ return ROK;
+
+ if(failureCause->causeType == E2_NOTHING)
+ {
+ failureCause->causeType = E2_RIC_REQUEST;
+ failureCause->cause = E2_ACTION_NOT_SUPPORTED;
+ }
+ return RFAILED;
+}
+
+/******************************************************************
+ *
+ * @brief Processes RIC Subscription Req sent by RIC
+ *
+ * @details
+ *
+ * Function : procRicSubscriptionRequest
+ *
+ * Functionality: Processes RIC Subscription Request from RIC
+ *
+ * @params[in] E2AP_PDU_t ASN decoded E2AP message
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
+{
+ uint8_t idx = 0;
+ uint8_t ret = ROK;
+ uint16_t ranFuncId = 0;
+ RicRequestId ricReqId;
+ CmLList *ricSubscriptionNode = NULLP;
+ RanFunction *ranFuncDb = NULLP;
+ RICsubscriptionRequest_t *ricSubsReq = NULLP;
+ RICsubscriptionDetails_t *subsDetails = NULLP;
+ RicSubscription *ricSubscriptionInfo = NULLP;
+ E2FailureCause failureCause;
+
+ DU_LOG("\nINFO --> E2AP : RIC Subscription request received");
+
+ memset(&failureCause, 0, sizeof(E2FailureCause));
+ memset(&ricReqId, 0, sizeof(RicRequestId));
+
+ ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
+ for(idx=0; idx<ricSubsReq->protocolIEs.list.count; idx++)
+ {
+ if(ricSubsReq->protocolIEs.list.array[idx])
+ {
+ switch(ricSubsReq->protocolIEs.list.array[idx]->id)
+ {
+ case ProtocolIE_IDE2_id_RICrequestID:
+ {
+ ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID;
+ ricReqId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID;
+
+ break;
+ }
+
+ case ProtocolIE_IDE2_id_RANfunctionID:
+ {
+ ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID;
+
+ /* Validating RAN Function id */
+ ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
+
+ if(!ranFuncDb)
+ {
+ failureCause.causeType = E2_RIC_REQUEST;
+ failureCause.cause = E2_RAN_FUNCTION_ID_INVALID;
+ ret = RFAILED;
+ break;
+ }
+
+ if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP)
+ {
+ failureCause.causeType = E2_RIC_REQUEST;
+ failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT;
+ ret = RFAILED;
+ break;
+ }
+
+ DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription));
+ if(!ricSubscriptionInfo)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation failed for ricSubscriptionInfo");
+ failureCause.causeType = E2_MISCELLANEOUS;
+ failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED;
+ ret = RFAILED;
+ break;
+ }
+ ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
+ ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
+
+ memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
+ memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId,
+ &ricReqId, sizeof(RicRequestId));
+ ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId;
+ break;
+ }
+
+ case ProtocolIE_IDE2_id_RICsubscriptionDetails:
+ {
+ subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails;
+
+ /* Decode, Validate and record Event Trigger Definition */
+ if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \
+ &failureCause) != ROK)
+ {
+ ret = RFAILED;
+ break;
+ }
+
+ /* Decode, Validate and record RIC actions */
+ if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \
+ &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK)
+ {
+ ret = RFAILED;
+ break;
+ }
+ }
+ break;
+
+ default:
+ DU_LOG("\nERROR --> E2AP : Invalid IE received in RIC SubsReq:%ld",
+ ricSubsReq->protocolIEs.list.array[idx]->id);
+ break;
+ }
+
+ if(ret == RFAILED)
+ break;
+ }
+ }
+
+ freeAperDecodingOfRicSubsReq(ricSubsReq);
+
+ if(ret == ROK)
+ {
+ /* Add RAN subcription detail to RAN function */
+ DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
+ if(ricSubscriptionNode)
+ {
+ ricSubscriptionNode->node = (PTR) ricSubscriptionInfo;
+ cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode);
+ }
+
+ ranFuncDb->numPendingSubsRsp++;
+
+#ifdef KPI_CALCULATION
+ /* Send statistics request to other DU entities */
+ BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo);
+#endif
+
+ /* TODO : Trigger RIC Indication once statistics indication is
+ * received from MAC .
+ * TBD in future gerrit */
+ //BuildAndSendRicIndication(ricSubscriptionInfo);
+ }
+ else
+ {
+ DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription));
+
+ if(ranFuncDb)
+ {
+ memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
+ }
+
+ /* Send RIC Subcription Failure */
+ BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause);
+ }
+
+ return ret;
+}
+
+/******************************************************************
+ *
+ * @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;
+}
+
+/*******************************************************************
+ *
+ * @brief Free the RicIndication Message
+ *
+ * @details
+ *
+ * Function : FreeRicIndication
+ *
+ * Functionality: Free the RicIndication Message
+ *
+ * @return void
+ *
+ *
+ ******************************************************************/
+void FreeRicIndication(E2AP_PDU_t *e2apMsg)
+{
+ uint8_t idx = 0;
+ RICindication_t *ricIndicationMsg= NULLP;
+
+ if(e2apMsg != NULLP)
+ {
+ if(e2apMsg->choice.initiatingMessage != NULLP)
+ {
+ ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
+ if(ricIndicationMsg!= NULLP)
+ {
+ if(ricIndicationMsg->protocolIEs.list.array != NULLP)
+ {
+ for(idx=0; idx<ricIndicationMsg->protocolIEs.list.count; idx++)
+ {
+ if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP)
+ {
+ switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
+ {
+ case ProtocolIE_IDE2_id_RICrequestID:
+ break;
+
+ case ProtocolIE_IDE2_id_RANfunctionID:
+ break;
+
+ case ProtocolIE_IDE2_id_RICactionID:
+ break;
+
+ case ProtocolIE_IDE2_id_RICindicationType:
+ break;
+
+ case ProtocolIE_IDE2_id_RICindicationHeader:
+ {
+ DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
+ break;
+ }
+ case ProtocolIE_IDE2_id_RICindicationMessage:
+ {
+ DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
+ break;
+ }
+ default:
+ break;
+ }
+ DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t));
+ }
+ }
+ DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size);
+ }
+ }
+ DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
+ }
+ DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));
+ }
+}
+
+/*******************************************************************
+ *
+ * brief Fill the RicIndication Message
+ *
+ * @details
+ *
+ * Function : FillRicIndication
+ *
+ * Functionality:Fills the RicIndication Message
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
+{
+ uint8_t elementCnt=0;
+ uint8_t idx=0;
+ uint8_t ret = ROK;
+ elementCnt = 6;
+
+ ricIndicationMsg->protocolIEs.list.count = elementCnt;
+ ricIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(RICindication_t);
+ /* Initialize the Ric Indication members */
+ DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
+ ricIndicationMsg->protocolIEs.list.size);
+ if(ricIndicationMsg->protocolIEs.list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
+ ret = RFAILED;
+ }
+ else
+ {
+ for(idx=0; idx<elementCnt; idx++)
+ {
+ DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
+ sizeof(RICindication_IEs_t));
+ if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
+ ret = RFAILED;
+ }
+ }
+ if(ret != RFAILED)
+ {
+ idx = 0;
+
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
+ RICindication_IEs__value_PR_RICrequestID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
+
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
+ RICindication_IEs__value_PR_RANfunctionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
+
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
+ RICindication_IEs__value_PR_RICactionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
+
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
+ RICindication_IEs__value_PR_RICindicationType;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
+
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
+ RICindication_IEs__value_PR_RICindicationHeader;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
+ sizeof(uint8_t);
+ DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
+ if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
+ ret = RFAILED;
+ }
+ else
+ {
+ buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
+ idx++;
+ /* TO BE CHANGED: RIC INDICATION DATA */
+ /* For now filling a dummy octect data, need to tested with PRBs*/
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
+ RICindication_IEs__value_PR_RICindicationMessage;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
+ sizeof(uint8_t);
+ DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
+ if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
+ ret = RFAILED;
+ }
+ else
+ {
+ buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Builds and Send the RicIndication Message
+ *
+ * @details
+ *
+ * Function : BuildAndSendRicIndication
+ *
+ * Functionality:Fills the RicIndication Message
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+
+uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
+{
+ E2AP_PDU_t *e2apMsg = NULLP;
+ RICindication_t *ricIndicationMsg=NULLP;
+ asn_enc_rval_t encRetVal; /* Encoder return value */
+ uint8_t ret = RFAILED;
+ uint8_t FillRicIndicationret = ROK;
+
+ while(true)
+ {
+ DU_LOG("\nINFO --> E2AP : Building RIC Indication Message\n");
+
+ DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
+ if(e2apMsg == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
+ 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");
+ break;
+ }
+ e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
+ e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
+ e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication;
+
+ ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
+
+ FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
+ if(FillRicIndicationret != ROK)
+ {
+ break;
+ }
+ /* 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,\