1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
18 #include "common_def.h"
25 #include "du_app_mac_inf.h"
26 #include "du_app_rlc_inf.h"
27 #include "du_e2ap_mgr.h"
28 #include "du_e2_conversions.h"
29 #include "du_e2ap_msg_hdl.h"
33 #include "du_mgr_main.h"
36 /*******************************************************************
38 * @brief Assigns new transaction id to DU initiated procedure
42 * Function : assignTransactionId
44 * Functionality: Assigns new transaction id to a DU initiated
47 * @params[in] Region region
49 * @return ROK - success
52 * ****************************************************************/
53 uint8_t assignTransactionId()
55 uint8_t currTransId = duCb.e2apDb.e2TransInfo.transIdCounter;
57 /* Update to next valid value */
58 duCb.e2apDb.e2TransInfo.transIdCounter++;
59 if(duCb.e2apDb.e2TransInfo.transIdCounter == MAX_NUM_TRANSACTION)
60 duCb.e2apDb.e2TransInfo.transIdCounter = 0;
65 /*******************************************************************
67 * @brief Decode subscription ID
71 * Function : decodeSubscriptionId
73 * Functionality: Decode subscription id to get RAN function ID
76 * @params[in] Subscription ID
77 * RAN Function ID to be extracted
78 * RIC Request ID to be extracted
81 * ****************************************************************/
82 void decodeSubscriptionId(uint64_t subscriptionId, uint16_t *ranFuncId, RicRequestId *ricReqId)
84 /* Extract following from 64 bit subscription-ID :
85 * First 16 MSB is unused
86 * Next 16 MSB = RAN-Function-ID
87 * Next 16 MSB = Requestor-ID in RIC-Request-ID
88 * Last 16 LSB = Instance-ID in RIC-Request-ID
90 ricReqId->instanceId = subscriptionId & 0xFFFF;
91 ricReqId->requestorId = (subscriptionId >> 16) & 0xFFFF;
92 *ranFuncId = (subscriptionId >> 32) & 0xFFFF;
95 /*******************************************************************
97 * @brief Encode subscription ID
101 * Function : encodeSubscriptionId
103 * Functionality: Encode subscription id to get RAN function ID
106 * @params[in] Subscription ID to be encoded
111 * ****************************************************************/
112 void encodeSubscriptionId(uint64_t *subscriptionId, uint16_t ranFuncId, RicRequestId ricReqId)
114 /* Calculate 64 bit subscription-ID :
115 * First 16 MSB is unused
116 * Next 16 MSB = RAN-Function-ID
117 * Next 16 MSB = Requestor-ID in RIC-Request-ID
118 * Last 16 LSB = Instance-ID in RIC-Request-ID
120 *subscriptionId = ricReqId.instanceId;
121 *subscriptionId |= ((uint64_t)ricReqId.requestorId << 16);
122 *subscriptionId |= ((uint64_t)ranFuncId << 32);
125 /*******************************************************************
127 * @brief Stores the current time at the start of reporting period
131 * Function : storeReportStartTime
133 * Functionality: Stores the current time at the start of
136 * @params[in] Start Timer to be stored
139 * ****************************************************************/
140 void storeReportStartTime(ReportStartTime *startTime)
144 gettimeofday(&tv, NULL);
145 startTime->timeInSec = tv.tv_sec;
146 startTime->timeInMilliSec = (tv.tv_usec/1000);
150 /*******************************************************************
152 * @brief Fetch Measurement Info using measurement type name
156 * Function : fetchMeasInfoFromMeasTypeName
158 * Functionality: Fetch Measurement Info using measurement type name
160 * @params[in] Measurement type name to search
161 * Measurement Info list to search from
162 * Measurement Info node found from list
163 * @return Measurement Info DB
165 * ****************************************************************/
166 MeasurementInfo *fetchMeasInfoFromMeasTypeName(char *e2MeasTypeName, CmLListCp *measInfoList, CmLList **measInfoNode)
168 MeasurementInfo *measInfo = NULLP;
170 /* Fetch subscription detail in RAN Function DB */
171 CM_LLIST_FIRST_NODE(measInfoList, *measInfoNode);
174 measInfo = (MeasurementInfo *)((*measInfoNode)->node);
175 if(measInfo && !strcmp(e2MeasTypeName, measInfo->measurementTypeName))
179 *measInfoNode = (*measInfoNode)->next;
185 DU_LOG("\nERROR --> E2AP : fetchMeasInfoFromMeasTypeName: Measurement [%s] not found", e2MeasTypeName);
191 /*******************************************************************
193 * @brief Fetch Action details
197 * Function : fetchActionInfoFromActionId
199 * Functionality: Fetch action details from RIC subscription DB
202 * @params[in] Action ID
203 * RIC Subscription DB
204 * @return Action Info DB
205 * NULL, in case of failure
207 * ****************************************************************/
208 ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSubscriptionInfo)
210 ActionInfo *actionInfoDb = NULLP;
211 if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId)
213 actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId];
217 DU_LOG("\nERROR --> E2AP : fetchActionInfoFromActionId: Action Id [%d] not found in \
218 subscription info [Requestor id : %d] [Instance Id : %d]", actionId,\
219 ricSubscriptionInfo->requestId.requestorId, ricSubscriptionInfo->requestId.instanceId);
225 /*******************************************************************
227 * @brief Fetch subscripton DB
231 * Function : fetchSubsInfoFromRicReqId
233 * Functionality: Fetches subscription DB from RAN Function DB
234 * using RIC Request ID
236 * @params[in] RIC Request ID
238 * Pointer to RIC Subscription node to be searched
239 * @return RIC Subscription from RAN Function's subcription list
240 * NULL, in case of failure
242 * ****************************************************************/
243 RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb, CmLList **ricSubscriptionNode)
245 RicSubscription *ricSubscriptionInfo = NULLP;
247 /* Fetch subscription detail in RAN Function DB */
248 CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, *ricSubscriptionNode);
249 while(*ricSubscriptionNode)
251 ricSubscriptionInfo = (RicSubscription *)((*ricSubscriptionNode)->node);
252 if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
253 (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
257 *ricSubscriptionNode = (*ricSubscriptionNode)->next;
258 ricSubscriptionInfo = NULLP;
261 if(!ricSubscriptionInfo)
263 DU_LOG("\nERROR --> E2AP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
264 Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id);
267 return ricSubscriptionInfo;
270 /*******************************************************************
272 * @brief Fetches RAN Function DB
276 * Function : fetchRanFuncFromRanFuncId
278 * Functionality: Fetches RAN function DB from E2AP DB using
281 * @params[in] RAN Function ID
282 * @return RAN Function DB
283 * NULL, in case of failure
285 * ****************************************************************/
286 RanFunction *fetchRanFuncFromRanFuncId(uint16_t ranFuncId)
288 RanFunction *ranFuncDb = NULLP;
290 /* Fetch RAN Function DB */
291 if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
293 ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
297 DU_LOG("\nERROR --> E2AP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
303 /*******************************************************************
305 * @brief Fetches subscription info
309 * Function : fetchSubsInfoFromSubsId
312 * 1. Firstly, RAN Function ID and RIC request ID is extracted
313 * from Subscription ID
314 * 2. Using RAN Function ID, RAN Function DB is searched
315 * 3. Using RIC Request ID, the subscription DB is searched in
318 * @params[in] Subscription ID
320 * RIC Subscription node from RAN Func's Subscription list
324 * ****************************************************************/
325 uint8_t fetchSubsInfoFromSubsId(uint64_t subscriptionId, RanFunction **ranFuncDb, CmLList **ricSubscriptionNode, \
326 RicSubscription **ricSubscriptionInfo)
328 uint16_t ranFuncId = 0;
329 RicRequestId ricReqId;
331 memset(&ricReqId, 0, sizeof(RicRequestId));
333 /* Decode subscription ID o get RIC Request ID and RAN Function ID */
334 decodeSubscriptionId(subscriptionId, &ranFuncId, &ricReqId);
336 /* Fetch RAN Function DB using RAN Function ID */
337 *ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
338 if((*ranFuncDb) == NULLP)
343 /* Fetch Sunscription DB from RAN Function using RIC Request ID */
344 *ricSubscriptionInfo = fetchSubsInfoFromRicReqId(ricReqId, *ranFuncDb, ricSubscriptionNode);
345 if((*ricSubscriptionInfo) == NULLP)
353 /*******************************************************************
355 * @brief Sends E2 msg over SCTP
359 * Function : SendE2APMsg
361 * Functionality: Sends E2 msg over SCTP
363 * @params[in] Region region
365 * @return ROK - success
368 * ****************************************************************/
370 uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize)
374 if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
376 if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
378 ODU_PRINT_MSG(mBuf, 0,0);
380 if(sctpSend(mBuf, E2_INTERFACE) != ROK)
382 DU_LOG("\nERROR --> E2AP : SCTP Send for E2 failed");
383 ODU_PUT_MSG_BUF(mBuf);
389 DU_LOG("\nERROR --> E2AP : ODU_ADD_POST_MSG_MULT failed");
390 ODU_PUT_MSG_BUF(mBuf);
393 ODU_PUT_MSG_BUF(mBuf);
397 DU_LOG("\nERROR --> E2AP : Failed to allocate memory");
404 /*******************************************************************
410 * Function : ResetE2Request
412 * Functionality: This function resets E2.
413 * As per ORAN WG3 E2GAP v3.0 Spec, section 5.5.3
414 * If E2 node initates reset procedure then:
415 * a. Send reset request to RIC
416 * b. Delete any pre-established RIC subscriptions
417 * c. Gracefully terminates any ongoing RIC services
418 * If RIC initiates reset procedure then :
419 * a. Delete any pre-established RIC subscriptions
420 * b. Gracefully terminates any ongoing RIC services
421 * c. Send reset response to RIC
424 * @return ROK - success
427 * ****************************************************************/
428 uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause)
430 /* Send Reset Request to RIC if DU detects any abnormal failure */
431 if(dir == E2_NODE_INITIATED)
433 if(BuildAndSendE2ResetRequest(resetCause) != ROK)
435 DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest failed");
440 /* TODO when RIC subscription service model is implemented
441 Process following steps of resetting E2
442 1. Deletes any pre-established RIC subscriptions
443 2. Gracefully terminates any ongoing RIC services
446 /* Send Reset Response if RIC initiated Reset request is received at DU */
447 if(dir == RIC_INITIATED)
449 //BuildAndSendE2ResetResponse();
454 /*******************************************************************
456 * @brief Fill RIC Subscription datils in MAC Statistics Request
460 * Function : fillRicSubsInMacStatsReq
462 * Functionality: Fill RIC Subscription datils in MAC Statistics
465 * @params[in] MAC Statistics Request to be filled
466 * RIC Subscription Info
468 * @return ROK - success
471 * ****************************************************************/
472 uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, RicSubscription* ricSubscriptionInfo)
474 uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0;
475 uint64_t subscriptionId = 0;
476 ActionInfo *actionDb = NULLP;
477 ActionDefFormat1 *format1Action = NULLP;
479 /* Generate subscription ID using RIC Request ID and RAN Function ID */
480 encodeSubscriptionId(&subscriptionId, ricSubscriptionInfo->ranFuncId, ricSubscriptionInfo->requestId);
482 macStatsReq->subscriptionId = subscriptionId;
483 for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
485 if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
487 actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
488 macStatsReq->statsGrpList[grpIdx].groupId = actionDb->actionId;
489 switch(actionDb->definition.formatType)
493 format1Action = &actionDb->definition.choice.format1;
494 macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
496 CmLList *node = NULLP;
497 MeasurementInfo *measInfo = NULLP;
499 /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
500 node = cmLListFirst(&format1Action->measurementInfoList);
503 measInfo = (MeasurementInfo *)(node->node);
504 switch(measInfo->measurementTypeId)
508 macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
513 macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
518 DU_LOG("\nERROR --> E2AP : Invalid measurement name");
524 macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
529 DU_LOG("\nERROR --> E2AP : fillRicSubsInMacStatsReq: Only Action Definition Format 1 supported");
533 if(macStatsReq->statsGrpList[grpIdx].numStats)
538 macStatsReq->numStatsGroup = grpIdx;
539 if(macStatsReq->numStatsGroup)
546 /*******************************************************************
548 * @brief Rejects all actions received in a subscription request
552 * Function : duRejectAllStatsGroup
554 * Functionality: Rejects all actions received in a subscription
556 * a. Removing the subscription entry from RAN function
557 * b. Sending RIC Subscription Failure to RIC with appropriate
560 * @params[in] RAN Function DB
561 * Subscription entry in RAN Function subscription list
562 * Statistics Response from MAC
564 * @return ROK - success
567 * ****************************************************************/
568 uint8_t rejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp)
571 RicRequestId requestId;
572 E2FailureCause failureCause;
574 /* Delete subcription from RAN Function */
575 memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId));
576 cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode);
577 deleteRicSubscriptionNode(ricSubscriptionNode);
578 ricSubscriptionNode = NULLP;
579 convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause);
581 /* Send RIC subscription failure to RIC */
582 ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause);
586 /*******************************************************************
588 * @brief Process statistics response from MAC
592 * Function : e2ProcStatsRsp
594 * Functionality: Processes statistics configuration response
595 * from MAC. If configuration is succsessful, DUAPP starts
596 * reporting period timer for this subscription request
599 * @params[in] Statistics response received from MAC
601 * @return ROK - success
604 * ****************************************************************/
605 uint8_t e2ProcStatsRsp(MacStatsRsp *statsRsp)
608 uint8_t actionId = 0;
609 uint32_t reportingPeriod = 0;
610 RanFunction *ranFuncDb = NULLP;
611 CmLList *ricSubscriptionNode = NULLP;
612 RicSubscription *ricSubscriptionInfo = NULLP;
613 ActionInfo *actionInfoDb = NULLP;
614 PendingSubsRspInfo *pendingSubsRsp = NULLP;
616 /* Fetch RAN Function and Subscription DB using subscription Id received in statistics response */
617 if(fetchSubsInfoFromSubsId(statsRsp->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
619 DU_LOG("\nERROR --> E2AP : DuProcMacStatsRsp: Failed to fetch subscriprtion details");
623 /* Fetch pre-stored statistics response info by DU APP */
624 for(idx=0; idx<ranFuncDb->numPendingSubsRsp; idx++)
626 if((ranFuncDb->pendingSubsRspInfo[idx].requestId.requestorId == ricSubscriptionInfo->requestId.requestorId) &&
627 (ricSubscriptionInfo->requestId.instanceId == ricSubscriptionInfo->requestId.instanceId))
629 pendingSubsRsp = &ranFuncDb->pendingSubsRspInfo[idx];
634 /* If no action is accepted
635 * a. Remove subcription entry from RAN Function
636 * b. Send RIC subscription failure */
637 if(statsRsp->numGrpAccepted == 0)
639 rejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp);
643 /* Once RIC subscription is successful, mark the config action as unknown */
644 ricSubscriptionInfo->action = CONFIG_UNKNOWN;
646 /* Start RIC Subscription reporting timer */
647 switch(ricSubscriptionInfo->eventTriggerDefinition.formatType)
651 reportingPeriod = ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod;
653 /* Save the start time of reporting period */
654 storeReportStartTime(&ricSubscriptionInfo->eventTriggerDefinition.choice.format1.startTime);
659 DU_LOG("\nERROR --> E2AP : Invalid event trigger format of RIC subscription");
663 if(duChkTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) != true)
665 duStartTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR, reportingPeriod);
669 DU_LOG("\nERROR --> E2AP : RIC Subscription reporting timer already running for RIC Subscription");
674 /* If even 1 action is accepted :
676 * For accepted groups:
677 * Mark subscribed-action's -> action = CONFIG_UNKNOWN
678 * Add to accepted-action-list of subscription response
680 for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
682 actionInfoDb = NULLP;
684 actionId = statsRsp->statsGrpAcceptedList[idx];
685 actionInfoDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo);
686 if(actionInfoDb && (actionInfoDb->action == CONFIG_ADD))
688 actionInfoDb->action = CONFIG_UNKNOWN;
689 pendingSubsRsp->acceptedActionList[pendingSubsRsp->numOfAcceptedActions++] = actionId;
693 /* For rejected groups:
694 * Remove entry from DU's RAN Function->subscription->actionList
695 * Add to rejected-action-list in subscription response
697 for(idx=0; idx<statsRsp->numGrpRejected; idx++)
699 actionId = statsRsp->statsGrpRejectedList[idx].groupId;
700 if(ricSubscriptionInfo->actionSequence[actionId].actionId == actionId)
702 memset(&ricSubscriptionInfo->actionSequence[actionId], 0, sizeof(ActionInfo));
703 ricSubscriptionInfo->numOfActions--;
705 pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].id = actionId;
706 convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[idx].cause, \
707 &pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].failureCause);
708 pendingSubsRsp->numOfRejectedActions++;
712 /* Send subscription response with accepted and rejected action lists to RIC */
713 BuildAndSendRicSubscriptionRsp(pendingSubsRsp);
715 memset(pendingSubsRsp, 0, sizeof(PendingSubsRspInfo));
719 /*******************************************************************
721 * @brief Extract and store statistics received from DU layers
725 * Function : e2ProcStatsInd
727 * Functionality: Extract statistics received from DU layers
728 * and store in respective RAN function's subscription's
731 * @params[in] Statistics Indication message received from MAC
732 * @return ROK-success
735 * ****************************************************************/
736 uint8_t e2ProcStatsInd(MacStatsInd *statsInd)
738 uint8_t statsIdx = 0;
739 RanFunction *ranFuncDb = NULLP;
740 CmLList *ricSubscriptionNode = NULLP;
741 RicSubscription *ricSubscriptionInfo = NULLP;
742 ActionInfo *actionInfo = NULLP;
743 ActionDefFormat1 *actionFormat = NULLP;
744 char e2MeasTypeName[STRING_SIZE_150_BYTES] = "";
745 MeasurementInfo *measInfo = NULLP;
746 CmLList *measInfoNode = NULLP;
747 double *measValue = NULLP;
748 CmLList *measValueNode = NULLP;
750 /* TODO : When stats indication is received
751 * DU APP searches for the message type in E2AP RIC subscription
752 * database and stores in the value in the list of subscribed measurements
754 * This will be implemented in next gerrit.
757 /* Fetch RAN Function and Subscription DB using subscription Id received
758 * in statistics response */
759 if(fetchSubsInfoFromSubsId(statsInd->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
761 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to fetch subscriprtion details");
765 /* Fetch RIC subscription's action DB */
766 actionInfo = fetchActionInfoFromActionId(statsInd->groupId, ricSubscriptionInfo);
767 if(actionInfo == NULLP)
769 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to fetch action ID [%d]", statsInd->groupId);
773 /* Check Action format */
774 switch(actionInfo->definition.formatType)
778 actionFormat = &actionInfo->definition.choice.format1;
783 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Action Format [%d] is not supported", \
784 actionInfo->definition.formatType);
789 /* Fetch each Measurement info from action info and store its reported value in DB */
790 for(statsIdx = 0; statsIdx < statsInd->numStats; statsIdx++)
792 memset(e2MeasTypeName, 0, STRING_SIZE_150_BYTES);
794 measInfoNode = NULLP;
796 /* Convert Measurement type from MAC-supported format to E2-supported format */
797 if(convertMacMeasTypeToE2MeasType(statsInd->measuredStatsList[statsIdx].type, e2MeasTypeName) != ROK)
799 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Failed to convert measurement type from MAC-supported\
800 MAC-supported format to E2-supported format");
804 /* Fetch Measurement Info using E2-supported measurement type name */
805 measInfo = fetchMeasInfoFromMeasTypeName(e2MeasTypeName, &actionFormat->measurementInfoList, &measInfoNode);
806 if(measInfo == NULLP)
808 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Measurement Type Name [%s] not found", e2MeasTypeName);
812 /* Store the measurement value in the measurement info DB fetched */
813 DU_ALLOC(measValue, sizeof(double));
816 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Memory allocation failed at line [%d]", __LINE__);
819 *measValue = statsInd->measuredStatsList[statsIdx].value;
821 DU_ALLOC(measValueNode, sizeof(CmLList));
824 DU_LOG("\nERROR --> E2AP : extractStatsMeasurement: Memory allocation failed at line [%d]", __LINE__);
825 DU_FREE(measValue, sizeof(double));
828 measValueNode->node = (PTR) measValue;
829 cmLListAdd2Tail(&measInfo->measuredValue, measValueNode);
834 /*******************************************************************
836 * @brief Handle RIC Subscription reporting timer expry
840 * Function : E2apHdlRicSubsReportTmrExp
842 * Functionality: On expiry of RIC subscription reporting
843 * timer expiry, RIC indication is sent for all actions
844 * in RIC subscription
846 * @params[in] RIC subscription DB
849 * ****************************************************************/
850 void E2apHdlRicSubsReportTmrExp(RicSubscription *ricSubscription)
852 uint8_t actionIdx = 0;
853 uint32_t reportingPeriod = 0;
855 for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
857 if(ricSubscription->actionSequence[actionIdx].actionId >= 0)
859 BuildAndSendRicIndication(ricSubscription, &ricSubscription->actionSequence[actionIdx]);
863 /* Start RIC Subscription reporting timer again */
864 switch(ricSubscription->eventTriggerDefinition.formatType)
868 reportingPeriod = ricSubscription->eventTriggerDefinition.choice.format1.reportingPeriod;
869 /* Save the start time of reporting period */
870 storeReportStartTime(&ricSubscription->eventTriggerDefinition.choice.format1.startTime);
876 if(duChkTmr((PTR)ricSubscription, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) != true)
878 duStartTmr((PTR)ricSubscription, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR, reportingPeriod);
882 DU_LOG("\nERROR --> E2AP : Failed in %s at line %d", __func__, __LINE__);
887 /******************************************************************
889 * @brief Search E2 node component with the help of action type
893 * Function : fetchE2NodeComponentInfo
895 * Functionality: Search E2 node component with the help of action type
900 * Pointer to E2 component node to be searched
903 * ****************************************************************/
905 E2NodeComponent *fetchE2NodeComponentInfo(InterfaceType interfaceType, uint64_t componentId, CmLList **e2ComponentNode)
907 E2NodeComponent *e2NodeComponentInfo=NULLP;
909 if(duCb.e2apDb.e2NodeComponentList.count)
911 CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, *e2ComponentNode);
912 while(*e2ComponentNode)
914 e2NodeComponentInfo = (E2NodeComponent*)((*e2ComponentNode)->node);
915 if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentId == componentId))
920 *e2ComponentNode = (*e2ComponentNode)->next;
921 e2NodeComponentInfo = NULLP;
924 return e2NodeComponentInfo;
927 /*******************************************************************
929 * @brief fill E2 node component rsp info
933 * Function : fillE2NodeComponentRspInfo
935 * Functionality: fill E2 Node Component rsp info
939 * Component action type
940 * Size of buffer which needs to be store
941 * buffer string which needs to be store
942 * @return ROK - success
945 * ****************************************************************/
947 uint8_t fillE2NodeComponentRspInfo(InterfaceType interfaceType, uint64_t componentId, uint8_t action, uint8_t bufSize, char *bufString)
949 E2NodeConfig *configInfo=NULLP;
950 E2NodeComponent *e2NodeComponentInfo= NULLP;
951 CmLList *node = NULLP;
953 e2NodeComponentInfo = fetchE2NodeComponentInfo(interfaceType, componentId, &node);
954 if(!e2NodeComponentInfo)
956 DU_LOG("\nERROR --> E2AP : Unable to find the node");
962 case E2_NODE_COMPONENT_ADD:
964 configInfo = e2NodeComponentInfo->addConfiguration;
967 case E2_NODE_COMPONENT_UPDATE:
969 configInfo = e2NodeComponentInfo->updateConfiguration;
974 DU_LOG("\nERROR --> E2AP : Invalid action %d received",action);
979 if(configInfo->componentRequestPart== NULLP)
981 DU_LOG("\nERROR --> E2AP : E2 node Component request part is not present");
985 configInfo->rspBufSize = bufSize;
986 DU_ALLOC(configInfo->componentResponsePart, bufSize);
987 if(configInfo->componentResponsePart == NULLP)
989 DU_LOG("\nERROR --> E2AP : Memory allocation failed to store the encoding of rsp");
992 memcpy(configInfo->componentResponsePart, bufString, configInfo->rspBufSize);
996 /*******************************************************************
998 * @brief add E2 node component req info
1002 * Function : addE2NodeComponent
1004 * Functionality: add E2 node component req info
1008 * Component action type
1009 * Size of buffer which needs to be store
1010 * buffer string which needs to be store
1011 * @return ROK - success
1014 ******************************************************************/
1016 uint8_t addE2NodeComponent(InterfaceType interfaceType, uint64_t componentId, uint8_t bufSize, char *bufString)
1018 E2NodeComponent *e2NodeComponentInfo= NULLP;
1019 CmLList *node = NULLP;
1021 DU_ALLOC(e2NodeComponentInfo, sizeof(E2NodeComponent));
1022 if(!e2NodeComponentInfo)
1024 DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
1027 e2NodeComponentInfo->interfaceType =interfaceType;
1028 e2NodeComponentInfo->componentId=componentId;
1030 DU_ALLOC(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig));
1031 if(!e2NodeComponentInfo->addConfiguration)
1033 DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
1037 e2NodeComponentInfo->addConfiguration->reqBufSize = bufSize;
1039 DU_ALLOC(e2NodeComponentInfo->addConfiguration->componentRequestPart, bufSize);
1040 if(e2NodeComponentInfo->addConfiguration->componentRequestPart == NULLP)
1042 DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
1043 DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
1046 memcpy(e2NodeComponentInfo->addConfiguration->componentRequestPart, bufString,\
1047 e2NodeComponentInfo->addConfiguration->reqBufSize);
1049 DU_ALLOC(node, sizeof(CmLList));
1052 node->node = (PTR) e2NodeComponentInfo;
1053 cmLListAdd2Tail(&duCb.e2apDb.e2NodeComponentList, node);
1057 DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
1058 DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, bufSize);
1059 DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig));
1060 DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
1066 /*******************************************************************
1068 * @brief update E2 node component req info
1072 * Function : updateE2NodeComponent
1074 * Functionality: update E2 node component req info
1078 * Size of buffer which needs to be store
1079 * buffer string which needs to be store
1080 * @return ROK - success
1083 ******************************************************************/
1085 uint8_t updateE2NodeComponent(InterfaceType interfaceType, uint64_t componentId, uint8_t bufSize, char *bufString)
1087 E2NodeComponent *e2NodeComponentInfo= NULLP;
1088 CmLList *node = NULLP;
1090 e2NodeComponentInfo = fetchE2NodeComponentInfo(interfaceType, componentId, &node);
1091 if(!e2NodeComponentInfo)
1093 DU_LOG("\nERROR --> E2AP : Received null information in %s",__func__);
1097 DU_ALLOC(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig));
1098 if(!e2NodeComponentInfo->updateConfiguration)
1100 DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
1104 e2NodeComponentInfo->updateConfiguration->reqBufSize = bufSize;
1106 DU_ALLOC(e2NodeComponentInfo->updateConfiguration->componentRequestPart, bufSize);
1107 if(e2NodeComponentInfo->updateConfiguration->componentRequestPart == NULLP)
1109 DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
1110 DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig));
1114 memcpy(e2NodeComponentInfo->updateConfiguration->componentRequestPart, bufString,\
1115 e2NodeComponentInfo->updateConfiguration->reqBufSize);
1120 /*******************************************************************
1122 * @brief delete E2 node component req info
1126 * Function : deleteE2NodeComponent
1128 * Functionality: delete E2 node component req info
1132 * @return ROK - success
1135 ******************************************************************/
1137 uint8_t deleteE2NodeComponent(InterfaceType interfaceType, uint64_t componentId)
1139 E2NodeComponent *e2NodeComponentInfo= NULLP;
1140 CmLList *node = NULLP;
1142 e2NodeComponentInfo = fetchE2NodeComponentInfo(interfaceType, componentId, &node);
1143 if(!e2NodeComponentInfo)
1145 DU_LOG("\nERROR --> E2AP : Received null information in %s",__func__);
1149 e2NodeComponentInfo->deleteConfiguration = true;
1153 /*******************************************************************
1155 * @brief fill E2 node component req info
1159 * Function : fillE2NodeComponentReqInfo
1161 * Functionality: fill E2 node component req info
1165 * Component action type
1166 * Size of buffer which needs to be store
1167 * buffer string which needs to be store
1168 * @return ROK - success
1171 ******************************************************************/
1173 uint8_t fillE2NodeComponentReqInfo(InterfaceType interfaceType, uint64_t componentId, uint8_t action, uint8_t bufSize, char *bufString)
1177 case E2_NODE_COMPONENT_ADD:
1179 if(addE2NodeComponent(interfaceType, componentId, bufSize, bufString) != ROK)
1181 DU_LOG("\nERROR --> E2AP : Failed to add e2 node component");
1186 case E2_NODE_COMPONENT_UPDATE:
1188 if(updateE2NodeComponent(interfaceType, componentId, bufSize, bufString) != ROK)
1190 DU_LOG("\nERROR --> E2AP : Failed to update e2 node component");
1195 case E2_NODE_COMPONENT_DEL:
1197 if(deleteE2NodeComponent(interfaceType, componentId) != ROK)
1199 DU_LOG("\nERROR --> E2AP : Failed to delete e2 node component");
1206 DU_LOG("\nERROR --> E2AP : Invalid action %d received",action);
1214 /******************************************************************
1216 * @brief Delete measured Value list
1220 * Function : deleteMeasuredValueList
1222 * Functionality: Delete measured Value list
1224 * @params[in] List of measured Value
1228 * ****************************************************************/
1229 void deleteMeasuredValueList(CmLListCp *measuredValueList)
1231 CmLList *measValNode = NULLP;
1233 CM_LLIST_FIRST_NODE(measuredValueList, measValNode);
1237 cmLListDelFrm(measuredValueList, measValNode);
1238 DU_FREE(measValNode->node, sizeof(double));
1239 DU_FREE(measValNode, sizeof(CmLList));
1240 CM_LLIST_FIRST_NODE(measuredValueList, measValNode);
1244 /******************************************************************
1246 * @brief Delete Measurement Info List
1250 * Function : deleteMeasurementInfoList
1252 * Functionality: Delete Measurement Info List
1254 * @params[in] List of Measurement Info List
1258 * ****************************************************************/
1259 void deleteMeasurementInfoList(CmLListCp *measInfoList)
1261 CmLList *measInfoNode = NULLP;
1262 MeasurementInfo *measInfo = NULLP;
1264 CM_LLIST_FIRST_NODE(measInfoList, measInfoNode);
1267 measInfo = (MeasurementInfo *)measInfoNode->node;
1268 cmLListDelFrm(measInfoList, measInfoNode);
1269 deleteMeasuredValueList(&measInfo->measuredValue);
1270 DU_FREE(measInfo, sizeof(MeasurementInfo));
1271 DU_FREE(measInfoNode, sizeof(CmLList));
1272 CM_LLIST_FIRST_NODE(measInfoList, measInfoNode);
1276 /******************************************************************
1278 * @brief Delete Ric subscription action
1282 * Function : deleteActionSequence
1284 * Functionality: Delete Ric subscription action
1286 * @params[in] Action info
1290 * ****************************************************************/
1291 void deleteActionSequence(ActionInfo *action)
1293 ActionDefinition *definition=NULLP;
1294 definition= &action->definition;
1296 switch(definition->formatType)
1300 deleteMeasurementInfoList(&definition->choice.format1.measurementInfoList);
1310 DU_LOG("\nERROR --> E2AP : Format %d does not supported", definition->formatType);
1314 memset(action, 0, sizeof(ActionInfo));
1315 action->actionId = -1;
1318 /******************************************************************
1320 * @brief Delete Ric subscription node
1324 * Function : deleteRicSubscriptionNode
1326 * Functionality: Delete Ric subscription node
1328 * @params[in] Ric subscription info
1332 * ****************************************************************/
1333 void deleteRicSubscriptionNode(CmLList *subscriptionNode)
1335 uint8_t actionIdx=0;
1336 RicSubscription *ricSubscriptionInfo = NULLP;
1338 ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;
1340 for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
1342 if(ricSubscriptionInfo->actionSequence[actionIdx].actionId > -1)
1344 deleteActionSequence(&ricSubscriptionInfo->actionSequence[actionIdx]);
1348 if(duChkTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) == TRUE)
1350 duStopTmr((PTR)ricSubscriptionInfo, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR);
1353 memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
1354 DU_FREE(subscriptionNode->node, sizeof(RicSubscription));
1355 DU_FREE(subscriptionNode, sizeof(CmLList));
1358 /******************************************************************
1360 * @brief Delete ric subscription list from the database
1364 * Function : deleteRicSubscriptionList
1366 * Functionality: Delete ric subscription list
1369 * Subscription List to be deleted
1373 * ****************************************************************/
1374 void deleteRicSubscriptionList(CmLListCp *subscriptionList)
1376 CmLList *subscriptionNode=NULLP;
1378 CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
1379 while(subscriptionNode)
1381 /* TODO - Remove subscription information from MAC and SCH as well */
1382 cmLListDelFrm(subscriptionList, subscriptionNode);
1383 deleteRicSubscriptionNode(subscriptionNode);
1384 CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
1388 /*******************************************************************
1390 * @brief Find all RIC subscriptions to be deleted in all RAN
1395 * Function : fetchRicSubsToBeDeleted
1397 * Functionality: Find all RIC subscriptions to be deleted in all
1398 * RAN functions and store in a temporary list
1400 * @parameter Temporary list to store subscriptions to be deleted
1403 ******************************************************************/
1404 void fetchRicSubsToBeDeleted(CmLListCp *ricSubsToBeDelList)
1406 uint16_t ranFuncIdx = 0;
1407 CmLList *subsNode = NULLP;
1408 CmLList *subsToDelNode = NULLP;
1410 for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
1412 if(duCb.e2apDb.ranFunction[ranFuncIdx].id > 0)
1414 CM_LLIST_FIRST_NODE(&duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList, subsNode);
1417 if(((RicSubscription *)subsNode->node)->action == CONFIG_DEL)
1419 DU_ALLOC(subsToDelNode, sizeof(CmLList));
1422 DU_LOG("\nERROR --> E2AP : %s: Memory allocation failure at %d", __func__, __LINE__);
1425 subsToDelNode->node = subsNode->node;
1426 cmLListAdd2Tail(ricSubsToBeDelList, subsToDelNode);
1428 subsToDelNode = NULLP;
1429 subsNode = subsNode->next;
1435 /******************************************************************
1437 * @brief Delete e2 node information from the database
1441 * Function : removeE2NodeInformation
1443 * Functionality: Delete e2 node information from the database
1449 ******************************************************************/
1450 void removeE2NodeInformation()
1452 uint16_t ranFuncIdx = 0;
1454 DU_LOG("\nINFO --> E2AP : Deleting all the E2 node configuration");
1455 for(ranFuncIdx=0; ranFuncIdx<MAX_RAN_FUNCTION; ranFuncIdx++)
1457 if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0)
1459 deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList));
1460 memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo));
1463 memset(&duCb.e2apDb.ricId, 0, sizeof(GlobalRicId));
1464 duCb.e2apDb.numOfTNLAssoc = 0;
1465 memset(&duCb.e2apDb.tnlAssoc, 0, MAX_TNL_ASSOCIATION*sizeof(TNLAssociation));
1466 cmInetClose(&ricParams.sockFd);
1467 memset(&ricParams, 0, sizeof(DuSctpDestCb));
1469 /**********************************************************************
1471 **********************************************************************/