From: lal.harshita Date: Thu, 14 Sep 2023 09:43:53 +0000 (+0530) Subject: [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-528] RIC Subscription Request X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=121b3a1d79469a65069e06a8aa204c54e913533f;p=o-du%2Fl2.git [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-528] RIC Subscription Request Change-Id: Ib89e09a0bac4f9b03f915bf0174cc7a1170eb108 Signed-off-by: lal.harshita --- diff --git a/src/du_app/du_e2ap_mgr.h b/src/du_app/du_e2ap_mgr.h index e59e646f9..e337f80e9 100644 --- a/src/du_app/du_e2ap_mgr.h +++ b/src/du_app/du_e2ap_mgr.h @@ -80,8 +80,8 @@ typedef enum /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.2.11 */ typedef enum { - INSERT, REPORT, + INSERT, POLICY }ActionType; @@ -261,7 +261,7 @@ typedef struct /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.1.1 */ typedef struct { - uint32_t reportingPeriod; + uint32_t reportingPeriod; /* In milliseconds */ }EventTriggerFormat1; /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.1 */ @@ -285,16 +285,13 @@ typedef struct /* O-RAN.WG3.E2SM-KPM-R003-v03.00 : Section 8.2.1.2.1 */ typedef struct { - union - { - char measurementTypeName[STRING_SIZE_150_BYTES]; - uint16_t measurementTypeId; - }choice; + char measurementTypeName[STRING_SIZE_150_BYTES]; + uint16_t measurementTypeId; /* As of now Labels are not used, hence it is not implemented completely */ //uint32_t numOfLabels; //LabelInfo LabelInfoList[MAX_LABEL_INFO]; - + CmLListCp measuredValue; /* To be filled when numOfLabels is 0, else values are calculated per Label */ }MeasurementInfo; @@ -333,6 +330,7 @@ typedef struct typedef struct { uint8_t styleType; + uint8_t formatType; union { ActionDefFormat1 format1; diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index d7a98bd29..f13282f3b 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -45,6 +45,11 @@ #include "RIC-EventTriggerStyle-Item.h" #include "RIC-ReportStyle-Item.h" #include "MeasurementInfo-Action-Item.h" +#include "E2SM-KPM-EventTriggerDefinition.h" +#include "E2SM-KPM-EventTriggerDefinition-Format1.h" +#include "E2SM-KPM-ActionDefinition.h" +#include "E2SM-KPM-ActionDefinition-Format1.h" +#include "MeasurementInfoItem.h" /******************************************************************* * @@ -1623,6 +1628,528 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) 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) +{ + 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"); + 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; + } + } + + /* 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) +{ + 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"); + 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) + 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); + 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) +{ + 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 */ + if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report) + { + ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; + 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) == ROK) + { + ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD; + ricSubscriptionInfo->numOfActions++; + } + else + { + memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo)); + /* TODO : Since this action addition failed, add to + * reject-action-list in subscription response */ + } + } + 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; + + return RFAILED; +} + /****************************************************************** * * @brief Processes RIC Subscription Req sent by RIC @@ -1641,13 +2168,14 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) { - uint8_t idx; - uint8_t ied; + uint8_t idx = 0; uint8_t ret = ROK; + uint16_t ranFuncId = 0; CmLList *ricSubscriptionNode = NULLP; - RICsubscriptionRequest_t *ricSubsReq; - RicSubscription *ricSubscriptionInfo; - RICaction_ToBeSetup_ItemIEs_t *actionItem; + RanFunction *ranFuncDb = NULLP; + RICsubscriptionRequest_t *ricSubsReq = NULLP; + RICsubscriptionDetails_t *subsDetails = NULLP; + RicSubscription *ricSubscriptionInfo = NULLP; DU_LOG("\nINFO --> E2AP : RIC Subscription request received"); ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; @@ -1660,84 +2188,93 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) { case ProtocolIE_IDE2_id_RICrequestID: { - /* TODO :- ricSubscriptionInfo details will be stored based on - * RAN function id, so first we need to search RAN function and then add - * subscription details to that ran function */ DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription)); if(!ricSubscriptionInfo) { DU_LOG("\nERROR --> E2AP : Memory allocation failed for ricSubscriptionInfo"); - return RFAILED; + ret = RFAILED; + break; } ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID; ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID; - DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); - if(ricSubscriptionNode) - { - ricSubscriptionNode->node = (PTR) ricSubscriptionInfo; - cmLListAdd2Tail(&duCb.e2apDb.ranFunction[0].subscriptionList,ricSubscriptionNode); - } + break; } + case ProtocolIE_IDE2_id_RANfunctionID: { - duCb.e2apDb.ranFunction[0].id = ricSubsReq->protocolIEs.list.array[idx]-> \ - value.choice.RANfunctionID; + ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; + + /* Validating RAN Function id */ + if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId) + { + ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1]; + } + else + { + /* TODO : Send RAN Subcription Failure */ + ret = RFAILED; + } break; } + case ProtocolIE_IDE2_id_RICsubscriptionDetails: { - if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ - list.array) + subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails; + + /* Decode, Validate and record Event Trigger Definition */ + if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition) != ROK) { - actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\ - .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\ - .list.array[0]; + /* TODO : Send RAN Subcription Failure */ + ret = RFAILED; + break; + } - for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\ - RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++) - { - switch(actionItem->id) - { - case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item: - { - ricSubscriptionInfo->actionSequence[0].id = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; - ricSubscriptionInfo->actionSequence[0].type = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType; - break; - } - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id); - break; - } - free(actionItem); - } - free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ - list.array); - -#ifdef KPI_CALCULATION - /* This is a dummy trigger for statistics request. It will - * be removed in next gerrit and actual statistics request - * will be sent when RIC subscription request is received - * from RIC */ - ricSubscriptionInfo->actionSequence[0].definition.styleType = 1; - BuildAndSendStatsReq(ricSubscriptionInfo->actionSequence[0].definition); -#endif + /* Decode, Validate and record RIC actions */ + if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List) != ROK) + { + /* TODO : Send RAN Subcription Failure */ + ret = RFAILED; + break; } - break; } + break; default: DU_LOG("\nERROR --> E2AP : Invalid IE received in RIC SubsReq:%ld", ricSubsReq->protocolIEs.list.array[idx]->id); break; } - free(ricSubsReq->protocolIEs.list.array[idx]); + + if(ret == RFAILED) + break; } } - free(ricSubsReq->protocolIEs.list.array); - ret = BuildAndSendRicSubscriptionRsp(); + + freeAperDecodingOfRicSubsReq(ricSubsReq); + + if(ret == ROK) { - BuildAndSendRicIndication(ricSubscriptionInfo); + /* Add RAN subcription detail to RAN function */ + DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); + if(ricSubscriptionNode) + { + ricSubscriptionNode->node = (PTR) ricSubscriptionInfo; + cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode); + } + +#ifdef KPI_CALCULATION + /* Send statistics request to other DU entities */ + BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo); +#endif + + /* TODO : Trigger RIC subscription response once statistics response is + * received from MAC . + * TBD in next gerrit */ + ret = BuildAndSendRicSubscriptionRsp(); + { + BuildAndSendRicIndication(ricSubscriptionInfo); + } } return ret; @@ -1759,63 +2296,63 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) ******************************************************************/ void FreeRicIndication(E2AP_PDU_t *e2apMsg) { - uint8_t idx=0; + 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; idxprotocolIEs.list.count; idx++) - { - if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP) - { - switch(ricIndicationMsg->protocolIEs.list.array[idx]->id) - { - case ProtocolIE_IDE2_id_RICrequestID: - break; + ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication; + if(ricIndicationMsg!= NULLP) + { + if(ricIndicationMsg->protocolIEs.list.array != NULLP) + { + for(idx=0; idxprotocolIEs.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_RANfunctionID: + break; - case ProtocolIE_IDE2_id_RICactionID: - break; + case ProtocolIE_IDE2_id_RICactionID: + break; - case ProtocolIE_IDE2_id_RICindicationType: - 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)); + 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 diff --git a/src/du_app/du_e2ap_msg_hdl.h b/src/du_app/du_e2ap_msg_hdl.h index 18edc2770..47f1b7ad3 100644 --- a/src/du_app/du_e2ap_msg_hdl.h +++ b/src/du_app/du_e2ap_msg_hdl.h @@ -25,7 +25,8 @@ uint8_t BuildAndSendE2NodeConfigUpdate(); uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause); void E2APMsgHdlr(Buffer *mBuf); uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo); -uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction); + +uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo); /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index 644494300..650284089 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -2093,34 +2093,93 @@ uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats) * RFAILED - failure * * ****************************************************************/ -uint8_t BuildAndSendStatsReqToMac(MacStatsReq duMacStatsReq) +uint8_t BuildAndSendStatsReqToMac(uint64_t subscriptionId, RicSubscription *ricSubscriptionInfo) { Pst pst; + uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0; + ActionInfo *actionDb = NULLP; + ActionDefFormat1 *format1Action = NULLP; MacStatsReq *macStatsReq = NULLP; - - DU_LOG("\nINFO --> DU_APP : Builds Statistics Request to send to MAC"); + /* Fill MAC statistics request */ DU_ALLOC_SHRABL_BUF(macStatsReq, sizeof(MacStatsReq)); if(macStatsReq == NULLP) { DU_LOG("\nERROR --> DU_APP : Memory allocation failed for macStatsReq in BuildAndSendStatsReqToMac"); return RFAILED; } - else + + macStatsReq->subscriptionId = subscriptionId; + for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++) { - memcpy(macStatsReq, &duMacStatsReq, sizeof(MacStatsReq)); + if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD) + { + actionDb = &ricSubscriptionInfo->actionSequence[actionIdx]; + macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id; + switch(actionDb->definition.formatType) + { + case 1: + { + format1Action = &actionDb->definition.choice.format1; + macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod; + + CmLList *node = NULLP; + MeasurementInfo *measInfo = NULLP; + statsIdx = 0; + /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */ + node = cmLListFirst(&format1Action->measurementInfoList); + while(node) + { + measInfo = (MeasurementInfo *)(node->node); + switch(measInfo->measurementTypeId) + { + case 1: + { + macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE; + break; + } + case 2: + { + macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE; + break; + } + default: + { + DU_LOG("\nERROR --> DU_APP : Invalid measurement name BuildAndSendStatsReqToMac"); + break; + } + } + node = node->next; + } + macStatsReq->statsGrpList[grpIdx].numStats = statsIdx; + break; + } + default: + { + DU_LOG("\nERROR --> DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported"); + break; + } + } + if(macStatsReq->statsGrpList[grpIdx].numStats) + grpIdx++; + } + } + macStatsReq->numStatsGroup = grpIdx; + if(macStatsReq->numStatsGroup) + { + DU_LOG("\nDEBUG --> DU_APP: Sending Statistics Request to MAC "); FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_REQ); - DU_LOG("\nDEBUG --> DU_APP: Sending Statistics Request to MAC "); - if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == RFAILED) - { - DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Request to MAC"); - DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq)); - return RFAILED; - } + if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == ROK) + return ROK; + + DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Request to MAC"); } - return ROK; + + DU_LOG("\nERROR --> DU_APP: No Statistics group found valid. Hence statistics request is not sent to MAC"); + DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq)); + return RFAILED; } /******************************************************************* @@ -2173,29 +2232,28 @@ Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1) * reporting configuration. If so, send the update to * respective layer. * - * @params[in] + * @params[in] Subscription Info * * @return ROK - success * RFAILED - failure * * ****************************************************************/ -uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction) +uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo) { - Statistics stats; - - switch(subscribedAction.styleType) - { - case 1: - stats = FetchStatsFromActionDefFormat1(subscribedAction.choice.format1); - case 2: - case 3: - case 4: - case 5: - default: - break; - } - - if(BuildAndSendStatsReqToMac(stats.macStatsReq) != ROK) + uint64_t subscriptionId = 0; + + /* Calculate 64 bit subscription-ID : + * First 16 MSB is unused + * Next 16 MSB = RAN-Function-ID + * Next 16 MSB = Requestor-ID in RIC-Request-ID + * Last 16 LSB = Instance-ID in RIC-Request-ID + */ + subscriptionId = ricSubscriptionInfo->requestId.instanceId; + subscriptionId |= ((uint64_t)ricSubscriptionInfo->requestId.requestorId << 16); + subscriptionId |= ((uint64_t)ranFuncId << 32); + + /* Build and sent subscription information to MAC in Statistics Request */ + if(BuildAndSendStatsReqToMac(subscriptionId, ricSubscriptionInfo) != ROK) { DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToMac()"); return RFAILED; @@ -2204,18 +2262,13 @@ uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction) /* TODO : When KPI collection from RLC will be supported, this function will be * called to configure KPIs to be colled */ #if 0 - if(BuildAndSendStatsReqToRlc(macStatsReq->rlcStatsReq) != ROK) + if(BuildAndSendStatsReqToRlc() != ROK) { - DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToRlc()"); - return RFAILED; + DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToRlc()"); + return RFAILED; } #endif - /* TODO : In the caller of this function, change ActionDefinition->action - * from CONFIG_ADD to CONFIG_UNKNOWN once configuration is sent - * To be done in next gerrit*/ - - return ROK; } @@ -2240,13 +2293,12 @@ uint8_t BuildAndSendStatsReq(ActionDefinition subscribedAction) * ****************************************************************/ uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp) { - uint8_t idx = 0; - DU_LOG("\nINFO --> DU_APP : DuProcMacStatsRsp: Received Statistics Response from MAC"); if(statsRsp) { #ifdef DEBUG_PRINT + uint8_t idx = 0; DU_LOG("\n Subscription Id [%ld]", statsRsp->subscriptionId); DU_LOG("\n Number of Accepted Groups [%d]", statsRsp->numGrpAccepted); @@ -2261,6 +2313,20 @@ uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp) DU_LOG("\n Group Id [%d]", statsRsp->statsGrpRejectedList[idx]); } #endif + + /* TODO : + * For accepted groups: + * Mark scubscrbed-action's -> action = CONFIG_UNKNOWN + * Add action ID to accpeted-action-list in Subscription response + * + * For rejected groups: + * Remove entry from DU's RAN Function->subscription->actionList + * Add Rejected action Id to reject-action-list created by DU APP while + * processing of subscription request. + * + * Send subscription response with accepted and rejected action lists to + * RIC + */ DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp)); return ROK; diff --git a/src/ric_stub/ric_e2ap_msg_hdl.c b/src/ric_stub/ric_e2ap_msg_hdl.c index 18b987629..9b4ce4149 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.c +++ b/src/ric_stub/ric_e2ap_msg_hdl.c @@ -37,6 +37,12 @@ #include "RIC-EventTriggerStyle-Item.h" #include "RIC-ReportStyle-Item.h" #include "MeasurementInfo-Action-Item.h" +#include "MeasurementInfoItem.h" +#include "E2SM-KPM-ActionDefinition-Format1.h" +#include "E2SM-KPM-ActionDefinition.h" +#include "E2SM-KPM-EventTriggerDefinition-Format1.h" +#include "E2SM-KPM-EventTriggerDefinition.h" + /******************************************************************* * @@ -482,8 +488,7 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId) idx++; e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID; e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - e2SetupRsp->protocolIEs.list.array[idx]->value.present = \ - E2setupResponseIEs__value_PR_GlobalRIC_ID; + e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID; if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK) { @@ -510,8 +515,9 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId) e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck; e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; e2SetupRsp->protocolIEs.list.array[idx]->value.present = \ - E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List; - if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->value.choice.E2nodeComponentConfigAdditionAck_List, duDb)!=ROK) + E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List; + if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\ + value.choice.E2nodeComponentConfigAdditionAck_List, duDb) != ROK) { DU_LOG("\nERROR --> E2AP : Failed to build E2Node Component config addition ack list"); break; @@ -547,89 +553,467 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId) } FreeE2SetupRsp(e2apMsg); - BuildAndSendRicSubscriptionReq(duDb->duId); + BuildAndSendRicSubscriptionReq(duDb); return ROK; } +/******************************************************************* + * + * @brief Free RIC Subscription Details + * + * @details + * + * Function : FreeRicSubsDetails + * + * Functionality: Free the RIC Subscription Details + * + * @params[in] RICsubscriptionDetails_t *subsDetails + * @return void + * + * ****************************************************************/ +void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails) +{ + uint8_t elementIdx = 0; + RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP; + + RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size); + + 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) + { + RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \ + actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size); + RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t)); + } + RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t)) + } + } + RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size); + } +} + +/******************************************************************* + * + * @brief Free RIC Subscription Request + * + * @details + * + * Function : FreeRicSubscriptionReq + * + * Functionality : Free RIC Subscription Request + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg) +{ + uint8_t idx = 0; + RICsubscriptionRequest_t *ricSubscriptionReq; + + if(e2apRicMsg) + { + if(e2apRicMsg->choice.initiatingMessage) + { + ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; + 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: + { + FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails)); + break; + } + } + RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t)); + } + RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size); + } + RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t)); + } +} + /******************************************************************* * * @brief Builds Ric Request Id * * @details * - * Function : BuildRicRequestId + * Function : BuildNewRicRequestId * - * Functionality: Building the Ric Request Id + * Functionality: Assign new Ric Request ID * - * @params[in] RICrequestID_t *ricReqId + * @params[in] RIC request ID to be sent + * RIC request ID stored in DB * @return ROK - success * RFAILED - failure * * ****************************************************************/ -uint8_t BuildRicRequestId(RICrequestID_t *ricReqId) +uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb) { + static uint16_t requestorId = 0; + static uint16_t instanceId = 0; if(ricReqId != NULLP) { - ricReqId->ricRequestorID = 1; - ricReqId->ricInstanceID = 1; + ricReqId->ricRequestorID = ++requestorId; + ricReqId->ricInstanceID = ++instanceId; + + reqIdDb->requestorId = ricReqId->ricRequestorID; + reqIdDb->instanceId = ricReqId->ricInstanceID; } return ROK; } /******************************************************************* * - * @brief Fills Ric Action To be Setup Item + * @brief Free RIC Action Definition * * @details * - * Function : fillSetupItems + * Function : FreeRicActionDefinition * - * Functionality: Filling ricAction Id, RicActionType + * Functionality: Free RIC Action Definition * - * @params[in] RICaction_ToBeSetup_Item_t *setupItems - * @return pointer of type RICaction_ToBeSetup_Item_t + * @params[in] E2SM-KPM Action definition + * @return void * * ****************************************************************/ +void FreeRicActionDefinition(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: + case MeasurementType_PR_measID: + break; + case MeasurementType_PR_measName: + { + RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size) + break; + } + } + RIC_FREE(measItem, sizeof(MeasurementInfoItem_t)); + } + } + RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size); + } + RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t)); + } + 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: + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING: + break; + } +} -RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems) +/******************************************************************* + * + * @brief Fill RIC Action Definition + * + * @details + * + * Function : fillRicActionDef + * + * Functionality: Fill RIC Action Definition + * + * @params[in] RIC Action definition + * @return ROK + * RFAILED + * + * ****************************************************************/ +uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef) { - if(setupItems != NULLP) + uint8_t ret = RFAILED; + asn_enc_rval_t encRetVal; + uint8_t elementCnt = 0, elementIdx = 0; + char *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"}; + E2SM_KPM_ActionDefinition_t actionDef; + E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP; + MeasurementInfoItem_t *measItem = NULLP; + + while(true) { - setupItems->ricActionID = 0; - setupItems->ricActionType = RICactionType_report; + /* Fill E2SM-KPM Action Definition Format 1 */ + + /* RIC Stype Type */ + actionDef.ric_Style_Type = RIC_STYLE_TYPE; + + /* RIC Action Definition Format 1 */ + actionDef.actionDefinition_formats.present = \ + E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1; + + RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \ + sizeof(E2SM_KPM_ActionDefinition_Format1_t)); + if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1; + + /* Measurement Info List */ + elementCnt = 2; + actionFormat1->measInfoList.list.count = elementCnt; + actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *); + RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size); + if(actionFormat1->measInfoList.list.array == NULL) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + for(elementIdx = 0; elementIdx < elementCnt; elementIdx++) + { + RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t)); + if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + measItem = actionFormat1->measInfoList.list.array[elementIdx]; + measItem->measType.present = MeasurementType_PR_measName; + + measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]); + RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size); + if(measItem->measType.choice.measName.buf == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size); + } + if(elementIdx < elementCnt) + break; + + /* Granularity Period */ + actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD; /* In ms */ + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef); + + /* Encode E2SM-KPM RIC Action Definition */ + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + + /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */ + ricActionDef->size = encBufSize; + RIC_ALLOC(ricActionDef->buf, encBufSize); + if(ricActionDef->buf == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + memcpy(ricActionDef->buf, encBuf, encBufSize); + + ret = ROK; + break; } - return (setupItems); + FreeRicActionDefinition(actionDef); + return ret; } /******************************************************************* * - * @brief Fills RIC Subscription Details Item List + * @brief Fills RIC Action To Be Setup Item * * @details * - * Function : fillSubsDetails + * Function : fillActionToBeSetup * - * Functionality: Fill the RIC Subscription Details Items List + * Functionality: Fill the RIC Action To Be Setup Ite, + * RIC subscription DB * * @params[in] RICaction_ToBeSetup_ItemIEs_t *items * @return ROK - success * RFAILED - failure * * ****************************************************************/ +uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb) +{ + static uint8_t ricActionId = 0; + + if(actionItem == NULLP) + { + DU_LOG("\nERROR --> E2AP : Failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } + + while(true) + { + actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item; + actionItem->criticality = CriticalityE2_ignore; + actionItem->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item; + + /* RIC Action ID */ + actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ++ricActionId; + ricSubsDb->actionSequence[ricSubsDb->numOfActions].id = \ + actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; + + /* RIC Action Type */ + actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report; + + /* RIC Action Definition */ + RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t)); + if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + ricSubsDb->numOfActions++; + return ROK; + } + + memset(&ricSubsDb->actionSequence[ricSubsDb->numOfActions], 0, sizeof(ActionInfo)); + return RFAILED; +} + +/******************************************************************* + * + * @brief Free Event Trigger Definition + * + * @details + * + * Function : FreeEventTriggerDef + * + * Functionality: Free Event Trigger Definition + * + * @params[in] E2SM-KPM Event Trigger Definition + * @return void + * + * ****************************************************************/ +void FreeEventTriggerDef(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: + RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \ + sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t)); + break; + } + } +} -uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items) +/******************************************************************* + * + * @brief Fill Event Trigger Definition + * + * @details + * + * Function : fillEventTriggerDef + * + * Functionality: Fill Event Trigger Definition + * + * @params[in] RIC Event Trigger Definition + * @return ROK + * RFAILED + * + * ****************************************************************/ +uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef) { - if(items != NULLP) + uint8_t ret = RFAILED; + asn_enc_rval_t encRetVal; + E2SM_KPM_EventTriggerDefinition_t eventTiggerDef; + + while(true) { - items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item; - items->criticality = CriticalityE2_ignore; - items->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item; - fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item)); + /* Fill E2SM-KPM Event Trigger Definition Format 1 */ + eventTiggerDef.eventDefinition_formats.present = \ + E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1; + + RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \ + sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t)); + if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */ + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef); + + /* Encode E2SM-KPM Event Trigger Definition */ + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + + /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */ + ricEventTriggerDef->size = encBufSize; + RIC_ALLOC(ricEventTriggerDef->buf, encBufSize); + if(ricEventTriggerDef->buf == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + memcpy(ricEventTriggerDef->buf, encBuf, encBufSize); + + ret = ROK; + break; } - return ROK; + + FreeEventTriggerDef(&eventTiggerDef); + return ret; } /******************************************************************* @@ -642,41 +1026,67 @@ uint8_t fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items) * * Functionality: Builds the RIC Subscription Details * - * @params[in] RICsubscriptionDetails_t *subsDetails + * @params[in] RIC Subscription details to be filled + * RIC subscriotion DB * @return ROK - success * RFAILED - failure * * ****************************************************************/ -uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails) +uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsDb) { + uint8_t elementCnt = 0; + uint8_t elementIdx = 0; - uint8_t elementCnt; + if(subsDetails == NULLP) + { + DU_LOG("\nERROR --> E2AP : Failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } - if(subsDetails != NULLP) + while(true) { - /* Octet string to be build here */ - /* Sending PLMN as Octect string */ - uint8_t byteSize = 3; - subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(uint8_t); - RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size); - buildPlmnId(ricCb.ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf); + /* RIC Event Trigger Definition */ + if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + /* RIC Actions To Be Setup List */ elementCnt = 1; subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt; - subsDetails->ricAction_ToBeSetup_List.list.size = \ - elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t); - RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \ - subsDetails->ricAction_ToBeSetup_List.list.size); + subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *); + RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size); if(subsDetails->ricAction_ToBeSetup_List.list.array == NULLP) { DU_LOG("\nERROR --> E2AP : Memory allocation for RICactionToBeSetup Items failed"); - return RFAILED; + break; } - RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\ - sizeof(RICaction_ToBeSetup_ItemIEs_t)); - fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]); + + for(elementIdx = 0; elementIdx < elementCnt; elementIdx++) + { + RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t)); + if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + if(elementIdx < elementCnt) + break; + + elementIdx = 0; + if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \ + ricSubsDb) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + return ROK; } - return ROK; + return RFAILED; } /******************************************************************* @@ -693,137 +1103,137 @@ uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails) * RFAILED - failure * ******************************************************************/ - -uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId) +uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb) { - + uint8_t ret = RFAILED; E2AP_PDU_t *e2apRicMsg = NULL; RICsubscriptionRequest_t *ricSubscriptionReq; uint8_t elementCnt; uint8_t idx; uint8_t ieId; - uint8_t ret; asn_enc_rval_t encRetVal; /* Encoder return value */ + RanFunction *ranFuncDb = &duDb->ranFunction[0]; DU_LOG("\nINFO --> E2AP : Building RIC Subscription Request\n"); - RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); - if(e2apRicMsg == NULLP) + while(true) { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - return RFAILED; - } + RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); + if(e2apRicMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } - e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage; - RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); - if(e2apRicMsg->choice.initiatingMessage == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t)); - return RFAILED; - } - e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription; - e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest; - - RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t)); - ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; - - elementCnt = 3; - ricSubscriptionReq->protocolIEs.list.count = elementCnt; - ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t); - - /* Initialize the subscription members */ - RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \ - ricSubscriptionReq->protocolIEs.list.size); - if(ricSubscriptionReq->protocolIEs.list.array == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for RICSubscriptionRequestIEs failed"); - RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); - RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t)); - return RFAILED; - } - - for(idx=0; idxprotocolIEs.list.array[idx],\ - sizeof(RICsubscriptionRequest_IEs_t)); - if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP) + e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage; + RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apRicMsg->choice.initiatingMessage == NULLP) { - for(ieId=0; ieIdprotocolIEs.list.array[ieId],\ - sizeof(RICsubscriptionRequest_IEs_t)); - } - RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\ - ricSubscriptionReq->protocolIEs.list.size); - RIC_FREE(e2apRicMsg->choice.initiatingMessage, \ - sizeof(InitiatingMessageE2_t)); - RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t)); - return RFAILED; + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; } - } + e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription; + e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest; - /* Filling RIC Request Id */ - idx = 0; - ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID; - ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\ - RICsubscriptionRequest_IEs__value_PR_RICrequestID; - - BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID); + ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; + elementCnt = 3; + ricSubscriptionReq->protocolIEs.list.count = elementCnt; + ricSubscriptionReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionRequest_IEs_t); - /* Filling RAN Function Id */ - idx++; - ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID; - ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\ - RICsubscriptionRequest_IEs__value_PR_RANfunctionID; - ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1; + /* Initialize the subscription members */ + RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size); + if(ricSubscriptionReq->protocolIEs.list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + + for(idx=0; idxprotocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t)); + if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + if(idx < elementCnt) + break; + /* Filling RIC Request Id */ + idx = 0; + ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\ + RICsubscriptionRequest_IEs__value_PR_RICrequestID; + if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \ + &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription].requestId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed at [%d] : Line [%d]", __func__, __LINE__); + break; + } - /* Filling RIC Subscription Details */ - idx++; - ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails; - ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\ - RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails; - BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails)); + /* Filling RAN Function Id */ + idx++; + ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\ + RICsubscriptionRequest_IEs__value_PR_RANfunctionID; + ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id; + /* Filling RIC Subscription Details */ + idx++; + ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails; + ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\ + RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails; + if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\ + &ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription]) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed at [%d] : Line [%d]", __func__, __LINE__); + break; + } - /* Prints the Msg formed */ - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg); + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg); - memset(encBuf, 0, ENC_BUF_MAX_LEN); - encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\ - encBuf); - if(encRetVal.encoded == ENCODE_FAIL) - { - DU_LOG("\nERROR --> E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\ - encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); - return RFAILED; - } - else - { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RicSubscriptionRequest\n"); - for(int i=0; i< encBufSize; i++) + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("%x",encBuf[i]); - } - } + DU_LOG("\nERROR --> E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RicSubscriptionRequest\n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } + } + /* Sending msg */ + if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Sending RIC subscription Request failed"); + break; + } - /* Sending msg */ - if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK) - { - DU_LOG("\nERROR --> E2AP : Sending RIC subscription Request failed"); - return RFAILED; + ranFuncDb->numOfSubscription++; + ret = ROK; + break; } - return ROK; + if(ret == RFAILED) + memset(&ranFuncDb->subscriptionList[ranFuncDb->numOfSubscription], 0, sizeof(RicSubscription)); + FreeRicSubscriptionReq(e2apRicMsg); + return ret; } /******************************************************************* @@ -1075,7 +1485,6 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t *e2SetupReq) } case ProtocolIE_IDE2_id_RANfunctionsAdded: { - ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; if(ranFunctionsList->list.array) @@ -1084,8 +1493,8 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t *e2SetupReq) { ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item; - duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; - duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; + duDb->ranFunction[duDb->numOfRanFunction].id = ranFunItem->ranFunctionID; + duDb->ranFunction[duDb->numOfRanFunction].revisionCounter = ranFunItem->ranFunctionRevision; duDb->numOfRanFunction++; } } @@ -1100,12 +1509,15 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t *e2SetupReq) { if(e2NodeAddList->list.array[e2NodeAddListIdx]) { - e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx]; - if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.\ - e2nodeComponentInterfaceTypeF1) + e2NodeAddItem = \ + (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx]; + if(e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\ + choice.e2nodeComponentInterfaceTypeF1) { duDb->e2NodeComponent.interfaceType = F1; - duDb->e2NodeComponent.componentId = e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; + duDb->e2NodeComponent.componentId = \ + e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID.\ + choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]; } } } diff --git a/src/ric_stub/ric_e2ap_msg_hdl.h b/src/ric_stub/ric_e2ap_msg_hdl.h index aba63d22e..e370ed6c0 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.h +++ b/src/ric_stub/ric_e2ap_msg_hdl.h @@ -22,14 +22,16 @@ #define TRANS_ID 1 #define RRC_SIZE 1 #define ENC_BUF_MAX_LEN 100 -#define SUL_BAND_COUNT 0 +#define SUL_BAND_COUNT 0 #define UL_SRBID 1 #define DL_SRBID 0 #define DU_ID 1 -#define RIC_ID 1 +#define RIC_ID 1 #define CRNTI 17017 #define CELL_INDEX 0 +#define RIC_STYLE_TYPE 1 +#define RIC_ACTION_GRANULARITY_PERIOD 100 /* allocate and zero out a static buffer */ #define RIC_ALLOC(_datPtr, _size) \ { \ @@ -53,7 +55,7 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf); uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId); -uint8_t BuildAndSendRicSubscriptionReq(uint32_t duId); +uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb); uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId); uint8_t BuildAndSendRicServiceQuery(DuDb *duDb); /********************************************************************** diff --git a/src/ric_stub/ric_stub.h b/src/ric_stub/ric_stub.h index 045282087..5213a7976 100644 --- a/src/ric_stub/ric_stub.h +++ b/src/ric_stub/ric_stub.h @@ -49,6 +49,10 @@ #define MAX_RAN_FUNCTION 256 /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.1.2.2 : maxofRANfunctionID */ #define MAX_NUM_TRANSACTION 256 /* As per, O-RAN WG3 E2AP v3.0, section 9.2.33 */ +#define MAX_RIC_ACTION 16 /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.1.1.1 : maxofRICActionID */ +#define MAX_RIC_REQUEST 5 /* As per O-RAN.WG3.E2AP-R003-v03.00 : Section 9.2.7, max request is 65535. \ + * But for our internal testing purpose, keeping it to 5 for now */ + /* allocate and zero out a static buffer */ #define RIC_ALLOC(_datPtr, _size) \ { \ @@ -90,11 +94,30 @@ typedef enum X2 }InterfaceType; +typedef struct +{ + uint16_t requestorId; + uint16_t instanceId; +}RicRequestId; + +typedef struct +{ + uint8_t id; +}ActionInfo; + +typedef struct ricSubscription +{ + RicRequestId requestId; + uint8_t numOfActions; + ActionInfo actionSequence[MAX_RIC_ACTION]; +}RicSubscription; typedef struct { uint16_t id; uint16_t revisionCounter; + uint8_t numOfSubscription; + RicSubscription subscriptionList[MAX_RIC_REQUEST]; }RanFunction; typedef struct