X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_e2ap_mgr.c;h=f813ef098d2ad24a3c8081b905236170412b4fa7;hb=7a8431f7dc43c83d2dd83a242924c1ee044e711a;hp=58f5845e7780ef5ef3471829f45dfa70b5089107;hpb=3740878d9d4bf9ab3d2639f0495b77f3f45bd3cb;p=o-du%2Fl2.git diff --git a/src/du_app/du_e2ap_mgr.c b/src/du_app/du_e2ap_mgr.c index 58f5845e7..f813ef098 100644 --- a/src/du_app/du_e2ap_mgr.c +++ b/src/du_app/du_e2ap_mgr.c @@ -16,6 +16,7 @@ ################################################################################ *******************************************************************************/ #include "common_def.h" +#include #include "du_tmr.h" #include "lrg.h" #include "lkw.x" @@ -121,6 +122,72 @@ void encodeSubscriptionId(uint64_t *subscriptionId, uint16_t ranFuncId, RicReque *subscriptionId |= ((uint64_t)ranFuncId << 32); } +/******************************************************************* + * + * @brief Stores the current time at the start of reporting period + * + * @details + * + * Function : storeReportStartTime + * + * Functionality: Stores the current time at the start of + * reporting period + * + * @params[in] Start Timer to be stored + * @return Void + * + * ****************************************************************/ +void storeReportStartTime(ReportStartTime *startTime) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + startTime->timeInSec = tv.tv_sec; + startTime->timeInMilliSec = (tv.tv_usec/1000); +} + + +/******************************************************************* + * + * @brief Fetch Measurement Info using measurement type name + * + * @details + * + * Function : fetchMeasInfoFromMeasTypeName + * + * Functionality: Fetch Measurement Info using measurement type name + * + * @params[in] Measurement type name to search + * Measurement Info list to search from + * Measurement Info node found from list + * @return Measurement Info DB + * + * ****************************************************************/ +MeasurementInfo *fetchMeasInfoFromMeasTypeName(char *e2MeasTypeName, CmLListCp *measInfoList, CmLList **measInfoNode) +{ + MeasurementInfo *measInfo = NULLP; + + /* Fetch subscription detail in RAN Function DB */ + CM_LLIST_FIRST_NODE(measInfoList, *measInfoNode); + while(*measInfoNode) + { + measInfo = (MeasurementInfo *)((*measInfoNode)->node); + if(measInfo && !strcmp(e2MeasTypeName, measInfo->measurementTypeName)) + { + break; + } + *measInfoNode = (*measInfoNode)->next; + measInfo = NULLP; + } + + if(!measInfo) + { + DU_LOG("\nERROR --> E2AP : fetchMeasInfoFromMeasTypeName: Measurement [%s] not found", e2MeasTypeName); + } + + return measInfo; +} + /******************************************************************* * * @brief Fetch Action details @@ -141,13 +208,13 @@ void encodeSubscriptionId(uint64_t *subscriptionId, uint16_t ranFuncId, RicReque ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSubscriptionInfo) { ActionInfo *actionInfoDb = NULLP; - if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId) + if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId) { - actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId-1]; + actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId]; } else { - DU_LOG("\nERROR --> DU_APP : fetchActionInfoFromActionId: Action Id [%d] not found in \ + DU_LOG("\nERROR --> E2AP : fetchActionInfoFromActionId: Action Id [%d] not found in \ subscription info [Requestor id : %d] [Instance Id : %d]", actionId,\ ricSubscriptionInfo->requestId.requestorId, ricSubscriptionInfo->requestId.instanceId); @@ -193,7 +260,7 @@ RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *r if(!ricSubscriptionInfo) { - DU_LOG("\nERROR --> DU_APP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \ + DU_LOG("\nERROR --> E2AP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \ Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id); } @@ -227,7 +294,7 @@ RanFunction *fetchRanFuncFromRanFuncId(uint16_t ranFuncId) } else { - DU_LOG("\nERROR --> DU_APP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId); + DU_LOG("\nERROR --> E2AP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId); } return ranFuncDb; @@ -396,14 +463,13 @@ uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause) * Request * * @params[in] MAC Statistics Request to be filled - * RAN Function ID * RIC Subscription Info * * @return ROK - success * RFAILED - failure * * ****************************************************************/ -uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, uint16_t ranFuncId, RicSubscription* ricSubscriptionInfo) +uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, RicSubscription* ricSubscriptionInfo) { uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0; uint64_t subscriptionId = 0; @@ -411,15 +477,15 @@ uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, uint16_t ranFuncId, R ActionDefFormat1 *format1Action = NULLP; /* Generate subscription ID using RIC Request ID and RAN Function ID */ - encodeSubscriptionId(&subscriptionId, ranFuncId, ricSubscriptionInfo->requestId); + encodeSubscriptionId(&subscriptionId, ricSubscriptionInfo->ranFuncId, ricSubscriptionInfo->requestId); macStatsReq->subscriptionId = subscriptionId; - for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++) + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) { if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD) { actionDb = &ricSubscriptionInfo->actionSequence[actionIdx]; - macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id; + macStatsReq->statsGrpList[grpIdx].groupId = actionDb->actionId; switch(actionDb->definition.formatType) { case 1: @@ -449,7 +515,7 @@ uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, uint16_t ranFuncId, R } default: { - DU_LOG("\nERROR --> DU_APP : Invalid measurement name"); + DU_LOG("\nERROR --> E2AP : Invalid measurement name"); break; } } @@ -460,7 +526,7 @@ uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, uint16_t ranFuncId, R } default: { - DU_LOG("\nERROR --> DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported"); + DU_LOG("\nERROR --> E2AP : fillRicSubsInMacStatsReq: Only Action Definition Format 1 supported"); break; } } @@ -508,9 +574,8 @@ uint8_t rejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode /* Delete subcription from RAN Function */ memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId)); cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode); - DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription)); - DU_FREE(ricSubscriptionNode, sizeof(CmLList)); - + deleteRicSubscriptionNode(ricSubscriptionNode); + ricSubscriptionNode = NULLP; convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause); /* Send RIC subscription failure to RIC */ @@ -531,16 +596,17 @@ uint8_t rejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode * reporting period timer for this subscription request * from RIC * - * @params[in] + * @params[in] Statistics response received from MAC * * @return ROK - success * RFAILED - failure * * ****************************************************************/ -void e2ProcStatsRsp(MacStatsRsp *statsRsp) +uint8_t e2ProcStatsRsp(MacStatsRsp *statsRsp) { uint8_t idx = 0; uint8_t actionId = 0; + uint32_t reportingPeriod = 0; RanFunction *ranFuncDb = NULLP; CmLList *ricSubscriptionNode = NULLP; RicSubscription *ricSubscriptionInfo = NULLP; @@ -550,8 +616,8 @@ void e2ProcStatsRsp(MacStatsRsp *statsRsp) /* Fetch RAN Function and Subscription DB using subscription Id received in statistics response */ if(fetchSubsInfoFromSubsId(statsRsp->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK) { - DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Failed to fetch subscriprtion details"); - return; + DU_LOG("\nERROR --> E2AP : DuProcMacStatsRsp: Failed to fetch subscriprtion details"); + return RFAILED; } /* Fetch pre-stored statistics response info by DU APP */ @@ -574,6 +640,37 @@ void e2ProcStatsRsp(MacStatsRsp *statsRsp) } else { + /* Once RIC subscription is successful, mark the config action as unknown */ + ricSubscriptionInfo->action = CONFIG_UNKNOWN; + + /* Start RIC Subscription reporting timer */ + switch(ricSubscriptionInfo->eventTriggerDefinition.formatType) + { + case 1: + { + reportingPeriod = ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod; + + /* Save the start time of reporting period */ + storeReportStartTime(&ricSubscriptionInfo->eventTriggerDefinition.choice.format1.startTime); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid event trigger format of RIC subscription"); + return RFAILED; + } + } + if(duChkTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) != true) + { + duStartTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR, reportingPeriod); + } + else + { + DU_LOG("\nERROR --> E2AP : RIC Subscription reporting timer already running for RIC Subscription"); + return RFAILED; + } + + /* If even 1 action is accepted : * * For accepted groups: @@ -600,9 +697,9 @@ void e2ProcStatsRsp(MacStatsRsp *statsRsp) for(idx=0; idxnumGrpRejected; idx++) { actionId = statsRsp->statsGrpRejectedList[idx].groupId; - if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId) + if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId) { - memset(&ricSubscriptionInfo->actionSequence[actionId-1], 0, sizeof(ActionInfo)); + memset(&ricSubscriptionInfo->actionSequence[actionId], 0, sizeof(ActionInfo)); ricSubscriptionInfo->numOfActions--; pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].id = actionId; @@ -616,6 +713,7 @@ void e2ProcStatsRsp(MacStatsRsp *statsRsp) BuildAndSendRicSubscriptionRsp(pendingSubsRsp); } memset(pendingSubsRsp, 0, sizeof(PendingSubsRspInfo)); + return ROK; } /******************************************************************* @@ -631,14 +729,23 @@ void e2ProcStatsRsp(MacStatsRsp *statsRsp) * action * * @params[in] Statistics Indication message received from MAC - * @return void + * @return ROK-success + * RFAILED-failure * * ****************************************************************/ -void e2ProcStatsInd(MacStatsInd *statsInd) +uint8_t e2ProcStatsInd(MacStatsInd *statsInd) { + uint8_t statsIdx = 0; RanFunction *ranFuncDb = NULLP; CmLList *ricSubscriptionNode = NULLP; RicSubscription *ricSubscriptionInfo = NULLP; + ActionInfo *actionInfo = NULLP; + ActionDefFormat1 *actionFormat = NULLP; + char e2MeasTypeName[STRING_SIZE_150_BYTES] = ""; + MeasurementInfo *measInfo = NULLP; + CmLList *measInfoNode = NULLP; + double *measValue = NULLP; + CmLList *measValueNode = NULLP; /* TODO : When stats indication is received * DU APP searches for the message type in E2AP RIC subscription @@ -651,7 +758,128 @@ void e2ProcStatsInd(MacStatsInd *statsInd) * in statistics response */ if(fetchSubsInfoFromSubsId(statsInd->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK) { - DU_LOG("\nERROR --> DU_APP : extractStatsMeasurement: Failed to fetch subscriprtion details"); + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to fetch subscriprtion details"); + return RFAILED; + } + + /* Fetch RIC subscription's action DB */ + actionInfo = fetchActionInfoFromActionId(statsInd->groupId, ricSubscriptionInfo); + if(actionInfo == NULLP) + { + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to fetch action ID [%d]", statsInd->groupId); + return RFAILED; + } + + /* Check Action format */ + switch(actionInfo->definition.formatType) + { + case 1: + { + actionFormat = &actionInfo->definition.choice.format1; + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Action Format [%d] is not supported", \ + actionInfo->definition.formatType); + return RFAILED; + } + } + + /* Fetch each Measurement info from action info and store its reported value in DB */ + for(statsIdx = 0; statsIdx < statsInd->numStats; statsIdx++) + { + memset(e2MeasTypeName, 0, STRING_SIZE_150_BYTES); + measInfo = NULLP; + measInfoNode = NULLP; + + /* Convert Measurement type from MAC-supported format to E2-supported format */ + if(convertMacMeasTypeToE2MeasType(statsInd->measuredStatsList[statsIdx].type, e2MeasTypeName) != ROK) + { + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to convert measurement type from MAC-supported\ + MAC-supported format to E2-supported format"); + continue; + } + + /* Fetch Measurement Info using E2-supported measurement type name */ + measInfo = fetchMeasInfoFromMeasTypeName(e2MeasTypeName, &actionFormat->measurementInfoList, &measInfoNode); + if(measInfo == NULLP) + { + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Measurement Type Name [%s] not found", e2MeasTypeName); + continue; + } + + /* Store the measurement value in the measurement info DB fetched */ + DU_ALLOC(measValue, sizeof(double)); + if(!measValue) + { + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Memory allocation failed at line [%d]", __LINE__); + return RFAILED; + } + *measValue = statsInd->measuredStatsList[statsIdx].value; + + DU_ALLOC(measValueNode, sizeof(CmLList)); + if(!measValueNode) + { + DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Memory allocation failed at line [%d]", __LINE__); + DU_FREE(measValue, sizeof(double)); + return RFAILED; + } + measValueNode->node = (PTR) measValue; + cmLListAdd2Tail(&measInfo->measuredValue, measValueNode); + } + return ROK; +} + +/******************************************************************* + * + * @brief Handle RIC Subscription reporting timer expry + * + * @details + * + * Function : E2apHdlRicSubsReportTmrExp + * + * Functionality: On expiry of RIC subscription reporting + * timer expiry, RIC indication is sent for all actions + * in RIC subscription + * + * @params[in] RIC subscription DB + * @return void + * + * ****************************************************************/ +void E2apHdlRicSubsReportTmrExp(RicSubscription *ricSubscription) +{ + uint8_t actionIdx = 0; + uint32_t reportingPeriod = 0; + + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + { + if(ricSubscription->actionSequence[actionIdx].actionId >= 0) + { + BuildAndSendRicIndication(ricSubscription, &ricSubscription->actionSequence[actionIdx]); + } + } + + /* Start RIC Subscription reporting timer again */ + switch(ricSubscription->eventTriggerDefinition.formatType) + { + case 1: + { + reportingPeriod = ricSubscription->eventTriggerDefinition.choice.format1.reportingPeriod; + /* Save the start time of reporting period */ + storeReportStartTime(&ricSubscription->eventTriggerDefinition.choice.format1.startTime); + break; + } + default: + return; + } + if(duChkTmr((PTR)ricSubscription, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) != true) + { + duStartTmr((PTR)ricSubscription, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR, reportingPeriod); + } + else + { + DU_LOG("\nERROR --> E2AP : Failed in %s at line %d", __func__, __LINE__); return; } } @@ -788,6 +1016,227 @@ uint8_t addOrModifyE2NodeComponent(InterfaceType interfaceType, uint8_t action, return ROK; } +/****************************************************************** + * + * @brief Delete measured Value list + * + * @details + * + * Function : deleteMeasuredValueList + * + * Functionality: Delete measured Value list + * + * @params[in] List of measured Value + * + * @return void + * + * ****************************************************************/ +void deleteMeasuredValueList(CmLListCp *measuredValueList) +{ + CmLList *measValNode = NULLP; + + CM_LLIST_FIRST_NODE(measuredValueList, measValNode); + + while(measValNode) + { + cmLListDelFrm(measuredValueList, measValNode); + DU_FREE(measValNode->node, sizeof(double)); + DU_FREE(measValNode, sizeof(CmLList)); + CM_LLIST_FIRST_NODE(measuredValueList, measValNode); + } +} + +/****************************************************************** + * + * @brief Delete Measurement Info List + * + * @details + * + * Function : deleteMeasurementInfoList + * + * Functionality: Delete Measurement Info List + * + * @params[in] List of Measurement Info List + * + * @return void + * + * ****************************************************************/ +void deleteMeasurementInfoList(CmLListCp *measInfoList) +{ + CmLList *measInfoNode = NULLP; + MeasurementInfo *measInfo = NULLP; + + CM_LLIST_FIRST_NODE(measInfoList, measInfoNode); + while(measInfoNode) + { + measInfo = (MeasurementInfo *)measInfoNode->node; + cmLListDelFrm(measInfoList, measInfoNode); + deleteMeasuredValueList(&measInfo->measuredValue); + DU_FREE(measInfo, sizeof(MeasurementInfo)); + DU_FREE(measInfoNode, sizeof(CmLList)); + CM_LLIST_FIRST_NODE(measInfoList, measInfoNode); + } +} + +/****************************************************************** + * + * @brief Delete Ric subscription action + * + * @details + * + * Function : deleteActionSequence + * + * Functionality: Delete Ric subscription action + * + * @params[in] Action info + * + * @return void + * + * ****************************************************************/ +void deleteActionSequence(ActionInfo *action) +{ + ActionDefinition *definition=NULLP; + definition= &action->definition; + + switch(definition->formatType) + { + case 1: + { + deleteMeasurementInfoList(&definition->choice.format1.measurementInfoList); + break; + } + + case 2: + case 3: + case 4: + case 5: + default: + { + DU_LOG("\nERROR --> E2AP : Format %d does not supported", definition->formatType); + break; + } + } + memset(action, 0, sizeof(ActionInfo)); + action->actionId = -1; +} + +/****************************************************************** + * + * @brief Delete Ric subscription node + * + * @details + * + * Function : deleteRicSubscriptionNode + * + * Functionality: Delete Ric subscription node + * + * @params[in] Ric subscription info + * + * @return void + * + * ****************************************************************/ +void deleteRicSubscriptionNode(CmLList *subscriptionNode) +{ + uint8_t actionIdx=0; + RicSubscription *ricSubscriptionInfo = NULLP; + + ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node; + + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + { + if(ricSubscriptionInfo->actionSequence[actionIdx].actionId > -1) + { + deleteActionSequence(&ricSubscriptionInfo->actionSequence[actionIdx]); + } + } + + if(duChkTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) == TRUE) + { + duStopTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR); + } + + memset(ricSubscriptionInfo, 0, sizeof(RicSubscription)); + DU_FREE(subscriptionNode->node, sizeof(RicSubscription)); + DU_FREE(subscriptionNode, sizeof(CmLList)); +} + +/****************************************************************** + * + * @brief Delete ric subscription list from the database + * + * @details + * + * Function : deleteRicSubscriptionList + * + * Functionality: Delete ric subscription list + * + * @params[in] + * Subscription List to be deleted + + * @return void + * + * ****************************************************************/ +void deleteRicSubscriptionList(CmLListCp *subscriptionList) +{ + CmLList *subscriptionNode=NULLP; + + CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode); + while(subscriptionNode) + { + /* TODO - Remove subscription information from MAC and SCH as well */ + cmLListDelFrm(subscriptionList, subscriptionNode); + deleteRicSubscriptionNode(subscriptionNode); + CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode); + } +} + +/******************************************************************* + * + * @brief Find all RIC subscriptions to be deleted in all RAN + * Functions + * + * @details + * + * Function : fetchRicSubsToBeDeleted + * + * Functionality: Find all RIC subscriptions to be deleted in all + * RAN functions and store in a temporary list + * + * @parameter Temporary list to store subscriptions to be deleted + * @return void + * + ******************************************************************/ +void fetchRicSubsToBeDeleted(CmLListCp *ricSubsToBeDelList) +{ + uint16_t ranFuncIdx = 0; + CmLList *subsNode = NULLP; + CmLList *subsToDelNode = NULLP; + + for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++) + { + if(duCb.e2apDb.ranFunction[ranFuncIdx].id > 0) + { + CM_LLIST_FIRST_NODE(&duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList, subsNode); + while(subsNode) + { + if(((RicSubscription *)subsNode->node)->action == CONFIG_DEL) + { + DU_ALLOC(subsToDelNode, sizeof(CmLList)); + if(!subsToDelNode) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failure at %d", __func__, __LINE__); + return; + } + subsToDelNode->node = subsNode->node; + cmLListAdd2Tail(ricSubsToBeDelList, subsToDelNode); + } + subsToDelNode = NULLP; + subsNode = subsNode->next; + } + } + } +} + /********************************************************************** End of file **********************************************************************/