+ }
+
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
+ {
+ e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
+ for(idx =0; idx <e2NodeCfgAckList->list.count; idx++)
+ {
+ e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx];
+ switch(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
+ {
+ case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
+ {
+ e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD, &node);
+ if(!e2NodeComponentInfo)
+ {
+ DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__);
+ return RFAILED;
+ }
+ else
+ {
+ cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node);
+ DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize);
+ DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize);
+ DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
+ DU_FREE(node, sizeof(CmLList));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ default:
+ DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld",
+ e2SetRspMsg->protocolIEs.list.array[arrIdx]->id);
+ break;
+ }
+ }
+ freeAperDecodingOfE2SetupRsp(e2SetRspMsg);
+
+ if(duSendE2NodeConfigurationUpdate() != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update");
+ return RFAILED;
+ }
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Free RIC Subscription Request
+ *
+ * @details
+ *
+ * Function : freeAperDecodingOfRicSubsReq
+ *
+ * Functionality : Free RIC Subscription Request
+ *
+ * @return void
+ *
+ ******************************************************************/
+void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq)
+{
+ uint8_t idx = 0;
+ uint8_t elementIdx = 0;
+ RICsubscriptionDetails_t *subsDetails = NULLP;
+ RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
+
+ if(ricSubscriptionReq->protocolIEs.list.array)
+ {
+ for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
+ {
+ switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
+ {
+ case ProtocolIE_IDE2_id_RICsubscriptionDetails:
+ {
+ subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails);
+ free(subsDetails->ricEventTriggerDefinition.buf);
+
+ if(subsDetails->ricAction_ToBeSetup_List.list.array)
+ {
+ for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
+ {
+ if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
+ {
+ actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
+ if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
+ {
+ free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf);
+ free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition);
+ }
+ free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]);
+ }
+ }
+ free(subsDetails->ricAction_ToBeSetup_List.list.array);
+ }
+ break;
+ }
+ }
+ free(ricSubscriptionReq->protocolIEs.list.array[idx]);
+ }
+ free(ricSubscriptionReq->protocolIEs.list.array);
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Free Event Trigger Definition
+ *
+ * @details
+ *
+ * Function : freeAperDecodingOfEventTriggerDef
+ *
+ * Functionality: Free Event Trigger Definition
+ *
+ * @params[in] E2SM-KPM Event Trigger Definition
+ * @return void
+ *
+ * ****************************************************************/
+void freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
+{
+ if(eventTiggerDef)
+ {
+ switch(eventTiggerDef->eventDefinition_formats.present)
+ {
+ case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
+ break;
+
+ case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1:
+ free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1);
+ break;
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Extract E2SM-KPM Event trigger definition
+ *
+ * @details
+ *
+ * Function : extractEventTriggerDef
+ *
+ * Functionality : This function :
+ * - Decodes E2SM-KPM Event Trigger Definition
+ * - Validates that even trigger style 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 Event Trigger Definition buffer received from RIC
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \
+ RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause)
+{
+ uint8_t ret = RFAILED;
+ uint8_t eventIdx = 0;
+ asn_dec_rval_t rval ={0};
+ E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP;
+
+ /* Decoding E2SM-KPM Even Trigger Definition */
+ eventTiggerDefPtr = &eventTiggerDef;
+ memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t));
+
+ rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\
+ ricEventTriggerDef->size, 0, 0);
+ if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+ {
+ DU_LOG("\nERROR --> E2AP : ASN decode failed for E2SM-KPM Event Trigger 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_EventTriggerDefinition, eventTiggerDefPtr);
+
+ /* Validating the received event trigger definition format */
+ for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++)
+ {
+ if((eventTiggerDefPtr->eventDefinition_formats.present != \
+ E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \
+ (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType))
+ {
+ ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType;
+ ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \
+ eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod;
+
+ ret = ROK;
+ break;
+ }
+ }
+
+ if(ret == RFAILED)
+ {
+ failureCause->causeType = E2_RIC_REQUEST;
+ failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED;
+ }
+ /* Free E2SM_KPM_EventTriggerDefinition_t */
+ freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Free RIC Action Definition
+ *
+ * @details
+ *
+ * Function : freeAperDecodingOfRicActionDefinition
+ *
+ * Functionality: Free RIC Action Definition
+ *
+ * @params[in] E2SM-KPM Action definition
+ * @return void
+ *
+ * ****************************************************************/
+void freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef)
+{
+ uint8_t elementIdx = 0;
+ E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
+ MeasurementInfoItem_t *measItem = NULLP;
+
+ switch(actionDef->actionDefinition_formats.present)
+ {
+ case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
+ {
+ if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1)
+ {
+ actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1;
+ if(actionFormat1->measInfoList.list.array)
+ {
+ for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
+ {
+ if(actionFormat1->measInfoList.list.array[elementIdx])
+ {
+ measItem = actionFormat1->measInfoList.list.array[elementIdx];
+ switch(measItem->measType.present)
+ {
+ case MeasurementType_PR_NOTHING:
+ break;
+
+ case MeasurementType_PR_measName:
+ {
+ free(measItem->measType.choice.measName.buf);
+ break;
+ }
+
+ case MeasurementType_PR_measID:
+ break;
+ }
+ free(measItem);
+ }
+ }
+ free(actionFormat1->measInfoList.list.array);
+ }
+ free(actionFormat1);
+ }
+ break;
+ }
+ case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
+ case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
+ case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
+ case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
+ default:
+ break;
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Extract Measurement Info list from action definition
+ *
+ * @details
+ *
+ * Function : extractMeasInfoList
+ *
+ * Functionality : This function :
+ * - Traverses Measurement-to-be-subscribed list
+ * - Validates that each measurement in Measurement-to-be-subscribed
+ * list is supported in RAN-Function->Measurement-supported list.
+ * - If all measurements in an action is supported by RAN function,
+ * it is added to measurement-subscribed list in local DB
+ *
+ * @params[in] Measurement Info supported list by RAN function
+ * Measurement Info to be subscribed as requested by RIC
+ * Measurement Info finally subscribed
+ * Memory failure indicator
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \
+ CmLListCp *measInfoSubscribedList, bool *memFailure)
+{
+ uint8_t elementIdx = 0;
+ MeasurementInfoForAction *measInfoSupportedDb = NULLP;
+ MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP;
+ CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;;
+ MeasurementInfoItem_t *measItem = NULLP;
+
+ /* Validate Measurement list is supported by E2 node.
+ *
+ * Traverse and compare the Measurement-Supported List in E2
+ * node with Measurement-to-be-subscribed list received from RIC.
+ * If a match is found, add it to measurement-subscription list.
+ */
+ for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++)
+ {
+ measInfoSubscribedDb = NULLP;
+ measToAddNode = NULLP;
+ measItem = measInfoToBeSubscribedList->list.array[elementIdx];
+
+ CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode);
+ while(supportedMeasNode)
+ {
+ measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node;
+ switch(measItem->measType.present)
+ {
+ case MeasurementType_PR_measName:
+ {
+ if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf))
+ {
+ DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
+ }
+ break;
+ }
+
+ case MeasurementType_PR_measID:
+ {
+ if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID)
+ {
+ DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo));
+ }
+ break;
+ }
+
+ default:
+ {
+ DU_LOG("\nERROR -> DUAPP: Invalid Measurement-type identifier in \
+ E2SM-KPM Action Definition Format");
+ break;
+ }
+ } /* End of switch, for measurement type identifier */
+
+ /* If measurement type is supported, add to measurement-subscription list */
+ if(measInfoSubscribedDb)
+ {
+ measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId;
+ memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \
+ strlen(measInfoSupportedDb->measurementTypeName));
+
+ DU_ALLOC(measToAddNode, sizeof(CmLList));
+ if(measToAddNode)
+ {
+ measToAddNode->node = (PTR) measInfoSubscribedDb;
+ cmLListAdd2Tail(measInfoSubscribedList, measToAddNode);
+
+ /* Break out of while loop if measurement info is found in measurement-supported list */
+ break;
+ }
+ else
+ {
+ DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo));
+ measInfoSubscribedDb = NULLP;
+ *memFailure = true;
+ break;
+ }
+ }
+
+ supportedMeasNode = supportedMeasNode->next;
+
+ } /* End of while for traversing measurement-supported list in a report style */
+
+ /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style
+ * Then :
+ * Delete all entries from measurement-subscription list and
+ * Break out of for loop to search in next report style */
+ if(!measInfoSubscribedDb)
+ {
+ while(measInfoSubscribedList->count)
+ {
+ measToDelNode = cmLListDelFrm(measInfoSubscribedList, measInfoSubscribedList->first);
+ measInfoToDel = (MeasurementInfo*)measToDelNode->node;
+ DU_FREE(measInfoToDel, sizeof(MeasurementInfo));
+ DU_FREE(measToDelNode, sizeof(CmLList));
+ }
+ break;
+ }
+
+ } /* 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;
+ }