[Epic-ID: ODUHIGH-516][Task-ID: 527] Implementation of E2 Node Configuration Update...
[o-du/l2.git] / src / du_app / du_e2ap_mgr.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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"
19 #include "du_tmr.h"
20 #include "lrg.h"
21 #include "lkw.x"
22 #include "lrg.x"
23 #include "legtp.h"
24 #include "du_app_mac_inf.h"
25 #include "du_app_rlc_inf.h"
26 #include "du_e2ap_mgr.h"
27 #include "du_e2_conversions.h"
28 #include "du_e2ap_msg_hdl.h"
29 #include "du_cfg.h"
30 #include "du_sctp.h"
31 #include "du_mgr.h"
32 #include "du_mgr_main.h"
33 #include "du_utils.h"
34
35 /*******************************************************************
36  *
37  * @brief Assigns new transaction id to DU initiated procedure
38  *
39  * @details
40  *
41  *    Function : assignTransactionId
42  *
43  *    Functionality: Assigns new transaction id to a DU initiated
44  *       procedure
45  *
46  * @params[in] Region region
47  *             Pool pool
48  * @return ROK     - success
49  *         RFAILED - failure
50  *
51  * ****************************************************************/
52 uint8_t assignTransactionId()
53 {
54    uint8_t currTransId = duCb.e2apDb.e2TransInfo.transIdCounter;
55
56    /* Update to next valid value */
57    duCb.e2apDb.e2TransInfo.transIdCounter++;
58    if(duCb.e2apDb.e2TransInfo.transIdCounter == MAX_NUM_TRANSACTION)
59       duCb.e2apDb.e2TransInfo.transIdCounter = 0;
60
61    return currTransId;
62 }
63
64 /*******************************************************************
65  *
66  * @brief Decode subscription ID
67  *
68  * @details
69  *
70  *    Function : decodeSubscriptionId
71  *
72  *    Functionality: Decode subscription id to get RAN function ID
73  *      and RIC Request ID
74  *
75  * @params[in] Subscription ID
76  *             RAN Function ID to be extracted
77  *             RIC Request ID to be extracted
78  * @return Void
79  *
80  * ****************************************************************/
81 void decodeSubscriptionId(uint64_t subscriptionId, uint16_t *ranFuncId, RicRequestId *ricReqId)
82 {
83    /* Extract following from 64 bit subscription-ID :
84     *  First 16 MSB is unused
85     *  Next 16 MSB = RAN-Function-ID
86     *  Next 16 MSB = Requestor-ID in RIC-Request-ID
87     *  Last 16 LSB = Instance-ID in RIC-Request-ID
88     */
89    ricReqId->instanceId = subscriptionId & 0xFFFF;
90    ricReqId->requestorId = (subscriptionId >> 16) & 0xFFFF;
91    *ranFuncId = (subscriptionId >> 32) & 0xFFFF;
92 }
93
94 /*******************************************************************
95  *
96  * @brief Encode subscription ID
97  *
98  * @details
99  *
100  *    Function : encodeSubscriptionId
101  *
102  *    Functionality: Encode subscription id to get RAN function ID
103  *      and RIC Request ID
104  *
105  * @params[in] Subscription ID to be encoded
106  *             RAN Function ID 
107  *             RIC Request ID
108  * @return Void
109  *
110  * ****************************************************************/
111 void encodeSubscriptionId(uint64_t *subscriptionId, uint16_t ranFuncId, RicRequestId ricReqId)
112 {
113    /* Calculate 64 bit subscription-ID :
114     *  First 16 MSB is unused
115     *  Next 16 MSB = RAN-Function-ID
116     *  Next 16 MSB = Requestor-ID in RIC-Request-ID
117     *  Last 16 LSB = Instance-ID in RIC-Request-ID
118     */
119    *subscriptionId = ricReqId.instanceId;
120    *subscriptionId |= ((uint64_t)ricReqId.requestorId << 16);
121    *subscriptionId |= ((uint64_t)ranFuncId << 32);
122 }
123
124 /*******************************************************************
125  *
126  * @brief Fetch Action details
127  *
128  * @details
129  *
130  *    Function : fetchActionInfoFromActionId
131  *
132  *    Functionality: Fetch action details from RIC subscription DB
133  *       using action ID
134  *
135  * @params[in] Action ID 
136  *             RIC Subscription DB
137  * @return Action Info DB
138  *         NULL, in case of failure
139  *
140  * ****************************************************************/
141 ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSubscriptionInfo)
142 {
143    ActionInfo *actionInfoDb = NULLP;
144    if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId)
145    {
146       actionInfoDb = &ricSubscriptionInfo->actionSequence[actionId-1];
147    }
148    else
149    {
150       DU_LOG("\nERROR  -->  DU_APP : fetchActionInfoFromActionId: Action Id [%d] not found in \
151          subscription info [Requestor id : %d] [Instance Id : %d]", actionId,\
152          ricSubscriptionInfo->requestId.requestorId, ricSubscriptionInfo->requestId.instanceId);
153
154    }
155    return actionInfoDb;
156 }
157
158 /*******************************************************************
159  *
160  * @brief Fetch subscripton DB 
161  *
162  * @details
163  *
164  *    Function : fetchSubsInfoFromRicReqId
165  *
166  *    Functionality: Fetches subscription DB from RAN Function DB
167  *       using RIC Request ID
168  *
169  * @params[in] RIC Request ID 
170  *             RAN Function DB
171  *             Pointer to RIC Subscription node to be searched
172  * @return RIC Subscription from RAN Function's subcription list
173  *         NULL, in case of failure
174  *
175  * ****************************************************************/
176 RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb, CmLList **ricSubscriptionNode)
177 {
178    RicSubscription *ricSubscriptionInfo = NULLP;
179
180    /* Fetch subscription detail in RAN Function DB */
181    CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, *ricSubscriptionNode);
182    while(*ricSubscriptionNode)
183    {
184       ricSubscriptionInfo = (RicSubscription *)((*ricSubscriptionNode)->node);
185       if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
186             (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
187       {
188          break;
189       }
190       *ricSubscriptionNode = (*ricSubscriptionNode)->next;
191       ricSubscriptionInfo = NULLP;
192    }
193
194    if(!ricSubscriptionInfo)
195    {
196       DU_LOG("\nERROR  -->  DU_APP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
197          Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id);
198    }
199
200    return ricSubscriptionInfo;
201 }
202
203 /*******************************************************************
204  *
205  * @brief Fetches RAN Function DB
206  *
207  * @details
208  *
209  *    Function : fetchRanFuncFromRanFuncId
210  *
211  *    Functionality: Fetches RAN function DB from E2AP DB using
212  *       RAN function ID 
213  *
214  * @params[in] RAN Function ID
215  * @return RAN Function DB
216  *         NULL, in case of failure
217  *
218  * ****************************************************************/
219 RanFunction *fetchRanFuncFromRanFuncId(uint16_t ranFuncId)
220 {
221    RanFunction *ranFuncDb = NULLP;
222
223    /* Fetch RAN Function DB */
224    if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
225    {
226       ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
227    }
228    else
229    {
230       DU_LOG("\nERROR  -->  DU_APP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
231    }
232
233    return ranFuncDb;
234 }
235
236 /*******************************************************************
237  *
238  * @brief Fetches subscription info
239  *
240  * @details
241  *
242  *    Function : fetchSubsInfoFromSubsId
243  *
244  *    Functionality: 
245  *       1. Firstly, RAN Function ID and RIC request ID is extracted
246  *          from Subscription ID 
247  *       2. Using RAN Function ID, RAN Function DB is searched
248  *       3. Using RIC Request ID, the subscription DB is searched in
249  *          RAN Function DB
250  *
251  * @params[in] Subscription ID
252  *             RAN Function DB
253  *             RIC Subscription node from RAN Func's Subscription list
254  * @return ROK
255  *         RFAILED
256  *
257  * ****************************************************************/
258 uint8_t fetchSubsInfoFromSubsId(uint64_t subscriptionId, RanFunction **ranFuncDb, CmLList **ricSubscriptionNode, \
259    RicSubscription **ricSubscriptionInfo)
260 {
261    uint16_t ranFuncId = 0;
262    RicRequestId ricReqId;
263
264    memset(&ricReqId, 0, sizeof(RicRequestId));
265
266    /* Decode subscription ID o get RIC Request ID and RAN Function ID */
267    decodeSubscriptionId(subscriptionId, &ranFuncId, &ricReqId);
268
269    /* Fetch RAN Function DB using RAN Function ID */
270    *ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
271    if((*ranFuncDb) == NULLP)
272    {
273       return RFAILED;
274    }
275
276    /* Fetch Sunscription DB from RAN Function using RIC Request ID */
277    *ricSubscriptionInfo = fetchSubsInfoFromRicReqId(ricReqId, *ranFuncDb, ricSubscriptionNode);
278    if((*ricSubscriptionInfo) == NULLP)
279    {
280       return RFAILED;
281    }
282
283    return ROK;
284 }
285
286 /*******************************************************************
287  *
288  * @brief Sends E2 msg over SCTP
289  *
290  * @details
291  *
292  *    Function : SendE2APMsg
293  *
294  *    Functionality: Sends E2 msg over SCTP
295  *
296  * @params[in] Region region
297  *             Pool pool
298  * @return ROK     - success
299  *         RFAILED - failure
300  *
301  * ****************************************************************/
302
303 uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize)
304 {
305    Buffer *mBuf=NULLP;
306
307    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
308    {
309       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
310       {
311          ODU_PRINT_MSG(mBuf, 0,0);
312
313          if(sctpSend(mBuf, E2_INTERFACE) != ROK)
314          {
315             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
316             ODU_PUT_MSG_BUF(mBuf);
317             return RFAILED;
318          }
319       }
320       else
321       {
322          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
323          ODU_PUT_MSG_BUF(mBuf);
324          return RFAILED;
325       }
326       ODU_PUT_MSG_BUF(mBuf);
327    }
328    else
329    {
330       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
331       return RFAILED;
332    }
333
334    return ROK;
335 } /* SendE2APMsg */
336
337 /*******************************************************************
338  *
339  * @brief Resets E2 
340  *
341  * @details
342  *
343  *    Function : ResetE2Request
344  *
345  *    Functionality: This function resets E2.
346  *       As per ORAN WG3 E2GAP v3.0 Spec, section 5.5.3
347  *       If E2 node initates reset procedure then:
348  *        a. Send reset request to RIC
349  *        b. Delete any pre-established RIC subscriptions
350  *        c. Gracefully terminates any ongoing RIC services
351  *       If RIC initiates reset procedure then :
352  *        a. Delete any pre-established RIC subscriptions
353  *        b. Gracefully terminates any ongoing RIC services
354  *        c. Send reset response to RIC
355  *
356  * @params[in]
357  * @return ROK     - success
358  *         RFAILED - failure
359  *
360  * ****************************************************************/
361 uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause)
362 {
363    /* Send Reset Request to RIC if DU detects any abnormal failure */
364    if(dir == E2_NODE_INITIATED)
365    {
366       if(BuildAndSendE2ResetRequest(resetCause) != ROK)
367       {
368          DU_LOG("\nERROR  -->  E2AP : BuildAndSendE2ResetRequest failed");
369          return RFAILED;
370       }
371    }
372
373    /* TODO when RIC subscription service model is implemented
374       Process following steps of resetting E2
375       1. Deletes any pre-established RIC subscriptions
376       2. Gracefully terminates any ongoing RIC services
377     */
378
379    /* Send Reset Response if RIC initiated Reset request is received at DU */
380    if(dir == RIC_INITIATED)
381    {
382       //BuildAndSendE2ResetResponse();
383    }   
384    return ROK;
385 }
386
387 /*******************************************************************
388  *
389  * @brief Fill RIC Subscription datils in MAC Statistics Request
390  *
391  * @details
392  *
393  *    Function : fillRicSubsInMacStatsReq
394  *
395  *    Functionality: Fill RIC Subscription datils in MAC Statistics 
396  *       Request
397  *
398  * @params[in] MAC Statistics Request to be filled
399  *             RAN Function ID
400  *             RIC Subscription Info
401  *
402  * @return ROK     - success
403  *         RFAILED - failure
404  *
405  * ****************************************************************/
406 uint8_t fillRicSubsInMacStatsReq(MacStatsReq *macStatsReq, uint16_t ranFuncId, RicSubscription* ricSubscriptionInfo)
407 {
408    uint8_t    actionIdx = 0, grpIdx = 0, statsIdx = 0;
409    uint64_t   subscriptionId = 0;
410    ActionInfo *actionDb = NULLP;
411    ActionDefFormat1 *format1Action = NULLP;
412
413    /* Generate subscription ID using RIC Request ID and RAN Function ID */
414    encodeSubscriptionId(&subscriptionId, ranFuncId, ricSubscriptionInfo->requestId);
415
416    macStatsReq->subscriptionId = subscriptionId;
417    for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
418    {
419       if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
420       {
421          actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
422          macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
423          switch(actionDb->definition.formatType)
424          {
425             case 1:
426                {
427                   format1Action = &actionDb->definition.choice.format1;
428                   macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
429
430                   CmLList *node = NULLP;
431                   MeasurementInfo *measInfo = NULLP;
432                   statsIdx = 0;
433                   /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
434                   node = cmLListFirst(&format1Action->measurementInfoList);
435                   while(node)
436                   {
437                      measInfo = (MeasurementInfo *)(node->node);
438                      switch(measInfo->measurementTypeId)
439                      {
440                         case 1:
441                            {
442                               macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
443                               break;
444                            }
445                         case 2:
446                            {
447                               macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
448                               break;
449                            }
450                         default:
451                            {
452                               DU_LOG("\nERROR  -->  DU_APP : Invalid measurement name");
453                               break;
454                            }
455                      }
456                      node = node->next;
457                   }
458                   macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
459                   break;
460                }
461             default:
462                {
463                   DU_LOG("\nERROR  -->  DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
464                   break;
465                }
466          }
467          if(macStatsReq->statsGrpList[grpIdx].numStats)
468             grpIdx++;
469       }
470    }
471
472    macStatsReq->numStatsGroup = grpIdx;
473    if(macStatsReq->numStatsGroup)
474    {
475       return ROK;
476    }
477    return RFAILED;
478 }
479
480 /*******************************************************************
481  *
482  * @brief Rejects all actions received in a subscription request
483  *
484  * @details
485  *
486  *    Function : duRejectAllStatsGroup
487  *
488  *    Functionality: Rejects all actions received in a subscription
489  *       request by :
490  *       a. Removing the subscription entry from RAN function
491  *       b. Sending RIC Subscription Failure to RIC with appropriate
492  *          cause of failure
493  *
494  * @params[in] RAN Function DB
495  *             Subscription entry in RAN Function subscription list
496  *             Statistics Response from MAC
497  *
498  * @return ROK     - success
499  *         RFAILED - failure
500  *
501  * ****************************************************************/
502 uint8_t rejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp)
503 {
504    uint8_t ret = ROK;
505    RicRequestId  requestId;
506    E2FailureCause failureCause;
507
508    /* Delete subcription from RAN Function */
509    memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId));
510    cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode);
511    DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription));
512    DU_FREE(ricSubscriptionNode, sizeof(CmLList));
513
514    convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause);
515
516    /* Send RIC subscription failure to RIC */
517    ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause);
518    return ret;
519 }
520
521 /*******************************************************************
522  *
523  * @brief Process statistics response from MAC
524  *
525  * @details
526  *
527  *    Function : e2ProcStatsRsp
528  *
529  *    Functionality: Processes statistics configuration response
530  *       from MAC. If configuration is succsessful, DUAPP starts
531  *       reporting period timer for this subscription request
532  *       from RIC
533  *
534  * @params[in]
535  *
536  * @return ROK     - success
537  *         RFAILED - failure
538  *
539  * ****************************************************************/
540 void e2ProcStatsRsp(MacStatsRsp *statsRsp)
541 {
542    uint8_t idx = 0;
543    uint8_t actionId = 0;
544    RanFunction *ranFuncDb = NULLP;
545    CmLList *ricSubscriptionNode = NULLP;
546    RicSubscription *ricSubscriptionInfo = NULLP;
547    ActionInfo *actionInfoDb = NULLP;
548    PendingSubsRspInfo *pendingSubsRsp = NULLP;
549
550    /* Fetch RAN Function and Subscription DB using subscription Id received in statistics response */
551    if(fetchSubsInfoFromSubsId(statsRsp->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
552    {
553       DU_LOG("\nERROR  -->  DU_APP : DuProcMacStatsRsp: Failed to fetch subscriprtion details");
554       return;
555    }
556
557    /* Fetch pre-stored statistics response info by DU APP */
558    for(idx=0; idx<ranFuncDb->numPendingSubsRsp; idx++)
559    {
560       if((ranFuncDb->pendingSubsRspInfo[idx].requestId.requestorId == ricSubscriptionInfo->requestId.requestorId) &&
561             (ricSubscriptionInfo->requestId.instanceId == ricSubscriptionInfo->requestId.instanceId))
562       {
563          pendingSubsRsp = &ranFuncDb->pendingSubsRspInfo[idx];
564          break;
565       }
566    }
567
568    /* If no action is accepted
569     *  a. Remove subcription entry from RAN Function
570     *  b. Send RIC subscription failure */
571    if(statsRsp->numGrpAccepted == 0)
572    {
573       rejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp);
574    }
575    else
576    {
577       /* If even 1 action is accepted :
578        *
579        * For accepted groups:
580        *    Mark subscribed-action's -> action = CONFIG_UNKNOWN
581        *    Add to accepted-action-list of subscription response
582        */
583       for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
584       {
585          actionInfoDb = NULLP;
586
587          actionId = statsRsp->statsGrpAcceptedList[idx];
588          actionInfoDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo);
589          if(actionInfoDb && (actionInfoDb->action == CONFIG_ADD))
590          {
591             actionInfoDb->action = CONFIG_UNKNOWN;
592             pendingSubsRsp->acceptedActionList[pendingSubsRsp->numOfAcceptedActions++] = actionId;
593          }
594       }
595
596       /* For rejected groups:
597        *    Remove entry from DU's RAN Function->subscription->actionList
598        *    Add to rejected-action-list in subscription response
599        */
600       for(idx=0; idx<statsRsp->numGrpRejected; idx++)
601       {
602          actionId = statsRsp->statsGrpRejectedList[idx].groupId;
603          if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId)
604          {
605             memset(&ricSubscriptionInfo->actionSequence[actionId-1], 0, sizeof(ActionInfo));
606             ricSubscriptionInfo->numOfActions--;
607
608             pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].id = actionId;
609             convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[idx].cause, \
610                   &pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].failureCause);
611             pendingSubsRsp->numOfRejectedActions++;
612          }
613       }
614
615       /* Send subscription response with accepted and rejected action lists to RIC */
616       BuildAndSendRicSubscriptionRsp(pendingSubsRsp);
617    }
618    memset(pendingSubsRsp, 0, sizeof(PendingSubsRspInfo));
619 }
620
621 /*******************************************************************
622  *
623  * @brief Extract and store statistics received from DU layers
624  *
625  * @details
626  *
627  *    Function : e2ProcStatsInd
628  *
629  *    Functionality: Extract statistics received from DU layers
630  *       and store in respective RAN function's subscription's
631  *       action
632  *
633  * @params[in] Statistics Indication message received from MAC
634  * @return void
635  *
636  * ****************************************************************/
637 void e2ProcStatsInd(MacStatsInd *statsInd)
638 {
639    RanFunction *ranFuncDb = NULLP;
640    CmLList *ricSubscriptionNode = NULLP;
641    RicSubscription *ricSubscriptionInfo = NULLP;
642
643    /* TODO : When stats indication is received
644     * DU APP searches for the message type in E2AP RIC subscription
645     * database and stores in the value in the list of subscribed measurements
646     *
647     * This will be implemented in next gerrit.
648     */
649
650    /* Fetch RAN Function and Subscription DB using subscription Id received
651     * in statistics response */
652    if(fetchSubsInfoFromSubsId(statsInd->subscriptionId, &ranFuncDb, &ricSubscriptionNode, &ricSubscriptionInfo) != ROK)
653    {
654       DU_LOG("\nERROR  -->  DU_APP : extractStatsMeasurement: Failed to fetch subscriprtion details");
655       return;
656    }
657 }
658
659 /******************************************************************
660  *
661  * @brief Search E2 node component with the help of action type
662  *
663  * @details
664  *
665  *    Function : fetchE2NodeComponentInfo 
666  *
667  *    Functionality: Search E2 node component with the help of action type 
668  *
669  * @params[in] 
670  *       Type of interface 
671  *       Component action type
672  *       Pointer to E2 component node to be searched 
673  * @return CmLList
674  *
675  * ****************************************************************/
676
677 E2NodeComponent *fetchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType, CmLList **e2ComponentNode)
678 {
679    E2NodeComponent *e2NodeComponentInfo=NULLP;
680
681    if(duCb.e2apDb.e2NodeComponentList.count)
682    {
683       CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, *e2ComponentNode);
684       while(*e2ComponentNode)
685       {
686          e2NodeComponentInfo = (E2NodeComponent*)((*e2ComponentNode)->node);
687          if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType))
688          {
689             
690             break;
691          }
692          
693          *e2ComponentNode = (*e2ComponentNode)->next;
694          e2NodeComponentInfo = NULLP;
695       }
696    }
697    return e2NodeComponentInfo; 
698 }
699
700 /*******************************************************************
701  *
702  * @brief add or modify E2NodeComponent list
703  *
704  * @details
705  *
706  *    Function : addOrModifyE2NodeComponent 
707  *
708  * Functionality: add or modify E2NodeComponent list 
709  *
710  * @parameter
711  *       Type of interface 
712  *       Component action type
713  *       boolean variable to check req or rsp msg type
714  *       Size of buffer which needs to be store
715  *       buffer string which needs to be store 
716  * @return ROK     - success
717  *         RFAILED - failure
718  *
719  ******************************************************************/
720
721 uint8_t addOrModifyE2NodeComponent(InterfaceType interfaceType, uint8_t action, bool reqPart, uint8_t bufSize, char *bufString)
722 {
723    E2NodeComponent *e2NodeComponentInfo= NULL;
724    CmLList  *node = NULLP;
725    
726    if(reqPart == true)
727    {
728       DU_ALLOC(e2NodeComponentInfo, sizeof(E2NodeComponent));
729       if(!e2NodeComponentInfo)
730       {
731          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for e2NodeComponentInfo in %s",__func__);
732          return RFAILED;
733       }
734       e2NodeComponentInfo->interfaceType =interfaceType;
735       e2NodeComponentInfo->componentId=duCfgParam.duId;
736       e2NodeComponentInfo->componentActionType = action;
737       e2NodeComponentInfo->reqBufSize = bufSize;
738
739       DU_ALLOC(e2NodeComponentInfo->componentRequestPart, bufSize);
740       if(e2NodeComponentInfo->componentRequestPart == NULLP)
741       {
742          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for componentRequestPart");
743          DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
744          return RFAILED;
745       }
746       memcpy(e2NodeComponentInfo->componentRequestPart, bufString, e2NodeComponentInfo->reqBufSize);
747       DU_ALLOC(node, sizeof(CmLList));
748       if(node)
749       {
750          node->node = (PTR) e2NodeComponentInfo;
751          cmLListAdd2Tail(&duCb.e2apDb.e2NodeComponentList, node);
752       }
753       else
754       {
755          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for e2NodeComponentList node");
756          DU_FREE(e2NodeComponentInfo->componentRequestPart, bufSize);
757          DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
758          return RFAILED;
759       }
760    }
761    else
762    {
763       if(duCb.e2apDb.e2NodeComponentList.count)
764       {
765          e2NodeComponentInfo = fetchE2NodeComponentInfo(interfaceType, action, &node);
766          if(e2NodeComponentInfo->componentRequestPart== NULLP)
767          {
768             DU_LOG("\nERROR  -->  E2AP : E2 node Component request part is not present");
769             return RFAILED;
770          }
771          
772          e2NodeComponentInfo->rspBufSize = bufSize;
773          DU_ALLOC(e2NodeComponentInfo->componentResponsePart, bufSize);
774          if(e2NodeComponentInfo->componentResponsePart == NULLP)
775          {
776             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed to store the encoding of rsp");
777             return RFAILED;
778          }
779          memcpy(e2NodeComponentInfo->componentResponsePart, bufString, e2NodeComponentInfo->rspBufSize);
780          return ROK;
781       }
782       else
783       {
784          DU_LOG("\nERROR  -->  E2AP : Unable to find the node");
785          return RFAILED;
786       }
787    } 
788    return ROK;
789 }
790
791 /**********************************************************************
792   End of file
793  **********************************************************************/
794