X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_msg_hdl.c;h=0795850456166ab379c68619e75e0bd8eccd11c2;hb=refs%2Fchanges%2F07%2F11807%2F4;hp=ca148c86ea383f90f92d685633e41891e98ed739;hpb=fa6899dae4aee415bbcfd00760b6e2b312ddceec;p=o-du%2Fl2.git diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index ca148c86e..079585045 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -19,6 +19,7 @@ /* This file contains message handling functionality for DU APP */ #include "common_def.h" #include "lrg.h" +#include "du_tmr.h" #include "legtp.h" #include "lkw.h" #include "kwu.h" @@ -27,6 +28,8 @@ #include "kwu.x" #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" +#include "du_e2ap_mgr.h" +#include "du_e2ap_msg_hdl.h" #include "du_cfg.h" #include "du_app_rlc_inf.h" #include "du_mgr.h" @@ -95,10 +98,18 @@ DuMacSliceCfgReq packMacSliceCfgReqOpts[] = DuMacSliceRecfgReq packMacSliceRecfgReqOpts[] = { - packDuMacSliceRecfgReq, /* Loose coupling */ - MacProcSliceRecfgReq, /* TIght coupling */ - packDuMacSliceRecfgReq /* Light weight-loose coupling */ + packDuMacSliceRecfgReq, /* Loose coupling */ + MacProcSliceRecfgReq, /* TIght coupling */ + packDuMacSliceRecfgReq /* Light weight-loose coupling */ }; + +DuMacStatsReqFunc packMacStatsReqOpts[]= +{ + packDuMacStatsReq, /* Loose Coupling */ + MacProcStatsReq, /* Tight Coupling */ + packDuMacStatsReq /* Light weight-loose coupling */ +}; + /************************************************************************** * @brief Function to fill configs required by RLC * @@ -724,7 +735,7 @@ uint8_t duBuildMacGenCfg() /*----------- Fill General Configuration Parameters ---------*/ genCfg->mem.region = MAC_MEM_REGION; genCfg->mem.pool = MAC_POOL; - genCfg->tmrRes = 10; + genCfg->tmrRes = 1; genCfg->numRguSaps = 2; genCfg->lmPst.dstProcId = DU_PROC; @@ -1297,7 +1308,7 @@ uint8_t duSendSchCfg() /* Filling of Gen config */ cfg->genCfg.mem.region = MAC_MEM_REGION; cfg->genCfg.mem.pool = MAC_POOL; - cfg->genCfg.tmrRes = 10; + cfg->genCfg.tmrRes = 1; #ifdef LTE_ADV cfg->genCfg.forceCntrlSrbBoOnPCel = FALSE; @@ -1861,40 +1872,6 @@ uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData) return ROK; } -/******************************************************************* - * - * @brief free the slice cfg rsp - * - * @details - * - * Function : duFreeSliceCfgRsp - * - * Functionality: free the slice cfg rsp - * - * @params[in] Post structure, MacSliceCfgRsp *cfgRsp - * - * @return ROK - success - * RFAILED - failure - * - **********************************************************************/ -void duFreeSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp) -{ - uint8_t cfgIdx; - - if(cfgRsp) - { - if(cfgRsp->numSliceCfgRsp) - { - for(cfgIdx = 0; cfgIdxnumSliceCfgRsp; cfgIdx++) - { - DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp->listOfSliceCfgRsp[cfgIdx], sizeof(MacSliceRsp)); - } - DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp->listOfSliceCfgRsp, cfgRsp->numSliceCfgRsp * sizeof(MacSliceRsp*)); - } - DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp, sizeof(MacSliceCfgRsp)); - } -} - /******************************************************************* * * @brief process the slice cfg rsp received from MAC @@ -1913,22 +1890,18 @@ void duFreeSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp) **********************************************************************/ uint8_t DuProcMacSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp) { - uint8_t cfgIdx = 0; - if(cfgRsp) { - if(cfgRsp->listOfSliceCfgRsp) - { - for(cfgIdx = 0; cfgIdxnumSliceCfgRsp; cfgIdx++) - { - if(cfgRsp->listOfSliceCfgRsp[cfgIdx]->rsp == MAC_DU_APP_RSP_OK) - { - duCb.sliceState = SLICE_CONFIGURED; - } - } - DU_LOG("\nINFO --> DU_APP : Slice Configuration is done successfully "); - } - duFreeSliceCfgRsp(pst, cfgRsp); + if(cfgRsp->rsp == MAC_DU_APP_RSP_OK) + { + duCb.sliceState = SLICE_CONFIGURED; + DU_LOG("\nINFO --> DU_APP : Slice configured successfully "); + } + else + { + DU_LOG("\nERROR --> DU_APP : Slice not available"); + } + DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp, sizeof(MacSliceCfgRsp)); } return ROK; } @@ -2038,28 +2011,20 @@ uint8_t BuildAndSendSliceRecfgReq() * RFAILED - failure * **********************************************************************/ -uint8_t DuProcMacSliceRecfgRsp(Pst *pst, MacSliceRecfgRsp *reCfgRsp) +uint8_t DuProcMacSliceRecfgRsp(Pst *pst, MacSliceRecfgRsp *recfgRsp) { - uint8_t cfgIdx = 0; - - if(reCfgRsp) + if(recfgRsp) { - if(reCfgRsp->listOfSliceCfgRsp) + if(recfgRsp->rsp == MAC_DU_APP_RSP_OK) { - for(cfgIdx = 0; cfgIdx < reCfgRsp->numSliceCfgRsp; cfgIdx++) - { - if(reCfgRsp->listOfSliceCfgRsp[cfgIdx]->rsp == MAC_DU_APP_RSP_OK) - { - duCb.sliceState = SLICE_RECONFIGURED; - } - else - { - DU_LOG("\nERROR --> DU_APP : Slice not available"); - } - } - DU_LOG("\nINFO --> DU_APP : Slice ReCOnfiguration response received"); + duCb.sliceState = SLICE_RECONFIGURED; + DU_LOG("\nINFO --> DU_APP : Slice Reconfigured successfully "); + } + else + { + DU_LOG("\nERROR --> DU_APP : Slice not available"); } - duFreeSliceCfgRsp(pst, reCfgRsp); + DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, recfgRsp, sizeof(MacSliceCfgRsp)); } return ROK; } @@ -2112,6 +2077,456 @@ uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats) return ROK; } + +/******************************************************************* + * + * @brief Send Statistics request to MAC + * + * @details + * + * Function : BuildAndSendStatsReqToMac() + * + * Functionality: Send Statistics Request To Mac + * + * @params[in] + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +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; + + /* 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; + } + + macStatsReq->subscriptionId = subscriptionId; + for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++) + { + 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); + + if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == ROK) + return ROK; + + DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Request to MAC"); + } + + 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; +} + +/******************************************************************* + * + * @brief Fetch statistics details from Action Definition Format 1 + * + * @details + * + * Function : FetchStatsFromActionDefFormat1() + * + * Functionality: Fetch statistics details from Action + * Definition Format 1 received in an E2 message from + * RIC. + * + * @params[in] ActionDefFormat1 + * + * @return Statistics + * + * ****************************************************************/ +Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1) +{ + Statistics stats; + + /* TODO : When E2AP subscription procedure is implemented: + * Measurement info list is traveresed + * Based on KPI type, stats.macStatsReq or stats.rlcstatsReq is filled */ + + /* Hardcoding values for now for testing purpose + * Will be removed in next gerrit */ + stats.macStatsReq.subscriptionId = 1; + stats.macStatsReq.numStatsGroup = 1; + stats.macStatsReq.statsGrpList[0].groupId = 1; + stats.macStatsReq.statsGrpList[0].periodicity = 100; + stats.macStatsReq.statsGrpList[0].numStats = 2; + stats.macStatsReq.statsGrpList[0].statsList[0] = MAC_DL_TOTAL_PRB_USAGE; + stats.macStatsReq.statsGrpList[0].statsList[1] = MAC_UL_TOTAL_PRB_USAGE; + + return stats; +} + +/******************************************************************* + * + * @brief Send Statistics request to DU layers + * + * @details + * + * Function : BuildAndSendStatsReq() + * + * Functionality: Check if there is an update in statistics + * reporting configuration. If so, send the update to + * respective layer. + * + * @params[in] Subscription Info + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo) +{ + 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; + } + +/* TODO : When KPI collection from RLC will be supported, this function will be + * called to configure KPIs to be colled */ +#if 0 + if(BuildAndSendStatsReqToRlc() != ROK) + { + DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToRlc()"); + return RFAILED; + } +#endif + + return ROK; +} + +/******************************************************************* + * + * @brief Converts DU specific failure cause to E2 interface + * failure cause + * + * @details + * + * Function : convertDuCauseToE2Cause + * + * Functionality: Converts DU specific failure cause to E2 + * interface failure cause + * + * @params[in] DU specific failure cause + * E2 specific failure cause + * + * @return void + * + * ****************************************************************/ +void convertDuCauseToE2Cause(CauseOfResult l2Cause, E2FailureCause *failureCause) +{ + switch(l2Cause) + { + case PARAM_INVALID: + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + break; + } + case RESOURCE_UNAVAILABLE: + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_FUNCTION_RESOURCE_LIMIT; + break; + } + default: + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_RIC_REQUEST_CAUSE_UNSPECIFIED; + break; + } + } +} + +/******************************************************************* + * + * @brief Rejects all actions received in a subscription request + * + * @details + * + * Function : duRejectAllStatsGroup + * + * Functionality: Rejects all actions received in a subscription + * request by : + * a. Removing the subscription entry from RAN function + * b. Sending RIC Subscription Failure to RIC with appropriate + * cause of failure + * + * @params[in] RAN Function DB + * Subscription entry in RAN Function subscription list + * Statistics Response from MAC + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t duRejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp) +{ + uint8_t ret = ROK; + RicRequestId requestId; + E2FailureCause failureCause; + + /* 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)); + + convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause); + + /* Send RIC subscription failure to RIC */ + ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause); + return ret; +} + +/******************************************************************* + * + * @brief Process statistics response from MAC + * + * @details + * + * Function : DuProcMacStatsRsp + * + * Functionality: Processes statistics configuration response + * from MAC. If configuration is succsessful, DUAPP starts + * reporting period timer for this subscription request + * from RIC + * + * @params[in] + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp) +{ + uint16_t ranFuncId = 0; + RicRequestId ricReqId; + RanFunction *ranFuncDb = NULLP; + CmLList *ricSubscriptionNode = NULLP; + RicSubscription *ricSubscriptionInfo = NULLP; + + 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); + for(idx=0; idxnumGrpAccepted; idx++) + { + DU_LOG("\n Group Id [%d]", statsRsp->statsGrpAcceptedList[idx]); + } + + DU_LOG("\n Number of Rejected Groups [%d]", statsRsp->numGrpRejected); + for(idx=0; idxnumGrpRejected; idx++) + { + DU_LOG("\n Group Id [%d]", statsRsp->statsGrpRejectedList[idx]); + } +#endif + + /* Extract following from 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 + */ + ricReqId.instanceId = statsRsp->subscriptionId & 0xFFFF; + ricReqId.requestorId = (statsRsp->subscriptionId >> 16) & 0xFFFF; + ranFuncId = (statsRsp->subscriptionId >> 32) & 0xFFFF; + + /* Fetch RAN Function DB */ + if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId) + { + ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1]; + } + else + { + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Invalid RAN Function ID[%d] with Subscription ID [%ld]", \ + ranFuncId, statsRsp->subscriptionId); + DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp)); + return RFAILED; + } + + /* Fetch subscription detail in RAN Function DB */ + CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, ricSubscriptionNode); + while(ricSubscriptionNode) + { + ricSubscriptionInfo = (RicSubscription *)ricSubscriptionNode->node; + if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) && + (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId)) + { + break; + } + ricSubscriptionNode = ricSubscriptionNode->next; + } + + if(ricSubscriptionNode == NULLP) + { + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Subscription not found for Requestor ID [%d] Instance ID [%d]",\ + ricReqId.requestorId, ricReqId.instanceId); + DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp)); + return RFAILED; + } + + /* If no action is accepted + * a. Remove subcription entry from RAN Function + * b. Send RIC subscription failure */ + if(statsRsp->numGrpAccepted == 0) + { + duRejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp); + } + + /* TODO : + * If even 1 action is accepted : + * + * 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; + } + + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Received NULL Pointer"); + return RFAILED; +} + +/******************************************************************* + * + * @brief Process statistics indication from MAC + * + * @details + * + * Function : DuProcMacStatsInd + * + * Functionality: Processes statistics indication from MAC. + * + * @params[in] + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t DuProcMacStatsInd(Pst *pst, MacStatsInd *statsInd) +{ + if(statsInd) + { +#ifdef DEBUG_PRINT + DU_LOG("\nDEBUG --> DU_APP : DuProcMacStatsInd: Received Statistics Indication"); + DU_LOG("\n Subscription Id [%ld]", statsInd->subscriptionId); + DU_LOG("\n Group Id [%d]", statsInd->groupId); + for(int idx = 0; idx < statsInd->numStats; idx++) + { + DU_LOG("\n Meas type [%d] Meas Value [%lf]", statsInd->measuredStatsList[idx].type,\ + statsInd->measuredStatsList[idx].value); + } +#endif + + /* TODO : When stats indication is received + * DU APP searches for the message type in E2AP RIC subscription database + * and stores in the value in the list of subscribed measurements + * + * This will be implemented in next gerrit. + */ + + DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsInd, sizeof(MacStatsInd)); + return ROK; + } + + DU_LOG("\nINFO --> DU_APP : DuProcMacStatsInd: Received NULL Pointer"); + return RFAILED; +} + /********************************************************************** End of file **********************************************************************/