+/*******************************************************************
+ *
+ * @brief Fill RIC Subscription datils in MAC Statistics Request
+ *
+ * @details
+ *
+ * Function : fillRicSubsInMacStatsReq
+ *
+ * Functionality: Fill RIC Subscription datils in MAC Statistics
+ * Request
+ *
+ * @params[in] MAC Statistics Request to be filled
+ * RAN Function ID
+ * RIC Subscription Info
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, uint16_t ranFuncId, RicSubscription* ricSubscriptionInfo)
+{
+ uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0;
+ uint64_t subscriptionId = 0;
+ ActionInfo *actionDb = NULLP;
+ ActionDefFormat1 *format1Action = NULLP;
+
+ /* Generate subscription ID using RIC Request ID and RAN Function ID */
+ encodeSubscriptionId(&subscriptionId, ranFuncId, ricSubscriptionInfo->requestId);
+
+ macStatsReq->subscriptionId = subscriptionId;
+ for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
+ {
+ if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
+ {
+ actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
+ macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
+ switch(actionDb->definition.formatType)
+ {
+ case 1:
+ {
+ format1Action = &actionDb->definition.choice.format1;
+ macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
+
+ CmLList *node = NULLP;
+ MeasurementInfo *measInfo = NULLP;
+ statsIdx = 0;
+ /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
+ node = cmLListFirst(&format1Action->measurementInfoList);
+ while(node)
+ {
+ measInfo = (MeasurementInfo *)(node->node);
+ switch(measInfo->measurementTypeId)
+ {
+ case 1:
+ {
+ macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
+ break;
+ }
+ case 2:
+ {
+ macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> DU_APP : Invalid measurement name");
+ break;
+ }
+ }
+ node = node->next;
+ }
+ macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
+ break;
+ }
+ }
+ if(macStatsReq->statsGrpList[grpIdx].numStats)
+ grpIdx++;
+ }
+ }
+
+ macStatsReq->numStatsGroup = grpIdx;
+ if(macStatsReq->numStatsGroup)
+ {
+ return ROK;
+ }
+ return RFAILED;
+}
+
+/*******************************************************************
+ *
+ * @brief Rejects all actions received in a subscription request
+ *
+ * @details
+ *
+ * Function : duRejectAllStatsGroup
+ *
+ * Functionality: Rejects all actions received in a subscription
+ * request by :
+ * a. Removing the subscription entry from RAN function
+ * b. Sending RIC Subscription Failure to RIC with appropriate
+ * cause of failure
+ *
+ * @params[in] RAN Function DB
+ * Subscription entry in RAN Function subscription list
+ * Statistics Response from MAC
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t rejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp)
+{
+ uint8_t ret = ROK;
+ RicRequestId requestId;
+ E2FailureCause failureCause;
+
+ /* Delete subcription from RAN Function */
+ memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId));
+ cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode);
+ DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription));
+ DU_FREE(ricSubscriptionNode, sizeof(CmLList));
+
+ convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause);
+
+ /* Send RIC subscription failure to RIC */
+ ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause);
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Process statistics response from MAC
+ *
+ * @details
+ *
+ * Function : e2ProcStatsRsp
+ *
+ * Functionality: Processes statistics configuration response
+ * from MAC. If configuration is succsessful, DUAPP starts
+ * reporting period timer for this subscription request
+ * from RIC
+ *
+ * @params[in]
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+void e2ProcStatsRsp(MacStatsRsp *statsRsp)
+{
+ uint8_t idx = 0;
+ uint8_t actionId = 0;
+ RanFunction *ranFuncDb = NULLP;
+ CmLList *ricSubscriptionNode = NULLP;
+ RicSubscription *ricSubscriptionInfo = NULLP;
+ ActionInfo *actionInfoDb = NULLP;
+ PendingSubsRspInfo *pendingSubsRsp = NULLP;
+
+ /* Fetch RAN Function and Subscription DB using subscription Id received in statistics response */
+ if(fetchSubsInfoFromSubsId(statsRsp->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
+ {
+ DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Failed to fetch subscriprtion details");
+ return;
+ }
+
+ /* Fetch pre-stored statistics response info by DU APP */
+ for(idx=0; idx<ranFuncDb->numPendingSubsRsp; idx++)
+ {
+ if((ranFuncDb->pendingSubsRspInfo[idx].requestId.requestorId == ricSubscriptionInfo->requestId.requestorId) &&
+ (ricSubscriptionInfo->requestId.instanceId == ricSubscriptionInfo->requestId.instanceId))
+ {
+ pendingSubsRsp = &ranFuncDb->pendingSubsRspInfo[idx];
+ break;
+ }
+ }
+
+ /* If no action is accepted
+ * a. Remove subcription entry from RAN Function
+ * b. Send RIC subscription failure */
+ if(statsRsp->numGrpAccepted == 0)
+ {
+ rejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp);
+ }
+ else
+ {
+ /* If even 1 action is accepted :
+ *
+ * For accepted groups:
+ * Mark subscribed-action's -> action = CONFIG_UNKNOWN
+ * Add to accepted-action-list of subscription response
+ */
+ for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
+ {
+ actionInfoDb = NULLP;
+
+ actionId = statsRsp->statsGrpAcceptedList[idx];
+ actionInfoDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo);
+ if(actionInfoDb && (actionInfoDb->action == CONFIG_ADD))
+ {
+ actionInfoDb->action = CONFIG_UNKNOWN;
+ pendingSubsRsp->acceptedActionList[pendingSubsRsp->numOfAcceptedActions++] = actionId;
+ }
+ }
+
+ /* For rejected groups:
+ * Remove entry from DU's RAN Function->subscription->actionList
+ * Add to rejected-action-list in subscription response
+ */
+ for(idx=0; idx<statsRsp->numGrpRejected; idx++)
+ {
+ actionId = statsRsp->statsGrpRejectedList[idx].groupId;
+ if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId)
+ {
+ memset(&ricSubscriptionInfo->actionSequence[actionId-1], 0, sizeof(ActionInfo));
+ ricSubscriptionInfo->numOfActions--;
+
+ pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].id = actionId;
+ convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[idx].cause, \
+ &pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].failureCause);
+ pendingSubsRsp->numOfRejectedActions++;
+ }
+ }
+
+ /* Send subscription response with accepted and rejected action lists to RIC */
+ BuildAndSendRicSubscriptionRsp(pendingSubsRsp);
+ }
+ memset(pendingSubsRsp, 0, sizeof(PendingSubsRspInfo));
+}
+
+/*******************************************************************
+ *
+ * @brief Extract and store statistics received from DU layers
+ *
+ * @details
+ *
+ * Function : e2ProcStatsInd
+ *
+ * Functionality: Extract statistics received from DU layers
+ * and store in respective RAN function's subscription's
+ * action
+ *
+ * @params[in] Statistics Indication message received from MAC
+ * @return void
+ *
+ * ****************************************************************/
+void e2ProcStatsInd(MacStatsInd *statsInd)
+{
+ RanFunction *ranFuncDb = NULLP;
+ CmLList *ricSubscriptionNode = NULLP;
+ RicSubscription *ricSubscriptionInfo = NULLP;
+
+ /* TODO : When stats indication is received
+ * DU APP searches for the message type in E2AP RIC subscription
+ * database and stores in the value in the list of subscribed measurements
+ *
+ * This will be implemented in next gerrit.
+ */
+
+ /* Fetch RAN Function and Subscription DB using subscription Id received
+ * in statistics response */
+ if(fetchSubsInfoFromSubsId(statsInd->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
+ {
+ DU_LOG("\nERROR --> DU_APP : extractStatsMeasurement: Failed to fetch subscriprtion details");
+ return;
+ }
+}
+