X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2F5gnrmac%2Fmac_cfg_hdl.c;h=0572fd7819eab0f44a6fcd5cc792f59ab249cf83;hb=b3d5c17f74361fcdcb9b9febff450292197e3a57;hp=fa17ba067245c09581585c435f491f5688555adc;hpb=f73456bd55152c329601f8286ae67fe9875025bc;p=o-du%2Fl2.git diff --git a/src/5gnrmac/mac_cfg_hdl.c b/src/5gnrmac/mac_cfg_hdl.c index fa17ba067..0572fd781 100644 --- a/src/5gnrmac/mac_cfg_hdl.c +++ b/src/5gnrmac/mac_cfg_hdl.c @@ -63,6 +63,14 @@ MacDuSliceRecfgRspFunc macDuSliceRecfgRspOpts[] = packDuMacSliceRecfgRsp /* packing for light weight loosly coupled */ }; +MacDuStatsRspFunc macDuStatsRspOpts[] = +{ + packDuMacStatsRsp, /* packing for loosely coupled */ + DuProcMacStatsRsp, /* packing for tightly coupled */ + packDuMacStatsRsp /* packing for light weight loosly coupled */ +}; + + /** * @brief Layer Manager Configuration request handler for Scheduler * @@ -1015,6 +1023,96 @@ uint8_t MacProcDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq) return ret; } +/** + * @brief Fill and send statistics response to DU APP + * + * @details + * + * Function : MacSendStatsRspToDuApp + * + * Fill and send statistics response to DU APP + * + * @param[in] Response + * @param[in] Cause of response + * @return int + * -# ROK + **/ +uint8_t MacSendStatsRspToDuApp(MacStatsRsp *statsRsp) +{ + uint8_t ret = ROK; + Pst pst; + MacStatsRsp *macStatsRsp = NULLP; + + DU_LOG("\nINFO --> MAC : MacSendStatsRspToDuApp: Sending Statistics Response to DU APP"); + + /* Workaround : To skip corrupted memory, allocating a pointer that will + * remain unused */ + uint8_t *dummyPtr = NULLP; + MAC_ALLOC_SHRABL_BUF(dummyPtr, sizeof(uint8_t)); + + MAC_ALLOC_SHRABL_BUF(macStatsRsp, sizeof(MacStatsRsp)); + if(macStatsRsp == NULLP) + { + DU_LOG("\nERROR --> MAC : Failed to allocate memory in MacProcSchStatsRsp"); + ret = RFAILED; + } + else + { + memcpy(macStatsRsp, statsRsp, sizeof(MacStatsRsp)); + memset(statsRsp, 0, sizeof(MacStatsRsp)); + + memset(&pst, 0, sizeof(Pst)); + FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_STATISTICS_RSP); + if(((*macDuStatsRspOpts[pst.selector])(&pst, macStatsRsp))!= ROK) + { + DU_LOG("\nERROR --> MAC : Failed to send statistics response to DU APP"); + MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, macStatsRsp, sizeof(MacStatsRsp)); + ret = RFAILED; + } + } + + /* Workaround : Freeing the dummy pointer */ + MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, dummyPtr, sizeof(uint8_t)); + return ret; +} + +/******************************************************************* + * + * @brief Rejects all statistics group requested by DU APP + * + * @details + * + * Function : MacRejectAllStats + * + * Functionality: Add all statistics group received in statistics + * request from DU APP, to Reject-Stats-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 MacRejectAllStats(MacStatsReq *macStatsReq, CauseOfResult cause) +{ + uint8_t grpIdx = 0; + MacStatsRsp macStatsRsp; + + memset(&macStatsRsp, 0, sizeof(MacStatsRsp)); + + /* Copying all stats group from stats request to stats response */ + macStatsRsp.subscriptionId = macStatsReq->subscriptionId; + for(grpIdx = 0; grpIdx < macStatsReq->numStatsGroup; grpIdx++) + { + macStatsRsp.statsGrpRejectedList[grpIdx].groupId = macStatsReq->statsGrpList[grpIdx].groupId; + macStatsRsp.statsGrpRejectedList[grpIdx].cause = cause; + } + macStatsRsp.numGrpRejected = macStatsReq->numStatsGroup; + + return MacSendStatsRspToDuApp(&macStatsRsp); +} + /** * @brief Mac process the statistics Req received from DUAPP * @@ -1022,7 +1120,20 @@ uint8_t MacProcDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq) * * Function : MacProcStatsReq * - * This function process the statistics request from duapp + * This function process the statistics 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] StatsReq *statsReq @@ -1031,85 +1142,196 @@ uint8_t MacProcDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq) **/ uint8_t MacProcStatsReq(Pst *pst, MacStatsReq *macStatsReq) { - uint8_t macStatsIdx = 0, schStatsIdx = 0; - uint8_t ret = RFAILED; - bool measTypeInvalid = false; - Pst schPst; - SchStatsReq *schStatsReq = NULLP; - CauseOfResult cause; + uint8_t macStatsGrpIdx = 0, macStatsIdx = 0, schStatsGrpIdx = 0, schStatsIdx = 0; + uint8_t ret = RFAILED; + bool measTypeInvalid = false; + Pst schPst; + MacStatsGrpInfo *macStatsGrp = NULLP; + SchStatsReq *schStatsReq = NULLP; + MacStatsRsp *macStatsRsp = NULLP; - if(macStatsReq) + DU_LOG("\nINFO --> MAC : Received Statistics Request from DU_APP"); + + if(macStatsReq == NULLP) { - DU_LOG("\nINFO --> MAC : Received Statistics Request from DU_APP"); + DU_LOG("\nERROR --> MAC : MacProcStatsReq(): Received Null pointer"); + return RFAILED; + } + + /* [Step 1] Basic validation. If fails, statistics response is sent to DU APP + * that rejectes all stats */ - MAC_ALLOC(schStatsReq, sizeof(SchStatsReq)); - if(schStatsReq == NULLP) - { - DU_LOG("\nERROR --> MAC : MacProcStatsReq: Failed to allocate memory"); - cause = RESOURCE_UNAVAILABLE; - } - else - { - schStatsReq->numStats = 0; - for(macStatsIdx=0; macStatsIdx < macStatsReq->numStats; macStatsIdx++) - { - /* Checking each measurement type to send only SCH related - * measurement config to SCH - * This will be useful in future when some measurement type will - * be configured for SCH and rest for only MAC */ - switch(macStatsReq->statsList[macStatsIdx].type) - { - case MAC_DL_TOTAL_PRB_USAGE: - { - schStatsReq->statsList[schStatsIdx].type = SCH_DL_TOTAL_PRB_USAGE; - break; - } - case MAC_UL_TOTAL_PRB_USAGE: - { - schStatsReq->statsList[schStatsIdx].type = SCH_UL_TOTAL_PRB_USAGE; - break; - } - default: - { - DU_LOG("\nERROR --> MAC : MacProcStatsReq: Invalid measurement type [%d]", \ - macStatsReq->statsList[macStatsIdx].type); - measTypeInvalid = true; - } - } + /* If number of statistics request for which response is still pending + * towards DU APP has reached its maximum limit */ + if(macCb.statistics.numPendingStatsRsp >= MAX_PENDING_STATS_RSP) + { + DU_LOG("\nERROR --> MAC : MacProcStatsReq: Maximum number of statistics response is pending. \ + Cannot process new request."); + MacRejectAllStats(macStatsReq, RESOURCE_UNAVAILABLE); + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq)); + return RFAILED; + } - if(!measTypeInvalid) - { - schStatsReq->statsList[schStatsIdx].periodicity = macStatsReq->statsList[macStatsIdx].periodicity; - schStatsIdx++; - measTypeInvalid = false; - } - } - schStatsReq->numStats = schStatsIdx; + /* If memory resources are unavailable */ + MAC_ALLOC(schStatsReq, sizeof(SchStatsReq)); + if(schStatsReq == NULLP) + { + DU_LOG("\nERROR --> MAC : MacProcStatsReq: Failed to allocate memory"); + MacRejectAllStats(macStatsReq, RESOURCE_UNAVAILABLE); + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq)); + return RFAILED; + } + + /* Add stats response to pending response list */ + macStatsRsp = &macCb.statistics.pendingStatsRsp[macCb.statistics.numPendingStatsRsp]; + memset(macStatsRsp, 0, sizeof(MacStatsRsp)); - /* If no measurement types are valid, it is failure scenario. - * Even if one measurement type is valid, send to SCH */ - if(schStatsReq->numStats) + /* [Step 2] Traverse all stats group and validate each measurement types in each group */ + schStatsReq->subscriptionId = macStatsReq->subscriptionId; + schStatsReq->numStatsGroup = 0; + for(macStatsGrpIdx = 0; macStatsGrpIdx < macStatsReq->numStatsGroup; macStatsGrpIdx++) + { + measTypeInvalid = false; + schStatsIdx = 0; + macStatsGrp = &macStatsReq->statsGrpList[macStatsGrpIdx]; + + for(macStatsIdx=0; macStatsIdx < macStatsGrp->numStats; macStatsIdx++) + { + /* Validate each measurement type */ + switch(macStatsGrp->statsList[macStatsIdx]) { - FILL_PST_MAC_TO_SCH(schPst, EVENT_STATISTICS_REQ_TO_SCH); - ret = SchMessageRouter(&schPst, (void *)schStatsReq); + case MAC_DL_TOTAL_PRB_USAGE: + { + schStatsReq->statsGrpList[schStatsGrpIdx].statsList[schStatsIdx] = SCH_DL_TOTAL_PRB_USAGE; + break; + } + case MAC_UL_TOTAL_PRB_USAGE: + { + schStatsReq->statsGrpList[schStatsGrpIdx].statsList[schStatsIdx] = SCH_UL_TOTAL_PRB_USAGE; + break; + } + default: + { + DU_LOG("\nERROR --> MAC : MacProcStatsReq: Invalid measurement type [%d]", \ + macStatsGrp->statsList[macStatsIdx]); + measTypeInvalid = true; + } } - else + + /* Even if one measurement type is invalid, this group is rejected */ + if(measTypeInvalid) { - cause = PARAM_INVALID; + memset(&schStatsReq->statsGrpList[schStatsGrpIdx], 0, sizeof(SchStatsGrpInfo)); + break; } + + schStatsIdx++; } - MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq)); + + /* If all measurement type is valid, add group info to send to SCH */ + if(!measTypeInvalid) + { + schStatsReq->statsGrpList[schStatsGrpIdx].groupId = macStatsGrp->groupId; + schStatsReq->statsGrpList[schStatsGrpIdx].periodicity = macStatsGrp->periodicity; + schStatsReq->statsGrpList[schStatsGrpIdx].numStats = schStatsIdx; + schStatsGrpIdx++; + } + else + { + /* [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 */ + macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].groupId = macStatsGrp->groupId; + macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].cause = PARAM_INVALID; + macStatsRsp->numGrpRejected++; + } + } + schStatsReq->numStatsGroup = schStatsGrpIdx; + + macStatsRsp->subscriptionId = macStatsReq->subscriptionId; + + if(schStatsReq->numStatsGroup) + { + /* [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. */ + macCb.statistics.numPendingStatsRsp++; + + FILL_PST_MAC_TO_SCH(schPst, EVENT_STATISTICS_REQ_TO_SCH); + ret = SchMessageRouter(&schPst, (void *)schStatsReq); } else { - DU_LOG("\nERROR --> MAC : MacProcStatsReq(): Received Null pointer"); - cause = PARAM_INVALID; + /* [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. */ + DU_LOG("\nERROR --> MAC : MacProcStatsReq: All statistics group found invalid"); + MAC_FREE(schStatsReq, sizeof(SchStatsReq)); + ret = MacSendStatsRspToDuApp(macStatsRsp); } - if(ret == RFAILED) + MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq)); + return ret; +} + +/** + * @brief Mac process the statistics rsp received from sch. + * + * @details + * + * Function : MacProcSchStatsRsp + * + * This function process the statistics response received from sch + * + * @param[in] Pst *pst + * @param[in] SchStatsRsp *schStatsRsp + * @return int + * -# ROK + **/ +uint8_t MacProcSchStatsRsp(Pst *pst, SchStatsRsp *schStatsRsp) +{ + uint8_t idx = 0, accptdIdx = 0, rjctdIdx = 0; + uint8_t ret = RFAILED; + MacStatsRsp *macStatsRsp = NULLP; + + if(schStatsRsp) { - /* Send negative acknowledgment to DU APP. TBD in next gerrit */ + /* Fetch pointer to statistics response from pending list saved at MAC + * during processing statistics request from DU APP */ + for(idx = 0; idx < macCb.statistics.numPendingStatsRsp; idx++) + { + if(macCb.statistics.pendingStatsRsp[idx].subscriptionId == schStatsRsp->subscriptionId) + { + macStatsRsp = &macCb.statistics.pendingStatsRsp[idx]; + break; + } + } + + if(macStatsRsp == NULLP) + { + MAC_FREE(schStatsRsp, sizeof(SchStatsRsp)); + return RFAILED; + } + + /* Copy Stats-group-accpeted list received from SCH */ + for(accptdIdx = 0; accptdIdxnumGrpAccepted && macStatsRsp->numGrpAcceptedstatsGrpAcceptedList[macStatsRsp->numGrpAccepted++] = schStatsRsp->statsGrpAcceptedList[accptdIdx]; + } + + /* List together all stats group rejected by MAC and by SCH */ + for(rjctdIdx = 0; rjctdIdx < schStatsRsp->numGrpRejected && macStatsRsp->numGrpRejectedstatsGrpRejectedList[macStatsRsp->numGrpRejected].groupId = \ + schStatsRsp->statsGrpRejectedList[rjctdIdx].groupId; + macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].cause = \ + schStatsRsp->statsGrpRejectedList[rjctdIdx].cause; + macStatsRsp->numGrpRejected++; + } + + /* Send statistics response to DU APP */ + ret = MacSendStatsRspToDuApp(macStatsRsp); } + MAC_FREE(schStatsRsp, sizeof(SchStatsRsp)); return ret; }