From: pborla Date: Sun, 26 Nov 2023 17:51:27 +0000 (+0530) Subject: [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-530] Implementation of Stats Modification... X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=ebe7300f91cb53117193fbec021b423013d1d6ef;p=o-du%2Fl2.git [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-530] Implementation of Stats Modification Req/Rsp API b/w DU Layers Change-Id: I3de463b0aba3480b8432b1b1e6f06bdf1f57830d Signed-off-by: pborla --- diff --git a/src/5gnrmac/mac.h b/src/5gnrmac/mac.h index 5a1db5a00..46b8a546c 100644 --- a/src/5gnrmac/mac.h +++ b/src/5gnrmac/mac.h @@ -303,6 +303,7 @@ uint8_t MacProcSchCellDeleteRsp(Pst *pst, SchCellDeleteRsp *schCellDeleteRsp); uint8_t MacProcSchStatsRsp(Pst *pst, SchStatsRsp *schStatsRsp); uint8_t MacProcSchStatsInd(Pst *pst, SchStatsInd *schStatsInd); uint8_t MacProcSchStatsDeleteRsp(Pst *pst, SchStatsDeleteRsp *schStatsDeleteRsp); +uint8_t MacProcSchStatsModificationRsp(Pst *pst, SchStatsModificationRsp *schStatsModificationRsp); #endif /********************************************************************** diff --git a/src/5gnrmac/mac_cfg_hdl.c b/src/5gnrmac/mac_cfg_hdl.c index c682a66a8..3957ac20a 100644 --- a/src/5gnrmac/mac_cfg_hdl.c +++ b/src/5gnrmac/mac_cfg_hdl.c @@ -77,6 +77,13 @@ MacDuStatsDeleteRspFunc macDuStatsDeleteRspOpts[] = packDuMacStatsDeleteRsp /* packing for light weight loosly coupled */ }; +MacDuStatsModificationRspFunc macDuStatsModificationRspOpts[] = +{ + packDuMacStatsModificationRsp, /* packing for loosely coupled */ + DuProcMacStatsModificationRsp, /* packing for tightly coupled */ + packDuMacStatsModificationRsp /* packing for light weight loosly coupled */ +}; + /** * @brief Layer Manager Configuration request handler for Scheduler * @@ -1524,6 +1531,301 @@ uint8_t MacProcStatsDeleteReq(Pst *pst, MacStatsDeleteReq *macStatsDeleteReq) return ret; } +/** + * @brief Fill and send statistics modification response to DU APP + * + * @details + * + * Function : MacSendStatsModificationRspToDuApp + * + * Fill and send statistics modification response to DU APP + * + * @param[in] Stats modification Response + * @return int + * -# ROK + **/ +uint8_t MacSendStatsModificationRspToDuApp(MacStatsModificationRsp *tmpMacStatsModRsp) +{ + Pst pst; + uint8_t ret = ROK; + MacStatsModificationRsp *macStatsModificationRsp = NULLP; + + DU_LOG("\nINFO --> MAC : MacSendStatsModificationRspToDuApp: Sending Statistics Modification Response to DU APP"); + + + MAC_ALLOC_SHRABL_BUF(macStatsModificationRsp, sizeof(MacStatsModificationRsp)); + if(macStatsModificationRsp == NULLP) + { + DU_LOG("\nERROR --> MAC : Failed to allocate memory in MacProcSchStatsModificationRsp"); + ret = RFAILED; + } + else + { + memcpy(macStatsModificationRsp, tmpMacStatsModRsp, sizeof(MacStatsModificationRsp)); + memset(tmpMacStatsModRsp, 0, sizeof(MacStatsModificationRsp)); + + memset(&pst, 0, sizeof(Pst)); + FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_STATISTICS_MODIFY_RSP); + if(((*macDuStatsModificationRspOpts[pst.selector])(&pst, macStatsModificationRsp))!= ROK) + { + DU_LOG("\nERROR --> MAC : Failed to send statistics modification response to DU APP"); + MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, macStatsModificationRsp, sizeof(MacStatsModificationRsp)); + ret = RFAILED; + } + } + + return ret; +} + +/** + * @brief Mac process the statistics modification rsp received from sch. + * + * @details + * + * Function : MacProcSchStatsModificationRsp + * + * This function process the statistics modification response received from sch + * [Step -1] Fetch pointer to statistics response from pending list saved at + * MAC during processing statistics request from DU APP + * [Step -2] Fill the list of accepted list + * [Step -3] Fill the list of rejected list + * [Step -4] Send statistics modification response to DU APP + * + * @param[in] Pst *pst + * @param[in] SchStatsModificationRsp *schStatsModificationRsp + * @return int + * -# ROK + **/ +uint8_t MacProcSchStatsModificationRsp(Pst *pst, SchStatsModificationRsp *schStatsModificationRsp) +{ + uint8_t ret = RFAILED; + uint8_t idx = 0, accptdIdx = 0, rjctdIdx = 0; + MacStatsModificationRsp *macStatsModificationRsp = NULLP; + + if(schStatsModificationRsp) + { + /* [Step -1] */ + for(idx = 0; idx < macCb.statistics.numPendingStatsRsp; idx++) + { + if(macCb.statistics.pendingStatsRsp[idx].subscriptionId == schStatsModificationRsp->subscriptionId) + { + macStatsModificationRsp = &macCb.statistics.pendingStatsRsp[idx]; + break; + } + } + + if(macStatsModificationRsp == NULLP) + { + MAC_FREE(schStatsModificationRsp, sizeof(SchStatsModificationRsp)); + return RFAILED; + } + + /* [Step -2] */ + for(accptdIdx = 0; accptdIdxnumGrpAccepted && macStatsModificationRsp->numGrpAcceptedstatsGrpAcceptedList[macStatsModificationRsp->numGrpAccepted++] = schStatsModificationRsp->statsGrpAcceptedList[accptdIdx]; + } + + /* [Step -3] */ + for(rjctdIdx = 0; rjctdIdx < schStatsModificationRsp->numGrpRejected && macStatsModificationRsp->numGrpRejectedstatsGrpRejectedList[macStatsModificationRsp->numGrpRejected].groupId = \ + schStatsModificationRsp->statsGrpRejectedList[rjctdIdx].groupId; + macStatsModificationRsp->statsGrpRejectedList[macStatsModificationRsp->numGrpRejected].cause = \ + schStatsModificationRsp->statsGrpRejectedList[rjctdIdx].cause; + macStatsModificationRsp->numGrpRejected++; + } + + /* [Step -4] */ + ret = MacSendStatsModificationRspToDuApp(macStatsModificationRsp); + } + MAC_FREE(schStatsModificationRsp, sizeof(SchStatsModificationRsp)); + return ret; +} + +/******************************************************************* + * + * @brief Rejects all statistics modification group requested by DU APP + * + * @details + * + * Function : MacRejectAllStatsModification + * + * Functionality: Add all statistics modification group received in statistics + * request from DU APP, to Reject-StatsModification-Group-List in statistics + * response to DU APP + * + * @params[in] Statistics request from DU APP + * Cause of rejection + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t MacRejectAllStatsModification(MacStatsModificationReq *macStatsModificationReq, CauseOfResult cause) +{ + uint8_t grpIdx = 0; + MacStatsModificationRsp macStatsModificationRsp; + + memset(&macStatsModificationRsp, 0, sizeof(MacStatsModificationRsp)); + + /* fill the subscriptionId and the rejected list in stats modification rsp */ + macStatsModificationRsp.subscriptionId = macStatsModificationReq->subscriptionId; + for(grpIdx = 0; grpIdx < macStatsModificationReq->numStatsGroup; grpIdx++) + { + macStatsModificationRsp.statsGrpRejectedList[grpIdx].groupId = macStatsModificationReq->statsGrpList[grpIdx].groupId; + macStatsModificationRsp.statsGrpRejectedList[grpIdx].cause = cause; + } + macStatsModificationRsp.numGrpRejected = macStatsModificationReq->numStatsGroup; + + return MacSendStatsModificationRspToDuApp(&macStatsModificationRsp); +} + +/** + * @brief Mac process the statistics Modification Req received from DUAPP + * + * @details + * + * Function : MacProcStatsModificationReq + * + * This function process the statistics Modification request from duapp: + * [Step 1] Basic validation. If fails, all stats group in stats request are + * rejected. + * [Step 2] If basic validations passed, traverse all stats group and + * validate each measurement types in each group. + * [Step 3] If any measurement type validation fails in a group, that group + * is not configured and it is added to stats-group-rejected-list in + * mac-stats-response message. + * [Step 4] Even if one group passes all validation, it is sent to SCH in + * statistics request. The mac-stats-response message is added to + * pending-response list. This will be sent to DU APP after stats response + * is received from SCH. + * [Step 5] If none of the groups passes all validation, mac-stats-response + * is sent to du app with all group as part of stats-group-rejected-list. + * + * @param[in] Pst *pst + * @param[in] StatsModificationReq *statsModificationReq + * @return int + * -# ROK + **/ +uint8_t MacProcStatsModificationReq(Pst *pst, MacStatsModificationReq *macStatsModificationReq) +{ + Pst schPst; + uint8_t ret = RFAILED; + bool measTypeInvalid = false; + uint8_t macStatsGrpIdx = 0, macStatsIdx = 0; + uint8_t schStatsGrpIdx = 0, schStatsIdx = 0; + MacStatsGrpInfo *macStatsGrp = NULLP; + SchStatsModificationReq *schStatsModificationReq = NULLP; + MacStatsModificationRsp *macStatsModificationRsp = NULLP; + + DU_LOG("\nINFO --> MAC : Received Statistics Modification Request from DU_APP"); + + if(macStatsModificationReq == NULLP) + { + DU_LOG("\nERROR --> MAC : MacProcStatsModificationReq(): Received Null pointer"); + return RFAILED; + } + + /* [Step -1] */ + if(macCb.statistics.numPendingStatsRsp >= MAX_PENDING_STATS_RSP) + { + DU_LOG("\nERROR --> MAC : MacProcStatsModificationReq: Maximum number of statistics response is pending. \ + Cannot process new request."); + MacRejectAllStatsModification(macStatsModificationReq, RESOURCE_UNAVAILABLE); + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsModificationReq, sizeof(MacStatsModificationReq)); + return RFAILED; + } + + MAC_ALLOC(schStatsModificationReq, sizeof(SchStatsModificationReq)); + if(schStatsModificationReq == NULLP) + { + DU_LOG("\nERROR --> MAC : MacProcStatsModificationReq: Failed to allocate memory"); + MacRejectAllStatsModification(macStatsModificationReq, RESOURCE_UNAVAILABLE); + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsModificationReq, sizeof(MacStatsModificationReq)); + return RFAILED; + } + + macStatsModificationRsp = &macCb.statistics.pendingStatsRsp[macCb.statistics.numPendingStatsRsp]; + memset(macStatsModificationRsp, 0, sizeof(MacStatsModificationRsp)); + + /* [Step 2] */ + schStatsModificationReq->subscriptionId = macStatsModificationReq->subscriptionId; + schStatsModificationReq->numStatsGroup = 0; + for(macStatsGrpIdx = 0; macStatsGrpIdx < macStatsModificationReq->numStatsGroup; macStatsGrpIdx++) + { + measTypeInvalid = false; + schStatsIdx = 0; + macStatsGrp = &macStatsModificationReq->statsGrpList[macStatsGrpIdx]; + + for(macStatsIdx=0; macStatsIdx < macStatsGrp->numStats; macStatsIdx++) + { + switch(macStatsGrp->statsList[macStatsIdx]) + { + case MAC_DL_TOTAL_PRB_USAGE: + { + schStatsModificationReq->statsGrpList[schStatsGrpIdx].statsList[schStatsIdx] = SCH_DL_TOTAL_PRB_USAGE; + break; + } + case MAC_UL_TOTAL_PRB_USAGE: + { + schStatsModificationReq->statsGrpList[schStatsGrpIdx].statsList[schStatsIdx] = SCH_UL_TOTAL_PRB_USAGE; + break; + } + default: + { + DU_LOG("\nERROR --> MAC : MacProcStatsModificationReq: Invalid measurement type [%d]", \ + macStatsGrp->statsList[macStatsIdx]); + measTypeInvalid = true; + } + } + + if(measTypeInvalid) + { + memset(&schStatsModificationReq->statsGrpList[schStatsGrpIdx], 0, sizeof(SchStatsGrpInfo)); + break; + } + + schStatsIdx++; + } + + if(!measTypeInvalid) + { + schStatsModificationReq->statsGrpList[schStatsGrpIdx].groupId = macStatsGrp->groupId; + schStatsModificationReq->statsGrpList[schStatsGrpIdx].periodicity = macStatsGrp->periodicity; + schStatsModificationReq->statsGrpList[schStatsGrpIdx].numStats = schStatsIdx; + schStatsGrpIdx++; + } + else + { + /* [Step 3] */ + macStatsModificationRsp->statsGrpRejectedList[macStatsModificationRsp->numGrpRejected].groupId = macStatsGrp->groupId; + macStatsModificationRsp->statsGrpRejectedList[macStatsModificationRsp->numGrpRejected].cause = PARAM_INVALID; + macStatsModificationRsp->numGrpRejected++; + } + } + schStatsModificationReq->numStatsGroup = schStatsGrpIdx; + + macStatsModificationRsp->subscriptionId = macStatsModificationReq->subscriptionId; + if(schStatsModificationReq->numStatsGroup) + { + /* [Step 4] */ + macCb.statistics.numPendingStatsRsp++; + + FILL_PST_MAC_TO_SCH(schPst, EVENT_STATISTICS_MODIFY_REQ_TO_SCH); + ret = SchMessageRouter(&schPst, (void *)schStatsModificationReq); + } + else + { + /* [Step 5] */ + DU_LOG("\nERROR --> MAC : MacProcStatsModificationReq: All statistics group found invalid"); + MAC_FREE(schStatsModificationReq, sizeof(SchStatsModificationReq)); + ret = MacSendStatsModificationRspToDuApp(macStatsModificationRsp); + } + + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsModificationReq, sizeof(MacStatsModificationReq)); + return ret; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrmac/mac_msg_router.c b/src/5gnrmac/mac_msg_router.c index 88c06893f..59d45be2a 100755 --- a/src/5gnrmac/mac_msg_router.c +++ b/src/5gnrmac/mac_msg_router.c @@ -200,6 +200,12 @@ void MacHdlDuappEvents(Pst *pst, Buffer *mBuf) unpackMacStatsDeleteReq(MacProcStatsDeleteReq, pst, mBuf); break; } + case EVENT_MAC_STATISTICS_MODIFY_REQ: + { + /* Process Statistics modification Request */ + unpackMacStatsModificationReq(MacProcStatsModificationReq, pst, mBuf); + break; + } default: @@ -358,6 +364,9 @@ void callFlowMacActvTsk(Pst *pst) case EVENT_MAC_STATS_DELETE_REQ: strcpy(message,"EVENT_MAC_STATS_DELETE_REQ"); break; + case EVENT_MAC_STATISTICS_MODIFY_REQ: + strcpy(message,"EVENT_MAC_STATISTICS_MODIFY_REQ"); + break; default: strcpy(message,"Invalid Event"); break; @@ -502,6 +511,11 @@ void callFlowMacActvTsk(Pst *pst) strcpy(message,"EVENT_STATISTICS_DELETE_RSP_TO_MAC"); break; } + case EVENT_STATISTICS_MODIFY_RSP_TO_MAC: + { + strcpy(message,"EVENT_STATISTICS_MODIFY_RSP_TO_MAC"); + break; + } default: strcpy(message,"Invalid Event"); break; @@ -661,6 +675,11 @@ uint8_t MacMessageRouter(Pst *pst, void *msg) MacProcSchStatsDeleteRsp(pst, (SchStatsDeleteRsp *)msg); break; } + case EVENT_STATISTICS_MODIFY_RSP_TO_MAC: + { + MacProcSchStatsModificationRsp(pst, (SchStatsModificationRsp *)msg); + break; + } default: { return RFAILED; diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index d8adc88f4..d3fbcecb6 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -2606,39 +2606,206 @@ uint8_t SchRejectAllStats(SchStatsReq *schStatsReq, CauseOfResult cause) * Instead, we can traverse through KPI-Active-List and update * all entries in this list. * - * @params[in] Statistics request from MAC - * Cause of rejection + * @params[in] Pointer to the prb usage info link list + * Pointer to the stats ccnfig which we need to add * @return ROK - success * RFAILED - failure * * ****************************************************************/ -uint8_t schAddToKpiActiveList(Inst inst, SchStatsGrp *grpInfo) +uint8_t schAddToKpiActiveList(CmLListCp *kpiList, PTR kpiStatsInfo) { CmLList *node = NULLP; - /* If DL Total PRB Usage configured for this stats group, add to list */ - if(grpInfo->kpiStats.dlTotalPrbUsage) + SCH_ALLOC(node, sizeof(CmLList)); + if(node) { - SCH_ALLOC(node, sizeof(CmLList)); - if(node) + node->node = kpiStatsInfo; + cmLListAdd2Tail(kpiList, node); + return ROK; + } + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d",__func__, __LINE__); + return RFAILED; +} + + /******************************************************************* + * + * @brief add the stats group information in statistics's statsGrpList + * + * @details + * + * Function : schAddToStatsGrpList + * + * Functionality: add the stats group information in statsGrpList + * [Step 1] - Allocating the memory for the stats group in which + * we need to fill into the list as a node. + * [Step 2] - If allocation is successful then start traversing + * each measurment cfg index of received group info. + * [Step 2.1] Validate all measurements. If validation succeeds, go + * to [step 2.2]. Otherwise, reject the stats group and go to step 3. + * [Step 2.2] Add each KPI/measurementCfg into activeKpiList one by one. + * If it fails for any KPI, reject the whole statsGrp and go to step 3.. + * [Step 2.3] Fill other group related information + * [Step 2.4] Initialise and start timer + * [Step 2.5] Once all validation and configuration is successful, add + * statsGrp node into statistic's StatsGrpList. + * [Step 2.5.1] If node successfully added to the list, then + * fill the group related info in stats rsp's accepted list. + * [Step 2.5.2] Else goto step 3 + * [Step 3] - If failed fill the group related info in stats rsp's + * rejected list. + * + * @params[in] + * Inst + * Pointer to the stats rsp + * Subscription Id + * Stats Grp Info which needs to be store in the list + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t schAddToStatsGrpList(Inst inst, struct schStatsRsp *statsRsp, uint64_t subscriptionId, SchStatsGrpInfo *grpInfo) +{ + uint8_t ret =ROK; + uint8_t grpIdx=0; + uint8_t reqMeasIdx=0; + CauseOfResult cause; + bool measTypeInvalid=false; + CmLList *statsGrpNode=NULLP; + SchStatsGrp *grpInfoDb = NULLP; + + /* Step 1 */ + SCH_ALLOC(grpInfoDb, sizeof(SchStatsGrp)); + if(grpInfoDb == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d",__func__, __LINE__); + cause = RESOURCE_UNAVAILABLE; + ret = RFAILED; + } + else + { + /* Step 2 */ + for(reqMeasIdx = 0; reqMeasIdx < grpInfo->numStats; reqMeasIdx++) { - node->node = (PTR)grpInfo->kpiStats.dlTotalPrbUsage; - cmLListAdd2Tail(&schCb[inst].statistics.activeKpiList.dlTotPrbUseList, node); + /* Step 2.1 */ + switch(grpInfo->statsList[reqMeasIdx]) + { + case SCH_DL_TOTAL_PRB_USAGE: + { + SCH_ALLOC(grpInfoDb->kpiStats.dlTotalPrbUsage, sizeof(TotalPrbUsage)); + if(!grpInfoDb->kpiStats.dlTotalPrbUsage) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d",__func__, __LINE__); + measTypeInvalid = true; + cause = RESOURCE_UNAVAILABLE; + break; + } + break; + } + + case SCH_UL_TOTAL_PRB_USAGE: + { + SCH_ALLOC(grpInfoDb->kpiStats.ulTotalPrbUsage, sizeof(TotalPrbUsage)); + if(!grpInfoDb->kpiStats.ulTotalPrbUsage) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d",__func__, __LINE__); + measTypeInvalid = true; + cause = RESOURCE_UNAVAILABLE; + break; + } + break; + } + + default: + { + DU_LOG("\nERROR --> SCH : SchProcStatsReq: Invalid measurement type [%d]", \ + grpInfo->statsList[reqMeasIdx]); + measTypeInvalid = true; + cause = PARAM_INVALID; + break; + } + } + + if(measTypeInvalid) + { + ret =RFAILED; + break; + } + } + + while(measTypeInvalid==false) + { + if(grpInfoDb->kpiStats.dlTotalPrbUsage) + { + /* Step 2.2 */ + if(schAddToKpiActiveList(&schCb[inst].statistics.activeKpiList.dlTotPrbUseList, (PTR)grpInfoDb->kpiStats.dlTotalPrbUsage)!=ROK) + { + DU_LOG("\nERROR --> E2AP : KPI addition failed in %s at %d",__func__,__LINE__); + cause = RESOURCE_UNAVAILABLE; + ret =RFAILED; + break; + } + } + + if(grpInfoDb->kpiStats.ulTotalPrbUsage) + { + /* Step 2.2 */ + if(schAddToKpiActiveList(&schCb[inst].statistics.activeKpiList.ulTotPrbUseList, (PTR)grpInfoDb->kpiStats.ulTotalPrbUsage) != ROK) + { + DU_LOG("\nERROR --> E2AP : KPI addition failed in %s at %d",__func__,__LINE__); + cause = RESOURCE_UNAVAILABLE; + ret =RFAILED; + break; + } + } + + /* Step 2.3 */ + grpInfoDb->schInst = inst; + grpInfoDb->groupId = grpInfo->groupId; + grpInfoDb->periodicity = grpInfo->periodicity; + grpInfoDb->subscriptionId = subscriptionId; + + /* Step 2.4 */ + cmInitTimers(&(grpInfoDb->periodTimer), 1); + schStartTmr(&schCb[inst], (PTR)(grpInfoDb), EVENT_STATISTICS_TMR, grpInfoDb->periodicity); + + /* Step 2.5 */ + SCH_ALLOC(statsGrpNode, sizeof(CmLList)); + if(statsGrpNode) + { + /* Step 2.5.1 */ + statsGrpNode->node = (PTR) grpInfoDb; + cmLListAdd2Tail(&schCb[inst].statistics.statsGrpList, statsGrpNode); + statsRsp->statsGrpAcceptedList[statsRsp->numGrpAccepted] = grpInfo->groupId; + statsRsp->numGrpAccepted++; + grpIdx++; + ret = ROK; + break; + } + else + { + /* Step 2.5.2 */ + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__); + cause = RESOURCE_UNAVAILABLE; + ret = RFAILED; + break; + } } } - /* If UL Total PRB Usage configured for this stats group, add to list */ - node = NULLP; - if(grpInfo->kpiStats.ulTotalPrbUsage) + if(ret != ROK) { - SCH_ALLOC(node, sizeof(CmLList)); - if(node) + /* Step 3 */ + if(grpInfoDb) { - node->node = (PTR)grpInfo->kpiStats.ulTotalPrbUsage; - cmLListAdd2Tail(&schCb[inst].statistics.activeKpiList.ulTotPrbUseList, node); + deleteStatsGrpInfo(inst, grpInfoDb); + SCH_FREE(grpInfoDb, sizeof(SchStatsGrp)); } + statsRsp->statsGrpRejectedList[statsRsp->numGrpRejected].groupId = grpInfo->groupId; + statsRsp->statsGrpRejectedList[statsRsp->numGrpRejected].cause = cause; + statsRsp->numGrpRejected++; + return RFAILED; } - return ROK; } @@ -2661,8 +2828,7 @@ uint8_t schAddToKpiActiveList(Inst inst, SchStatsGrp *grpInfo) * is not configured and it is added to stats-group-rejected-list in * sch-stats-response message. * [Step 4] If a group passes all validation, it is added to SCH database. - * A timer is started for this group. And the group is added to - * stats-group-accepted-list in sch-stats-response message. + * And the group is added to stats-group-accepted-list in sch-stats-response message. * [Step 5] sch-stats-response is sent to du app with stats-group-rejected-list * and stats-group-accepted-list. * @@ -2674,14 +2840,11 @@ uint8_t schAddToKpiActiveList(Inst inst, SchStatsGrp *grpInfo) * ****************************************************************/ uint8_t SchProcStatsReq(Pst *pst, SchStatsReq *statsReq) { - uint8_t grpIdx = 0, reqGrpIdx = 0, reqMeasIdx = 0; - Inst inst = pst->dstInst - SCH_INST_START; - bool measTypeInvalid; - CauseOfResult cause; - CmLList *statsGrpNode=NULLP; + bool allocFailed = false; + uint8_t grpIdx = 0, reqGrpIdx = 0; SchStatsGrpInfo *grpInfo = NULLP; - SchStatsGrp *grpInfoDb = NULLP; SchStatsRsp schStatsRsp; + Inst inst = pst->dstInst - SCH_INST_START; DU_LOG("\nINFO --> SCH : Received Statistics Request from MAC"); @@ -2691,9 +2854,7 @@ uint8_t SchProcStatsReq(Pst *pst, SchStatsReq *statsReq) return RFAILED; } - /* [Step 1] Basic validation. If fails, all stats group in stats request are rejected */ - - /* If maximum number of statistics already configured */ + /*Step -1*/ if(schCb[inst].statistics.statsGrpList.count >= MAX_NUM_STATS_GRP) { DU_LOG("\nERROR --> SCH : SchProcStatsReq: Maximum number of statistics configured. \ @@ -2705,133 +2866,40 @@ uint8_t SchProcStatsReq(Pst *pst, SchStatsReq *statsReq) memset(&schStatsRsp, 0, sizeof(SchStatsRsp)); - /* [Step 2] Traverse all stats group and validate each measurement types in each group */ + /*Step -2*/ for(reqGrpIdx=0; reqGrpIdxnumStatsGroup && grpIdxstatsGrpList[reqGrpIdx]; - SCH_ALLOC(grpInfoDb, sizeof(SchStatsGrp)); - if(grpInfoDb == NULLP) + /*Step -3 */ + if(allocFailed == true) { - - DU_LOG("\nERROR --> SCH : Memory allocation failed for dlTotalPrbUsage in \ - SchProcStatsReq()"); - measTypeInvalid = true; - cause = RESOURCE_UNAVAILABLE; + schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected].groupId = grpInfo->groupId; + schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected].cause = RESOURCE_UNAVAILABLE; + schStatsRsp.numGrpRejected++; } else { - for(reqMeasIdx = 0; reqMeasIdx < grpInfo->numStats; reqMeasIdx++) + /*Step -4 */ + if(schAddToStatsGrpList(inst, &schStatsRsp, statsReq->subscriptionId, grpInfo) != ROK) { - switch(grpInfo->statsList[reqMeasIdx]) - { - case SCH_DL_TOTAL_PRB_USAGE: - { - /* Allocate memory */ - SCH_ALLOC(grpInfoDb->kpiStats.dlTotalPrbUsage, sizeof(TotalPrbUsage)); - if(!grpInfoDb->kpiStats.dlTotalPrbUsage) - { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d",__func__, __LINE__); - measTypeInvalid = true; - cause = RESOURCE_UNAVAILABLE; - } - break; - } - - case SCH_UL_TOTAL_PRB_USAGE: - { - /* Allocate memory */ - SCH_ALLOC(grpInfoDb->kpiStats.ulTotalPrbUsage, sizeof(TotalPrbUsage)); - if(!grpInfoDb->kpiStats.ulTotalPrbUsage) - { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d",__func__, __LINE__); - measTypeInvalid = true; - cause = RESOURCE_UNAVAILABLE; - } - break; - } - - default: - { - DU_LOG("\nERROR --> SCH : SchProcStatsReq: Invalid measurement type [%d]", \ - grpInfo->statsList[reqMeasIdx]); - measTypeInvalid = true; - cause = PARAM_INVALID; - break; - } - } - - /* [Step 3 a] If any measurement type validation fails in a group, that group - * is not configured */ - if(measTypeInvalid) - { - SCH_FREE(grpInfoDb->kpiStats.dlTotalPrbUsage, sizeof(TotalPrbUsage)); - SCH_FREE(grpInfoDb->kpiStats.ulTotalPrbUsage, sizeof(TotalPrbUsage)); - memset(grpInfoDb, 0, sizeof(SchStatsGrp)); - break; + DU_LOG("\nERROR --> SCH : SchProcStatsReq(): Failed to fill the stats group list"); + if((schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected-1].groupId == grpInfo->groupId &&\ + (schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected-1].cause == RESOURCE_UNAVAILABLE))) + { + allocFailed = true; } } - } - /* [Step 4] If a group passes all validation, it is added to SCH database. - * A timer is started for this group. And the group is added to - * stats-group-accepted-list in sch-stats-response message. */ - if(!measTypeInvalid) - { - /* Add this group's configured KPIs to list of Active KPIs */ - if(schAddToKpiActiveList(inst, grpInfoDb) == ROK) - { - grpInfoDb->schInst = inst; - grpInfoDb->subscriptionId = statsReq->subscriptionId; - grpInfoDb->groupId = grpInfo->groupId; - grpInfoDb->periodicity = grpInfo->periodicity; - - - /* Start timer */ - cmInitTimers(&(grpInfoDb->periodTimer), 1); - schStartTmr(&schCb[inst], (PTR)(grpInfoDb), EVENT_STATISTICS_TMR, grpInfoDb->periodicity); - - - /* Adding the information in link list*/ - SCH_ALLOC(statsGrpNode, sizeof(CmLList)); - if(statsGrpNode) - { - statsGrpNode->node = (PTR) grpInfoDb; - cmLListAdd2Tail(&schCb[inst].statistics.statsGrpList, statsGrpNode); - schStatsRsp.statsGrpAcceptedList[schStatsRsp.numGrpAccepted] = grpInfo->groupId; - schStatsRsp.numGrpAccepted++; - grpIdx++; - } - else - { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__); - SCH_FREE(grpInfoDb->kpiStats.dlTotalPrbUsage, sizeof(TotalPrbUsage)); - SCH_FREE(grpInfoDb->kpiStats.ulTotalPrbUsage, sizeof(TotalPrbUsage)); - SCH_FREE(grpInfoDb, sizeof(SchStatsGrp)); - schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected].groupId = grpInfo->groupId; - schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected].cause = cause; - schStatsRsp.numGrpRejected++; - } - } - } - else - { - /* [Step 3 b] The rejected group is added to stats-group-rejected-list in - * sch-stats-response message */ - schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected].groupId = grpInfo->groupId; - schStatsRsp.statsGrpRejectedList[schStatsRsp.numGrpRejected].cause = cause; - schStatsRsp.numGrpRejected++; } } - schStatsRsp.subscriptionId = statsReq->subscriptionId; + schStatsRsp.subscriptionId = statsReq->subscriptionId; SCH_FREE(statsReq, sizeof(SchStatsReq)); - - /* [Step 5] sch-stats-response is sent to du app with stats-group-rejected-list - * and stats-group-accepted-list. */ + + /*Step -5 */ SchSendStatsRspToMac(&schStatsRsp); return ROK; -} /* End of SchProcStatsReq */ +} /******************************************************************* * @@ -2957,35 +3025,106 @@ uint8_t schCalcAndSendGrpStats(SchStatsGrp *grpInfo) /******************************************************************* * - * @brief Delete statistics group + * @brief Delete node from active kpi list * * @details * - * Function : deleteStatsGrp + * Function :deleteNodeFrmKpiList * * Functionality: * Delete statistics group * * @params[in] + * Kpi list from which a node needs to be deleted + * Nodes info which a node needs to be deleted + * @return void + * ****************************************************************/ + +void deleteNodeFrmKpiList(CmLListCp *kpiList, PTR kpiNodeInfoToDel) +{ + CmLList *kpiNode=NULLP; + + CM_LLIST_FIRST_NODE(kpiList, kpiNode); + while(kpiNode) + { + if(kpiNode->node == kpiNodeInfoToDel) + { + cmLListDelFrm(kpiList, kpiNode); + SCH_FREE(kpiNode, sizeof(CmLList)); + break; + } + kpiNode = kpiNode->next; + } + +} + +/******************************************************************* + * + * @brief Delete statistics group info + * + * @details + * + * Function : deleteStatsGrpInfo + * + * Functionality: + * Delete statistics group info + * + * @params[in] * Inst - * Stats Grp Node - * @return ROK - success - * RFAILED - failure + * Stats Grp info + * @return void * * ****************************************************************/ -void deleteStatsGrp(Inst inst, CmLList *grpNode) +void deleteStatsGrpInfo(Inst inst, SchStatsGrp *statsGrpInfo) { - SchStatsGrp *statsGrpInfo=NULLP; - - if(grpNode) + if(statsGrpInfo) { - statsGrpInfo = (SchStatsGrp*)grpNode->node; - SCH_FREE(statsGrpInfo->kpiStats.dlTotalPrbUsage, sizeof(TotalPrbUsage)); - SCH_FREE(statsGrpInfo->kpiStats.ulTotalPrbUsage, sizeof(TotalPrbUsage)); + if(statsGrpInfo->kpiStats.dlTotalPrbUsage) + { + deleteNodeFrmKpiList(&schCb[inst].statistics.activeKpiList.dlTotPrbUseList, (PTR) statsGrpInfo->kpiStats.dlTotalPrbUsage); + SCH_FREE(statsGrpInfo->kpiStats.dlTotalPrbUsage, sizeof(TotalPrbUsage)); + } + + if(statsGrpInfo->kpiStats.ulTotalPrbUsage) + { + deleteNodeFrmKpiList(&schCb[inst].statistics.activeKpiList.ulTotPrbUseList, (PTR) statsGrpInfo->kpiStats.ulTotalPrbUsage); + SCH_FREE(statsGrpInfo->kpiStats.ulTotalPrbUsage, sizeof(TotalPrbUsage)); + } + if(schChkTmr((PTR)statsGrpInfo, EVENT_STATISTICS_TMR) == true) { schStopTmr(&schCb[inst], (PTR)statsGrpInfo, EVENT_STATISTICS_TMR); } + + memset(statsGrpInfo, 0, sizeof(SchStatsGrp)); + } +} + +/******************************************************************* + * + * @brief Delete statistics group Node + * + * @details + * + * Function : deleteStatsGrpNode + * + * Functionality: + * Delete statistics group node + * + * @params[in] + * Inst + * Stats Grp Node + * @return void + * + * ****************************************************************/ +void deleteStatsGrpNode(Inst inst, CmLList *grpNode) +{ + SchStatsGrp *statsGrpInfo=NULLP; + + if(grpNode) + { + statsGrpInfo = (SchStatsGrp*)grpNode->node; + deleteStatsGrpInfo(inst, statsGrpInfo); memset(statsGrpInfo, 0, sizeof(SchStatsGrp)); SCH_FREE(grpNode->node, sizeof(SchStatsGrp)); SCH_FREE(grpNode, sizeof(CmLList)); @@ -3043,7 +3182,7 @@ uint8_t deleteFromStatsGrpList(Inst inst, CmLListCp *statsGrpList, uint64_t sub { /* [Step 3] */ cmLListDelFrm(statsGrpList, grpNode); - deleteStatsGrp(inst, grpNode); + deleteStatsGrpNode(inst, grpNode); } else { @@ -3051,7 +3190,7 @@ uint8_t deleteFromStatsGrpList(Inst inst, CmLListCp *statsGrpList, uint64_t sub if(statsGrpInfo->groupId== groupId) { cmLListDelFrm(statsGrpList, grpNode); - deleteStatsGrp(inst, grpNode); + deleteStatsGrpNode(inst, grpNode); statsFound = true; } } @@ -3207,6 +3346,232 @@ uint8_t SchProcStatsDeleteReq(Pst *pst, SchStatsDeleteReq *statsDeleteReq) return ret; } /* End of SchProcStatsDeleteReq */ +/******************************************************************* + * + * @brief Fill and send statistics modification response to MAC + * + * @details + * + * Function : SchSendStatsRspToMac + * + * Functionality: Fill and send statistics + * modification response to MAC + * + * @params[in] Inst inst, SchMacRsp result + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t SchSendStatsModificationRspToMac(SchStatsModificationRsp *tmpSchStatsModRsp) +{ + Pst rspPst; + uint8_t ret = ROK; + SchStatsModificationRsp *schStatsModificationRsp=NULLP; + + DU_LOG("\nINFO --> SCH : Filling statistics modification response"); + SCH_ALLOC(schStatsModificationRsp, sizeof(SchStatsModificationRsp)); + if(schStatsModificationRsp == NULLP) + { + DU_LOG("\nERROR --> SCH : Failed to allocate memory in SchSendStatsModificationRspToMac()"); + return RFAILED; + } + + memcpy(schStatsModificationRsp, tmpSchStatsModRsp, sizeof(SchStatsModificationRsp)); + memset(tmpSchStatsModRsp, 0, sizeof(SchStatsModificationRsp)); + + /* Filling response post */ + memset(&rspPst, 0, sizeof(Pst)); + FILL_PST_SCH_TO_MAC(rspPst, inst); + rspPst.event = EVENT_STATISTICS_MODIFY_RSP_TO_MAC; + + ret = MacMessageRouter(&rspPst, (void *)schStatsModificationRsp); + if(ret == RFAILED) + { + DU_LOG("\nERROR --> SCH : SchSendStatsModificationRspToMac(): Failed to send Statistics Modification Response"); + return ret; + } + return ret; +} + +/******************************************************************* + * + * @brief Rejects all statistics modification group requested by MAC + * + * @details + * + * Function : SchRejectAllStatsModification + * + * Functionality: Add all statistics modification group received in statistics + * request from MAC, to Reject-StatsModification-Group-List in statistics + * response to MAC + * + * @params[in] Statistics request from MAC + * Cause of rejection + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t SchRejectAllStatsModification(SchStatsModificationReq *statsModificationReq, CauseOfResult cause) +{ + uint8_t grpIdx = 0; + SchStatsModificationRsp statsModificationRsp; + + memset(&statsModificationRsp, 0, sizeof(SchStatsModificationRsp)); + + /* fill the subscriptionId and the rejected list in stats modification rsp */ + statsModificationRsp.subscriptionId = statsModificationReq->subscriptionId; + for(grpIdx = 0; grpIdx < statsModificationReq->numStatsGroup; grpIdx++) + { + statsModificationRsp.statsGrpRejectedList[grpIdx].groupId = statsModificationReq->statsGrpList[grpIdx].groupId; + statsModificationRsp.statsGrpRejectedList[grpIdx].cause = cause; + } + statsModificationRsp.numGrpRejected = statsModificationReq->numStatsGroup; + + return SchSendStatsModificationRspToMac(&statsModificationRsp); +} + +/**************************************************************************************** +* +* @brief Processes Statistics modification Request from MAC +* +* @details +* +* Function :SchProcStatsModificationReq +* +* Functionality: +* This function process the statistics modification request from MAC: +* [Step -1] Check the stored stats group list empty. +* [Step - 1.1] If empty Send the rejected group list to MAC as a stats +* modification response. +* [Step - 1.2] Else go to step 2. +* [Step -2] Traverse all stats group and validate each measurement types in +* each group. +* [Step -3] Check for any failure and if failed fill the remaining group's +* info in rejected list. +* [Step -4] Else Check if the received subscriptionId and groupId match the +* values with the database node. +* [Step -4.1] If matches then follow the below mentioned steps. +* [Step -4.1.1] Stop the timer. +* [Step -4.1.2] Reconfigure stats group by adding a new entry for this +* statsGroup with updated configuration in database. +* [Step -4.1.3] if configured successfully, store stats info into +* stats mod rsp's accepted list, restart timer and go to step 4.1.4 +* [Step -4.1.4] Delete the old entry of this stats group.. +* [Step -4.2] Else fill the group related info in stats modification rsp's +* rejected list. +* [Step -5] Send the stats modification rsp to MAC +* @params[in] Post structure +* Statistics modification Request from MAC +* @return ROK - success +* RFAILED - failure +* +* *******************************************************************************************/ +uint8_t SchProcStatsModificationReq(Pst *pst, SchStatsModificationReq *statsModificationReq) +{ + Inst inst; + uint8_t reqGrpIdx=0; + uint64_t subscriptionId =0; + bool allocFailed = false; + bool statsGrpFound= false; + CmLList *grpNode = NULLP; + SchStatsGrp *statsGrpInfo=NULLP; + SchStatsGrpInfo statsGrpToModify; + SchStatsModificationRsp statsModificationRsp; + + inst=pst->dstInst - SCH_INST_START; + + DU_LOG("\nINFO --> SCH : Received Statistics modification request from MAC"); + + if(statsModificationReq == NULLP) + { + DU_LOG("\nERROR --> SCH : SchProcStatsModificationReq(): Received Null pointer"); + return RFAILED; + } + memset(&statsModificationRsp, 0, sizeof(SchStatsRsp)); + + /* [Step -1] */ + if(schCb[inst].statistics.statsGrpList.count) + { + /* [Step -1.2] */ + subscriptionId = statsModificationReq->subscriptionId; + + /* [Step - 2] */ + for(reqGrpIdx=0; reqGrpIdxnumStatsGroup; reqGrpIdx++) + { + /* [Step - 3] */ + statsGrpToModify = statsModificationReq->statsGrpList[reqGrpIdx]; + if(allocFailed != true) + { + CM_LLIST_FIRST_NODE(&schCb[inst].statistics.statsGrpList, grpNode); + while(grpNode) + { + /* [Step - 4] */ + statsGrpInfo = (SchStatsGrp*)grpNode->node; + if((statsGrpInfo->subscriptionId== subscriptionId) && (statsGrpInfo->groupId== statsGrpToModify.groupId)) + { + statsGrpFound= true; + break; + } + grpNode = grpNode->next; + } + + /* [Step - 4.1] */ + if(statsGrpFound== true) + { + /* [Step - 4.1.1] */ + if(schChkTmr((PTR)statsGrpInfo, EVENT_STATISTICS_TMR) == true) + { + schStopTmr(&schCb[inst], (PTR)statsGrpInfo, EVENT_STATISTICS_TMR); + } + + /* [Step - 4.1.2] */ + if(schAddToStatsGrpList(inst, &statsModificationRsp, subscriptionId, &statsGrpToModify) != ROK) + { + DU_LOG("\nERROR --> SCH : SchProcStatsReq(): Failed to fill the stats group list"); + if(statsModificationRsp.statsGrpRejectedList[statsModificationRsp.numGrpRejected-1].groupId == statsGrpToModify.groupId) + { + /* [Step - 4.1.3] */ + schStartTmr(&schCb[inst], (PTR)(statsGrpInfo), EVENT_STATISTICS_TMR, statsGrpInfo->periodicity); + if(statsModificationRsp.statsGrpRejectedList[statsModificationRsp.numGrpRejected-1].cause == RESOURCE_UNAVAILABLE) + { + allocFailed = true; + break; + } + } + } + else + { + /* [Step - 4.1.4] */ + deleteStatsGrpNode(inst, grpNode); + } + } + else + { + /* [Step - 4.2] */ + statsModificationRsp.statsGrpRejectedList[statsModificationRsp.numGrpRejected].groupId = statsGrpToModify.groupId; + statsModificationRsp.statsGrpRejectedList[statsModificationRsp.numGrpRejected].cause = STATS_ID_NOT_FOUND; + statsModificationRsp.numGrpRejected++; + } + } + else + { + statsModificationRsp.statsGrpRejectedList[statsModificationRsp.numGrpRejected].groupId = statsGrpToModify.groupId; + statsModificationRsp.statsGrpRejectedList[statsModificationRsp.numGrpRejected].cause = RESOURCE_UNAVAILABLE; + statsModificationRsp.numGrpRejected++; + } + } + + statsModificationRsp.subscriptionId = statsModificationReq->subscriptionId; + SchSendStatsModificationRspToMac(&statsModificationRsp); + } + else + { + /* [Step -1.1] */ + SchRejectAllStatsModification(statsModificationReq, STATS_ID_NOT_FOUND); + } + SCH_FREE(statsModificationReq, sizeof(SchStatsModificationReq)); + return ROK; +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch.h b/src/5gnrsch/sch.h index 58e1c6813..3d5e9f1ed 100644 --- a/src/5gnrsch/sch.h +++ b/src/5gnrsch/sch.h @@ -818,6 +818,8 @@ uint8_t SchProcStatsReq(Pst *pst, SchStatsReq *statsReq); uint8_t SchSendStatsIndToMac(Inst inst, SchStatsInd *statsInd); uint8_t schCalcAndSendGrpStats(SchStatsGrp *grpInfo); uint8_t SchProcStatsDeleteReq(Pst *pst, SchStatsDeleteReq *statsDeleteReq); +uint8_t SchProcStatsModificationReq(Pst *pst, SchStatsModificationReq *statsModificationReq); +void deleteStatsGrpInfo(Inst inst, SchStatsGrp *statsGrpInfo); /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_msg_router.c b/src/5gnrsch/sch_msg_router.c index bad7ceac0..4cbd9581e 100755 --- a/src/5gnrsch/sch_msg_router.c +++ b/src/5gnrsch/sch_msg_router.c @@ -254,6 +254,11 @@ void callFlowSchMsgRouter(Pst *pst) strcpy(message,"EVENT_STATISTICS_DELETE_REQ_TO_SCH"); break; } + case EVENT_STATISTICS_MODIFY_REQ_TO_SCH: + { + strcpy(message,"EVENT_STATISTICS_MODIFY_REQ_TO_SCH"); + break; + } default: strcpy(message,"Invalid Event"); break; @@ -386,6 +391,11 @@ uint8_t SchMessageRouter(Pst *pst, void *msg) SchProcStatsDeleteReq(pst, (SchStatsDeleteReq *)msg); break; } + case EVENT_STATISTICS_MODIFY_REQ_TO_SCH: + { + SchProcStatsModificationReq(pst, (SchStatsModificationReq *)msg); + break; + } default: { DU_LOG("\nERROR --> SCH : SchMessageRouter(): Invalid event [%d] received", pst->event); diff --git a/src/5gnrsch/sch_slot_ind.c b/src/5gnrsch/sch_slot_ind.c index 2a21774e5..534100d60 100644 --- a/src/5gnrsch/sch_slot_ind.c +++ b/src/5gnrsch/sch_slot_ind.c @@ -757,8 +757,11 @@ uint8_t SchProcSlotInd(Pst *pst, SlotTimingInfo *slotInd) while(node) { dlTotalPrbUsage = (TotalPrbUsage *)node->node; - dlTotalPrbUsage->numPrbUsedForTx += cell->schDlSlotInfo[slot]->prbAlloc.numPrbAlloc; - dlTotalPrbUsage->totalPrbAvailForTx += MAX_NUM_RB; + if(dlTotalPrbUsage) + { + dlTotalPrbUsage->numPrbUsedForTx += cell->schDlSlotInfo[slot]->prbAlloc.numPrbAlloc; + dlTotalPrbUsage->totalPrbAvailForTx += MAX_NUM_RB; + } node = node->next; } diff --git a/src/cm/du_app_mac_inf.c b/src/cm/du_app_mac_inf.c index 4886061bb..b05b9889a 100644 --- a/src/cm/du_app_mac_inf.c +++ b/src/cm/du_app_mac_inf.c @@ -2713,6 +2713,164 @@ uint8_t unpackDuMacStatsDeleteRsp(MacDuStatsDeleteRspFunc func, Pst *pst, Buffer return RFAILED; } +/******************************************************************* +* +* @brief Packs and Sends Statistics Modification Request from DUAPP to MAC +* +* @details +* +* Function : packDuMacStatsModificationReq +* +* Functionality: +* Packs and Sends statistics Modification request from DUAPP to MAC +* +* +* @params[in] Post structure pointer +* StatsModificationReq pointer +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t packDuMacStatsModificationReq(Pst *pst, MacStatsModificationReq *statsModificationReq) +{ + Buffer *mBuf = NULLP; + + if(pst->selector == ODU_SELECTOR_LWLC) + { + if (ODU_GET_MSG_BUF(pst->region, pst->pool, &mBuf) != ROK) + { + DU_LOG("\nERROR --> MAC : Memory allocation failed at packDuMacStatsModificationReq"); + return RFAILED; + } + /* pack the address of the structure */ + CMCHKPK(oduPackPointer,(PTR)statsModificationReq, mBuf); + } + else + { + DU_LOG("\nERROR --> MAC: Only LWLC supported for packDuMacStatsModificationReq"); + return RFAILED; + } + return ODU_POST_TASK(pst,mBuf); +} + +/******************************************************************* +* +* @brief Unpacks Statistics Modification Request received from DU APP +* +* @details +* +* Function : unpackMacStatsModificationReq +* +* Functionality: +* Unpacks Statistics Modification Request received from DU APP +* +* @params[in] Pointer to Handler +* Post structure pointer +* Message Buffer +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t unpackMacStatsModificationReq(DuMacStatsModificationReqFunc func, Pst *pst, Buffer *mBuf) +{ + if(pst->selector == ODU_SELECTOR_LWLC) + { + MacStatsModificationReq *statsModificationReq=NULLP; + + /* unpack the address of the structure */ + CMCHKUNPK(oduUnpackPointer, (PTR *)&statsModificationReq, mBuf); + ODU_PUT_MSG_BUF(mBuf); + return (*func)(pst, statsModificationReq); + } + else + { + /* Nothing to do for other selectors */ + DU_LOG("\nERROR --> DU APP : Only LWLC supported for Statistics Modification Request "); + ODU_PUT_MSG_BUF(mBuf); + } + + return RFAILED; +} + +/******************************************************************* +* +* @brief Packs and Sends Statistics Modification Response from MAC to DUAPP +* +* @details +* +* Function : packDuMacStatsModificationRsp +* +* Functionality: +* Packs and Sends statistics Modification response from MAC to DUAPP +* +* +* @params[in] Post structure pointer +* StatsModificationRsp pointer +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t packDuMacStatsModificationRsp(Pst *pst, MacStatsModificationRsp *statsModificationRsp) +{ + Buffer *mBuf = NULLP; + + if(pst->selector == ODU_SELECTOR_LWLC) + { + if (ODU_GET_MSG_BUF(pst->region, pst->pool, &mBuf) != ROK) + { + DU_LOG("\nERROR --> MAC : Memory allocation failed at packDuMacStatsModificationRsp"); + return RFAILED; + } + /* pack the address of the structure */ + CMCHKPK(oduPackPointer,(PTR)statsModificationRsp, mBuf); + } + else + { + DU_LOG("\nERROR --> MAC: Only LWLC supported for packDuMacStatsModificationRsp"); + return RFAILED; + } + return ODU_POST_TASK(pst,mBuf); +} + +/******************************************************************* +* +* @brief Unpacks Statistics Modification Response received from MAC +* +* @details +* +* Function : unpackDuMacStatsModificationRsp +* +* Functionality: +* Unpacks Statistics Modification Response received from MAC +* +* @params[in] Pointer to Handler +* Post structure pointer +* Message Buffer +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +uint8_t unpackDuMacStatsModificationRsp(MacDuStatsModificationRspFunc func, Pst *pst, Buffer *mBuf) +{ + if(pst->selector == ODU_SELECTOR_LWLC) + { + MacStatsModificationRsp *statsModificationRsp=NULLP; + + /* unpack the address of the structure */ + CMCHKUNPK(oduUnpackPointer, (PTR *)&statsModificationRsp, mBuf); + ODU_PUT_MSG_BUF(mBuf); + return (*func)(pst, statsModificationRsp); + } + else + { + /* Nothing to do for other selectors */ + DU_LOG("\nERROR --> DU APP : Only LWLC supported for Statistics Modification Response "); + ODU_PUT_MSG_BUF(mBuf); + } + + return RFAILED; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/du_app_mac_inf.h b/src/cm/du_app_mac_inf.h index 9450cac38..9631cc597 100644 --- a/src/cm/du_app_mac_inf.h +++ b/src/cm/du_app_mac_inf.h @@ -94,6 +94,8 @@ #define EVENT_MAC_STATISTICS_IND 231 #define EVENT_MAC_STATS_DELETE_REQ 232 #define EVENT_MAC_STATS_DELETE_RSP 233 +#define EVENT_MAC_STATISTICS_MODIFY_REQ 234 +#define EVENT_MAC_STATISTICS_MODIFY_RSP 235 #define BSR_PERIODIC_TIMER_SF_10 10 #define BSR_RETX_TIMER_SF_320 320 @@ -1924,6 +1926,9 @@ typedef struct macStatsDeleteRsp MacStatsDeleteInfo statsGrpDelInfo[MAX_NUM_STATS_GRP]; /*list of the deletion statuses for specific actions */ }MacStatsDeleteRsp; +typedef struct macStatsReq MacStatsModificationReq; +typedef struct macStatsRsp MacStatsModificationRsp; + /****************** FUNCTION POINTERS ********************************/ /* DL broadcast req from DU APP to MAC*/ @@ -2103,6 +2108,16 @@ typedef uint8_t (*MacDuStatsDeleteRspFunc) ARGS(( Pst *pst, MacStatsDeleteRsp *statsDeleteRsp)); +/* Statitics Modification Request from DU APP to MAC */ +typedef uint8_t (*DuMacStatsModificationReqFunc) ARGS(( + Pst *pst, + MacStatsModificationReq *statsModificationReq)); + +/* Statistics Modification Response from MAC to DU APP */ +typedef uint8_t (*MacDuStatsModificationRspFunc) ARGS(( + Pst *pst, + MacStatsModificationRsp *statsModificationRsp)); + /******************** FUNCTION DECLARATIONS ********************************/ uint8_t packMacCellUpInd(Pst *pst, OduCellId *cellId); uint8_t unpackMacCellUpInd(DuMacCellUpInd func, Pst *pst, Buffer *mBuf); @@ -2244,6 +2259,15 @@ uint8_t packDuMacStatsDeleteRsp(Pst *pst, MacStatsDeleteRsp *statsDeleteRsp); uint8_t DuProcMacStatsDeleteRsp(Pst *pst, MacStatsDeleteRsp *statsDeleteRsp); uint8_t unpackDuMacStatsDeleteRsp(MacDuStatsDeleteRspFunc func, Pst *pst, Buffer *mBuf); +uint8_t packDuMacStatsModificationReq(Pst *pst, MacStatsModificationReq *statsModificationReq); +uint8_t MacProcStatsModificationReq(Pst *pst, MacStatsModificationReq *statsModificationReq); +uint8_t unpackMacStatsModificationReq(DuMacStatsModificationReqFunc func, Pst *pst, Buffer *mBuf); + +uint8_t packDuMacStatsModificationRsp(Pst *pst, MacStatsModificationRsp *statsModificationRsp); +uint8_t DuProcMacStatsModificationRsp(Pst *pst, MacStatsModificationRsp *statsModificationRsp); +uint8_t unpackDuMacStatsModificationRsp(MacDuStatsModificationRspFunc func, Pst *pst, Buffer *mBuf); + + #endif diff --git a/src/cm/mac_sch_interface.h b/src/cm/mac_sch_interface.h index 985d7bbc3..769ff9d52 100644 --- a/src/cm/mac_sch_interface.h +++ b/src/cm/mac_sch_interface.h @@ -56,6 +56,8 @@ #define EVENT_STATISTICS_IND_TO_MAC 37 #define EVENT_STATISTICS_DELETE_REQ_TO_SCH 38 #define EVENT_STATISTICS_DELETE_RSP_TO_MAC 39 +#define EVENT_STATISTICS_MODIFY_REQ_TO_SCH 40 +#define EVENT_STATISTICS_MODIFY_RSP_TO_MAC 41 /*macros*/ #define MAX_SSB_IDX 1 /* forcing it as 1 for now. Right value is 64 */ @@ -2263,6 +2265,9 @@ typedef struct schStatsReq SchStatsGrpInfo statsGrpList[MAX_NUM_STATS_GRP]; }SchStatsReq; +typedef struct schStatsReq SchStatsModificationReq; +typedef struct schStatsRsp SchStatsModificationRsp; + /* Statistics Response from SCH to MAC */ typedef struct schStatsGrpRejected { diff --git a/src/du_app/du_e2ap_mgr.c b/src/du_app/du_e2ap_mgr.c index 57b751ccf..b1b350ad3 100644 --- a/src/du_app/du_e2ap_mgr.c +++ b/src/du_app/du_e2ap_mgr.c @@ -1579,6 +1579,116 @@ uint8_t e2ProcStatsDeleteRsp(MacStatsDeleteRsp *statsDeleteRsp) return ROK; } +/******************************************************************* + * + * @brief Fill RIC Subscription datils in MAC Statistics + * ModificationRequest + * + * @details + * + * Function : fillRicSubsInMacStatsModificationReq + * + * Functionality: Fill RIC Subscription datils in MAC + * Modification Statistics Request + * [Step -1] Generate subscription ID using RIC Request ID and + * RAN Function ID + * [Step -2] Check all the action staus of each action present + * in the ric subscription. If action is CONFIG_MOD then fill + * the information in stats group list. + * [Step -3] Fill group related information in stats modification + * req's in stats group list + * [Step -4] fill measurement information in stats group list + * [Step -5] If the number of stats which needs to modify is + * greater then zero then return ROK else return RFAILED + * + * @params[in] MAC Statistics Modification Request to be filled + * RIC Subscription Info + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t fillRicSubsInMacStatsModificationReq(MacStatsModificationReq *macStatsModificationReq, RicSubscription* ricSubscriptionInfo) +{ + uint8_t grpIdx = 0; + uint8_t statsModifyReqIdx = 0; + uint64_t subscriptionId = 0; + CmLList *node = NULLP; + ActionInfo *actionDb = NULLP; + CmLList *actionNode = NULLP; + MeasurementInfo *measInfo = NULLP; + ActionDefFormat1 *format1Action = NULLP; + + /* [Step -1] */ + encodeSubscriptionId(&subscriptionId, ricSubscriptionInfo->ranFuncId, ricSubscriptionInfo->requestId); + + macStatsModificationReq->subscriptionId = subscriptionId; + CM_LLIST_FIRST_NODE(&ricSubscriptionInfo->actionSequence, actionNode); + while(actionNode) + { + actionDb = (ActionInfo*)(actionNode->node); + /* [Step -2] */ + if(actionDb->action == CONFIG_MOD) + { + /* [Step -3] */ + macStatsModificationReq->statsGrpList[grpIdx].groupId = actionDb->actionId; + switch(actionDb->definition.formatType) + { + case 1: + { + format1Action = &actionDb->definition.choice.format1; + macStatsModificationReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod; + + statsModifyReqIdx = 0; + node = cmLListFirst(&format1Action->measurementInfoList); + while(node) + { + /* [Step -4] */ + measInfo = (MeasurementInfo *)(node->node); + switch(measInfo->measurementTypeId) + { + case 1: + { + macStatsModificationReq->statsGrpList[grpIdx].statsList[statsModifyReqIdx++] = MAC_DL_TOTAL_PRB_USAGE; + break; + } + case 2: + { + macStatsModificationReq->statsGrpList[grpIdx].statsList[statsModifyReqIdx++] = MAC_UL_TOTAL_PRB_USAGE; + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid measurement name"); + break; + } + } + node = node->next; + } + macStatsModificationReq->statsGrpList[grpIdx].numStats = statsModifyReqIdx; + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : fillRicSubsInMacStatsModificationReq: Only Action Definition Format 1 supported"); + break; + } + } + if(macStatsModificationReq->statsGrpList[grpIdx].numStats) + grpIdx++; + } + actionNode = actionNode->next; + } + + /* [Step -5] */ + macStatsModificationReq->numStatsGroup = grpIdx; + if(macStatsModificationReq->numStatsGroup) + { + return ROK; + } + return RFAILED; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_e2ap_mgr.h b/src/du_app/du_e2ap_mgr.h index 9952474d8..85447f225 100644 --- a/src/du_app/du_e2ap_mgr.h +++ b/src/du_app/du_e2ap_mgr.h @@ -534,6 +534,7 @@ void deleteMeasuredValueList(CmLListCp *measuredValueList); void removeE2NodeInformation(); void encodeSubscriptionId(uint64_t *subscriptionId, uint16_t ranFuncId, RicRequestId ricReqId); uint8_t e2ProcStatsDeleteRsp(MacStatsDeleteRsp *statsDeleteRsp); +uint8_t fillRicSubsInMacStatsModificationReq(MacStatsModificationReq *macStatsModReq, RicSubscription* ricSubscriptionInfo); /********************************************************************** End of file diff --git a/src/du_app/du_mgr_msg_router.c b/src/du_app/du_mgr_msg_router.c index a1112d051..0338f742b 100644 --- a/src/du_app/du_mgr_msg_router.c +++ b/src/du_app/du_mgr_msg_router.c @@ -302,6 +302,11 @@ void callFlowduActvTsk(Pst *pst) strcpy(message,"EVENT_MAC_STATS_DELETE_RSP"); break; } + case EVENT_MAC_STATISTICS_MODIFY_RSP: + { + strcpy(message,"EVENT_MAC_STATISTICS_MODIFY_RSP"); + break; + } default: { strcpy(message,"Invalid Event"); @@ -612,6 +617,11 @@ uint8_t duActvTsk(Pst *pst, Buffer *mBuf) ret = unpackDuMacStatsDeleteRsp(DuProcMacStatsDeleteRsp, pst, mBuf); break; } + case EVENT_MAC_STATISTICS_MODIFY_RSP: + { + ret = unpackDuMacStatsModificationRsp(DuProcMacStatsModificationRsp, pst, mBuf); + break; + } default: { DU_LOG("\nERROR --> DU_APP : Invalid event received at duActvTsk from ENTMAC"); diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index 39b2702c1..1089a5ec1 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -118,6 +118,13 @@ DuMacStatsDeleteReqFunc packMacStatsDeleteReqOpts[]= packDuMacStatsDeleteReq /* Light weight-loose coupling */ }; +DuMacStatsModificationReqFunc packMacStatsModificationReqOpts[]= +{ + packDuMacStatsModificationReq, /* Loose Coupling */ + MacProcStatsModificationReq, /* Tight Coupling */ + packDuMacStatsModificationReq /* Light weight-loose coupling */ +}; + /************************************************************************** * @brief Function to fill configs required by RLC * @@ -2436,6 +2443,144 @@ uint8_t BuildAndSendStatsDeleteReq(RicSubscription *ricSubscriptionInfo) return ROK; } + /******************************************************************* + * + * @brief Send Statistics Modification request to MAC + * + * @details + * + * Function : BuildAndSendStatsModificationReqToMac() + * + * Functionality: Send Statistics Modification Request To Mac + * + * @params[in] Ric subscription info + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendStatsModificationReqToMac(RicSubscription *ricSubscriptionInfo) +{ + Pst pst; + MacStatsModificationReq *macStatsModificationReq = NULLP; + + /* Fill MAC statistics modification request */ + DU_ALLOC_SHRABL_BUF(macStatsModificationReq, sizeof(MacStatsModificationReq)); + if(macStatsModificationReq == NULLP) + { + DU_LOG("\nERROR --> DU_APP : Memory allocation failed for macStatsModificationReq in BuildAndSendStatsModificationReqToMac"); + return RFAILED; + } + + /* Fill E2 Subscription Info in MAC Statistics Modification Request and send to MAC */ + if(fillRicSubsInMacStatsModificationReq(macStatsModificationReq, ricSubscriptionInfo) == ROK) + { + DU_LOG("\nDEBUG --> DU_APP: Sending Statistics Modification Request to MAC "); + FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_MODIFY_REQ); + + if( (*packMacStatsModificationReqOpts[pst.selector])(&pst, macStatsModificationReq) == ROK) + return ROK; + + DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Modification Request to MAC"); + } + + DU_LOG("\nERROR --> DU_APP: No Statistics group found valid. Hence statistics Modification request is not sent to MAC"); + DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsModificationReq, sizeof(MacStatsModificationReq)); + return RFAILED; +} + +/******************************************************************* + * + * @brief Send Statistics Modification request to DU layers + * + * @details + * + * Function : BuildAndSendStatsModificationReq() + * + * Functionality: Check if there is an update in statistics + * reporting configuration. If so, send the update Modification to + * respective layer. + * + * @params[in] Subscription Info + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendStatsModificationReq(RicSubscription *ricSubscriptionInfo) +{ + /* Build and sent subscription information to MAC in Statistics Modification Request */ + if(BuildAndSendStatsModificationReqToMac(ricSubscriptionInfo) != ROK) + { + DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsModificationReqToMac()"); + return RFAILED; + } + + return ROK; +} + +/******************************************************************* + * + * @brief Process statistics modification response from MAC + * + * @details + * + * Function : DuProcMacStatsModificationRsp + * + * Functionality: Processes statistics modification configuration + * response from MAC. If configuration is succsessful, DUAPP starts + * reporting period timer for this subscription request + * from RIC + * + * @params[in] + * PST structure + * MAC stats modification rsp + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t DuProcMacStatsModificationRsp(Pst *pst, MacStatsModificationRsp *statsModificationRsp) +{ + uint8_t ret = RFAILED; + DU_LOG("\nINFO --> DU_APP : DuProcMacStatsModificationRsp: Received Statistics Modification Response from MAC"); + + if(statsModificationRsp) + { +#ifdef DEBUG_PRINT + uint8_t idx = 0; + DU_LOG("\n Subscription Id [%ld]", statsModificationRsp->subscriptionId); + + DU_LOG("\n Number of Accepted Groups [%d]", statsModificationRsp->numGrpAccepted); + for(idx=0; idxnumGrpAccepted; idx++) + { + DU_LOG("\n Group Id [%d]", statsModificationRsp->statsGrpAcceptedList[idx]); + } + + DU_LOG("\n Number of Rejected Groups [%d]", statsModificationRsp->numGrpRejected); + for(idx=0; idxnumGrpRejected; idx++) + { + DU_LOG("\n Group Id [%d]", statsModificationRsp->statsGrpRejectedList[idx].groupId); + } +#endif +#if 0 + /*TODO*/ + /* Check the list of accepted and rejected statistics group and send + * Ric subscription modification response/failure accordingly */ + if((ret = e2ProcStatsModificationRsp(statsModificationRsp)) != ROK) + { + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsModificationRsp: Failed in %s at line %d", __func__, __LINE__); + } +#endif + DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsModificationRsp, sizeof(MacStatsModificationRsp)); + } + else + { + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsModificationRsp: Received NULL Pointer"); + } + return ret; +} + /********************************************************************** End of file **********************************************************************/