################################################################################
*******************************************************************************/
#include "common_def.h"
+#include <sys/time.h>
#include "du_tmr.h"
#include "lrg.h"
#include "lkw.x"
*subscriptionId |= ((uint64_t)ranFuncId << 32);
}
+/*******************************************************************
+ *
+ * @brief Stores the current time at the start of reporting period
+ *
+ * @details
+ *
+ * Function : storeReportStartTime
+ *
+ * Functionality: Stores the current time at the start of
+ * reporting period
+ *
+ * @params[in] Start Timer to be stored
+ * @return Void
+ *
+ * ****************************************************************/
+void storeReportStartTime(ReportStartTime *startTime)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ startTime->timeInSec = tv.tv_sec;
+ startTime->timeInMilliSec = (tv.tv_usec/1000);
+}
+
+
+/*******************************************************************
+ *
+ * @brief Fetch Measurement Info using measurement type name
+ *
+ * @details
+ *
+ * Function : fetchMeasInfoFromMeasTypeName
+ *
+ * Functionality: Fetch Measurement Info using measurement type name
+ *
+ * @params[in] Measurement type name to search
+ * Measurement Info list to search from
+ * Measurement Info node found from list
+ * @return Measurement Info DB
+ *
+ * ****************************************************************/
+MeasurementInfo *fetchMeasInfoFromMeasTypeName(char *e2MeasTypeName, CmLListCp *measInfoList, CmLList **measInfoNode)
+{
+ MeasurementInfo *measInfo = NULLP;
+
+ /* Fetch subscription detail in RAN Function DB */
+ CM_LLIST_FIRST_NODE(measInfoList, *measInfoNode);
+ while(*measInfoNode)
+ {
+ measInfo = (MeasurementInfo *)((*measInfoNode)->node);
+ if(measInfo && !strcmp(e2MeasTypeName, measInfo->measurementTypeName))
+ {
+ break;
+ }
+ *measInfoNode = (*measInfoNode)->next;
+ measInfo = NULLP;
+ }
+
+ if(!measInfo)
+ {
+ DU_LOG("\nERROR --> E2AP : fetchMeasInfoFromMeasTypeName: Measurement [%s] not found", e2MeasTypeName);
+ }
+
+ return measInfo;
+}
+
/*******************************************************************
*
* @brief Fetch Action details
ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSubscriptionInfo)
{
ActionInfo *actionInfoDb = NULLP;
- if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId)
+ if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId)
{
- actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId-1];
+ actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId];
}
else
{
- DU_LOG("\nERROR --> DU_APP : fetchActionInfoFromActionId: Action Id [%d] not found in \
+ DU_LOG("\nERROR --> E2AP : fetchActionInfoFromActionId: Action Id [%d] not found in \
subscription info [Requestor id : %d] [Instance Id : %d]", actionId,\
ricSubscriptionInfo->requestId.requestorId, ricSubscriptionInfo->requestId.instanceId);
if(!ricSubscriptionInfo)
{
- DU_LOG("\nERROR --> DU_APP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
+ DU_LOG("\nERROR --> E2AP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id);
}
}
else
{
- DU_LOG("\nERROR --> DU_APP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
+ DU_LOG("\nERROR --> E2AP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
}
return ranFuncDb;
* 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 fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, RicSubscription* ricSubscriptionInfo)
{
uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0;
uint64_t subscriptionId = 0;
ActionDefFormat1 *format1Action = NULLP;
/* Generate subscription ID using RIC Request ID and RAN Function ID */
- encodeSubscriptionId(&subscriptionId, ranFuncId, ricSubscriptionInfo->requestId);
+ encodeSubscriptionId(&subscriptionId, ricSubscriptionInfo->ranFuncId, ricSubscriptionInfo->requestId);
macStatsReq->subscriptionId = subscriptionId;
- for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
+ for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
{
if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
{
actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
- macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
+ macStatsReq->statsGrpList[grpIdx].groupId = actionDb->actionId;
switch(actionDb->definition.formatType)
{
case 1:
}
default:
{
- DU_LOG("\nERROR --> DU_APP : Invalid measurement name");
+ DU_LOG("\nERROR --> E2AP : Invalid measurement name");
break;
}
}
}
default:
{
- DU_LOG("\nERROR --> DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
+ DU_LOG("\nERROR --> E2AP : fillRicSubsInMacStatsReq: Only Action Definition Format 1 supported");
break;
}
}
* reporting period timer for this subscription request
* from RIC
*
- * @params[in]
+ * @params[in] Statistics response received from MAC
*
* @return ROK - success
* RFAILED - failure
*
* ****************************************************************/
-void e2ProcStatsRsp(MacStatsRsp *statsRsp)
+uint8_t e2ProcStatsRsp(MacStatsRsp *statsRsp)
{
uint8_t idx = 0;
uint8_t actionId = 0;
+ uint32_t reportingPeriod = 0;
RanFunction *ranFuncDb = NULLP;
CmLList *ricSubscriptionNode = NULLP;
RicSubscription *ricSubscriptionInfo = 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;
+ DU_LOG("\nERROR --> E2AP : DuProcMacStatsRsp: Failed to fetch subscriprtion details");
+ return RFAILED;
}
/* Fetch pre-stored statistics response info by DU APP */
}
else
{
+ /* Start RIC Subscription reporting timer */
+ switch(ricSubscriptionInfo->eventTriggerDefinition.formatType)
+ {
+ case 1:
+ {
+ reportingPeriod = ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod;
+
+ /* Save the start time of reporting period */
+ storeReportStartTime(&ricSubscriptionInfo->eventTriggerDefinition.choice.format1.startTime);
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> E2AP : Invalid event trigger format of RIC subscription");
+ return RFAILED;
+ }
+ }
+ if(duChkTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) != true)
+ {
+ duStartTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR, reportingPeriod);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> E2AP : RIC Subscription reporting timer already running for RIC Subscription");
+ return RFAILED;
+ }
+
+
/* If even 1 action is accepted :
*
* For accepted groups:
for(idx=0; idx<statsRsp->numGrpRejected; idx++)
{
actionId = statsRsp->statsGrpRejectedList[idx].groupId;
- if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId)
+ if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId)
{
- memset(&ricSubscriptionInfo->actionSequence[actionId-1], 0, sizeof(ActionInfo));
+ memset(&ricSubscriptionInfo->actionSequence[actionId], 0, sizeof(ActionInfo));
ricSubscriptionInfo->numOfActions--;
pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].id = actionId;
BuildAndSendRicSubscriptionRsp(pendingSubsRsp);
}
memset(pendingSubsRsp, 0, sizeof(PendingSubsRspInfo));
+ return ROK;
}
/*******************************************************************
* action
*
* @params[in] Statistics Indication message received from MAC
- * @return void
+ * @return ROK-success
+ * RFAILED-failure
*
* ****************************************************************/
-void e2ProcStatsInd(MacStatsInd *statsInd)
+uint8_t e2ProcStatsInd(MacStatsInd *statsInd)
{
+ uint8_t statsIdx = 0;
RanFunction *ranFuncDb = NULLP;
CmLList *ricSubscriptionNode = NULLP;
RicSubscription *ricSubscriptionInfo = NULLP;
+ ActionInfo *actionInfo = NULLP;
+ ActionDefFormat1 *actionFormat = NULLP;
+ char e2MeasTypeName[STRING_SIZE_150_BYTES] = "";
+ MeasurementInfo *measInfo = NULLP;
+ CmLList *measInfoNode = NULLP;
+ double *measValue = NULLP;
+ CmLList *measValueNode = NULLP;
/* TODO : When stats indication is received
* DU APP searches for the message type in E2AP RIC subscription
* in statistics response */
if(fetchSubsInfoFromSubsId(statsInd->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
{
- DU_LOG("\nERROR --> DU_APP : extractStatsMeasurement: Failed to fetch subscriprtion details");
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to fetch subscriprtion details");
+ return RFAILED;
+ }
+
+ /* Fetch RIC subscription's action DB */
+ actionInfo = fetchActionInfoFromActionId(statsInd->groupId, ricSubscriptionInfo);
+ if(actionInfo == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to fetch action ID [%d]", statsInd->groupId);
+ return RFAILED;
+ }
+
+ /* Check Action format */
+ switch(actionInfo->definition.formatType)
+ {
+ case 1:
+ {
+ actionFormat = &actionInfo->definition.choice.format1;
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Action Format [%d] is not supported", \
+ actionInfo->definition.formatType);
+ return RFAILED;
+ }
+ }
+
+ /* Fetch each Measurement info from action info and store its reported value in DB */
+ for(statsIdx = 0; statsIdx < statsInd->numStats; statsIdx++)
+ {
+ memset(e2MeasTypeName, 0, STRING_SIZE_150_BYTES);
+ measInfo = NULLP;
+ measInfoNode = NULLP;
+
+ /* Convert Measurement type from MAC-supported format to E2-supported format */
+ if(convertMacMeasTypeToE2MeasType(statsInd->measuredStatsList[statsIdx].type, e2MeasTypeName) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to convert measurement type from MAC-supported\
+ MAC-supported format to E2-supported format");
+ continue;
+ }
+
+ /* Fetch Measurement Info using E2-supported measurement type name */
+ measInfo = fetchMeasInfoFromMeasTypeName(e2MeasTypeName, &actionFormat->measurementInfoList, &measInfoNode);
+ if(measInfo == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Measurement Type Name [%s] not found", e2MeasTypeName);
+ continue;
+ }
+
+ /* Store the measurement value in the measurement info DB fetched */
+ DU_ALLOC(measValue, sizeof(double));
+ if(!measValue)
+ {
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Memory allocation failed at line [%d]", __LINE__);
+ return RFAILED;
+ }
+ *measValue = statsInd->measuredStatsList[statsIdx].value;
+
+ DU_ALLOC(measValueNode, sizeof(CmLList));
+ if(!measValueNode)
+ {
+ DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Memory allocation failed at line [%d]", __LINE__);
+ DU_FREE(measValue, sizeof(double));
+ return RFAILED;
+ }
+ measValueNode->node = (PTR) measValue;
+ cmLListAdd2Tail(&measInfo->measuredValue, measValueNode);
+ }
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Handle RIC Subscription reporting timer expry
+ *
+ * @details
+ *
+ * Function : E2apHdlRicSubsReportTmrExp
+ *
+ * Functionality: On expiry of RIC subscription reporting
+ * timer expiry, RIC indication is sent for all actions
+ * in RIC subscription
+ *
+ * @params[in] RIC subscription DB
+ * @return void
+ *
+ * ****************************************************************/
+void E2apHdlRicSubsReportTmrExp(RicSubscription *ricSubscription)
+{
+ uint8_t actionIdx = 0;
+ uint32_t reportingPeriod = 0;
+
+ for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
+ {
+ if(ricSubscription->actionSequence[actionIdx].actionId >= 0)
+ {
+ BuildAndSendRicIndication(ricSubscription, &ricSubscription->actionSequence[actionIdx]);
+ }
+ }
+
+ /* Start RIC Subscription reporting timer again */
+ switch(ricSubscription->eventTriggerDefinition.formatType)
+ {
+ case 1:
+ {
+ reportingPeriod = ricSubscription->eventTriggerDefinition.choice.format1.reportingPeriod;
+ /* Save the start time of reporting period */
+ storeReportStartTime(&ricSubscription->eventTriggerDefinition.choice.format1.startTime);
+ break;
+ }
+ default:
+ return;
+ }
+ if(duChkTmr((PTR)ricSubscription, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) != true)
+ {
+ duStartTmr((PTR)ricSubscription, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR, reportingPeriod);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> E2AP : Failed in %s at line %d", __func__, __LINE__);
return;
}
}
#include "E2SM-KPM-ActionDefinition-Format1.h"
#include "MeasurementInfoItem.h"
#include "RANfunctionsIDcause-List.h"
+#include "MeasurementRecord.h"
+#include "MeasurementData.h"
+#include "MeasurementRecordItem.h"
+#include "MeasurementDataItem.h"
+#include "E2SM-KPM-IndicationMessage-Format1.h"
+#include "E2SM-KPM-IndicationMessage.h"
+#include "E2SM-KPM-IndicationHeader.h"
+#include "E2SM-KPM-IndicationHeader-Format1.h"
+#include "LabelInfoItem.h"
/*******************************************************************
*
if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report)
{
- ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId;
- ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT;
+ ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId;
+ ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT;
- if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \
+ if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \
actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK)
{
- ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD;
+ ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD;
ricSubscriptionInfo->numOfActions++;
break;
}
/* In case of any failure, action is rejected
* Added to rejected-action-list in subscription response */
- memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo));
+ memset(&ricSubscriptionInfo->actionSequence[ricActionId], 0, sizeof(ActionInfo));
+ ricSubscriptionInfo->actionSequence[ricActionId].actionId = -1;
+
subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId;
if(failureCause->causeType == E2_NOTHING)
{
* ****************************************************************/
uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg)
{
- uint8_t idx = 0;
+ uint8_t idx = 0, actionIdx = 0;
uint8_t ret = ROK;
uint16_t ranFuncId = 0;
RicRequestId ricReqId;
}
ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId;
ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId;
+ ricSubscriptionInfo->ranFuncId = ranFuncId;
+
+ for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
+ {
+ ricSubscriptionInfo->actionSequence[actionIdx].actionId = -1;
+ }
memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo));
memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId,
if(ret == ROK)
{
+ cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1);
+
/* Add RAN subcription detail to RAN function */
DU_ALLOC(ricSubscriptionNode, sizeof(CmLList));
if(ricSubscriptionNode)
#ifdef KPI_CALCULATION
/* Send statistics request to other DU entities */
- BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo);
+ BuildAndSendStatsReq(ricSubscriptionInfo);
#endif
-
- /* TODO : Trigger RIC Indication once statistics indication is
- * received from MAC .
- * TBD in future gerrit */
- //BuildAndSendRicIndication(ricSubscriptionInfo);
}
else
{
switch(ricIndicationMsg->protocolIEs.list.array[idx]->id)
{
case ProtocolIE_IDE2_id_RICrequestID:
- break;
-
case ProtocolIE_IDE2_id_RANfunctionID:
- break;
-
case ProtocolIE_IDE2_id_RICactionID:
- break;
-
case ProtocolIE_IDE2_id_RICindicationType:
break;
/*******************************************************************
*
- * brief Fill the RicIndication Message
+ * @brief Free measurement record
*
* @details
*
- * Function : FillRicIndication
+ * Function : freeMeasRecord
*
- * Functionality:Fills the RicIndication Message
+ * Functionality: Free all measurement recorded for a measurement
+ * within an action in a RIC subscription
+ *
+ * @param Measurement data to be freed
+ * @return void
+ *
+ ******************************************************************/
+void freeMeasData(MeasurementData_t *measData)
+{
+ uint8_t measIdx = 0, measRecIdx = 0;
+ MeasurementRecord_t *measRecord = NULLP;
+
+ if(measData->list.array)
+ {
+ for(measIdx = 0; measIdx < measData->list.count; measIdx++)
+ {
+ if(measData->list.array[measIdx])
+ {
+ measRecord = &measData->list.array[measIdx]->measRecord;
+ if(measRecord->list.array)
+ {
+ for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
+ {
+ DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
+ }
+ DU_FREE(measRecord->list.array, measRecord->list.size);
+ }
+ DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
+ }
+ }
+ DU_FREE(measData->list.array, measData->list.size);
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Fill measurement info list
+ *
+ * @details
+ *
+ * Function : freeMeasInfoList
+ *
+ * Functionality: Fills all measurement info within an action
+ * in a RIC subscription
+ *
+ * @param Measurement Info list to be freed
+ * @return void
+ *
+ ******************************************************************/
+void freeMeasInfoList(MeasurementInfoList_t *measInfoList)
+{
+ uint8_t measInfoIdx = 0;
+
+ if(measInfoList->list.array)
+ {
+ for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++)
+ {
+ if(measInfoList->list.array[measInfoIdx])
+ {
+ DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \
+ measInfoList->list.array[measInfoIdx]->measType.choice.measName.size);
+
+ DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size);
+ }
+ }
+ DU_FREE(measInfoList->list.array, measInfoList->list.size);
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Free E2SM-KPM Indication Message
+ *
+ * @details
*
+ * Function : FreeE2smKpmIndicationMessage
+ *
+ * Functionality: Free E2SM-KPM Indication Message
+ *
+ * @param E2SM-KPM Indication message to be freed
+ * @return void
+ *
+ ******************************************************************/
+void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg)
+{
+ E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP;
+
+ switch(e2smKpmIndMsg->indicationMessage_formats.present)
+ {
+ case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
+ {
+ if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1)
+ {
+ format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1;
+
+ /* Measurement Data */
+ freeMeasData(&format1Msg->measData);
+
+ /* Measurement Info List */
+ if(format1Msg->measInfoList)
+ {
+ freeMeasInfoList(format1Msg->measInfoList);
+ DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
+ }
+
+ /* Granularity Period */
+ DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
+
+ DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t));
+ }
+ break;
+ }
+
+ case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
+ case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
+ default:
+ break;
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Fill measurement record
+ *
+ * @details
+ *
+ * Function : fillMeasRecord
+ *
+ * Functionality: Fills all measurement value for a measurement
+ * within an action in a RIC subscription
+ *
+ * @param Measurement record to be filled
+ * Measurement database with measurement records
* @return ROK - success
* RFAILED - failure
*
******************************************************************/
-uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo)
+uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb)
{
- uint8_t elementCnt=0;
- uint8_t idx=0;
+ uint8_t measRecIdx = 0;
+ CmLList *measValNode = NULLP;
+ double measVal = 0;
+
+ measRecord->list.count = measInfoDb->measuredValue.count;
+ measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *);
+
+ DU_ALLOC(measRecord->list.array, measRecord->list.size);
+ if(!measRecord->list.array)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++)
+ {
+ DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t));
+ if(!measRecord->list.array[measRecIdx])
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+ }
+
+ measRecIdx = 0;
+ CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
+ while(measValNode)
+ {
+ measVal = *(double *)measValNode->node;
+ if(measVal == (int)measVal)
+ {
+ measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer;
+ measRecord->list.array[measRecIdx]->choice.integer = (int)measVal;
+ }
+ else
+ {
+ measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real;
+ measRecord->list.array[measRecIdx]->choice.real = measVal;
+ }
+ measRecIdx++;
+
+ /* Once the measurement record is added to the message, delete it from DB */
+ cmLListDelFrm(&measInfoDb->measuredValue, measValNode);
+ DU_FREE(measValNode->node, sizeof(double));
+ DU_FREE(measValNode, sizeof(CmLList));
+
+ CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode);
+ measVal = 0;
+ }
+
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Fills measuerement data
+ *
+ * @details
+ *
+ * Function : fillMeasData
+ *
+ * Functionality: Fill all measurement recorded for all measurements
+ * in an action in a RIC subscription
+ *
+ * @param Measurement data to be filled
+ * Measurement info list from an action DB
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb)
+{
+ uint8_t measIdx = 0;
+ CmLList *measInfoNode = NULLP;
+ MeasurementInfo *measInfoDb = NULLP;
+ MeasurementRecord_t *measRecord = NULLP;
+
+ measData->list.count = measInfoListDb->count;
+ measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *);
+
+ DU_ALLOC(measData->list.array, measData->list.size);
+ if(!measData->list.array)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ measIdx = 0;
+ CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
+ while(measInfoNode)
+ {
+ measInfoDb = (MeasurementInfo *)measInfoNode->node;
+ if(measInfoDb)
+ {
+ DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t));
+ if(!measData->list.array[measIdx])
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ measRecord = &measData->list.array[measIdx]->measRecord;
+ if(fillMeasRecord(measRecord, measInfoDb) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to fill measurement record");
+ return RFAILED;
+ }
+ measIdx++;
+ }
+ measInfoNode = measInfoNode->next;
+ }
+
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Fill all measurement info
+ *
+ * @details
+ *
+ * Function : fillMeasInfoList
+ *
+ * Functionality: Fills all measurement info belonging to an action
+ * in a RIC subscription
+ *
+ * @param Measurement Info list to be filled
+ * Measurement Info list from E2AP DB
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb)
+{
+ uint8_t measInfoIdx = 0;
+ CmLList *measInfoNode = NULLP;
+ MeasurementInfo *measInfoDb = NULLP;
+ MeasurementInfoItem_t *measInfoItem = NULLP;
+
+ measInfoList->list.count = measInfoListDb->count;
+ measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *);
+
+ DU_ALLOC(measInfoList->list.array, measInfoList->list.size);
+ if(!measInfoList->list.array)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ measInfoIdx = 0;
+ CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode);
+ while(measInfoNode)
+ {
+ DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t));
+ if(!measInfoList->list.array[measInfoIdx])
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ measInfoItem = measInfoList->list.array[measInfoIdx];
+ measInfoDb = (MeasurementInfo *)measInfoNode->node;
+ if(measInfoDb)
+ {
+ /* Measurement Type */
+ measInfoItem->measType.present = MeasurementType_PR_measName;
+ measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName);
+
+ DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size);
+ if(!measInfoItem->measType.choice.measName.buf)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\
+ measInfoItem->measType.choice.measName.size);
+
+ measInfoIdx++;
+ }
+ measInfoNode = measInfoNode->next;
+ measInfoDb = NULLP;
+ }
+
+ return ROK;
+}
+
+ /*******************************************************************
+ *
+ * @brief Fill E2SM-KPM Indication Message Format 1
+ *
+ * @details
+ *
+ * Function : fillE2smKpmIndMsgFormat1
+ *
+ * Functionality: Fill E2SM-KPM Indication Message Format 1
+ *
+ * @param Format 1 Message to be filled
+ * Action Definition format 1 from E2AP DB
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1)
+{
+ /* Measurement Data */
+ if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to fill measurement data");
+ return RFAILED;
+ }
+
+ /* Measurement Information */
+ DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t));
+ if(!format1Msg->measInfoList)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+
+ if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to fill measurement information list");
+ return RFAILED;
+ }
+
+ /* Granularity Period */
+ DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t));
+ if(!format1Msg->granulPeriod)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
+ }
+ *(format1Msg->granulPeriod) = format1->granularityPeriod;
+
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Fill RIC Indication Message buffer
+ *
+ * @details
+ *
+ * Function : fillRicIndMsgBuf
+ *
+ * Functionality: Fill E2SM-KPM Indication Message
+ * Encode this message and copy to RIC Indication Message buffer
+ *
+ * @param RIC Indication Message buffer to be filled
+ * Source action info from E2AP DB
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo)
+{
+ uint8_t ret = RFAILED;
+ bool failedInFormat = false;
+ E2SM_KPM_IndicationMessage_t e2smKpmIndMsg;
+ asn_enc_rval_t encRetVal; /* Encoder return value */
+
+ memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t));
+
+ while(true)
+ {
+ /* E2SM-KPM Indication message format type */
+ e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType;
+ switch(e2smKpmIndMsg.indicationMessage_formats.present)
+ {
+ case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1:
+ {
+ /* E2SM-KPM Indication message format 1 */
+ DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
+ sizeof(E2SM_KPM_IndicationMessage_Format1_t));
+ if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ failedInFormat = true;
+ break;
+ }
+
+ if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \
+ &actionInfo->definition.choice.format1) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to fill E2SM-KPM Indication message format 1");
+ failedInFormat = true;
+ break;
+ }
+ break;
+ }
+
+ case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING:
+ case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2:
+ default:
+ {
+ DU_LOG("\nERROR --> E2AP : fillRicIndMsgBuf: Only Format 1 supported");
+ failedInFormat = true;
+ break;
+ }
+ }
+
+ if(failedInFormat)
+ break;
+
+ /* Encode E2SM-KPM Indication Message */
+ xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg);
+ memset(encBuf, 0, ENC_BUF_MAX_LEN);
+ encBufSize = 0;
+ encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf);
+ if(encRetVal.encoded == ENCODE_FAIL)
+ {
+ DU_LOG("\nERROR --> E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
+ }
+ else
+ {
+ DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SM-KPM Indication Message \n");
+#ifdef DEBUG_ASN_PRINT
+ for(int i=0; i< encBufSize; i++)
+ {
+ printf("%x",encBuf[i]);
+ }
+#endif
+ }
+
+ /* Copy encoded string to RIC Indication Message buffer */
+ ricIndMsgBuf->size = encBufSize;
+ DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size);
+ if(!ricIndMsgBuf->buf)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ break;
+ }
+ memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size);
+ memcpy(ricIndMsgBuf->buf, encBuf, encBufSize);
+
+ ret = ROK;
+ break;
+ }
+
+ /* Free E2SM-KPM Indication Message */
+ FreeE2smKpmIndicationMessage(&e2smKpmIndMsg);
+
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Free E2SM-KPM Indication Header
+ *
+ * @details
+ *
+ * Function : FreeE2smKpmIndicationHeader
+ *
+ * Functionality: Free E2SM-KPM Indication Header
+ *
+ * @param E2SM-KPM Indication Header to be free
+ * @return void
+ *
+ ******************************************************************/
+void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr)
+{
+ E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
+
+ if(e2smKpmIndHdr)
+ {
+ switch(e2smKpmIndHdr->indicationHeader_formats.present)
+ {
+ case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
+ {
+ if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1)
+ {
+ format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1;
+
+ DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size);
+ DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t));
+ }
+ break;
+ }
+ case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
+ default:
+ break;
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Fill RIC Indication Header buffer
+ *
+ * @details
+ *
+ * Function : fillRicIndHeader
+ *
+ * Functionality: Fill E2SM-KPM Indication Header
+ * Encode this message and copy to RIC Indication Header buffer
+ *
+ * @param RIC Indication Header buffer to be filled
+ * Source RIC subscription info from E2AP DB
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo)
+{
+ uint8_t ret = RFAILED;
+ uint8_t secBufIdx = 0, milliSecBufIdx = 0;
+ int8_t byteIdx = 0;
+ bool formatFailure = false;
+ RanFunction *ranFunc = NULLP;
+ ReportStartTime *startTime = NULLP;
+ E2SM_KPM_IndicationHeader_t e2smKpmIndHdr;
+ E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP;
+ asn_enc_rval_t encRetVal; /* Encoder return value */
+
+ while(true)
+ {
+ ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId);
+ if(ranFunc == NULLP)
+ {
+ DU_LOG("\nERROR --> E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId);
+ break;
+ }
+
+ memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t));
+
+ e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat;
+ switch(e2smKpmIndHdr.indicationHeader_formats.present)
+ {
+ case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1:
+ {
+ DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \
+ sizeof(E2SM_KPM_IndicationHeader_Format1_t));
+ if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ formatFailure = true;
+ break;
+ }
+ format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1;
+
+ /* Fetch reporting period start time from DB */
+ switch(ricSubsInfo->eventTriggerDefinition.formatType)
+ {
+ case 1:
+ {
+ startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime;
+ }
+ }
+
+ format1->colletStartTime.size = 8 * sizeof(uint8_t);
+ DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size);
+ if(!format1->colletStartTime.buf)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ formatFailure = true;
+ break;
+ }
+
+ /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and
+ * RFC 5905, section 6 :
+ * Time stamp has a 64-bit format where first 32-bit is seconds
+ * and next 32-bit is fraction in picosecond-level.
+ * This fraction has been rounded in microseconds.
+ *
+ * Hence,
+ * Storing 32-bit seconds at MSB 0-3 and
+ * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7
+ */
+ secBufIdx = 0;
+ milliSecBufIdx = 4;
+ for(byteIdx = 3; byteIdx >= 0; byteIdx--)
+ {
+ format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx);
+ format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx);
+ }
+ break;
+ }
+
+ case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING:
+ default:
+ {
+ DU_LOG("\nERROR --> E2AP : Only E2SM-KPM Indication Header Format 1 supported");
+ formatFailure = true;
+ break;
+ }
+ }
+
+ if(formatFailure)
+ break;
+
+ /* Encode E2SM-KPM Indication Header */
+ xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr);
+ memset(encBuf, 0, ENC_BUF_MAX_LEN);
+ encBufSize = 0;
+ encRetVal = aper_encode(&asn_DEF_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf);
+ if(encRetVal.encoded == ENCODE_FAIL)
+ {
+ DU_LOG("\nERROR --> E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
+ }
+ else
+ {
+ DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \n");
+#ifdef DEBUG_ASN_PRINT
+ for(int i=0; i< encBufSize; i++)
+ {
+ printf("%x",encBuf[i]);
+ }
+#endif
+ }
+
+ /* Copy encoded string to RIC Indication Header buffer */
+ ricIndHdr->size = encBufSize;
+ DU_ALLOC(ricIndHdr->buf, ricIndHdr->size);
+ if(!ricIndHdr->buf)
+ {
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ break;
+ }
+ memset(ricIndHdr->buf, 0, ricIndHdr->size);
+ memcpy(ricIndHdr->buf, encBuf, encBufSize);
+ ret = ROK;
+ break;
+ }
+
+ /* Free E2SM-KPM Indication Header */
+ FreeE2smKpmIndicationHeader(&e2smKpmIndHdr);
+
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * brief Fill the RIC Indication Message
+ *
+ * @details
+ *
+ * Function : fillRicIndication
+ *
+ * Functionality: Fills the RIC Indication Message
+ *
+ * @param RIC Indication Message to be filled
+ * RIC Subscription DB
+ * Action DB
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ ******************************************************************/
+uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
+{
+ uint8_t elementCnt = 0, idx = 0;
uint8_t ret = ROK;
+
elementCnt = 6;
ricIndicationMsg->protocolIEs.list.count = elementCnt;
- ricIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(RICindication_t);
+ ricIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(RICindication_IEs_t *);
+
/* Initialize the Ric Indication members */
- DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \
- ricIndicationMsg->protocolIEs.list.size);
+ DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size);
if(ricIndicationMsg->protocolIEs.list.array == NULLP)
{
- DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
- ret = RFAILED;
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
}
- else
+
+ for(idx=0; idx<elementCnt; idx++)
{
- for(idx=0; idx<elementCnt; idx++)
+ DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx], sizeof(RICindication_IEs_t));
+ if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
{
- DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\
- sizeof(RICindication_IEs_t));
- if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP)
- {
- DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
- ret = RFAILED;
- }
- }
- if(ret != RFAILED)
- {
- idx = 0;
-
- ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
- ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
- RICindication_IEs__value_PR_RICrequestID;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId;
-
- idx++;
- ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
- ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
- RICindication_IEs__value_PR_RANfunctionID;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id;
-
- idx++;
- ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
- ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
- RICindication_IEs__value_PR_RICactionID;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id;
-
- idx++;
- ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
- ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
- RICindication_IEs__value_PR_RICindicationType;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type;
-
- idx++;
- ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
- ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
- RICindication_IEs__value_PR_RICindicationHeader;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 *
- sizeof(uint8_t);
- DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size);
- if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP)
- {
- DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
- ret = RFAILED;
- }
- else
- {
- buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf);
- idx++;
- /* TO BE CHANGED: RIC INDICATION DATA */
- /* For now filling a dummy octect data, need to tested with PRBs*/
- ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
- ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \
- RICindication_IEs__value_PR_RICindicationMessage;
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 *
- sizeof(uint8_t);
- DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size);
- if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP)
- {
- DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed");
- ret = RFAILED;
- }
- else
- {
- buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \
- ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf);
- }
- }
+ DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__);
+ return RFAILED;
}
}
+
+ /* RIC Request ID */
+ idx = 0;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \
+ ricSubscriptionInfo->requestId.requestorId;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \
+ ricSubscriptionInfo->requestId.instanceId;
+
+ /* RAN Function ID */
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId;
+
+ /* RIC Action ID */
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId;
+
+ /* RIC Indication Type */
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type;
+
+ /* RIC Indication Header */
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader;
+ if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \
+ ricSubscriptionInfo) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to fill RIC Indication header");
+ return RFAILED;
+ }
+
+ /* RIC Indication Message */
+ idx++;
+ ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage;
+ ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
+ ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage;
+ if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \
+ actionInfo) != ROK)
+ {
+ DU_LOG("\nERROR --> E2AP : Failed to fill RIC Indication Message");
+ return RFAILED;
+ }
+
return ret;
}
*
******************************************************************/
-uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo)
+uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo)
{
- E2AP_PDU_t *e2apMsg = NULLP;
- RICindication_t *ricIndicationMsg=NULLP;
- asn_enc_rval_t encRetVal; /* Encoder return value */
- uint8_t ret = RFAILED;
- uint8_t FillRicIndicationret = ROK;
+ uint8_t ret = RFAILED;
+ E2AP_PDU_t *e2apMsg = NULLP;
+ RICindication_t *ricIndicationMsg = NULLP;
+ asn_enc_rval_t encRetVal; /* Encoder return value */
while(true)
{
DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
if(e2apMsg == NULLP)
{
- DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
- break;
+ DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
+ break;
}
e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
if(e2apMsg->choice.initiatingMessage == NULLP)
{
- DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
- break;
+ DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed");
+ break;
}
e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication;
e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication;
- FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo);
- if(FillRicIndicationret != ROK)
+ if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK)
{
- break;
+ DU_LOG("\nERROR --> E2AP : Failed to fill RIC Indication message");
+ break;
}
+
/* Prints the Msg formed */
xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
memset(encBuf, 0, ENC_BUF_MAX_LEN);
encBufSize = 0;
encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
- encBuf);
+ encBuf);
if(encRetVal.encoded == ENCODE_FAIL)
{
- DU_LOG("\nERROR --> E2AP : Could not encode RIC Indication Message (at %s)\n",\
- encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
- break;
+ DU_LOG("\nERROR --> E2AP : Could not encode RIC Indication Message (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
}
else
{
- DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Indication Message \n");
+ DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Indication Message \n");
#ifdef DEBUG_ASN_PRINT
- for(int i=0; i< encBufSize; i++)
- {
- printf("%x",encBuf[i]);
- }
+ for(int i=0; i< encBufSize; i++)
+ {
+ printf("%x",encBuf[i]);
+ }
#endif
}
if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK)
{
- DU_LOG("\nINFO --> E2AP : Sending RIC Indication Message");
+ DU_LOG("\nINFO --> E2AP : Sending RIC Indication Message");
}
ret = ROK;