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
/**********************************************************************
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
*
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; accptdIdx<schStatsModificationRsp->numGrpAccepted && macStatsModificationRsp->numGrpAccepted<MAX_NUM_STATS_GRP; accptdIdx++)
+ {
+ macStatsModificationRsp->statsGrpAcceptedList[macStatsModificationRsp->numGrpAccepted++] = schStatsModificationRsp->statsGrpAcceptedList[accptdIdx];
+ }
+
+ /* [Step -3] */
+ for(rjctdIdx = 0; rjctdIdx < schStatsModificationRsp->numGrpRejected && macStatsModificationRsp->numGrpRejected<MAX_NUM_STATS_GRP; rjctdIdx++)
+ {
+ macStatsModificationRsp->statsGrpRejectedList[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
**********************************************************************/
unpackMacStatsDeleteReq(MacProcStatsDeleteReq, pst, mBuf);
break;
}
+ case EVENT_MAC_STATISTICS_MODIFY_REQ:
+ {
+ /* Process Statistics modification Request */
+ unpackMacStatsModificationReq(MacProcStatsModificationReq, pst, mBuf);
+ break;
+ }
default:
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;
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;
MacProcSchStatsDeleteRsp(pst, (SchStatsDeleteRsp *)msg);
break;
}
+ case EVENT_STATISTICS_MODIFY_RSP_TO_MAC:
+ {
+ MacProcSchStatsModificationRsp(pst, (SchStatsModificationRsp *)msg);
+ break;
+ }
default:
{
return RFAILED;
* 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;
}
* 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.
*
* ****************************************************************/
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");
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. \
memset(&schStatsRsp, 0, sizeof(SchStatsRsp));
- /* [Step 2] Traverse all stats group and validate each measurement types in each group */
+ /*Step -2*/
for(reqGrpIdx=0; reqGrpIdx<statsReq->numStatsGroup && grpIdx<MAX_NUM_STATS; reqGrpIdx++)
{
- measTypeInvalid = false;
grpInfo = &statsReq->statsGrpList[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 */
+}
/*******************************************************************
*
/*******************************************************************
*
- * @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));
{
/* [Step 3] */
cmLListDelFrm(statsGrpList, grpNode);
- deleteStatsGrp(inst, grpNode);
+ deleteStatsGrpNode(inst, grpNode);
}
else
{
if(statsGrpInfo->groupId== groupId)
{
cmLListDelFrm(statsGrpList, grpNode);
- deleteStatsGrp(inst, grpNode);
+ deleteStatsGrpNode(inst, grpNode);
statsFound = true;
}
}
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; reqGrpIdx<statsModificationReq->numStatsGroup; 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
**********************************************************************/
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
**********************************************************************/
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;
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);
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;
}
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
**********************************************************************/
#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
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*/
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);
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
#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 */
SchStatsGrpInfo statsGrpList[MAX_NUM_STATS_GRP];
}SchStatsReq;
+typedef struct schStatsReq SchStatsModificationReq;
+typedef struct schStatsRsp SchStatsModificationRsp;
+
/* Statistics Response from SCH to MAC */
typedef struct schStatsGrpRejected
{
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
**********************************************************************/
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
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");
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");
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
*
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; idx<statsModificationRsp->numGrpAccepted; idx++)
+ {
+ DU_LOG("\n Group Id [%d]", statsModificationRsp->statsGrpAcceptedList[idx]);
+ }
+
+ DU_LOG("\n Number of Rejected Groups [%d]", statsModificationRsp->numGrpRejected);
+ for(idx=0; idx<statsModificationRsp->numGrpRejected; 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
**********************************************************************/