[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-553] Transid fixes in E2AP procedures
[o-du/l2.git] / src / ric_stub / ric_e2ap_msg_hdl.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
19 /* This file contains E2AP message handler functions */
20 #include "common_def.h"
21 #include "OCTET_STRING.h"
22 #include "BIT_STRING.h"
23 #include "odu_common_codec.h"
24 #include "ric_stub_sctp.h"
25 #include "ric_stub.h"
26 #include "ric_e2ap_msg_hdl.h"
27 #include "GlobalE2node-gNB-ID.h"
28 #include "ProtocolIE-FieldE2.h"
29 #include "InitiatingMessageE2.h"
30 #include "SuccessfulOutcomeE2.h"
31 #include "UnsuccessfulOutcomeE2.h"
32 #include "E2AP-PDU.h"
33 #include "du_log.h"
34 #include "E2nodeComponentInterfaceF1.h"
35 #include "E2SM-KPM-RANfunction-Description.h"
36 #include "RANfunction-Name.h"
37 #include "RIC-EventTriggerStyle-Item.h"
38 #include "RIC-ReportStyle-Item.h"
39 #include "MeasurementInfo-Action-Item.h"
40 #include "MeasurementInfoItem.h"
41 #include "E2SM-KPM-ActionDefinition-Format1.h"
42 #include "E2SM-KPM-ActionDefinition.h"
43 #include "E2SM-KPM-EventTriggerDefinition-Format1.h"
44 #include "E2SM-KPM-EventTriggerDefinition.h"
45 #include "E2connectionUpdate-Item.h"
46
47 /*******************************************************************
48  *
49  * @brief Printing Type and Cause of failure
50  *
51  * @details
52  *
53  *    Function : printE2ErrorCause
54  *
55  *    Functionality: Printing Type and Cause of failure
56  *
57  * @params[in] E2 Cause
58  * @return void
59  *
60  ******************************************************************/
61
62 void printE2ErrorCause(CauseE2_t *cause)
63 {
64    switch(cause->present)
65    {
66       case CauseE2_PR_ricRequest:
67          {
68             DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Request", cause->choice.ricRequest);
69             break;
70          }
71       case CauseE2_PR_ricService:
72          {
73             DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Service", cause->choice.ricService);
74             break;
75          }
76       case CauseE2_PR_e2Node:
77          {
78             DU_LOG("Failure_Type [%s] Cause [%ld]", "E2_Node", cause->choice.e2Node);
79             break;
80          }
81       case CauseE2_PR_transport:
82          {
83             DU_LOG("Failure_Type [%s] Cause [%ld]", "Transport", cause->choice.transport);
84             break;
85          }
86       case CauseE2_PR_protocol:
87          {
88             DU_LOG("Failure_Type [%s] Cause [%ld]", "Protocol", cause->choice.protocol);
89             break;
90          }
91       case CauseE2_PR_misc:
92          {
93             DU_LOG("Failure_Type [%s] Cause [%ld]", "Miscellaneous", cause->choice.misc);
94             break;
95          }
96       default:
97          {
98             DU_LOG("Failure_Type and Cause unknown");
99             break;
100          }
101    }
102 }
103
104 /*******************************************************************
105  *
106  * @brief fill E2 failure cause 
107  *
108  * @details
109  *
110  *    Function : fillE2FailureCause
111  *
112  * Functionality: fill E2 failure cause
113  * @return ROK     - success
114  *         RFAILED - failure
115  *
116  ******************************************************************/
117
118 void fillE2FailureCause(CauseE2_t *cause, CauseE2_PR causePresent, uint8_t reason)
119 {
120    cause->present = causePresent;
121
122    switch(cause->present)
123    {
124       case CauseE2_PR_ricRequest:
125          cause->choice.ricRequest = reason;
126          break;
127       case CauseE2_PR_ricService:
128          cause->choice.ricService = reason;
129          break;
130       case CauseE2_PR_e2Node:
131          cause->choice.e2Node = reason;
132          break;
133       case CauseE2_PR_transport:
134          cause->choice.transport = reason;
135          break;
136       case CauseE2_PR_protocol:
137          cause->choice.protocol = reason;
138          break;
139       case CauseE2_PR_misc:
140          cause->choice.misc = reason;
141          break;
142       default:
143          cause->choice.misc = CauseE2Misc_unspecified;
144          break;
145    }
146 }
147
148 /*******************************************************************
149  *
150  * @brief Assigns new transaction id to RIC initiated procedure
151  *
152  * @details
153  *
154  *    Function : assignTransactionId
155  *
156  *    Functionality: Assigns new transaction id to a RIC initiated
157  *       procedure
158  *
159  * @params[in] Region region
160  *             Pool pool
161  * @return ROK     - success
162  *         RFAILED - failure
163  *
164  * ****************************************************************/
165
166 uint8_t assignTransactionId(DuDb *duDb)
167 {
168    uint8_t currTransId = duDb->ricTransIdCounter;
169
170    /* Update to next valid value */
171    duDb->ricTransIdCounter++;
172    if(duDb->ricTransIdCounter == MAX_NUM_TRANSACTION)
173       duDb->ricTransIdCounter = 0;
174
175    return currTransId;
176 }
177
178  /*******************************************************************
179  *
180  * @brief add RIC Subs action info
181  *
182  * @details
183  *
184  *    Function : addRicSubsAction
185  *
186  * Functionality: add Ric Subs action info
187  *
188  * @parameter
189  *    RIC action id
190  *    List of action 
191  * @return ROK     - success
192  *         RFAILED - failure
193  *
194  ******************************************************************/
195 CmLList *addRicSubsAction(uint8_t ricActionID, CmLListCp *actionSequence)
196 {
197    ActionInfo *actionDb = NULLP;
198    CmLList *actionNode=NULLP;
199    
200    RIC_ALLOC(actionDb, sizeof(ActionInfo));
201    if(actionDb==NULLP)
202    {
203       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
204       return NULLP;
205    }
206    
207    actionDb->actionId = ricActionID;   
208    RIC_ALLOC(actionNode, sizeof(CmLList));
209    if(actionNode)
210    {
211       actionNode->node = (PTR) actionDb;
212       cmLListAdd2Tail(actionSequence, actionNode);
213    }
214    else
215    {
216       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at %d",__func__,__LINE__);
217       RIC_FREE(actionDb, sizeof(ActionInfo));
218       return NULLP;
219    }
220    
221    return actionNode;
222 }
223
224 /*******************************************************************
225 *
226 * @brief Sends E2 msg over SCTP
227 *
228 * @details
229 *
230 *    Function : SendE2APMsg
231 *
232 *    Functionality: Sends E2 msg over SCTP
233 *
234 * @params[in] Region region
235 *             Pool pool
236 * @return ROK     - success
237 *         RFAILED - failure
238 *
239 * ****************************************************************/
240
241 uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId)
242 {
243    Buffer *mBuf;
244
245    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
246    {
247       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
248       {
249          ODU_PRINT_MSG(mBuf, 0,0);
250
251          if(sctpSend(duId, mBuf) != ROK)
252          {
253             DU_LOG("\nERROR  -->  E2AP : SCTP Send for E2  failed");
254             ODU_PUT_MSG_BUF(mBuf);
255             return RFAILED;
256          }
257       }
258       else
259       {
260          DU_LOG("\nERROR  -->  E2AP : ODU_ADD_POST_MSG_MULT failed");
261          ODU_PUT_MSG_BUF(mBuf);
262          return RFAILED;
263       }
264       ODU_PUT_MSG_BUF(mBuf);
265    }
266    else
267    {
268       DU_LOG("\nERROR  -->  E2AP : Failed to allocate memory");
269       return RFAILED;
270    }
271
272    return ROK;
273 } /* SendE2APMsg */
274
275 /*******************************************************************
276  *
277  * @brief Deallocate the memory allocated for RemovalRequest msg
278  *
279  * @details
280  *
281  *    Function : FreeRemovalRequest
282  *
283  *    Functionality:
284  *       - freeing the memory allocated for RemovalRequest
285  *
286  * @params[in] E2AP_PDU_t *e2apMsg
287  * @return ROK     - success
288  *         RFAILED - failure
289  *
290  * ****************************************************************/
291 void FreeRemovalRequest(E2AP_PDU_t *e2apMsg)
292 {
293    uint8_t ieIdx =0;
294    E2RemovalRequest_t  *removalReq = NULLP;
295
296    if(e2apMsg != NULLP)
297    {
298       if(e2apMsg->choice.initiatingMessage != NULLP)
299       {
300          removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
301          if(removalReq->protocolIEs.list.array)
302          {
303             for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++)
304             {
305                RIC_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
306             }
307             RIC_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
308          }
309          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
310       }
311       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
312    }
313 }
314
315 /*******************************************************************
316  *
317  * @brief Build and send the removal request msg
318  *
319  * @details
320  *
321  *    Function : BuildAndSendRemovalRequest
322  *
323  *    Functionality:
324  *         - Buld and send the removal request msg to E2 node
325  *
326  * @params[in]
327  *    DU database
328  *    Type of failure
329  *    Cause of failure
330  * @return ROK     - success
331  *         RFAILED - failure
332  *
333  * ****************************************************************/
334 uint8_t BuildAndSendRemovalRequest(DuDb *duDb)
335 {
336    uint8_t ieIdx = 0, elementCnt = 0;
337    uint16_t transId = 0;
338    uint8_t ret = RFAILED;
339    E2AP_PDU_t        *e2apMsg = NULLP;
340    E2RemovalRequest_t  *removalReq = NULLP;
341    asn_enc_rval_t     encRetVal;       /* Encoder return value */
342
343    DU_LOG("\nINFO   -->  E2AP : Building Removal Request\n");
344
345    do
346    {
347       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
348       if(e2apMsg == NULLP)
349       {
350          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
351          break;
352       }
353
354       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
355       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
356       if(e2apMsg->choice.initiatingMessage == NULLP)
357       {
358          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
359          break;
360       }
361
362       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal;
363       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
364       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest;
365       removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest;
366
367       elementCnt = 1;
368       removalReq->protocolIEs.list.count = elementCnt;
369       removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *);
370
371       RIC_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size);
372       if(!removalReq->protocolIEs.list.array)
373       {
374          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
375          break;
376       }
377
378       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
379       {
380          RIC_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t));
381          if(!removalReq->protocolIEs.list.array[ieIdx])
382          {
383             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
384             break;
385          }
386       }
387
388       /* In case of failure */
389       if(ieIdx < elementCnt)
390          break;
391
392       ieIdx = 0;
393       removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
394       removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
395       removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID;
396       transId = assignTransactionId(duDb);
397       removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
398
399       /* Prints the Msg formed */
400       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
401
402       memset(encBuf, 0, ENC_BUF_MAX_LEN);
403       encBufSize = 0;
404       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
405             encBuf);
406       if(encRetVal.encoded == ENCODE_FAIL)
407       {
408          DU_LOG("\nERROR  -->  E2AP : Could not encode removal request structure (at %s)\n",\
409                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
410          break;
411       }
412       else
413       {
414          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for removal request\n");
415 #ifdef DEBUG_ASN_PRINT
416          for(int i=0; i< encBufSize; i++)
417          {
418             printf("%x",encBuf[i]);
419          }
420 #endif
421       }
422       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
423       {
424          DU_LOG("\nERROR  -->  E2AP : Sending removal request failed");
425          break;
426       }
427
428
429       ret = ROK;
430       break;
431    }while(true);
432
433    /* Free all memory */
434    FreeRemovalRequest(e2apMsg);
435    return ret;
436 }
437
438 /*******************************************************************
439  *
440  * @brief Fetches RAN Function DB
441  *
442  * @details
443  *
444  *    Function : fetchRanFuncFromRanFuncId
445  *
446  *    Functionality: Fetches RAN function DB from E2AP DB using
447  *       RAN function ID
448  *
449  * @params[in] RAN Function ID
450  * @return RAN Function DB
451  *         NULL, in case of failure
452  *
453  * ****************************************************************/
454 RanFunction *fetchRanFuncFromRanFuncId(DuDb *duDb, uint16_t ranFuncId)
455 {
456    RanFunction *ranFuncDb = NULLP;
457
458    /* Fetch RAN Function DB */
459    if(duDb->ranFunction[ranFuncId-1].id == ranFuncId)
460    {
461       ranFuncDb = &duDb->ranFunction[ranFuncId-1];
462    }
463    else
464    {
465       DU_LOG("\nERROR  -->  DU_APP : fetchRanFuncFromRanFuncId: Invalid RAN Function ID[%d]", ranFuncId);
466    }
467
468    return ranFuncDb;
469 }
470
471 /*******************************************************************
472  *
473  * @brief Fetch subscripton DB
474  *
475  * @details
476  *
477  *    Function : fetchSubsInfoFromRicReqId
478  *
479  *    Functionality: Fetches subscription DB from RAN Function DB
480  *       using RIC Request ID
481  *
482  * @params[in] RIC Request ID
483  *             RAN Function DB
484  *             Pointer to RIC Subscription node to be searched
485  * @return RIC Subscription from RAN Function's subcription list
486  *         NULL, in case of failure
487  *
488  * ****************************************************************/
489 RicSubscription *fetchSubsInfoFromRicReqId(RicRequestId ricReqId, RanFunction *ranFuncDb, CmLList **ricSubscriptionNode)
490 {
491    RicSubscription *ricSubscriptionInfo = NULLP;
492
493    /* Fetch subscription detail in RAN Function DB */
494    CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, *ricSubscriptionNode);
495    while(*ricSubscriptionNode)
496    {
497       ricSubscriptionInfo = (RicSubscription *)((*ricSubscriptionNode)->node);
498       if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
499             (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
500       {
501          break;
502       }
503       *ricSubscriptionNode = (*ricSubscriptionNode)->next;
504       ricSubscriptionInfo = NULLP;
505    }
506
507    if(!ricSubscriptionInfo)
508    {
509       DU_LOG("\nERROR  -->  E2AP : fetchSubsInfoFromRicReqId: Subscription not found for Requestor ID [%d] \
510          Instance ID [%d] in RAN Function ID [%d]", ricReqId.requestorId, ricReqId.instanceId, ranFuncDb->id);
511    }
512
513    return ricSubscriptionInfo;
514 }
515
516 /*******************************************************************
517  *
518  * @brief Fetch Action details
519  *
520  * @details
521  *
522  *    Function : fetchActionInfoFromActionId
523  *
524  *    Functionality: Fetch action details from RIC subscription DB
525  *       using action ID
526  *
527  * @params[in] Action ID
528  *             RIC Subscription DB
529  *             List of action 
530  * @return Action Info DB
531  *         NULL, in case of failure
532  *
533  * ****************************************************************/
534 ActionInfo *fetchActionInfoFromActionId(uint8_t actionId, RicSubscription *ricSubscriptionInfo, CmLList ** actionNode)
535 {
536    ActionInfo *actionInfoDb = NULLP;
537
538    CM_LLIST_FIRST_NODE(&ricSubscriptionInfo->actionSequence, *actionNode);
539    while(*actionNode)
540    {
541        actionInfoDb = (ActionInfo*)((*actionNode)->node);
542       if(actionInfoDb->actionId == actionId)
543       {
544          break;
545       }
546       *actionNode= (*actionNode)->next;
547    }
548    if(actionInfoDb==NULLP) 
549    {
550       DU_LOG("\nERROR  -->  E2AP : fetchActionInfoFromActionId: Action Id [%d] not found in \
551             subscription info [Requestor id : %d] [Instance Id : %d]", actionId,\
552             ricSubscriptionInfo->requestId.requestorId, ricSubscriptionInfo->requestId.instanceId);
553
554    }
555    return actionInfoDb;
556 }
557
558 /******************************************************************
559  *
560  * @brief Search E2 node component with the help of interface type
561  * and component Id
562  *
563  * @details
564  *
565  *    Function : fetchE2NodeComponentInfo
566  *
567  *    Functionality: Search E2 node component 
568  *
569  * @params[in]
570  *       DU databse
571  *       Type of interface
572  *       Pointer to E2 component node to be searched
573  * @return CmLList
574  *
575  * ****************************************************************/
576
577 E2NodeComponent *fetchE2NodeComponentInfo(DuDb *duDb, InterfaceType interfaceType,CmLList **e2ComponentNode)
578 {
579    E2NodeComponent *e2NodeComponentInfo=NULLP;
580
581    if(duDb->e2NodeComponent.count)
582    {
583       CM_LLIST_FIRST_NODE(&duDb->e2NodeComponent, *e2ComponentNode);
584       while(*e2ComponentNode)
585       {
586          e2NodeComponentInfo = (E2NodeComponent*)((*e2ComponentNode)->node);
587          if((e2NodeComponentInfo->interfaceType == interfaceType))
588          {
589             break;
590          }
591
592          *e2ComponentNode = (*e2ComponentNode)->next;
593          e2NodeComponentInfo = NULLP;
594       }
595    }
596    return e2NodeComponentInfo;
597 }
598
599 /*******************************************************************
600  *
601  * @brief update E2 node config list
602  *
603  * @details
604  *
605  *    Function : updateE2NodeConfigList
606  *
607  *    Functionality:
608  *         - update E2 node config list
609  * @params[in]
610  *    DU databse
611  *    Protocol Id
612  *    Configuration which need to update in Database
613  *
614  * @return ROK     - success
615  *         RFAILED - failure
616  *
617  * ****************************************************************/
618 uint8_t updateE2NodeConfigList(DuDb **duDb, uint8_t protocolId, E2NodeConfigItem *tmpCfg)
619 {
620    CmLList *node;
621    E2NodeComponent * e2NodeComponentInfo;
622    bool configFound= false;
623
624    switch(protocolId)
625    {
626       case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
627          {
628             /* Adding the new e2 node component in DB*/
629             RIC_ALLOC(e2NodeComponentInfo, sizeof(E2NodeComponent));
630             e2NodeComponentInfo->interfaceType = tmpCfg->componentInfo.interfaceType;
631             e2NodeComponentInfo->componentId =tmpCfg->componentInfo.componentId;
632             RIC_ALLOC(node, sizeof(CmLList));
633             if(node)
634             {
635                node->node = (PTR) e2NodeComponentInfo;
636                cmLListAdd2Tail(&(*duDb)->e2NodeComponent, node);
637                configFound =true;
638             }
639             else
640             {
641                DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for e2NodeComponentList node");
642                RIC_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
643                return RFAILED;
644             }
645             break;
646          }
647       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
648          {
649             /* searching for information in a database */
650             e2NodeComponentInfo = fetchE2NodeComponentInfo((*duDb),tmpCfg->componentInfo.interfaceType,  &node);
651             if(!e2NodeComponentInfo)
652             {
653                DU_LOG("\nERROR  -->  E2AP : Failed to find the e2 component node");
654                return RFAILED;
655             }
656             /* If the node is present then update the value */
657             e2NodeComponentInfo->componentId =tmpCfg->componentInfo.componentId;
658             configFound =true;
659             break;
660          }
661       case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
662          {
663             /* searching for information in a database */
664             e2NodeComponentInfo = fetchE2NodeComponentInfo((*duDb),tmpCfg->componentInfo.interfaceType, &node);
665             if(!e2NodeComponentInfo)
666             {
667                DU_LOG("\nERROR  -->  E2AP : Failed to find the e2 component node");
668                return RFAILED;
669             }
670             /* Delete the node from the list  */
671             e2NodeComponentInfo->componentId = tmpCfg->componentInfo.componentId;
672             cmLListDelFrm(&(*duDb)->e2NodeComponent, node);
673             RIC_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent));
674             configFound =true;
675             break;
676          }
677    }
678
679    /* If the configuration update was successful, then mark the isSuccessful as
680     * true; otherwise, mark it as false. */ 
681    if(configFound == true)
682       tmpCfg->isSuccessful = true;
683    else
684       tmpCfg->isSuccessful = false;
685
686    return ROK;
687 }
688
689 /*******************************************************************
690  *
691  * @brief Handling the E2 node configuration depending on the add, 
692  * update, or remove configuration type
693  *
694  * @details
695  *
696  *    Function : handleE2NodeComponentAction
697  *
698  *    Functionality:
699  *         - Handling the E2 node configuration depending on the add,
700  *         update, or remove configuration type
701  * @params[in] 
702  *    DU database
703  *    Pointer to e2NodeCfg which has info 
704  *    ProtocolId
705  *    E2NodeConfigItem to be filled
706  *
707  * @return ROK     - success
708  *         RFAILED - failure
709  *
710  * ****************************************************************/
711
712 uint8_t handleE2NodeComponentAction(DuDb *duDb, PTR e2NodeCfg, uint8_t protocolId, E2NodeConfigItem *storeCfg)
713 {
714    uint8_t configFound = ROK;
715    E2NodeConfigItem tmpCfg;
716    E2nodeComponentID_t componentId;
717    E2nodeComponentInterfaceType_t interface;
718    E2nodeComponentConfigAddition_Item_t *addCfg=NULL;
719    E2nodeComponentConfigUpdate_Item_t *updateCfg=NULL;
720    E2nodeComponentConfigRemoval_Item_t *removeCfg=NULL;
721    
722    /* fetching the interface and component id information from the e2NodeCfg */
723    memset(storeCfg, 0, sizeof(E2NodeConfigItem));
724    storeCfg->isSuccessful=false;
725    memset(&tmpCfg, 0, sizeof(E2NodeConfigItem));
726
727    switch(protocolId)
728    {
729       case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
730          {
731             addCfg = (E2nodeComponentConfigAddition_Item_t *)e2NodeCfg;
732             interface = addCfg->e2nodeComponentInterfaceType;
733             componentId = addCfg->e2nodeComponentID;
734             break;
735          }
736       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
737          {
738             updateCfg = (E2nodeComponentConfigUpdate_Item_t *)e2NodeCfg;
739             interface = updateCfg->e2nodeComponentInterfaceType;
740             componentId = updateCfg->e2nodeComponentID;
741             break;
742          }
743       case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
744          {
745             removeCfg = (E2nodeComponentConfigRemoval_Item_t*)e2NodeCfg;
746             interface = removeCfg->e2nodeComponentInterfaceType;
747             componentId = removeCfg->e2nodeComponentID;
748             break;
749          }
750    }
751    
752    /* Storing the information in temporary structure */
753    tmpCfg.componentInfo.interfaceType = interface;
754
755    switch(componentId.present)
756    {
757       case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
758          {
759             if(componentId.choice.e2nodeComponentInterfaceTypeF1)
760             {
761                tmpCfg.componentInfo.componentId = componentId.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0];
762             }
763             break;
764          }
765       default:
766          {
767             break;
768          }
769    }
770
771    /* Updating the database configuration  */ 
772    configFound = updateE2NodeConfigList(&duDb, protocolId, &tmpCfg);
773
774    memcpy(storeCfg, &tmpCfg,sizeof(E2NodeConfigItem));  
775    return configFound;
776
777 }
778
779 /*******************************************************************
780  *
781  * @brief deallocate memory allocated in E2 Node Config Update Failure
782  *
783  * @details
784  *
785  *    Function : FreeE2ConfigUpdateFail
786  *
787  *    Functionality: deallocate memory allocated in E2 Node Config Update Failure
788  *
789  * @params[in] E2AP_PDU_t *e2apMsg
790  *
791  * @return void
792  * ****************************************************************/
793
794 void FreeE2ConfigUpdateFail(E2AP_PDU_t *e2apMsg)
795 {
796    uint8_t arrIdx = 0;
797    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL;
798
799    if(e2apMsg)
800    {
801       if(e2apMsg->choice.unsuccessfulOutcome)
802       {
803          e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
804          if(e2NodeCfgUpdFail->protocolIEs.list.array)
805          {
806             for(arrIdx=0; arrIdx<e2NodeCfgUpdFail->protocolIEs.list.count; arrIdx++)
807             {
808                RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateFailure_IEs_t));
809             }
810             RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array, e2NodeCfgUpdFail->protocolIEs.list.size);
811          }
812          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
813       }
814       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
815    }
816 }
817
818 /*******************************************************************
819  *
820  * @brief Buld and send the E2 Node Config Update failure
821  *
822  * @details
823  *
824  *    Function : BuildAndSendE2NodeConfigUpdateFailure
825  *
826  *    Functionality:
827  *         - Buld and send the E2 Node Config Update failure
828  * @return ROK     - success
829  *         RFAILED - failure
830  *
831  * ****************************************************************/
832
833 uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint16_t transId, uint8_t causeInfo, uint8_t causeReason)
834 {
835    E2AP_PDU_t         *e2apMsg = NULL;
836    asn_enc_rval_t     encRetVal;
837    uint8_t            arrIdx=0;
838    uint8_t            elementCnt=0;
839    bool  memAllocFailed = false;
840    E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdateFail=NULL;
841
842    DU_LOG("\nINFO   -->  E2AP : Building E2 Node Config Update failure\n");
843    while(true)
844    {
845       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
846       if(e2apMsg == NULLP)
847       {
848          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
849          break;
850       }
851       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
852       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
853       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
854       {
855          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
856          break;
857       }
858
859       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
860       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
861       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure;
862       e2NodeCfgUpdateFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure;
863
864       elementCnt = 3;
865       e2NodeCfgUpdateFail->protocolIEs.list.count = elementCnt;
866       e2NodeCfgUpdateFail->protocolIEs.list.size  = elementCnt * sizeof(struct E2nodeConfigurationUpdateFailure_IEs *);
867
868       RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array, e2NodeCfgUpdateFail->protocolIEs.list.size);
869       if(e2NodeCfgUpdateFail->protocolIEs.list.array == NULLP)
870       {
871          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2 node config update failure array failed");
872          break;
873       }
874
875       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
876       {
877          RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx], sizeof(struct E2nodeConfigurationUpdateFailure_IEs));
878          if(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx] == NULLP)
879          {
880             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2 node config update failure IEs failed");
881             memAllocFailed = true;
882             break;
883          }
884       }
885
886       if(memAllocFailed == true)
887       {
888           break;
889       }
890
891       /* Trans Id */
892       arrIdx = 0;
893       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
894       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
895       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
896       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
897
898       arrIdx++;
899       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
900       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
901       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
902       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = causeInfo;
903       if(causeInfo == CauseE2_PR_e2Node) 
904          e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.e2Node = causeReason;
905       else
906          e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.misc = causeReason;
907
908       arrIdx++;
909       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
910       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
911       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
912       e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
913
914       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
915       memset(encBuf, 0, ENC_BUF_MAX_LEN);
916       encBufSize = 0;
917       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
918
919       /* Check encode results */
920       if(encRetVal.encoded == ENCODE_FAIL)
921       {
922          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node Config Update failure structure (at %s)\n",\
923                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
924          break;
925       }
926       else
927       {
928          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node Config Update Failure\n");
929          for(int i=0; i< encBufSize; i++)
930          {
931             DU_LOG("%x",encBuf[i]);
932          }
933       }
934
935       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
936       {
937          DU_LOG("\nERROR  -->  E2AP : Sending E2 Node Config Update Failure failed");
938          break;
939       }
940       break;
941    }
942
943    FreeE2ConfigUpdateFail(e2apMsg);
944    return ROK;
945 }
946
947 /*******************************************************************
948  *
949  * @brief process the E2 node configuration update
950  *
951  * @details
952  *
953  *    Function : ProcE2NodeConfigUpdate 
954  *
955  * Functionality: Process E2 node configuration update
956  *
957  * @params[in]
958  *    DU id
959  *    Pointer to E2nodeConfigurationUpdate
960  * @return Void
961  *
962  ******************************************************************/
963
964 void ProcE2NodeConfigUpdate(uint32_t duId, E2nodeConfigurationUpdate_t *e2NodeConfigUpdate)
965 {
966    DuDb    *duDb = NULLP;
967    E2NodeConfigList tmpE2NodeList;
968    uint16_t arrIdx=0;
969    uint8_t ieIdx = 0, duIdx = 0, elementCnt=0;
970    uint16_t transId = 0; 
971    E2nodeComponentConfigAddition_List_t *e2NodeAddList=NULL;
972    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe=NULL;
973    E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL;
974    E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList=NULLP;
975    E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe=NULLP;
976    E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULLP;
977    E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList=NULL;
978    E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL;
979    E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL;
980
981    SEARCH_DU_DB(duIdx, duId, duDb);
982    if(duDb == NULLP)
983    {
984       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
985       return;
986    }
987    
988    memset(&tmpE2NodeList, 0, sizeof(E2NodeConfigList));
989    if(!e2NodeConfigUpdate)
990    {
991       DU_LOG("\nERROR  -->  E2AP : e2NodeConfigUpdate pointer is null");
992       return;
993    }
994    if(!e2NodeConfigUpdate->protocolIEs.list.array)
995    {
996        DU_LOG("\nERROR  -->  E2AP : e2NodeConfigUpdate array pointer is null");
997       return;
998    }
999    
1000    elementCnt = e2NodeConfigUpdate->protocolIEs.list.count;
1001    for(ieIdx=0; ieIdx < e2NodeConfigUpdate->protocolIEs.list.count; ieIdx++)
1002    {
1003       if(!e2NodeConfigUpdate->protocolIEs.list.array[ieIdx])
1004       {
1005          DU_LOG("\nERROR  -->  E2AP : e2NodeConfigUpdate array idx %d pointer is null",arrIdx);
1006          break;
1007       }
1008       
1009       switch(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->id)
1010       {
1011          case ProtocolIE_IDE2_id_TransactionID:
1012             {
1013                transId = e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
1014                if(transId < 0 || transId > 255)
1015                {
1016                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
1017                   return;
1018                }
1019                break;
1020             }
1021
1022          case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
1023             {
1024                e2NodeAddList =&e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2nodeComponentConfigAddition_List;
1025                if(e2NodeAddList->list.array)
1026                {
1027                   for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++)
1028                   {
1029                      e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx];
1030                      e2NodeAddItem =  &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item;
1031                      /* Storing the E2 node information in DB */
1032                      if(handleE2NodeComponentAction(duDb, (PTR)e2NodeAddItem, ProtocolIE_IDE2_id_E2nodeComponentConfigAddition,\
1033                      &tmpE2NodeList.addedE2Node[tmpE2NodeList.addedE2NodeCount++]) != ROK)
1034                      {
1035                         DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",arrIdx);
1036                      }
1037                   }
1038                }
1039                break;
1040             }
1041
1042          case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate:
1043             {
1044                e2NodeUpdateList =&e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2nodeComponentConfigUpdate_List;
1045                if(e2NodeUpdateList->list.array)
1046                {
1047                   for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++)
1048                   {
1049                      e2NodeUpdateItemIe = (E2nodeComponentConfigUpdate_ItemIEs_t*) e2NodeUpdateList->list.array[arrIdx];
1050                      e2NodeUpdateItem =  &e2NodeUpdateItemIe->value.choice.E2nodeComponentConfigUpdate_Item;
1051
1052                      /* Updating the E2 node information in DB */
1053                      if(handleE2NodeComponentAction(duDb, (PTR)e2NodeUpdateItem, ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate,\
1054                               &tmpE2NodeList.updatedE2Node[tmpE2NodeList.updatedE2NodeCount++]) != ROK)
1055                      {
1056                         DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",arrIdx);
1057                      }
1058                   }
1059                }
1060                break;
1061             }
1062
1063          case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval:
1064             {
1065                e2NodeRemoveList = &e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2nodeComponentConfigRemoval_List;
1066                if(e2NodeRemoveList->list.array)
1067                {
1068                   for(arrIdx = 0; arrIdx< e2NodeRemoveList->list.count; arrIdx++)
1069                   {
1070                      e2NodeRemovalItemIe = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemoveList->list.array[arrIdx];
1071                      e2NodeRemovalItem =  &e2NodeRemovalItemIe->value.choice.E2nodeComponentConfigRemoval_Item;
1072
1073                      /* Removing the E2 node information in DB */
1074                      if(handleE2NodeComponentAction(duDb, (PTR)e2NodeRemovalItem, ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval,\
1075                               &tmpE2NodeList.removedE2Node[tmpE2NodeList.removedE2NodeCount++]) != ROK)
1076                      {
1077                         DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",arrIdx);
1078                      }
1079                   }
1080                }
1081                break;
1082             }
1083
1084          default:
1085             {
1086                break;
1087             }
1088       }
1089    }
1090    /* If all of the IEs are processed successfully, we will send an e2 node
1091     * config update ack message. 
1092     * else we will be sendinf e2 node config update failure */
1093    if(elementCnt == ieIdx)
1094    {
1095      if(BuildAndSendE2NodeConfigUpdateAck(duDb, transId, &tmpE2NodeList) !=ROK)
1096       {
1097          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 node config ack");
1098          return;
1099       }
1100    }
1101    else
1102    {
1103       if(BuildAndSendE2NodeConfigUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
1104       {
1105          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 node config Failure");
1106          return;
1107       }
1108    }
1109 }
1110 /*******************************************************************
1111  *
1112  * @brief Builds Global RIC Id Params
1113  *
1114  * @details
1115  *
1116  *    Function : BuildGlobalRicId
1117  *
1118  *    Functionality: Building the Plmn and ric id
1119  *
1120  * @params[in] GlobalRIC_ID_t *ricId
1121  * @return ROK     - success
1122  *         RFAILED - failure
1123  *
1124  * ****************************************************************/
1125
1126 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
1127 {
1128    uint8_t unused = 4;
1129    uint8_t byteSize = 3;
1130    uint8_t ricVal= 1;
1131    if(ricId != NULLP)
1132    {
1133       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
1134       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
1135       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
1136       /* fill ric Id */
1137       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
1138       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
1139       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
1140    }
1141    return ROK;   
1142 }
1143
1144 /*******************************************************************
1145  *
1146  * @brief deallocate the memory allocated in E2SetupResponse
1147  *
1148  * @details
1149  *
1150  *    Function : FreeE2SetupRsp 
1151  *
1152  *    Functionality: deallocate the memory allocated in E2SetupResponse 
1153  *
1154  * @params[in] E2AP_PDU_t *e2apMsg
1155  *
1156  * @return void
1157  * ****************************************************************/
1158 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
1159 {
1160    uint8_t arrIdx = 0, e2NodeConfigIdx=0, ranFuncIdx=0;
1161    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
1162    E2setupResponse_t  *e2SetupRsp=NULL;
1163    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULL;
1164    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULL;
1165    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULL;
1166    
1167    if(e2apMsg)
1168    {
1169       if(e2apMsg->choice.successfulOutcome)
1170       {
1171          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
1172          if(e2SetupRsp->protocolIEs.list.array)
1173          {
1174             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
1175             {
1176                switch(e2SetupRsp->protocolIEs.list.array[arrIdx]->id)
1177                {
1178                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
1179                   {
1180                      ranFuncAcceptedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
1181                      if(ranFuncAcceptedList->list.array)
1182                      {
1183                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
1184                         {
1185                            if(ranFuncAcceptedList->list.array[ranFuncIdx])
1186                            {
1187                               RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1188                            }
1189                         }
1190                         RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
1191                      }
1192                      break;
1193                   }
1194                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1195                   {
1196                      e2NodeConfigAdditionAckList =&e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
1197                      if(e2NodeConfigAdditionAckList->list.count)
1198                      {
1199                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<e2NodeConfigAdditionAckList->list.count; e2NodeConfigIdx++)
1200                         {
1201                            e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2NodeConfigIdx];
1202                            if(e2NodeAddAckItemIe)
1203                            {
1204                               f1InterfaceInfo = e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; 
1205                               if(f1InterfaceInfo)
1206                               {
1207                                  RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
1208                                  RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
1209                               }
1210                               RIC_FREE(e2NodeAddAckItemIe, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
1211                            }
1212                         }
1213                         RIC_FREE(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
1214                      }
1215                      break;
1216                   }
1217                }
1218                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
1219             }
1220             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
1221          }
1222          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1223       }
1224       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
1225    }
1226 }
1227
1228 /*******************************************************************
1229  *
1230  * @brief fill e2 node configuration for ack msg 
1231  *
1232  * @details
1233  *
1234  *    Function : fillE2NodeConfigAck
1235  *
1236  *    Functionality:
1237  *       - fill e2 node configuration for ack msg
1238  *
1239  * @params[in] 
1240  *    Pointer to e2NodeCfg to be filled
1241  *    procedure Code
1242  *    E2 Node Component information
1243  *    Is successful or failure response
1244  * @return ROK     - success
1245  *         RFAILED - failure
1246  *
1247  * ****************************************************************/
1248
1249 uint8_t fillE2NodeConfigAck(PTR e2NodeCfg, uint8_t procedureCode, E2NodeComponent *componentInfo, bool isSuccessful)
1250 {
1251    E2nodeComponentID_t *e2nodeComponentID=NULLP;
1252    E2nodeComponentInterfaceType_t *e2nodeComponentInterfaceType=NULLP;
1253    E2nodeComponentConfigurationAck_t *e2nodeComponentConfigurationAck=NULLP;
1254    E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP;
1255    E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP;
1256    E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP;
1257    
1258    /* filling the interface type, component id, configuration ack based on the
1259     * e2 node configuration add, update, delete type  */
1260    switch(procedureCode)
1261    {
1262       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
1263          {
1264             additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg;
1265             e2nodeComponentInterfaceType = &((E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg)->e2nodeComponentInterfaceType;
1266             e2nodeComponentID = &additionAckItem->e2nodeComponentID;
1267             e2nodeComponentConfigurationAck = &additionAckItem->e2nodeComponentConfigurationAck;
1268             break;
1269          }
1270       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
1271          {
1272             updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg;
1273             e2nodeComponentInterfaceType = &updateAckItem->e2nodeComponentInterfaceType;
1274             e2nodeComponentID = &updateAckItem->e2nodeComponentID;
1275             e2nodeComponentConfigurationAck = &updateAckItem->e2nodeComponentConfigurationAck;
1276             break;
1277          }
1278       case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
1279          {
1280             removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
1281             e2nodeComponentInterfaceType = &removalAckItem->e2nodeComponentInterfaceType;
1282             e2nodeComponentID = &removalAckItem->e2nodeComponentID;
1283             e2nodeComponentConfigurationAck = &removalAckItem->e2nodeComponentConfigurationAck;
1284             break;
1285          }
1286    }
1287
1288    /* >E2 Node Component interface type */
1289    if(componentInfo->interfaceType>=NG && componentInfo->interfaceType<=X2)
1290    {
1291       *e2nodeComponentInterfaceType = componentInfo->interfaceType;
1292    }
1293    else
1294    {
1295       DU_LOG("\nERROR  --> E2AP: Received an invalid interface value %d",componentInfo->interfaceType);
1296       return RFAILED;
1297    }
1298
1299    if(*e2nodeComponentInterfaceType == E2nodeComponentInterfaceType_f1)
1300    {
1301       /* >E2 Node Component ID */
1302       e2nodeComponentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
1303       RIC_ALLOC(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
1304       if(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP)
1305       {
1306          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
1307          return RFAILED;
1308       }
1309       e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
1310       RIC_ALLOC(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1311
1312       if(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
1313       {
1314          DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
1315          return RFAILED;
1316       }
1317       e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = componentInfo->componentId;
1318    }
1319
1320    if(isSuccessful)
1321    {
1322       /* >E2 Node Component Configuration Acknowledge*/
1323       e2nodeComponentConfigurationAck->updateOutcome = E2nodeComponentConfigurationAck__updateOutcome_success;
1324    }
1325    else
1326    {
1327       /* >E2 Node Component Configuration Acknowledge*/
1328       e2nodeComponentConfigurationAck->updateOutcome = E2nodeComponentConfigurationAck__updateOutcome_failure;
1329       RIC_ALLOC(e2nodeComponentConfigurationAck->failureCauseE2, sizeof(struct CauseE2));
1330       if(e2nodeComponentConfigurationAck->failureCauseE2)
1331       {
1332          fillE2FailureCause(e2nodeComponentConfigurationAck->failureCauseE2, CauseE2_PR_e2Node, CauseE2node_e2node_component_unknown);
1333       }
1334       else
1335       {
1336          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
1337          return RFAILED;
1338       }
1339    }
1340    return ROK;
1341 }
1342
1343 /*******************************************************************
1344  *
1345  * @brief Build E2node Component config addition ack list
1346  *
1347  * @details
1348  *
1349  *    Function :  BuildE2nodeComponentConfigAdditionAck
1350  *
1351  *    Functionality:  Build E2node Component config addition ack list 
1352  *
1353  * @params[in] 
1354  *    E2nodeComponentConfigAdditionAck_List to be filled
1355  *    Count of e2 node to be added
1356  *    list of e2 node cfg to be added
1357  *
1358  * @return ROK - success
1359  *         RFAILED - failure
1360  * ****************************************************************/
1361
1362 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, \
1363 uint16_t addedE2NodeCount, E2NodeConfigItem *addedE2Node)
1364 {
1365    uint16_t arrIdx = 0;
1366    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULLP;
1367   
1368    e2NodeConfigAdditionAckList->list.count = addedE2NodeCount;
1369    
1370    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
1371    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
1372    if(e2NodeConfigAdditionAckList->list.array == NULLP)
1373    {
1374       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
1375       return RFAILED;
1376    }
1377
1378    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
1379    {
1380       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
1381       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
1382       {
1383          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
1384          return RFAILED;
1385       }
1386       e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[arrIdx];
1387       e2NodeAddAckItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
1388       e2NodeAddAckItemIe->criticality = CriticalityE2_reject;
1389       e2NodeAddAckItemIe->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
1390
1391       /* Filling the e2 node config addition ack item */
1392       fillE2NodeConfigAck((PTR)&e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck,\
1393       &addedE2Node[arrIdx].componentInfo, addedE2Node[arrIdx].isSuccessful);
1394    }
1395    return ROK;  
1396 }
1397
1398 /*******************************************************************
1399  *
1400  * @brief Build RAN function accepted list
1401  *
1402  * @details
1403  *
1404  *    Function : BuildRanFunctionAcceptedList
1405  *
1406  *    Functionality: Build RAN function accepted list 
1407  *     ->For ProcedureCodeE2_id_E2setup or ProcedureCodeE2_id_RICserviceQuery  
1408  *     we add all the RAN Function list which is present in RIC database.
1409  *     ->For any other procedures, we just fill the RAN functions whose ID 
1410  *     is present in the recvList
1411  *
1412  * @params[in] 
1413  *    Stored DU databse 
1414  *    Count of ran functions to be accepted in the list 
1415  *    Received list of RAN functions
1416  *    RAN Function list  
1417  *    Procedure Code 
1418  *
1419  * @return ROK - success
1420  *         RFAILED - failure
1421  * ****************************************************************/
1422
1423 uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ranFunAcceptedList, RANfunctionsID_List_t *ranFuncAcceptedList, uint8_t procedureCode)
1424 {
1425    uint16_t ranFuncIdx = 0;
1426    RANfunctionID_ItemIEs_t *ranFuncAcceptedItemIe=NULL;
1427    
1428    /* For ProcedureCodeE2_id_E2setup and ProcedureCodeE2_id_RICserviceQuery, 
1429     * the number of RAN function list items is equal to the number of 
1430     * ran function entries stored in the database.
1431     * For any other procedure, the RAN function list count is equal
1432     * to the count of ran functions obtained from the function's caller */
1433
1434    if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
1435       ranFuncAcceptedList->list.count = duDb->numOfRanFunction;
1436    else
1437       ranFuncAcceptedList->list.count = count;
1438    
1439    ranFuncAcceptedList->list.size = ranFuncAcceptedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
1440    RIC_ALLOC(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
1441    if(ranFuncAcceptedList->list.array)
1442    {
1443       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAcceptedList->list.count; ranFuncIdx++)
1444       {
1445          RIC_ALLOC(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1446          if(ranFuncAcceptedList->list.array[ranFuncIdx] == NULLP)
1447          {
1448             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
1449             return RFAILED;
1450          }
1451          ranFuncAcceptedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAcceptedList->list.array[ranFuncIdx];
1452          ranFuncAcceptedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
1453          ranFuncAcceptedItemIe->criticality= CriticalityE2_ignore;
1454          ranFuncAcceptedItemIe->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
1455          if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
1456          {
1457             /* filling the RAN function information with the help of DuDb */
1458             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = duDb->ranFunction[ranFuncIdx].id;
1459             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= duDb->ranFunction[ranFuncIdx].revisionCounter;
1460          }
1461          else
1462          {
1463             /* filling the the RAN function information with the help received list of RAN functions */
1464             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = ranFunAcceptedList[ranFuncIdx].id;
1465             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= ranFunAcceptedList[ranFuncIdx].revisionCounter;
1466          }
1467       }
1468    }
1469    else
1470    {
1471       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array");
1472       return RFAILED;
1473    }
1474    return ROK;
1475 }
1476
1477 /*******************************************************************
1478  *
1479  * @brief Builds and sends the E2SetupResponse
1480  *
1481  * @details
1482  *
1483  *    Function : BuildAndSendE2SetupRsp
1484  *
1485  *    Functionality: Builds and sends the E2SetupResponse
1486  *
1487  * @params[in] 
1488  *      Du datbase
1489  *      Trans id
1490  *      List of E2node cofniguration which needs to be send
1491  *
1492  * @return ROK     - success
1493  *         RFAILED - failure
1494  *
1495  * ****************************************************************/
1496
1497 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint16_t transId, E2NodeConfigList e2NodeList)
1498 {
1499    E2AP_PDU_t         *e2apMsg = NULL;
1500    E2setupResponse_t  *e2SetupRsp;
1501    asn_enc_rval_t     encRetVal; 
1502    uint8_t            idx;
1503    uint8_t            elementCnt;
1504    bool  memAllocFailed = false;
1505  
1506    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
1507    while(true)
1508    {
1509       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
1510       if(e2apMsg == NULLP)
1511       {
1512          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1513          break;
1514       }
1515       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
1516       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1517       if(e2apMsg->choice.successfulOutcome == NULLP)
1518       {
1519          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1520          break;  
1521       }
1522
1523       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1524       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1525       e2apMsg->choice.successfulOutcome->value.present = \
1526                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
1527       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
1528
1529       elementCnt = 3;
1530       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
1531       if(duDb->numOfRanFunction)
1532          elementCnt++;
1533
1534       e2SetupRsp->protocolIEs.list.count = elementCnt;
1535       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
1536
1537       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
1538       if(e2SetupRsp->protocolIEs.list.array == NULLP)
1539       {
1540          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
1541          break;  
1542       }
1543
1544       for(idx=0; idx<elementCnt; idx++)
1545       {
1546          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
1547          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
1548          { 
1549             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
1550             memAllocFailed = true;
1551             break;
1552          }    
1553       }
1554       
1555       if(memAllocFailed == true)
1556       {
1557           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
1558           break;
1559       }
1560       /* Trans Id */
1561       idx = 0;
1562       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
1563       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1564       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
1565       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
1566
1567       /* Global RIC ID */
1568       idx++;
1569       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
1570       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1571       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID;
1572
1573       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
1574       {
1575          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
1576          break;
1577       }
1578       
1579       if(duDb->numOfRanFunction)
1580       {
1581          /* Accepted RAN function Id */
1582          idx++;
1583          e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
1584          e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1585          e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_RANfunctionsID_List;
1586          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &e2SetupRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_E2setup)!=ROK)
1587          {
1588             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
1589             break;         
1590          }
1591       }
1592
1593       /* E2 Node Component Configuration Addition Acknowledge List*/
1594       idx++;
1595       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
1596       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1597       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
1598          E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
1599       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\
1600          value.choice.E2nodeComponentConfigAdditionAck_List, e2NodeList.addedE2NodeCount, e2NodeList.addedE2Node) != ROK)
1601       {
1602          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
1603          break;
1604       }
1605
1606       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1607       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1608       encBufSize = 0;
1609       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1610
1611       /* Check encode results */
1612       if(encRetVal.encoded == ENCODE_FAIL)
1613       {
1614          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
1615                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1616          break;   
1617       } 
1618       else 
1619       {
1620          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
1621          for(int i=0; i< encBufSize; i++)
1622          {
1623             DU_LOG("%x",encBuf[i]);
1624          } 
1625       }
1626
1627       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1628       {
1629          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
1630          break;   
1631       }
1632       break;
1633    }
1634
1635    FreeE2SetupRsp(e2apMsg);
1636    BuildAndSendRicSubscriptionReq(duDb);
1637    return ROK;
1638 }
1639
1640 /*******************************************************************
1641  *
1642  * @brief Free RIC Subscription Details
1643  *
1644  * @details
1645  *
1646  *    Function : FreeRicSubsDetails
1647  *
1648  *    Functionality: Free the RIC Subscription Details
1649  *
1650  * @params[in] RICsubscriptionDetails_t *subsDetails
1651  * @return void
1652  *
1653  * ****************************************************************/
1654 void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
1655 {
1656    uint8_t elementIdx = 0;
1657    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
1658
1659    RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
1660
1661    if(subsDetails->ricAction_ToBeSetup_List.list.array)
1662    {
1663       for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
1664       {
1665          if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1666          {
1667             actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
1668             if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1669             {
1670                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \
1671                   actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size);
1672                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
1673             }
1674             RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t))
1675          }
1676       }
1677       RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1678    }
1679 }
1680
1681 /*******************************************************************
1682  *
1683  * @brief Free RIC Subscription Request
1684  *
1685  * @details
1686  *
1687  *    Function : FreeRicSubscriptionReq
1688  *
1689  * Functionality : Free RIC Subscription Request
1690  *
1691  * @return ROK     - success
1692  *         RFAILED - failure
1693  *
1694  ******************************************************************/
1695 void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg)
1696 {
1697    uint8_t idx = 0;
1698    RICsubscriptionRequest_t   *ricSubscriptionReq;
1699
1700    if(e2apRicMsg)
1701    {
1702       if(e2apRicMsg->choice.initiatingMessage)
1703       {
1704          ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1705          if(ricSubscriptionReq->protocolIEs.list.array)
1706          {
1707             for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
1708             {
1709                switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
1710                {
1711                   case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1712                      {
1713                         FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
1714                         break;
1715                      }
1716                }               
1717                RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1718             }
1719             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1720          }
1721          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1722       }
1723       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
1724    }
1725 }
1726
1727 /*******************************************************************
1728  *
1729  * @brief Builds Ric Request Id
1730  *
1731  * @details
1732  *
1733  *    Function : BuildNewRicRequestId
1734  *
1735  *    Functionality: Assign new Ric Request ID
1736  *
1737  * @params[in] RIC request ID to be sent
1738  *             RIC request ID stored in DB
1739  * @return ROK     - success
1740  *         RFAILED - failure
1741  *
1742  * ****************************************************************/
1743
1744 uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb)
1745 {
1746    static uint16_t requestorId = 0;
1747    static uint16_t instanceId = 0;
1748
1749    if(ricReqId != NULLP)
1750    {
1751       ricReqId->ricRequestorID = ++requestorId;
1752       ricReqId->ricInstanceID  = ++instanceId;
1753
1754       reqIdDb->requestorId = ricReqId->ricRequestorID;
1755       reqIdDb->instanceId = ricReqId->ricInstanceID;
1756    }
1757    return ROK;
1758 }
1759
1760 /*******************************************************************
1761  *
1762  * @brief Free RIC Action Definition
1763  *
1764  * @details
1765  *
1766  *    Function : FreeRicActionDefinition
1767  *
1768  *    Functionality: Free RIC Action Definition
1769  *
1770  * @params[in] E2SM-KPM Action definition
1771  * @return void
1772  *
1773  * ****************************************************************/
1774 void  FreeRicActionDefinition(E2SM_KPM_ActionDefinition_t actionDef)
1775 {
1776    uint8_t  elementIdx = 0;
1777    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1778    MeasurementInfoItem_t *measItem = NULLP;
1779
1780    switch(actionDef.actionDefinition_formats.present)
1781    {
1782       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
1783          {
1784             if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1)
1785             {
1786                actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1787                if(actionFormat1->measInfoList.list.array)
1788                {
1789                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
1790                   {
1791                      if(actionFormat1->measInfoList.list.array[elementIdx])
1792                      {
1793                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
1794                         switch(measItem->measType.present)
1795                         {
1796                            case MeasurementType_PR_NOTHING:
1797                            case MeasurementType_PR_measID:
1798                               break;
1799                            case MeasurementType_PR_measName:
1800                            {
1801                               RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size)
1802                               break;
1803                            }
1804                         }
1805                         RIC_FREE(measItem, sizeof(MeasurementInfoItem_t));
1806                      }
1807                   }
1808                   RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1809                }
1810                RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1811             }
1812             break;
1813          }
1814
1815       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
1816       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
1817       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
1818       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
1819       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING:
1820          break;
1821    }
1822 }
1823
1824 /*******************************************************************
1825  *
1826  * @brief Fill RIC Action Definition
1827  *
1828  * @details
1829  *
1830  *    Function : fillRicActionDef
1831  *
1832  *    Functionality: Fill RIC Action Definition
1833  *
1834  * @params[in] RIC Action definition
1835  * @return ROK 
1836  *         RFAILED
1837  *
1838  * ****************************************************************/
1839 uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef, uint8_t ricActionId, ConfigType configType)
1840 {
1841    uint8_t ret = RFAILED;
1842    asn_enc_rval_t  encRetVal;
1843    uint8_t elementCnt = 0, elementIdx = 0;
1844    char    *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"};
1845    E2SM_KPM_ActionDefinition_t actionDef;
1846    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1847    MeasurementInfoItem_t *measItem = NULLP;
1848    
1849    while(true)
1850    {
1851       /* Fill E2SM-KPM Action Definition Format 1 */
1852
1853       /* RIC Stype Type */
1854       actionDef.ric_Style_Type = RIC_STYLE_TYPE;
1855
1856       /* RIC Action Definition Format 1 */
1857       actionDef.actionDefinition_formats.present = \
1858            E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1;
1859
1860       RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \
1861             sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1862       if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP)
1863       {
1864          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1865          break;
1866       }
1867       actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1868
1869       /* Measurement Info List */
1870       elementCnt = 2;
1871       actionFormat1->measInfoList.list.count = elementCnt;
1872       actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *);
1873       RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1874       if(actionFormat1->measInfoList.list.array == NULL)
1875       {
1876          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1877          break;
1878       }
1879
1880       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1881       {
1882          RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t));
1883          if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP)
1884          {
1885             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1886             break;
1887          }
1888
1889          measItem = actionFormat1->measInfoList.list.array[elementIdx];
1890          measItem->measType.present = MeasurementType_PR_measName;
1891
1892          measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]);
1893          RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size);
1894          if(measItem->measType.choice.measName.buf == NULLP)
1895          {
1896             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1897             break;
1898          }
1899          memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size);
1900       }
1901       if(elementIdx < elementCnt)
1902          break;
1903
1904       /* Granularity Period */
1905       actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD(configType, ricActionId); /* In ms */
1906
1907       /* Prints the Msg formed */
1908       xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef);
1909
1910       /* Encode E2SM-KPM RIC Action Definition */
1911       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1912       encBufSize = 0;
1913       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf);
1914       if(encRetVal.encoded == ENCODE_FAIL)
1915       {
1916          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\
1917                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1918          break;
1919       }
1920
1921       /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */
1922       ricActionDef->size = encBufSize;
1923       RIC_ALLOC(ricActionDef->buf, encBufSize);
1924       if(ricActionDef->buf == NULLP)
1925       {
1926          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1927          break;
1928       }
1929       memcpy(ricActionDef->buf, encBuf, encBufSize);
1930
1931       ret = ROK;
1932       break;
1933    }
1934
1935    FreeRicActionDefinition(actionDef);
1936    return ret;
1937 }
1938
1939 /*******************************************************************
1940  *
1941  * @brief Fills RIC Action To Be Setup Item
1942  *
1943  * @details
1944  *
1945  *    Function : fillActionToBeSetup
1946  *
1947  *    Functionality: Fill the RIC Action To Be Setup Ite,
1948  *                   RIC subscription DB
1949  *
1950  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
1951  * @return ROK     - success
1952  *         RFAILED - failure
1953  *
1954  * ****************************************************************/
1955 uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb)
1956 {
1957    static uint8_t ricActionId = 0;
1958    CmLList *actionNode=NULLP;
1959    if(actionItem == NULLP)
1960    {
1961       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1962       return RFAILED;
1963    }
1964
1965    while(true)
1966    {
1967       actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
1968       actionItem->criticality   =  CriticalityE2_ignore;
1969       actionItem->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
1970       
1971       /* RIC Action ID */
1972       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ricActionId;
1973       actionNode = addRicSubsAction(ricActionId, &ricSubsDb->actionSequence);
1974       ricActionId++;
1975
1976       /* RIC Action Type */
1977       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
1978
1979       /* RIC Action Definition */
1980       RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
1981       if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1982       {
1983          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1984          break;
1985       }
1986       if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, ricActionId, CONFIG_ADD) != ROK)
1987       {
1988          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1989          break;
1990       }
1991       
1992       return ROK;
1993    }
1994    
1995    if(actionNode)
1996    {
1997       cmLListDelFrm(&ricSubsDb->actionSequence, actionNode);
1998       deleteActionSequence(actionNode);
1999    }
2000    return RFAILED;
2001 }
2002
2003 /*******************************************************************
2004  *
2005  * @brief Free Event Trigger Definition
2006  *
2007  * @details
2008  *
2009  *    Function : FreeEventTriggerDef
2010  *
2011  *    Functionality: Free Event Trigger Definition
2012  *
2013  * @params[in] E2SM-KPM Event Trigger Definition
2014  * @return void
2015  *
2016  * ****************************************************************/
2017 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
2018 {
2019    if(eventTiggerDef)
2020    {
2021       switch(eventTiggerDef->eventDefinition_formats.present)
2022       {
2023          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
2024             break;
2025          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
2026             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
2027                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
2028             break;                  
2029       }         
2030    }
2031 }
2032
2033 /*******************************************************************
2034  *
2035  * @brief Fill Event Trigger Definition
2036  *
2037  * @details
2038  *
2039  *    Function : fillEventTriggerDef
2040  *
2041  *    Functionality: Fill Event Trigger Definition
2042  *
2043  * @params[in] RIC Event Trigger Definition
2044  * @return ROK
2045  *         RFAILED
2046  *
2047  * ****************************************************************/
2048 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
2049 {
2050    uint8_t ret = RFAILED;
2051    asn_enc_rval_t  encRetVal;
2052    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
2053
2054    while(true)
2055    {
2056       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
2057       eventTiggerDef.eventDefinition_formats.present = \
2058        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
2059
2060       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
2061             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
2062       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
2063       {
2064          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2065          break;
2066       }
2067
2068       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
2069
2070       /* Prints the Msg formed */
2071       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
2072
2073       /* Encode E2SM-KPM Event Trigger Definition */
2074       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2075       encBufSize = 0;
2076       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
2077       if(encRetVal.encoded == ENCODE_FAIL)
2078       {
2079          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
2080                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2081          break;
2082       }
2083
2084       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
2085       ricEventTriggerDef->size = encBufSize;
2086       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
2087       if(ricEventTriggerDef->buf == NULLP)
2088       {
2089          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2090          break;
2091       }
2092       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
2093
2094       ret = ROK;
2095       break;
2096    }
2097
2098    FreeEventTriggerDef(&eventTiggerDef);
2099    return ret;
2100 }
2101
2102 /*******************************************************************
2103  *
2104  * @brief builds RIC Subscription Details
2105  *
2106  * @details
2107  *
2108  *    Function : BuildsRicSubsDetails
2109  *
2110  *    Functionality: Builds the RIC Subscription Details
2111  *
2112  * @params[in] RIC Subscription details to be filled
2113  *             RIC subscriotion DB
2114  * @return ROK     - success
2115  *         RFAILED - failure
2116  *
2117  * ****************************************************************/
2118
2119 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsInfo)
2120 {
2121    uint8_t elementCnt = 0;
2122    uint8_t elementIdx = 0;
2123
2124    if(subsDetails == NULLP)
2125    {
2126       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
2127       return RFAILED;
2128    }
2129
2130    while(true)
2131    {
2132       /* RIC Event Trigger Definition */
2133       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
2134       {
2135          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
2136          break;
2137       }
2138
2139       /* RIC Actions To Be Setup List */
2140       elementCnt = 1;
2141       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
2142       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
2143       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
2144       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
2145       {
2146          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
2147          break;
2148       } 
2149
2150       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
2151       {
2152          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
2153          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
2154          {
2155             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2156             break;
2157          }
2158       }
2159       if(elementIdx < elementCnt)
2160          break;
2161
2162
2163       elementIdx = 0;
2164       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
2165          ricSubsInfo) != ROK)
2166       {
2167          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
2168          break;
2169       }
2170
2171       return ROK;
2172    }
2173    return RFAILED;
2174 }
2175
2176 /*******************************************************************
2177  *
2178  * @brief Builds and Send the RicSubscriptionReq
2179  *
2180  * @details
2181  *
2182  *    Function : BuildAndSendRicSubscriptionReq
2183  *
2184  * Functionality:Fills the RicSubscriptionReq
2185  *
2186  * @return ROK     - success
2187  *         RFAILED - failure
2188  *
2189  ******************************************************************/
2190 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
2191 {
2192    uint8_t         ret = RFAILED;
2193    uint8_t         elementCnt = 0;
2194    uint8_t         idx = 0;
2195    asn_enc_rval_t  encRetVal;        /* Encoder return value */
2196    E2AP_PDU_t                 *e2apRicMsg = NULL;
2197    RICsubscriptionRequest_t   *ricSubscriptionReq;
2198    RanFunction  *ranFuncDb = &duDb->ranFunction[0];
2199    CmLList *ricSubsNode = NULLP;
2200    RicSubscription *ricSubsInfo = NULLP;
2201
2202    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
2203
2204    /* Allocate memory to store RIC subscription info in RIC DB */
2205    RIC_ALLOC(ricSubsInfo, sizeof(RicSubscription));
2206    if(!ricSubsInfo)
2207    {
2208       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2209       return RFAILED;
2210    }
2211
2212    while(true)
2213    {
2214       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
2215       if(e2apRicMsg == NULLP)
2216       {
2217          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2218          break;
2219       }
2220
2221       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
2222       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2223       if(e2apRicMsg->choice.initiatingMessage == NULLP)
2224       {
2225          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2226          break;
2227       }
2228       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
2229       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2230       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
2231
2232       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
2233
2234       elementCnt = 3;
2235       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
2236       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
2237
2238       /* Initialize the subscription members */
2239       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
2240       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
2241       {
2242          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2243          break;
2244       }
2245
2246       for(idx=0; idx<elementCnt; idx++)
2247       {
2248          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
2249          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
2250          {
2251             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2252             break;
2253          }
2254       }
2255       if(idx < elementCnt)
2256          break;
2257
2258       /* Filling RIC Request Id */
2259       idx = 0;
2260       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
2261       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2262       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2263                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
2264       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
2265          &ricSubsInfo->requestId) != ROK)
2266       {
2267          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
2268          break;
2269       }
2270
2271
2272       /* Filling RAN Function Id */
2273       idx++;
2274       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
2275       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2276       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2277                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
2278       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
2279       ricSubsInfo->ranFuncId = ranFuncDb->id;
2280
2281       /* Filling RIC Subscription Details */
2282       idx++;
2283       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
2284       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2285       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2286                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
2287       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
2288          ricSubsInfo) != ROK)
2289       {
2290          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
2291          break;
2292       }
2293
2294       /* Prints the Msg formed */
2295       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
2296
2297       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2298       encBufSize = 0;
2299       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
2300       if(encRetVal.encoded == ENCODE_FAIL)
2301       {
2302          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
2303                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2304          break;               
2305       }
2306       else
2307       {
2308          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
2309          for(int i=0; i< encBufSize; i++)
2310          {
2311             DU_LOG("%x",encBuf[i]);
2312          } 
2313       }
2314
2315       /* Sending msg */
2316       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2317       {
2318          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
2319          break;
2320       }
2321
2322       /* Add RIC Subscription Info to RAN Function's RIC Subscription List */
2323       RIC_ALLOC(ricSubsNode , sizeof(CmLList));
2324       if(!ricSubsNode)
2325       {
2326          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2327          break;
2328       }
2329       ricSubsNode->node = (PTR)ricSubsInfo;
2330       cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubsNode);
2331
2332       ret = ROK;
2333       break;
2334    }
2335
2336    if(ret == RFAILED)
2337    {
2338       RIC_FREE(ricSubsInfo, sizeof(RicSubscription));
2339       RIC_FREE(ricSubsNode , sizeof(CmLList));
2340    }
2341
2342    FreeRicSubscriptionReq(e2apRicMsg);
2343    return ret;
2344 }
2345
2346 /*******************************************************************
2347  *
2348  * @brief Process RicSubscriptionResponse
2349  *
2350  * @details
2351  *
2352  *    Function : ProcRicSubscriptionRsp
2353  *
2354  * Functionality: Processes RicSubscriptionRsp
2355  *
2356  * @return ROK     - void
2357  *
2358  ******************************************************************/
2359
2360 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
2361 {
2362    uint8_t duIdx = 0, ieIdx = 0, notAdmitIdx = 0;
2363    uint8_t ranFuncId = 0, actionId = 0;
2364    DuDb *duDb = NULLP;
2365    bool ricReqIdDecoded = false;
2366    RicRequestId ricReqId;
2367    RanFunction  *ranFuncDb = NULLP;
2368    RicSubscription *ricSubs = NULLP;
2369    CmLList *ricSubsNode = NULLP;
2370    CmLList *actionNode = NULLP;
2371    ActionInfo *action = NULLP;
2372    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
2373    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
2374
2375    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
2376
2377    /* Fetch DU DB */
2378    SEARCH_DU_DB(duIdx, duId, duDb);
2379    if(duDb == NULLP)
2380    {
2381       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2382       return;
2383    }
2384
2385    memset(&ricReqId, 0, sizeof(RicRequestId));
2386    if(ricSubscriptionRsp)
2387    {
2388       if(ricSubscriptionRsp->protocolIEs.list.array)
2389       {
2390          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
2391          {
2392             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
2393             {
2394                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2395                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
2396                {
2397                   case ProtocolIE_IDE2_id_RICrequestID:
2398                      {
2399                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
2400                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
2401                         ricReqIdDecoded = true;
2402                         break;
2403                      }
2404                   case ProtocolIE_IDE2_id_RANfunctionID:
2405                      {
2406                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
2407                         ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
2408                         if(!ranFuncDb)
2409                         {
2410                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
2411                            return;
2412                         }
2413                         break; 
2414                      }
2415                   case ProtocolIE_IDE2_id_RICactions_Admitted:
2416                      {
2417                         break;
2418                      }
2419                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
2420                      {
2421                         if(!(ranFuncDb && ricReqIdDecoded))
2422                            return;
2423
2424                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
2425                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
2426                         {
2427                            actionNode=NULLP;
2428                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
2429                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
2430
2431                            /* Remove action from RAN Function's subscription list */
2432                            ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
2433                            if(ricSubs)
2434                            {
2435                               action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
2436                               if(action)
2437                               {
2438                                  cmLListDelFrm(&ricSubs->actionSequence, actionNode);
2439                                  deleteActionSequence(actionNode);
2440                               }
2441                            }
2442                         }
2443                         break;
2444                      }
2445                }
2446             }
2447          }
2448       }
2449    } 
2450 }
2451
2452 /*******************************************************************
2453  *
2454  * @brief deallocate the memory allocated in E2SetupFailure
2455  *
2456  * @details
2457  *
2458  *    Function : FreeE2SetupFailure 
2459  *
2460  *    Functionality: deallocate the memory allocated in E2SetupFailure 
2461  *
2462  * @params[in] E2AP_PDU_t *e2apMsg
2463  *
2464  * @return void
2465  * ****************************************************************/
2466 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
2467 {
2468    uint8_t arrIdx = 0;
2469    E2setupFailure_t  *e2SetupFail;
2470
2471    if(e2apMsg)
2472    {
2473       if(e2apMsg->choice.unsuccessfulOutcome)
2474       {
2475          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2476          if(e2SetupFail->protocolIEs.list.array)
2477          {
2478             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
2479             {
2480                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
2481             }
2482             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
2483          }
2484          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2485       }
2486       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2487    }
2488 }
2489
2490 /*******************************************************************
2491  *
2492  * @brief Buld and send the E2 Setup failure
2493  *
2494  * @details
2495  *
2496  *    Function : BuildAndSendE2SetupFailure
2497  *
2498  *    Functionality:
2499  *         - Buld and send the E2 Setup failure
2500  * @return ROK     - success
2501  *         RFAILED - failure
2502  *
2503  * ****************************************************************/
2504
2505 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint16_t transId)
2506 {
2507    uint8_t            ret = RFAILED;
2508    E2AP_PDU_t         *e2apMsg = NULL;
2509    E2setupFailure_t   *e2SetupFailure;
2510    asn_enc_rval_t     encRetVal;
2511    uint8_t            arrIdx;
2512    uint8_t            elementCnt;
2513    bool  memAllocFailed = false;
2514
2515    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
2516    while(true)
2517    {
2518       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2519       if(e2apMsg == NULLP)
2520       {
2521          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2522          break;
2523       }
2524       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2525       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2526       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2527       {
2528          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2529          break;
2530       }
2531
2532       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
2533       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2534       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
2535       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2536
2537       elementCnt = 3;
2538       e2SetupFailure->protocolIEs.list.count = elementCnt;
2539       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
2540
2541       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
2542       if(e2SetupFailure->protocolIEs.list.array == NULLP)
2543       {
2544          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2545          break;
2546       }
2547
2548       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2549       {
2550          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
2551          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
2552          {
2553             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2554             memAllocFailed = true;
2555             break;
2556          }
2557       }
2558
2559       if(memAllocFailed == true)
2560       {
2561           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2562           break;
2563       }
2564
2565       /* Trans Id */
2566       arrIdx = 0;
2567       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2568       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2569       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
2570       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2571
2572       arrIdx++;
2573       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2574       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2575       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
2576       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
2577       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
2578
2579       arrIdx++;
2580       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2581       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2582       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
2583       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2584
2585       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2586       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2587       encBufSize = 0;
2588       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2589
2590       /* Check encode results */
2591       if(encRetVal.encoded == ENCODE_FAIL)
2592       {
2593          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
2594                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2595          break;
2596       }
2597       else
2598       {
2599          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
2600          for(int i=0; i< encBufSize; i++)
2601          {
2602             DU_LOG("%x",encBuf[i]);
2603          }
2604       }
2605
2606       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2607       {
2608          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
2609          break;
2610       }
2611
2612       ret = ROK;
2613       break;
2614    }
2615
2616    FreeE2SetupFailure(e2apMsg);
2617    return ret;
2618 }
2619
2620 /*******************************************************************
2621  *
2622  * @brief process the e2setup request 
2623  *
2624  * @details
2625  *
2626  *    Function : ProcE2SetupReq
2627  *
2628  * Functionality: process the e2setup request
2629  *
2630  * @return void
2631  *
2632  ******************************************************************/
2633
2634 void ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
2635 {
2636    uint8_t arrIdx = 0, duIdx = 0;
2637    uint16_t transId =0;
2638    uint16_t ranFuncIdx=0, e2NodeAddListIdx =0;
2639    E2NodeConfigList tmpE2NodeList;
2640    DuDb    *duDb = NULLP;
2641    E2nodeComponentConfigAddition_List_t *e2NodeAddList=NULLP;
2642    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem=NULLP;
2643    RANfunction_ItemIEs_t *ranFuncItemIe=NULLP;
2644    RANfunction_Item_t  *ranFunItem=NULLP;
2645    RANfunctions_List_t *ranFunctionsList=NULLP;
2646
2647    memset(&tmpE2NodeList, 0, sizeof(E2NodeConfigList));
2648    if(!e2SetupReq)
2649    {
2650       DU_LOG("\nERROR  -->  E2AP : e2SetupReq pointer is null");
2651       return;
2652    }
2653    if(!e2SetupReq->protocolIEs.list.array)
2654    {
2655       DU_LOG("\nERROR  -->  E2AP : e2SetupReq array pointer is null");
2656       return;
2657    }
2658
2659    for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
2660    {
2661       if(e2SetupReq->protocolIEs.list.array[arrIdx])
2662       {
2663          switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
2664          {
2665             case ProtocolIE_IDE2_id_TransactionID:
2666                {
2667                   transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
2668                   break;
2669                }
2670             case ProtocolIE_IDE2_id_GlobalE2node_ID:
2671                {
2672                   if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
2673                   {
2674                      *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
2675
2676                      SEARCH_DU_DB(duIdx, *duId, duDb); 
2677                      if(duDb == NULLP)
2678                      {
2679                         duDb = &ricCb.duInfo[ricCb.numDu];
2680                         ricCb.numDu++;
2681                      }
2682                      memset(duDb, 0, sizeof(DuDb));
2683                      duDb->duId = *duId;
2684                   }
2685                   break;
2686                }
2687             case ProtocolIE_IDE2_id_RANfunctionsAdded:
2688                {
2689                   ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2690
2691                   if(ranFunctionsList->list.array)
2692                   {
2693                      for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
2694                      {
2695                         ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
2696                         ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2697                         duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
2698                         duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
2699                         cmLListInit(&duDb->ranFunction[ranFunItem->ranFunctionID-1].subscriptionList);
2700                         duDb->numOfRanFunction++;
2701                      }
2702                   }
2703                   break;
2704                }
2705             case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
2706                {
2707                   e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
2708                   if(e2NodeAddList->list.array)
2709                   {
2710                      for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
2711                      {
2712                         if(e2NodeAddList->list.array[e2NodeAddListIdx])
2713                         {
2714                            /* Storing the E2 node information in DB */
2715                            e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
2716                            if(handleE2NodeComponentAction(duDb, (PTR)&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item,\
2717                                     ProtocolIE_IDE2_id_E2nodeComponentConfigAddition, &tmpE2NodeList.addedE2Node[tmpE2NodeList.addedE2NodeCount++]) != ROK)
2718                            {
2719                               DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",e2NodeAddListIdx);
2720                            }
2721
2722                         }
2723                      }
2724                   }
2725                   break;
2726                }
2727             default:
2728                break;
2729          }
2730       }
2731    }
2732    
2733    if(BuildAndSendE2SetupRsp(duDb, transId, tmpE2NodeList) !=ROK)
2734    {
2735       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
2736    }
2737 }
2738 /*******************************************************************
2739  *
2740  * @brief Deallocate the memory allocated for E2 Reset Response
2741  *
2742  * @details
2743  *
2744  *    Function : FreeE2ResetResponse
2745  *
2746  *    Functionality:
2747  *       - freeing the memory allocated for E2ResetResponse
2748  *
2749  * @params[in] E2AP_PDU_t *e2apMsg
2750  * @return ROK     - success
2751  *         RFAILED - failure
2752  *
2753  * ****************************************************************/
2754 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
2755 {
2756    uint8_t ieIdx =0;
2757    ResetResponseE2_t *resetResponse =NULLP;
2758
2759    if(e2apMsg != NULLP)
2760    {
2761       if(e2apMsg->choice.successfulOutcome != NULLP)
2762       {
2763          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2764          if(resetResponse->protocolIEs.list.array)
2765          {
2766             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2767             {
2768                if(resetResponse->protocolIEs.list.array[ieIdx])
2769                {
2770                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2771                }
2772             }
2773             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2774          }
2775          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2776       }
2777       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2778    }
2779 }
2780
2781 /*******************************************************************
2782  *
2783  * @brief Buld and send the Reset Response msg
2784  *
2785  * @details
2786  *
2787  *    Function : BuildAndSendResetResponse 
2788  *
2789  *    Functionality:
2790  *         - Buld and send the Reset Response Message
2791  *
2792  * @params[in] 
2793  *    DU id
2794  *    TransId Id
2795  * @return ROK     - success
2796  *         RFAILED - failure
2797  *
2798  * ****************************************************************/
2799 uint8_t BuildAndSendResetResponse(uint32_t duId, uint16_t transId)
2800 {
2801    uint8_t           ieIdx = 0, elementCnt = 0;
2802    uint8_t           ret = RFAILED;
2803    E2AP_PDU_t        *e2apMsg = NULLP;
2804    ResetResponseE2_t *resetResponse=NULL;
2805    asn_enc_rval_t    encRetVal;       /* Encoder return value */
2806
2807    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
2808    do
2809    {
2810       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2811       if(e2apMsg == NULLP)
2812       {
2813          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
2814          break;
2815       }
2816       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
2817
2818       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2819       if(e2apMsg->choice.successfulOutcome == NULLP)
2820       {
2821          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
2822          break;
2823       }
2824  
2825       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
2826       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2827       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
2828       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2829
2830       elementCnt = 1;
2831       resetResponse->protocolIEs.list.count = elementCnt;
2832       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
2833       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2834       if(!resetResponse->protocolIEs.list.array)
2835       {
2836          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
2837          break;
2838       }
2839
2840       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
2841       {
2842          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2843          if(!resetResponse->protocolIEs.list.array[ieIdx])
2844          {
2845             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
2846             break;
2847          }
2848       }
2849       if(ieIdx < elementCnt)
2850          break;
2851
2852       ieIdx = 0; 
2853       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
2854       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2855       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
2856       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2857
2858       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2859
2860       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2861       encBufSize = 0;
2862       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2863       if(encRetVal.encoded == ENCODE_FAIL)
2864       {
2865          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
2866                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2867          break;
2868       }
2869       else
2870       {
2871          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
2872          for(int i=0; i< encBufSize; i++)
2873          {
2874             DU_LOG("%x",encBuf[i]);
2875          }
2876       }
2877
2878       /* Sending msg */
2879       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2880       {
2881          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
2882          break;
2883       }
2884
2885       ret = ROK;
2886       break;
2887    }while(true);
2888
2889    FreeE2ResetResponse(e2apMsg);
2890    return ret;
2891 }
2892
2893 /*******************************************************************
2894  *
2895  * @brief deallocate the memory allocated in building the
2896  *    Service Query message
2897  *
2898  * @details
2899  *
2900  *    Function : FreeRicServiceQuery 
2901  *
2902  *    Functionality: deallocate the memory allocated in building
2903  *    Ric Service Query message
2904  *
2905  * @params[in] E2AP_PDU_t *e2apMsg
2906  *
2907  * @return void
2908  * ****************************************************************/
2909
2910 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2911 {
2912    uint8_t arrIdx = 0, ranFuncIdx=0;
2913    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2914    RICserviceQuery_t *ricServiceQuery=NULL;
2915    
2916    if(e2apMsg)
2917    {
2918       if(e2apMsg->choice.initiatingMessage)
2919       {
2920          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2921          if(ricServiceQuery->protocolIEs.list.array)
2922          {
2923             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2924             {
2925                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2926                {
2927                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2928                   {
2929                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2930                         {
2931                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2932                            if(ranFuncAcceptedList->list.array)
2933                            {
2934                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2935                               {
2936                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2937                               }
2938                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2939                            }
2940                            break;
2941                         }
2942                      case RICserviceQuery_IEs__value_PR_TransactionID:
2943                         {
2944                            break;
2945                         }
2946                   }
2947                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2948                }
2949             }
2950             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2951          }
2952          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2953       }
2954       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2955    }
2956 }
2957
2958 /*******************************************************************
2959  *
2960  * @brief build and send the ric service Query 
2961  *
2962  * @details
2963  *
2964  *    Function : BuildAndSendRicServiceQuery
2965  *
2966  * Functionality: build and send the ric service Query 
2967  * @return ROK     - success
2968  *         RFAILED - Acknowledge
2969  *
2970  ******************************************************************/
2971
2972 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2973 {
2974    uint8_t arrIdx;
2975    uint8_t elementCnt;
2976    uint8_t ret = RFAILED;
2977    bool  memAllocFailed = false;
2978    E2AP_PDU_t     *e2apMsg = NULL;
2979    asn_enc_rval_t encRetVal;
2980    RICserviceQuery_t *ricServiceQuery;
2981
2982    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2983    while(true)
2984    {
2985       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2986       if(e2apMsg == NULLP)
2987       {
2988          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2989          break;
2990       }
2991       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2992       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2993       if(e2apMsg->choice.initiatingMessage == NULLP)
2994       {
2995          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2996          break;
2997       }
2998
2999       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
3000       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3001       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
3002       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
3003
3004       elementCnt = 1;
3005       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
3006       if(duDb->numOfRanFunction)
3007          elementCnt++;
3008
3009       ricServiceQuery->protocolIEs.list.count = elementCnt;
3010       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
3011
3012       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
3013       if(ricServiceQuery->protocolIEs.list.array == NULLP)
3014       {
3015          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
3016          break;
3017       }
3018
3019       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3020       {
3021          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
3022          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
3023          {
3024             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
3025             memAllocFailed = true;
3026             break;
3027          }
3028       }
3029       if(memAllocFailed == true)
3030       {
3031          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
3032          break;
3033       }
3034
3035       /* Trans Id */
3036       arrIdx = 0;
3037       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3038       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3039       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
3040       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
3041       
3042       if(duDb->numOfRanFunction)
3043       {
3044          /* Accepted RAN function Id */
3045          arrIdx++;
3046          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
3047          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3048          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
3049          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
3050          {
3051             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
3052             break;         
3053          }
3054       }
3055       
3056       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3057       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3058       encBufSize = 0;
3059       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3060
3061       /* Check encode results */
3062       if(encRetVal.encoded == ENCODE_FAIL)
3063       {
3064          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
3065                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3066          break;
3067       }
3068       else
3069       {
3070          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
3071          for(int i=0; i< encBufSize; i++)
3072          {
3073             DU_LOG("%x",encBuf[i]);
3074          }
3075       }
3076
3077       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
3078       {
3079          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
3080          break;
3081       }
3082
3083       ret =ROK;
3084       break;
3085    }
3086    FreeRicServiceQuery(e2apMsg);
3087    return ret;
3088 }
3089
3090 /*******************************************************************
3091  *
3092  * @brief deallocate the memory allocated in RicServiceUpdateFailure
3093  *
3094  * @details
3095  *
3096  *    Function : FreeRicServiceUpdateFailure 
3097  *
3098  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
3099  *
3100  * @params[in] E2AP_PDU_t *e2apMsg
3101  *
3102  * @return void
3103  * ****************************************************************/
3104
3105 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
3106 {
3107    uint8_t arrIdx = 0;
3108    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
3109    
3110    if(e2apMsg)
3111    {
3112       if(e2apMsg->choice.unsuccessfulOutcome)
3113       {
3114          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
3115          if(ricServiceUpdateFailure->protocolIEs.list.array)
3116          {
3117             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
3118             {
3119                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
3120             }
3121             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
3122          }
3123          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3124       }
3125       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3126    }
3127 }
3128
3129 /*******************************************************************
3130  *
3131  * @brief build and send the ric service update failure 
3132  *
3133  * @details
3134  *
3135  *    Function : BuildAndSendRicServiceUpdateFailure
3136  *
3137  * Functionality: build and send the ric service update failure 
3138  * @return ROK     - success
3139  *         RFAILED - failure
3140  *
3141  ******************************************************************/
3142
3143 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, uint16_t transId, CauseE2_PR causePresent, uint8_t reason)
3144 {
3145
3146    E2AP_PDU_t         *e2apMsg = NULL;
3147    asn_enc_rval_t     encRetVal;
3148    uint8_t            ret = RFAILED;
3149    uint8_t            arrIdx=0;
3150    uint8_t            elementCnt=0;
3151    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
3152
3153    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
3154    while(true)
3155    {
3156       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3157       if(e2apMsg == NULLP)
3158       {
3159          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3160          break;
3161       }
3162       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3163       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
3164       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3165       {
3166          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3167          break;
3168       }
3169
3170       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3171       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3172       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
3173       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
3174
3175       elementCnt = 3;
3176       ricServiceFailure->protocolIEs.list.count = elementCnt;
3177       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
3178
3179       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
3180       if(ricServiceFailure->protocolIEs.list.array == NULLP)
3181       {
3182          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
3183          break;
3184       }
3185
3186       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3187       {
3188          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
3189          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
3190          {
3191             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
3192             break;
3193          }
3194       }
3195       if(arrIdx<elementCnt)
3196       {
3197          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
3198          break;
3199       }
3200
3201       /* Trans Id */
3202       arrIdx = 0;
3203       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3204       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3205       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
3206       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
3207
3208       arrIdx++;
3209       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
3210       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3211       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
3212       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
3213
3214       arrIdx++;
3215       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
3216       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
3217       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
3218       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
3219
3220       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3221       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3222       encBufSize = 0;
3223       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3224
3225       /* Check encode results */
3226       if(encRetVal.encoded == ENCODE_FAIL)
3227       {
3228          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
3229                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3230          break;
3231       }
3232       else
3233       {
3234          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
3235          for(int i=0; i< encBufSize; i++)
3236          {
3237             DU_LOG("%x",encBuf[i]);
3238          }
3239       }
3240
3241       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3242       {
3243          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
3244          break;
3245       }
3246       ret = ROK;
3247       break;
3248    }
3249
3250    FreeRicServiceUpdateFailure(e2apMsg);
3251    return ret;
3252 }
3253
3254
3255 /*******************************************************************
3256  *
3257  * @brief deallocate the memory allocated in RicServiceUpdateAck(
3258  *
3259  * @details
3260  *
3261  *    Function : FreeRicServiceUpdateAck 
3262  *
3263  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
3264  *
3265  * @params[in] E2AP_PDU_t *e2apMsg
3266  *
3267  * @return void
3268  * ****************************************************************/
3269
3270 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
3271 {
3272    uint8_t arrIdx = 0, ranFuncIdx=0;
3273    RANfunctionsID_List_t *acceptedList=NULL;
3274    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
3275    RANfunctionsIDcause_List_t  *rejectedList=NULL;
3276
3277    if(e2apMsg)
3278    {
3279       if(e2apMsg->choice.successfulOutcome)
3280       {
3281          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3282          if(ricServiceUpdateAck->protocolIEs.list.array)
3283          {
3284             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
3285             {
3286                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
3287                {
3288                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
3289                   {
3290                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3291                         {
3292                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3293                            if(acceptedList->list.array)
3294                            {
3295                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
3296                               {
3297                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
3298                               }
3299                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
3300                            }
3301                            break;
3302                         }
3303
3304                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
3305                         {
3306                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
3307                            if(rejectedList->list.array)
3308                            {
3309                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
3310                               {
3311                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
3312                               }
3313                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
3314                            }
3315                            break;
3316                         }
3317                   }
3318                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
3319                }
3320             }
3321             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
3322          }
3323          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
3324       }
3325       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3326    }
3327 }
3328
3329 /*******************************************************************
3330  *
3331  * @brief Build RAN function rejected list
3332  *
3333  * @details
3334  *
3335  *    Function : BuildRanFunctionRejectedList
3336  *
3337  *    Functionality: Build RAN function rejected list 
3338  *
3339  * @params[in] 
3340  *    Count of ran functions to be rejected in the list 
3341  *    Received list of RAN functions
3342  *
3343  * @return ROK - success
3344  *         RFAILED - failure
3345  * ****************************************************************/
3346
3347 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
3348 {
3349    uint8_t ranFuncIdx = 0;
3350    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
3351    
3352    ranFuncRejectedList->list.count = count;
3353    
3354    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
3355    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
3356    if(ranFuncRejectedList->list.array == NULLP)
3357    {
3358       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
3359       return RFAILED;
3360    }
3361    
3362    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
3363    {
3364       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
3365       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
3366       {
3367          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
3368          return RFAILED;
3369       }
3370       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
3371       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
3372       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
3373       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
3374       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
3375       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
3376             CauseE2RICservice_ran_function_not_supported);
3377    }
3378    
3379    return ROK;
3380 }
3381
3382 /*******************************************************************
3383  *
3384  * @brief build and send the ric service update Acknowledge 
3385  *
3386  * @details
3387  *
3388  *    Function : BuildAndSendRicServiceUpdateAcknowledge
3389  *
3390  * Functionality: build and send the ric service update Acknowledge 
3391  * @return ROK     - success
3392  *         RFAILED - Acknowledge
3393  *
3394  ******************************************************************/
3395
3396 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, uint16_t transId, RicTmpRanFunList ricRanFuncList)
3397 {
3398    E2AP_PDU_t         *e2apMsg = NULL;
3399    asn_enc_rval_t     encRetVal;
3400    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
3401    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
3402
3403    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
3404    while(true)
3405    {
3406       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3407       if(e2apMsg == NULLP)
3408       {
3409          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3410          break;
3411       }
3412       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
3413       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
3414       if(e2apMsg->choice.successfulOutcome == NULLP)
3415       {
3416          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3417          break;
3418       }
3419
3420       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3421       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
3422       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
3423       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3424
3425       elementCnt = 1;
3426       if(ricRanFuncList.numOfRanFunAccepted)
3427          elementCnt++;
3428       if(ricRanFuncList.numOfRanFuneRejected)
3429          elementCnt++;
3430       
3431
3432       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
3433       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
3434
3435       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
3436       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
3437       {
3438          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3439          break;
3440       }
3441
3442       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3443       {
3444          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
3445          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
3446          {
3447             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3448             break;
3449          }
3450       }
3451       if(arrIdx<elementCnt)
3452       {
3453          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3454          break;
3455       }
3456
3457       /* Trans Id */
3458       arrIdx = 0;
3459       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3460       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3461       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
3462       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
3463
3464       if(ricRanFuncList.numOfRanFunAccepted)
3465       {
3466          /* Accepted RAN function List */
3467          arrIdx++;
3468          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
3469          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3470          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
3471          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
3472          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
3473          {
3474             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
3475             break;         
3476          }
3477       }
3478       
3479       if(ricRanFuncList.numOfRanFuneRejected)
3480       {
3481          /* RAN Functions Rejected List */
3482          arrIdx++;
3483          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
3484          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3485          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
3486          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
3487          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
3488          {
3489             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
3490             break;         
3491          }
3492       }
3493       
3494       
3495       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3496       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3497       encBufSize = 0;
3498       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3499
3500       /* Check encode results */
3501       if(encRetVal.encoded == ENCODE_FAIL)
3502       {
3503          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
3504                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3505          break;
3506       }
3507       else
3508       {
3509          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
3510          for(int i=0; i< encBufSize; i++)
3511          {
3512             DU_LOG("%x",encBuf[i]);
3513          }
3514       }
3515
3516       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
3517       {
3518          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
3519          break;
3520       }
3521       ret =ROK;
3522       break;
3523    }
3524    FreeRicServiceUpdateAck(e2apMsg);
3525    return ret; 
3526 }
3527
3528 /*******************************************************************
3529  *
3530  * @brief process the RIC service update 
3531  *
3532  * @details
3533  *
3534  *    Function : ProcRicserviceUpdate 
3535  *
3536  * Functionality: process the RIC service update 
3537  *
3538  * @return ROK     - success
3539  *         RFAILED - failure
3540  *
3541  ******************************************************************/
3542
3543 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
3544 {
3545    RicTmpRanFunList ricRanFuncList;
3546    DuDb    *duDb = NULLP;
3547    int8_t transId =-1;
3548    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
3549    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
3550    RanFunction *ranFuncDb = NULLP;
3551    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
3552    RANfunction_Item_t  *ranFuncItem =NULL;
3553    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
3554    RANfunctions_List_t *ranFuncList=NULL;
3555    RANfunctionsID_List_t *deleteList=NULL;
3556    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
3557
3558    SEARCH_DU_DB(duIdx, duId, duDb); 
3559    if(duDb == NULLP)
3560    {
3561       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3562       return;
3563    }
3564    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
3565
3566    if(!ricServiceUpdate)
3567    {
3568       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
3569       return;
3570    }
3571
3572    if(!ricServiceUpdate->protocolIEs.list.array)      
3573    {
3574       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
3575       return;
3576    }
3577    elementCnt = ricServiceUpdate->protocolIEs.list.count;
3578    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
3579    {
3580       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
3581       {
3582          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
3583          return;
3584       }
3585
3586       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
3587       {
3588          case ProtocolIE_IDE2_id_TransactionID:
3589             {
3590                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3591
3592                if(transId < 0 || transId > 255)
3593                {
3594                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
3595                   return;
3596                }
3597                break;
3598             }
3599
3600          case ProtocolIE_IDE2_id_RANfunctionsAdded:
3601             {
3602                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
3603
3604                if(ranFuncList->list.array)
3605                {
3606                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
3607                   {
3608                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
3609                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3610
3611                      /* Adding the ran function in temporary list */
3612                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
3613                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
3614                      ricRanFuncList.numOfRanFunAccepted++;
3615
3616                      /* Adding the new ran function in DB*/
3617                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
3618                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
3619                      duDb->numOfRanFunction++;
3620
3621                      /* Calculating total number of ran fuctions which are received for addition */
3622                      recvdRanFuncCount++;
3623                   }
3624                }
3625                break;
3626             }
3627
3628          case ProtocolIE_IDE2_id_RANfunctionsModified:
3629             {
3630
3631                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
3632                if(ranFuncList->list.array)
3633                {
3634                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
3635                   {
3636                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
3637                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3638                      if(fetchRanFuncFromRanFuncId(duDb, ranFuncItem->ranFunctionID) == NULLP)
3639                      {
3640                         /* Calculating total number of ran fuctions which are not present */
3641                         failedRanFuncCount++;
3642
3643                         /* Adding the ran function in temporary list */
3644                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
3645                         ricRanFuncList.numOfRanFuneRejected++;
3646                      }
3647                      else
3648                      {
3649
3650                         /* Adding the ran function in temporary list */
3651                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
3652                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
3653                         ricRanFuncList.numOfRanFunAccepted++;
3654
3655                         /* Updating the new ran function in DB*/
3656                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
3657                      }
3658                      /* Calculating total number of ran fuctions which are received for modification */
3659                      recvdRanFuncCount++;
3660                   }
3661                }
3662                break;
3663             }
3664          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
3665             {
3666
3667                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
3668                if(deleteList->list.array)
3669                {
3670                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
3671                   {
3672                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
3673                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
3674                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncIdItem->ranFunctionID);
3675                      if(ranFuncDb)
3676                      {
3677                         memset(ranFuncDb, 0, sizeof(RanFunction));
3678                         duDb->numOfRanFunction--; 
3679                      }
3680
3681                      /* Calculating total number of ran fuctions which are received for deletion */
3682                      recvdRanFuncCount++;
3683                   }
3684                }
3685                break;
3686             }
3687
3688          default:
3689             {
3690                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
3691                break;
3692             }
3693       }
3694    }
3695    
3696    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
3697     * Else sending RIC Service Update Acknowledge */  
3698    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
3699    {
3700       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
3701       {
3702          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
3703          return;
3704       }
3705    }
3706    else
3707    {
3708       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
3709       {
3710          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
3711          return;
3712       }
3713    }
3714 }
3715
3716 /*******************************************************************
3717  *
3718  * @brief Processing RIC subscription failure from DU
3719  *
3720  * @details
3721  *
3722  *    Function : ProcRicSubscriptionFailure
3723  *
3724  * Functionality: Processing RIC subscription failure from DU
3725  *
3726  * @param  ID of DU from which message was sent
3727  *         RIC Subscription failure message
3728  * @return ROK     - success
3729  *         RFAILED - failure
3730  *
3731  ******************************************************************/
3732 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
3733 {
3734    uint8_t ieIdx = 0, duIdx = 0;
3735    uint8_t ranFuncId = 0;
3736    DuDb    *duDb = NULLP;
3737    RanFunction *ranFuncDb = NULLP;
3738    RicSubscription *ricSubs = NULLP;
3739    CmLList *ricSubsNode = NULLP;
3740    RicRequestId ricReqId;
3741    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3742
3743    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
3744
3745    SEARCH_DU_DB(duIdx, duId, duDb);
3746    if(duDb == NULLP)
3747    {
3748       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3749       return RFAILED;
3750    }
3751
3752    memset(&ricReqId, 0, sizeof(RicRequestId));
3753    if(ricSubscriptionFailure)
3754    {
3755       if(ricSubscriptionFailure->protocolIEs.list.array)
3756       {
3757          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
3758          {
3759             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
3760             {
3761                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
3762                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
3763                {
3764                   case ProtocolIE_IDE2_id_RICrequestID:
3765                   {
3766                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
3767                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
3768                      break;
3769                   }
3770                   case ProtocolIE_IDE2_id_RANfunctionID:
3771                   {
3772                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
3773                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3774                      if(!ranFuncDb)
3775                      {
3776                         DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionFailure : RAN Function Id [%d] not found", ranFuncId);
3777                         return RFAILED;
3778                      }
3779                      else
3780                      {
3781                         /* Remove subscription entry from RAN Function */
3782                         ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3783                         if(ricSubs)
3784                         {
3785                            cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
3786                            deleteRicSubscriptionNode(ricSubsNode);
3787                         }
3788                      }
3789                      break; 
3790                   }
3791                   case ProtocolIE_IDE2_id_CauseE2:
3792                   default:
3793                      /* No handling required as of now since this is a stub */
3794                      break;
3795                }
3796             }
3797          }
3798       }
3799    }
3800    return ROK;
3801 }
3802
3803 /*******************************************************************
3804  *
3805  * @brief Free RIC Subscription Modification Refuse
3806  *
3807  * @details
3808  *
3809  *    Function : FreeRicSubsModRefuse
3810  *
3811  * Functionality: Free RIC Subscription Modification Refuse
3812  *
3813  * @param  E2AP Message PDU to be freed
3814  * @return void
3815  *
3816  ******************************************************************/
3817 void FreeRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
3818 {
3819    uint8_t ieIdx =0;
3820    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3821
3822    if(e2apMsg)
3823    {
3824       if(e2apMsg->choice.unsuccessfulOutcome)
3825       {
3826          ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3827          if(ricSubsModRefuse->protocolIEs.list.array)
3828          {
3829             for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
3830             {
3831                RIC_FREE(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3832             }
3833             RIC_FREE(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3834          }
3835          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3836       }
3837       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3838    }
3839 }
3840
3841 /*******************************************************************
3842  *
3843  * @brief Build And Send RIC Subscription Modification Refuse
3844  *
3845  * @details
3846  *
3847  *    Function : BuildAndSendRicSubsModRefuse
3848  *
3849  * Functionality: Build And Send RIC Subscription Modification Refuse
3850  *
3851  * @param DU ID
3852  *        RIC Request ID of subscription
3853  *        RAN Function ID
3854  *        Type of failure
3855  *        Cause of failure
3856  * @return ROK - success
3857  *         RFAILED - failure
3858  *
3859  ******************************************************************/
3860 uint8_t BuildAndSendRicSubsModRefuse(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, CauseE2_PR causeType, \
3861    uint8_t cause)
3862 {
3863    uint8_t ieIdx = 0, elementCnt = 0;
3864    uint8_t ret = RFAILED;
3865    E2AP_PDU_t *e2apMsg = NULL;
3866    asn_enc_rval_t encRetVal;
3867    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3868    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
3869
3870    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Refuse\n");
3871    while(true)
3872    {
3873       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3874       if(e2apMsg == NULLP)
3875       {
3876          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3877          break;
3878       }
3879       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3880       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3881       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3882       {
3883          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3884          break;
3885       }
3886
3887       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3888       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3889       e2apMsg->choice.unsuccessfulOutcome->value.present = \
3890          UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse;
3891       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3892
3893       elementCnt = 3;
3894       ricSubsModRefuse->protocolIEs.list.count = elementCnt;
3895       ricSubsModRefuse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRefuse_IEs_t *);
3896       RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3897       if(!ricSubsModRefuse->protocolIEs.list.array)
3898       {
3899          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3900          break;
3901       }
3902
3903       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3904       {
3905          RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3906          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
3907          {
3908             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3909             break;
3910          }
3911       }
3912       
3913       /* RIC Request ID */
3914       ieIdx = 0;
3915       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3916       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RICrequestID;
3917       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3918       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RICrequestID;
3919       ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3920       ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3921
3922       /* RAN Function ID */
3923       ieIdx++;
3924       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3925       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3926       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3927       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RANfunctionID;
3928       ricSubsModRefuseIe->value.choice.RANfunctionID = ranFuncId;
3929
3930       /* Cause */
3931       ieIdx++;
3932       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3933       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_CauseE2;
3934       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3935       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_CauseE2;
3936       fillE2FailureCause(&ricSubsModRefuseIe->value.choice.CauseE2, causeType, cause); 
3937
3938       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3939       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3940       encBufSize = 0;
3941       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3942
3943       /* Check encode results */
3944       if(encRetVal.encoded == ENCODE_FAIL)
3945       {
3946          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification refuse (at %s)\n",\
3947                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3948          break;
3949       }
3950       else
3951       {
3952          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification refuse\n");
3953          for(int i=0; i< encBufSize; i++)
3954          {
3955             DU_LOG("%x",encBuf[i]);
3956          }
3957       }
3958
3959       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3960       {
3961          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Refused");
3962          break;
3963       }
3964
3965       ret =ROK;
3966       break;
3967    }
3968    FreeRicSubsModRefuse(e2apMsg);
3969    return ret;
3970 }
3971
3972 /*******************************************************************
3973  *
3974  * @brief Free memory for RIC Subscription Modification Confirm
3975  *
3976  * @details
3977  *
3978  *    Function : FreeRicSubsModConfirm
3979  *
3980  * Functionality: Free memory for RIC subscription modification
3981  *    confirm
3982  *
3983  * @param E2AP Message PDU to be freed
3984  * @return Void
3985  *
3986  ******************************************************************/
3987 void FreeRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
3988 {
3989    uint8_t ieIdx = 0, arrIdx=0;
3990    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3991    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3992    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
3993    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
3994    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
3995    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
3996
3997    if(e2apMsg)
3998    {
3999       if(e2apMsg->choice.successfulOutcome)
4000       {
4001          ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
4002          if(ricSubsModCfm->protocolIEs.list.array)
4003          {
4004             for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
4005             {
4006                if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
4007                {
4008                   ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4009                   switch(ricSubsModCfmIe->id)
4010                   {
4011                      case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
4012                         {
4013                            modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
4014                            if(modCfmList->list.array)
4015                            {
4016                               for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
4017                               {
4018                                  RIC_FREE(modCfmList->list.array[arrIdx], \
4019                                     sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
4020                               }
4021                               RIC_FREE(modCfmList->list.array,  modCfmList->list.size);
4022                            }
4023                            break;
4024                         }
4025
4026                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
4027                         {
4028                            modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
4029                            if(modRefusedList->list.array)
4030                            {
4031                               for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
4032                               {
4033                                  RIC_FREE(modRefusedList->list.array[arrIdx], \
4034                                        sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
4035                               }
4036                               RIC_FREE(modRefusedList->list.array,  modRefusedList->list.size);
4037                            }
4038                            break;
4039                         }
4040
4041                      case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
4042                         {
4043                            rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
4044                            if(rmvCfmList->list.array)
4045                            {
4046                               for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
4047                               {
4048                                  RIC_FREE(rmvCfmList->list.array[arrIdx], \
4049                                        sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
4050                               }
4051                               RIC_FREE(rmvCfmList->list.array,  rmvCfmList->list.size);
4052                            }
4053                            break;
4054                         }
4055
4056                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
4057                         {
4058                            rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
4059                            if(rmvFailList->list.array)
4060                            {
4061                               for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
4062                               {
4063                                  RIC_ALLOC(rmvFailList->list.array[arrIdx], \
4064                                     sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
4065                               }
4066                               RIC_FREE(rmvFailList->list.array,  rmvFailList->list.size);
4067                            }
4068                            break;
4069                         }
4070
4071                      default:
4072                         break;
4073
4074                   }
4075                   RIC_FREE(ricSubsModCfmIe, sizeof(RICsubscriptionModificationConfirm_IEs_t));
4076                }
4077             }
4078             RIC_FREE(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
4079          }
4080          RIC_FREE(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
4081       }
4082       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4083    }
4084 }
4085
4086 /*******************************************************************
4087  *
4088  * @brief Fill the list of actions confirmed for modification
4089  *
4090  * @details
4091  *
4092  *    Function : fillActionModConfirmedList
4093  *
4094  * Functionality: Fill the list of actions confirmed for modification
4095  *
4096  * @param List to be filled
4097  *        Number of actions
4098  *        Source list of actions
4099  * @return ROK - success
4100  *         RFAILED - failure
4101  *
4102  ******************************************************************/
4103 uint8_t fillActionModConfirmedList(RICactions_ConfirmedForModification_List_t *modCfmList, uint8_t numActions, \
4104    uint8_t *actionModifiedList)
4105 {
4106    uint8_t arrIdx = 0;
4107    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
4108
4109    modCfmList->list.count = numActions;
4110    modCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForModification_ItemIEs_t *);
4111    RIC_ALLOC(modCfmList->list.array,  modCfmList->list.size);
4112    if(!modCfmList->list.array)
4113    {
4114       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4115       return RFAILED;
4116    }
4117
4118    for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
4119    {
4120       RIC_ALLOC(modCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
4121       if(!modCfmList->list.array[arrIdx])
4122       {
4123          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4124          return RFAILED;
4125       }
4126
4127       modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
4128       modCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForModification_Item;
4129       modCfmListItem->criticality = CriticalityE2_ignore;
4130       modCfmListItem->value.present = \
4131          RICaction_ConfirmedForModification_ItemIEs__value_PR_RICaction_ConfirmedForModification_Item;
4132       modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID = actionModifiedList[arrIdx];
4133    }
4134
4135    return ROK;
4136 }
4137
4138 /*******************************************************************
4139  *
4140  * @brief Fill the list of actions refused to be modified
4141  *
4142  * @details
4143  *
4144  *    Function : fillActionModRefusedList
4145  *
4146  * Functionality: Fill the list of actions refused to be modified
4147  *
4148  * @param List to be filled
4149  *        Number of list
4150  *        Source list of actions refused tobe modified
4151  * @return ROK - success
4152  *         RFAILED - failure
4153  *
4154  ******************************************************************/
4155 uint8_t fillActionModRefusedList(RICactions_RefusedToBeModified_List_t *modRefusedList, uint8_t numActions, \
4156    ActionFailed *actionModFailedList)
4157 {
4158    uint8_t arrIdx = 0;
4159    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
4160
4161    modRefusedList->list.count = numActions;
4162    modRefusedList->list.size = numActions * sizeof(RICaction_RefusedToBeModified_ItemIEs_t *);
4163    RIC_ALLOC(modRefusedList->list.array,  modRefusedList->list.size);
4164    if(!modRefusedList->list.array)
4165    {
4166       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4167       return RFAILED;
4168    }
4169
4170    for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
4171    {
4172       RIC_ALLOC(modRefusedList->list.array[arrIdx], sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
4173       if(!modRefusedList->list.array[arrIdx])
4174       {
4175          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4176          return RFAILED;
4177       }
4178
4179       modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
4180       modRefusedListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeModified_Item;
4181       modRefusedListItem->criticality = CriticalityE2_ignore;
4182       modRefusedListItem->value.present = \
4183          RICaction_RefusedToBeModified_ItemIEs__value_PR_RICaction_RefusedToBeModified_Item;
4184       modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID = \
4185          actionModFailedList[arrIdx].actionId;
4186       fillE2FailureCause(&modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.cause, \
4187          actionModFailedList[arrIdx].failureType, actionModFailedList[arrIdx].cause);
4188    }
4189
4190    return ROK;
4191 }
4192
4193 /*******************************************************************
4194  *
4195  * @brief Fill the list of action confirmed for removal
4196  *
4197  * @details
4198  *
4199  *    Function : fillActionRemovalConfirmedList
4200  *
4201  * Functionality: Fill the list of action confirmed for removal
4202  *
4203  * @param List to be filled
4204  *        Number of actions
4205  *        Source list of actions removed
4206  * @return ROK - success
4207  *         RFAILED - failure
4208  *
4209  ******************************************************************/
4210 uint8_t fillActionRemovalConfirmedList(RICactions_ConfirmedForRemoval_List_t *rmvCfmList, uint8_t numActions, \
4211    uint8_t *actionRemovedList)
4212 {
4213    uint8_t arrIdx = 0;
4214    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
4215
4216    rmvCfmList->list.count = numActions;
4217    rmvCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t *);
4218    RIC_ALLOC(rmvCfmList->list.array,  rmvCfmList->list.size);
4219    if(!rmvCfmList->list.array)
4220    {
4221       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4222       return RFAILED;
4223    }
4224
4225    for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
4226    {
4227       RIC_ALLOC(rmvCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
4228       if(!rmvCfmList->list.array[arrIdx])
4229       {
4230          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4231          return RFAILED;
4232       }
4233
4234       rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
4235       rmvCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForRemoval_Item;
4236       rmvCfmListItem->criticality = CriticalityE2_ignore;
4237       rmvCfmListItem->value.present = \
4238          RICaction_ConfirmedForRemoval_ItemIEs__value_PR_RICaction_ConfirmedForRemoval_Item;
4239       rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID = actionRemovedList[arrIdx];
4240    }
4241
4242    return ROK;
4243 }
4244
4245 /*******************************************************************
4246  *
4247  * @brief Fill the list of actions refused to be removed
4248  *
4249  * @details
4250  *
4251  *    Function : fillActionRemovalRefusedList
4252  *
4253  * Functionality: Fill the list of actions refused to be removed
4254  *
4255  * @param List to be filled
4256  *        Number of list
4257  *        Source list of actions refused to be removed
4258  * @return ROK - success
4259  *         RFAILED - failure
4260  *
4261  ******************************************************************/
4262 uint8_t fillActionRemovalRefusedList(RICactions_RefusedToBeRemoved_List_t *rmvFailList, \
4263    uint8_t numActions, ActionFailed *actionRmvlFailList)
4264 {
4265    uint8_t arrIdx = 0;
4266    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
4267
4268    rmvFailList->list.count = numActions;
4269    rmvFailList->list.size = numActions * sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t *);
4270    RIC_ALLOC(rmvFailList->list.array,  rmvFailList->list.size);
4271    if(!rmvFailList->list.array)
4272    {
4273       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4274       return RFAILED;
4275    }
4276
4277    for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
4278    {
4279       RIC_ALLOC(rmvFailList->list.array[arrIdx], sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
4280       if(!rmvFailList->list.array[arrIdx])
4281       {
4282          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4283          return RFAILED;
4284       }
4285
4286       rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
4287       rmvFailListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeRemoved_Item;
4288       rmvFailListItem->criticality = CriticalityE2_ignore;
4289       rmvFailListItem->value.present = \
4290          RICaction_RefusedToBeRemoved_ItemIEs__value_PR_RICaction_RefusedToBeRemoved_Item;
4291       rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID = actionRmvlFailList[arrIdx].actionId;
4292       fillE2FailureCause(&rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.cause, \
4293          actionRmvlFailList[arrIdx].failureType, actionRmvlFailList[arrIdx].cause);
4294    }
4295
4296    return ROK;
4297
4298 }
4299
4300 /*******************************************************************
4301  *
4302  * @brief Build And Send RIC Subscription Modification Confirm
4303  *
4304  * @details
4305  *
4306  *    Function : BuildAndSendRicSubsModConfirm
4307  *
4308  * Functionality: Build And Send RIC Subscription Modification Confirm
4309  *
4310  * @param DU ID
4311  *        RIC Request ID of subscription
4312  *        RAN Function ID
4313  *        Temporary source action list
4314  * @return ROK - success
4315  *         RFAILED - failure
4316  *
4317  ******************************************************************/
4318 uint8_t BuildAndSendRicSubsModConfirm(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, RicTmpActionList tmpActionList)
4319 {
4320    uint8_t ieIdx = 0, elementCnt = 0;
4321    uint8_t ret = RFAILED;
4322    E2AP_PDU_t *e2apMsg = NULLP;
4323    asn_enc_rval_t encRetVal;
4324    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
4325    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
4326
4327    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Confirm\n");
4328    while(true)
4329    {
4330       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4331       if(e2apMsg == NULLP)
4332       {
4333          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4334          break;
4335       }
4336
4337       /* Successful Outcome */
4338       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
4339       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
4340       if(e2apMsg->choice.successfulOutcome == NULLP)
4341       {
4342          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4343          break;
4344       }
4345
4346       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
4347       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
4348       e2apMsg->choice.successfulOutcome->value.present = \
4349          SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm;
4350       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
4351
4352       elementCnt = 2;
4353       if(tmpActionList.numActionModified)
4354          elementCnt++;
4355       if(tmpActionList.numActionModFailed)
4356          elementCnt++;
4357       if(tmpActionList.numActionRemoved)
4358          elementCnt++;
4359       if(tmpActionList.numActionRemovalFailed)
4360          elementCnt++;
4361
4362       ricSubsModCfm->protocolIEs.list.count = elementCnt;
4363       ricSubsModCfm->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationConfirm_IEs_t *);
4364       RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
4365       if(!ricSubsModCfm->protocolIEs.list.array)
4366       {
4367          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4368          break;
4369       }
4370
4371       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4372       {
4373          RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationConfirm_IEs_t));
4374          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
4375          {
4376             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4377             break;
4378          }
4379       }
4380       
4381       /* RIC Request ID */
4382       ieIdx = 0;
4383       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4384       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICrequestID;
4385       ricSubsModCfmIe->criticality = CriticalityE2_reject;
4386       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RICrequestID;
4387       ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
4388       ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
4389
4390       /* RAN Function ID */
4391       ieIdx++;
4392       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4393       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RANfunctionID;
4394       ricSubsModCfmIe->criticality = CriticalityE2_reject;
4395       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RANfunctionID;
4396       ricSubsModCfmIe->value.choice.RANfunctionID = ranFuncId;
4397
4398       /* RIC Actions List confirmed for modification */
4399       if(tmpActionList.numActionModified)
4400       {
4401          ieIdx++;
4402          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4403          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List;
4404          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4405          ricSubsModCfmIe->value.present = \
4406             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForModification_List;
4407          if(fillActionModConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List, \
4408             tmpActionList.numActionModified, tmpActionList.actionModifiedList) != ROK)
4409          {
4410             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Modification List", __func__);
4411             break;
4412          }
4413       }
4414
4415       /* RIC Actions List refured to be modified */
4416       if(tmpActionList.numActionModFailed)
4417       {
4418          ieIdx++;
4419          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4420          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List;
4421          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4422          ricSubsModCfmIe->value.present = \
4423             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeModified_List;
4424          if(fillActionModRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List, \
4425             tmpActionList.numActionModFailed, tmpActionList.actionModFailedList) != ROK)
4426          {
4427             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Refused to be Modified List", __func__);
4428             break;
4429          }
4430       }
4431
4432       /* RIC Actions List confirmed for removal */
4433       if(tmpActionList.numActionRemoved)
4434       {
4435          ieIdx++;
4436          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4437          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List;
4438          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4439          ricSubsModCfmIe->value.present = \
4440             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForRemoval_List;
4441          if(fillActionRemovalConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List, \
4442             tmpActionList.numActionRemoved, tmpActionList.actionRemovedList) != ROK)
4443          {
4444             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Removal List", __func__);
4445             break;
4446          }
4447       }
4448
4449       /* RIC Actions List Refused to be removed */
4450       if(tmpActionList.numActionRemovalFailed)
4451       {
4452          ieIdx++;
4453          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4454          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List;
4455          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4456          ricSubsModCfmIe->value.present = \
4457             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeRemoved_List;
4458          if(fillActionRemovalRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List, \
4459             tmpActionList.numActionRemovalFailed, tmpActionList.actionRemovalFailedList) != ROK)
4460          {
4461             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Failed to be Removed List", __func__);
4462             break;
4463          }
4464       }
4465
4466       /* Print and encode E2AP Message PDU */
4467       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4468       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4469       encBufSize = 0;
4470       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4471
4472       /* Check encode results */
4473       if(encRetVal.encoded == ENCODE_FAIL)
4474       {
4475          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification confirm (at %s)\n",\
4476                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4477          break;
4478       }
4479       else
4480       {
4481          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification confirm\n");
4482          for(int i=0; i< encBufSize; i++)
4483          {
4484             DU_LOG("%x",encBuf[i]);
4485          }
4486       }
4487
4488       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4489       {
4490          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Confirm");
4491          break;
4492       }
4493
4494       ret =ROK;
4495       break;
4496    }
4497
4498    FreeRicSubsModConfirm(e2apMsg);
4499    return ret;
4500 }
4501
4502 /*******************************************************************
4503  *
4504  * @brief Processing of RIC Subscription Modification Required
4505  *
4506  * @details
4507  *
4508  *    Function : ProcRicSubsModReqd
4509  *
4510  * Functionality: Processing of RIC Subscription Modification Required
4511  *    As of now, we do not identify any scenario where this message
4512  *    shall be sent by DU. Hence, bare minimum handling has been
4513  *    done here.
4514  *
4515  * @param  DU ID
4516  *         RIC Subscription Modification Required IEs
4517  * @return ROK-success
4518  *         RFAILED-failure
4519  *
4520  ******************************************************************/
4521 uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t *ricSubsModReqd)
4522 {
4523    uint8_t ieIdx = 0, actionIdx = 0, duIdx = 0;
4524    DuDb    *duDb = NULLP;
4525    uint16_t ranFuncId;
4526    uint16_t actionId;
4527    RicRequestId ricReqId;
4528    RanFunction *ranFuncDb = NULLP;
4529    RicSubscription *ricSubs = NULLP;
4530    CmLList *ricSubsNode = NULLP;
4531    CmLList *actionNode = NULLP;
4532    ActionInfo *action = NULLP;
4533    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
4534    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
4535    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
4536    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULLP;
4537    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULLP;
4538    RicTmpActionList tmpActionList;
4539
4540    memset(&ricReqId, 0, sizeof(RicRequestId));
4541    memset(&tmpActionList, 0, sizeof(RicTmpActionList));
4542
4543    SEARCH_DU_DB(duIdx, duId, duDb);
4544    if(duDb == NULLP)
4545    {
4546       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4547       return RFAILED;
4548    }
4549
4550    for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
4551    {
4552       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
4553       switch(ricSubsModReqdIe->id)
4554       {
4555          case ProtocolIE_IDE2_id_RICrequestID:
4556             {
4557                ricReqId.requestorId = ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID;
4558                ricReqId.instanceId = ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID;
4559                break;
4560             }
4561          case ProtocolIE_IDE2_id_RANfunctionID:
4562             {
4563                ranFuncId = ricSubsModReqdIe->value.choice.RANfunctionID;
4564                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
4565                if(!ranFuncDb)
4566                {
4567                   /* If RIC Subscription not found, send RIC Subscription modification refuse to DU */
4568                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RIC Subscription not found");
4569                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
4570                      CauseE2RICrequest_ran_function_id_invalid);
4571                   return RFAILED;
4572                }
4573
4574                ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
4575                if(!ricSubs)
4576                {
4577                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
4578                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RAN Function ID [%d] not found",ranFuncId);
4579                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, \
4580                      CauseE2_PR_ricRequest, CauseE2RICrequest_request_id_unknown);
4581                   return RFAILED; 
4582                }
4583                break;
4584             }
4585          case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
4586             {
4587                actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
4588                for(actionIdx = 0; actionIdx < actionToBeModList->list.count; actionIdx++)
4589                {
4590                   actionNode=NULLP;
4591                   actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[actionIdx];
4592                   actionId = actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID;
4593                   action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
4594                   if(action)
4595                   {
4596                      /* No modification required as of now, hence directly adding to the list */
4597                      tmpActionList.actionModifiedList[tmpActionList.numActionModified++] = actionId;
4598                   }
4599                   else
4600                   {
4601                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].actionId = actionId;
4602                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].failureType = \
4603                         CauseE2_PR_ricRequest;
4604                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].cause = \
4605                         CauseE2RICrequest_action_not_supported;
4606                      tmpActionList.numActionModFailed++;
4607                   }
4608                }
4609                break;
4610             }
4611          case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
4612             {
4613                actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
4614                for(actionIdx = 0; actionIdx < actionToBeRmvList->list.count; actionIdx++)
4615                {
4616                   actionNode=NULLP;
4617                   actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[actionIdx];
4618                   actionId = actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID;
4619                   action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
4620                   if(action)
4621                   {
4622                      tmpActionList.actionRemovedList[tmpActionList.numActionRemoved++] = actionId;
4623                      cmLListDelFrm(&ricSubs->actionSequence, actionNode);
4624                      deleteActionSequence(actionNode);
4625                   }
4626                }
4627                break;
4628             }
4629          default:
4630             break;
4631       }
4632    }
4633
4634    /* If none of the action modification/removal is supported, 
4635     *   send RIC Subscription Modification Refuse
4636     * Else
4637     *   send RIC Subscription Modification Confirm
4638     */
4639    if(tmpActionList.numActionModified || tmpActionList.numActionRemoved)
4640    {
4641       BuildAndSendRicSubsModConfirm(duId, ricReqId, ranFuncId, tmpActionList);
4642    }
4643    else
4644    {
4645       BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
4646             CauseE2RICrequest_action_not_supported);
4647    }
4648    
4649    return ROK;
4650 }
4651
4652 /*******************************************************************
4653  *
4654  * @brief Free the ErrorIndication Message
4655  *
4656  * @details
4657  *
4658  *    Function : FreeRicIndication
4659  *
4660  * Functionality: Free the ErrorIndication Message
4661  *
4662  * @return void
4663  *
4664  *
4665  ******************************************************************/
4666 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
4667 {
4668    uint8_t arrIdx = 0;
4669    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
4670
4671    if(e2apMsg != NULLP)
4672    {
4673       if(e2apMsg->choice.initiatingMessage != NULLP)
4674       {
4675          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4676          if(errorIndicationMsg!= NULLP)
4677          {
4678             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
4679             {
4680                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
4681                {
4682                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
4683                }
4684                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
4685             }
4686          }
4687          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4688       }
4689       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4690    }
4691 }
4692
4693
4694 /*******************************************************************
4695  *
4696  * @brief Builds and Send the ErrorIndication Message
4697  *
4698  * @details
4699  *
4700  *    Function : BuildAndSendErrorIndication
4701  *
4702  * Functionality:Fills the ErrorIndication Message
4703  *
4704  * @params[in] 
4705  *    DU id
4706  *    Trans id
4707  *    Ric req id
4708  *    Ran function id
4709  *    Reason of failure
4710  * @return ROK     - success
4711  *         RFAILED - failure
4712  *
4713  ******************************************************************/
4714
4715 uint8_t BuildAndSendErrorIndication(uint32_t duId, uint16_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
4716 {
4717    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
4718    E2AP_PDU_t         *e2apMsg = NULLP;
4719    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
4720    asn_enc_rval_t     encRetVal;        /* Encoder return value */
4721
4722    while(true)
4723    {
4724       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
4725
4726       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4727       if(e2apMsg == NULLP)
4728       {
4729          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4730          break;
4731       }
4732
4733       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4734       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4735       if(e2apMsg->choice.initiatingMessage == NULLP)
4736       {
4737          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4738          break;
4739       }
4740       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
4741       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4742       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
4743
4744       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4745
4746       /* Element count is 2 for TransactionID/RICrequestID and Cause.
4747        * If the RAN function id is present, the count will be increased.*/
4748       elementCnt = 2;
4749       if(ranFuncId>0)
4750          elementCnt++;
4751
4752       errorIndicationMsg->protocolIEs.list.count = elementCnt;
4753       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
4754
4755       /* Initialize the E2Setup members */
4756       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
4757       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
4758       {
4759          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
4760          break;
4761       }
4762       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
4763       {
4764          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
4765          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
4766          {
4767             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
4768             break;
4769          }
4770       }
4771       if(arrIdx < elementCnt)
4772          break;
4773
4774       arrIdx = 0;
4775
4776       if(transId >=0 && transId<=255)
4777       {
4778          /* TransactionID */
4779          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4780          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4781          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
4782          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4783       }
4784       else
4785       {
4786          /* RICrequestID */
4787          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
4788          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4789          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
4790          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
4791          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
4792       }
4793       
4794       if(ranFuncId>0)
4795       {
4796          /* RAN Function ID */
4797          arrIdx++;
4798          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4799          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4800          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
4801          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
4802       }
4803      
4804       /* Cause */
4805       arrIdx++;
4806       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4807       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
4808       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
4809       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
4810
4811
4812       /* Prints the Msg formed */
4813       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4814       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4815       encBufSize = 0;
4816       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4817             encBuf);
4818       if(encRetVal.encoded == ENCODE_FAIL)
4819       {
4820          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
4821                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4822          break;
4823       }
4824       else
4825       {
4826          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
4827 #ifdef DEBUG_ASN_PRINT
4828          for(int i=0; i< encBufSize; i++)
4829          {
4830             printf("%x",encBuf[i]);
4831          }
4832 #endif
4833       }
4834
4835       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4836       {
4837          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
4838
4839       }
4840       ret = ROK;
4841       break;
4842    }
4843    FreeErrorIndication(e2apMsg);
4844    return ret;
4845 }
4846
4847 /*******************************************************************
4848  *
4849  * @brief Deallocate the memory allocated for ResetRequest msg
4850  *
4851  * @details
4852  *
4853  *    Function : FreeResetRequest
4854  *
4855  *    Functionality:
4856  *       - freeing the memory allocated for ResetRequest
4857  *
4858  * @params[in] E2AP_PDU_t *e2apMsg
4859  * @return ROK     - success
4860  *         RFAILED - failure
4861  *
4862  * ****************************************************************/
4863 void FreeResetRequest(E2AP_PDU_t *e2apMsg)
4864 {
4865    uint8_t ieIdx =0;
4866    ResetRequestE2_t  *resetReq = NULLP;
4867
4868    if(e2apMsg != NULLP)
4869    {
4870       if(e2apMsg->choice.initiatingMessage != NULLP)
4871       {
4872          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4873          if(resetReq->protocolIEs.list.array)
4874          {
4875             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4876             {
4877                RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4878             }
4879             RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4880          }
4881          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4882       }
4883       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4884    }
4885 }
4886
4887 /*******************************************************************
4888  *
4889  * @brief Build and send the reset request msg
4890  *
4891  * @details
4892  *
4893  *    Function : BuildAndSendResetRequest
4894  *
4895  *    Functionality:
4896  *         - Buld and send the reset request msg to E2 node
4897  *
4898  * @params[in]
4899  *    DU database
4900  *    Type of failure 
4901  *    Cause of failure
4902  * @return ROK     - success
4903  *         RFAILED - failure
4904  *
4905  * ****************************************************************/
4906 uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
4907 {
4908    uint8_t ieIdx = 0, elementCnt = 0;
4909    uint16_t transId = 0;
4910    uint8_t ret = RFAILED;
4911    E2AP_PDU_t        *e2apMsg = NULLP;
4912    ResetRequestE2_t  *resetReq = NULLP;
4913    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4914
4915    DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
4916
4917    do
4918    {
4919       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4920       if(e2apMsg == NULLP)
4921       {
4922          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
4923          break;
4924       }
4925
4926       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4927       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4928       if(e2apMsg->choice.initiatingMessage == NULLP)
4929       {
4930          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
4931          break;
4932       }
4933
4934       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4935       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4936       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4937       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4938
4939       elementCnt = 2;
4940       resetReq->protocolIEs.list.count = elementCnt;
4941       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4942
4943       RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4944       if(!resetReq->protocolIEs.list.array)
4945       {
4946          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4947                Reset Request IE array");
4948          break;
4949       }
4950
4951       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4952       {
4953          RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4954          if(!resetReq->protocolIEs.list.array[ieIdx])
4955          {
4956             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4957                   Reset Request IE array element");
4958             break;
4959          }
4960       }
4961
4962       /* In case of failure */
4963       if(ieIdx < elementCnt)
4964          break;
4965
4966       ieIdx = 0;
4967       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4968       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4969       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4970       transId = assignTransactionId(duDb);
4971       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4972
4973       ieIdx++;
4974       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4975       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4976       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4977       fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
4978
4979       /* Prints the Msg formed */
4980       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4981
4982       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4983       encBufSize = 0;
4984       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4985             encBuf);
4986       if(encRetVal.encoded == ENCODE_FAIL)
4987       {
4988          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
4989                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4990          break;
4991       }
4992       else
4993       {
4994          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
4995 #ifdef DEBUG_ASN_PRINT
4996          for(int i=0; i< encBufSize; i++)
4997          {
4998             printf("%x",encBuf[i]);
4999          }
5000 #endif
5001       }
5002       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
5003       {
5004          DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
5005          break;
5006       }
5007
5008
5009       ret = ROK;
5010       break;
5011    }while(true);
5012
5013    /* Free all memory */
5014    FreeResetRequest(e2apMsg);
5015    return ret;
5016 }
5017
5018 /******************************************************************
5019  *
5020  * @brief Delete Ric subscription action
5021  *
5022  * @details
5023  *
5024  *    Function : deleteActionSequence
5025  *
5026  *    Functionality: Delete Ric subscription action
5027  *
5028  * @params[in] Action info
5029  *
5030  * @return void
5031  *
5032  * ****************************************************************/
5033 void deleteActionSequence(CmLList *actionNode)
5034 {
5035    ActionInfo *action = NULLP;
5036
5037    if(actionNode)
5038    {
5039       action = (ActionInfo*)actionNode->node;
5040       memset(action, 0, sizeof(ActionInfo));
5041       RIC_FREE(actionNode->node, sizeof(ActionInfo));
5042       RIC_FREE(actionNode, sizeof(CmLList));
5043    }
5044 }
5045
5046 /******************************************************************
5047  *
5048  * @brief Delete Ric subscription action list
5049  *
5050  * @details
5051  *
5052  *    Function : deleteActionSequenceList
5053  *
5054  *    Functionality: Delete Ric subscription action list
5055  *
5056  * @params[in] Action info list
5057  *
5058  * @return void
5059  *
5060  * ****************************************************************/
5061 void deleteActionSequenceList(CmLListCp *actionList)
5062 {
5063    CmLList *actionNode=NULLP;
5064
5065    CM_LLIST_FIRST_NODE(actionList, actionNode);
5066    while(actionNode)
5067    {
5068       cmLListDelFrm(actionList, actionNode);
5069       deleteActionSequence(actionNode);
5070       CM_LLIST_FIRST_NODE(actionList, actionNode);
5071    }
5072
5073 }
5074
5075 /******************************************************************
5076  *
5077  * @brief Delete Ric subscription node
5078  *
5079  * @details
5080  *
5081  *    Function : deleteRicSubscriptionNode
5082  *
5083  *    Functionality: Delete Ric subscription node
5084  *
5085  * @params[in] Ric subscription info
5086  *
5087  * @return void
5088  *
5089  * ****************************************************************/
5090 void deleteRicSubscriptionNode(CmLList *subscriptionNode)
5091 {
5092    RicSubscription *ricSubscriptionInfo = NULLP;
5093
5094    ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;
5095    
5096    deleteActionSequenceList(&ricSubscriptionInfo->actionSequence);
5097    
5098    memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
5099    RIC_FREE(subscriptionNode->node, sizeof(RicSubscription));
5100    RIC_FREE(subscriptionNode, sizeof(CmLList));
5101 }
5102
5103 /*******************************************************************
5104  *
5105  * @brief Delete RIC subscription List
5106  *
5107  * @details
5108  *
5109  *    Function : deleteRicSubscriptionList 
5110  *
5111  * Functionality: Delete RIC subscription list
5112  *
5113  * @params[in] RIC Subscription list
5114  * @return void
5115
5116  *
5117  ******************************************************************/
5118 void deleteRicSubscriptionList(CmLListCp *subscriptionList)
5119 {
5120    CmLList *subscriptionNode = NULLP;
5121
5122    CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
5123    while(subscriptionNode)
5124    {
5125       cmLListDelFrm(subscriptionList, subscriptionNode);
5126       deleteRicSubscriptionNode(subscriptionNode);
5127       CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
5128    }
5129 }
5130
5131 /*******************************************************************
5132  *
5133  * @brief process the E2 Reset Response
5134  *
5135  * @details
5136  *
5137  *    Function : ProcResetResponse 
5138  *
5139  * Functionality: Process E2 Reset Response 
5140  *
5141  * @params[in] 
5142  *       du Id
5143  *       Pointer to reset response 
5144  * @return void
5145  *
5146  ******************************************************************/
5147
5148 void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
5149 {
5150    uint8_t ieIdx = 0, duIdx =0;
5151    DuDb *duDb = NULLP;
5152    RanFunction *ranFuncDb = NULLP;
5153    uint16_t ranFuncIdx = 0;
5154
5155    SEARCH_DU_DB(duIdx, duId, duDb); 
5156    if(duDb == NULLP)
5157    {
5158       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5159       return;
5160    }
5161    
5162    if(!resetRsp)
5163    {
5164       DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
5165       return;
5166    }
5167
5168    if(!resetRsp->protocolIEs.list.array)      
5169    {
5170       DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
5171       return;
5172    }
5173    
5174    for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
5175    {
5176       if(resetRsp->protocolIEs.list.array[ieIdx])
5177       {
5178          switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
5179          {
5180             case ProtocolIE_IDE2_id_TransactionID:
5181                {
5182                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
5183                   {
5184                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
5185                      if(ranFuncDb->id > 0)
5186                      {
5187                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
5188                      }
5189                   }
5190                   break;
5191                }
5192             case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5193                {
5194                   break;
5195                }
5196          }
5197       }
5198    }
5199 }
5200
5201
5202 /*******************************************************************
5203  *
5204  * @brief process the E2 Reset Request
5205  *
5206  * @details
5207  *
5208  *    Function : ProcResetRequest 
5209  *
5210  * Functionality: Process E2 Reset Request 
5211  *
5212  * @params[in] 
5213  *       du Id
5214  *       Pointer to reset response 
5215  * @return void
5216  *
5217  ******************************************************************/
5218
5219 void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
5220 {
5221    uint8_t ieIdx = 0, duIdx =0;
5222    uint16_t transId=0;
5223    DuDb *duDb = NULLP;
5224    RanFunction *ranFuncDb = NULLP;
5225    uint16_t ranFuncIdx = 0;
5226
5227    SEARCH_DU_DB(duIdx, duId, duDb); 
5228    if(duDb == NULLP)
5229    {
5230       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5231       return;
5232    }
5233    
5234    if(!resetReq)
5235    {
5236       DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
5237       return;
5238    }
5239
5240    if(!resetReq->protocolIEs.list.array)      
5241    {
5242       DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
5243       return;
5244    }
5245    
5246    for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
5247    {
5248       if(resetReq->protocolIEs.list.array[ieIdx])
5249       {
5250          switch(resetReq->protocolIEs.list.array[ieIdx]->id)
5251          {
5252             case ProtocolIE_IDE2_id_TransactionID:
5253                {
5254                   transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
5255                   break;
5256                }
5257             case ProtocolIE_IDE2_id_CauseE2:
5258                {
5259                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
5260                   {
5261                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
5262                      if(ranFuncDb->id > 0)
5263                      {
5264                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
5265                      }
5266                   }
5267                   break;
5268                }
5269          }
5270       }
5271    }
5272
5273    if(BuildAndSendResetResponse(duId, transId) !=ROK)
5274    {
5275       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
5276    }
5277 }
5278
5279 /*******************************************************************
5280  *
5281  * @brief Free RIC Subscription Delete Request Message
5282  *
5283  * @details
5284  *
5285  *    Function : FreeRicSubscriptionDeleteRequest
5286  *
5287  * Functionality:  Free RIC Subscription Delete Request
5288  *
5289  * @param  E2AP Message PDU
5290  * @return void
5291  *
5292  ******************************************************************/
5293 void FreeRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
5294 {
5295    uint8_t ieIdx = 0;
5296    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
5297
5298    if(e2apMsg)
5299    {
5300       if(e2apMsg->choice.initiatingMessage)
5301       {
5302          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
5303          if(ricSubsDelReq->protocolIEs.list.array)
5304          {
5305             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
5306             {
5307                RIC_FREE(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
5308             }
5309             RIC_FREE(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
5310          }
5311          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5312       }
5313       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
5314    }
5315 }
5316
5317 /*******************************************************************
5318  *
5319  * @brief Builds and Send RIC Subscription delete request
5320  *
5321  * @details
5322  *
5323  *    Function : BuildAndSendRicSubscriptionDeleteRequest
5324  *
5325  * Functionality: Build and send RIC subscription delete request.
5326  *
5327  * @params[in] DU ID
5328  *             RIC subscription info to be deleted
5329  * @return ROK     - success
5330  *         RFAILED - failure
5331  *
5332  ******************************************************************/
5333 uint8_t BuildAndSendRicSubscriptionDeleteRequest(uint32_t duId, RicSubscription *ricSubsDb)
5334 {
5335    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
5336    E2AP_PDU_t         *e2apMsg = NULLP;
5337    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
5338    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
5339    asn_enc_rval_t     encRetVal;        /* Encoder return value */
5340
5341    while(true)
5342    {
5343       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Request Message\n");
5344
5345       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5346       if(e2apMsg == NULLP)
5347       {
5348          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
5349          break;
5350       }
5351
5352       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5353       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5354       if(e2apMsg->choice.initiatingMessage == NULLP)
5355       {
5356          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
5357          break;
5358       }
5359       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
5360       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5361       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest;
5362
5363       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
5364
5365       elementCnt = 2;
5366       ricSubsDelReq->protocolIEs.list.count = elementCnt;
5367       ricSubsDelReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequest_IEs_t *);
5368
5369       RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
5370       if(ricSubsDelReq->protocolIEs.list.array == NULLP)
5371       {
5372          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
5373          break;
5374       }
5375
5376       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5377       {
5378          RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequest_IEs_t));
5379          if(ricSubsDelReq->protocolIEs.list.array[ieIdx] == NULLP)
5380          {
5381             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
5382                   __func__, ieIdx, __LINE__);
5383             break;
5384          }
5385       }
5386       if(ieIdx < elementCnt)
5387          break;
5388       
5389       /* RIC Request ID */
5390       ieIdx = 0;
5391       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
5392       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RICrequestID;
5393       ricSubsDelReqIe->criticality = CriticalityE2_reject;
5394       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
5395       ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID = ricSubsDb->requestId.requestorId;
5396       ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID = ricSubsDb->requestId.instanceId;
5397
5398       /* RAN Function ID */
5399       ieIdx++;
5400       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
5401       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RANfunctionID;
5402       ricSubsDelReqIe->criticality = CriticalityE2_reject;
5403       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
5404       ricSubsDelReqIe->value.choice.RANfunctionID = ricSubsDb->ranFuncId;
5405
5406       /* Prints the Msg formed */
5407       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5408       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5409       encBufSize = 0;
5410       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5411       if(encRetVal.encoded == ENCODE_FAIL)
5412       {
5413          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Request Message (at %s)\n",\
5414                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5415          break;
5416       }
5417       else
5418       {
5419          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Request Message \n");
5420 #ifdef DEBUG_ASN_PRINT
5421          for(int i=0; i< encBufSize; i++)
5422          {
5423             printf("%x",encBuf[i]);
5424          } 
5425 #endif
5426       }
5427
5428       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
5429       {
5430          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Request Message");      
5431          break;
5432       }
5433
5434       ret = ROK;
5435       break;
5436    }
5437
5438    FreeRicSubscriptionDeleteRequest(e2apMsg);  
5439    return ret;
5440 }
5441
5442 /*******************************************************************
5443  *
5444  * @brief Processing of RIC Subscription Delete Required
5445  *
5446  * @details
5447  *
5448  *    Function : ProcRicSubsDeleteReqd
5449  *
5450  * Functionality: Processing of RIC Subscription Delete Required
5451  *    When received, RIC stub will initiate the RIC subscription
5452  *    deletion procedure towards DU
5453  *
5454  * @param  DU ID
5455  *         RIC Subscription Delete Required IEs
5456  * @return ROK-success
5457  *         RFAILED-failure
5458  *
5459  ******************************************************************/
5460 uint8_t ProcRicSubsDeleteReqd(uint32_t duId, RICsubscriptionDeleteRequired_t *ricSubsDelRqd)
5461 {
5462    uint8_t ieIdx = 0, duIdx = 0;
5463    uint16_t arrIdx = 0;
5464    DuDb *duDb = NULLP;
5465    RicRequestId ricReqId;
5466    RanFunction *ranFuncDb = NULLP;
5467    RicSubscription *subsDb = NULLP;
5468    CmLList *ricSubsNode = NULLP;
5469
5470    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
5471    RICsubscription_List_withCause_t *ricSubsList = NULLP;
5472    RICsubscription_withCause_Item_t *subsItem = NULLP;
5473
5474    memset(&ricReqId, 0, sizeof(RicRequestId));
5475
5476    if(!ricSubsDelRqd)
5477    {
5478       DU_LOG("\nERROR  -->  E2AP : %s: Received NULL message", __func__);
5479       return RFAILED;
5480    }
5481
5482    SEARCH_DU_DB(duIdx, duId, duDb);
5483    if(duDb == NULLP)
5484    {
5485       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5486       return RFAILED;
5487    }
5488
5489    for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
5490    {
5491       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
5492       switch(ricSubsDelRqdIe->id)
5493       {
5494          case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
5495          {
5496             ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
5497             for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
5498             {
5499                subsItem = &(((RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[arrIdx])->\
5500                   value.choice.RICsubscription_withCause_Item);
5501                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, subsItem->ranFunctionID);
5502                if(!ranFuncDb)
5503                {
5504                   DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%ld] not found", __func__, subsItem->ranFunctionID);
5505                   return RFAILED;
5506                }
5507                
5508                ricReqId.requestorId = subsItem->ricRequestID.ricRequestorID;
5509                ricReqId.instanceId = subsItem->ricRequestID.ricInstanceID;
5510                subsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
5511                if(!subsDb)
5512                {
5513                   DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%ld] Instance_ID [%ld]", \
5514                      __func__, subsItem->ricRequestID.ricRequestorID, subsItem->ricRequestID.ricInstanceID);
5515                   return RFAILED;
5516                }
5517
5518                /* Delete RIC Subcription from RAN Function */
5519                cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
5520                
5521                /* Send RIC Subscription delete request and then free any memory
5522                 * allocated to store subscription info at RIC */
5523                BuildAndSendRicSubscriptionDeleteRequest(duId, (RicSubscription *)ricSubsNode->node);
5524                deleteRicSubscriptionNode(ricSubsNode);
5525             }
5526             
5527             break;
5528          }
5529          default:
5530             break;
5531       }
5532    }  
5533    
5534    return ROK;
5535 }
5536
5537 /*******************************************************************
5538  *
5539  * @brief Deallocate memory allocated for E2nodeConfigurationUpdate 
5540  *
5541  * @details
5542  *
5543  *    Function : freeE2NodeConfigItem 
5544  *
5545  *    Functionality:
5546  *       - freeing the memory allocated for E2nodeConfigurationUpdate
5547  *
5548  * @params[in]
5549  *       uint8_t protocolIe
5550  *       PTR to e2NodeCfg which is to be freed
5551  * @return ROK     - success
5552  *         RFAILED - failure
5553  *
5554  * ****************************************************************/
5555
5556 void freeE2NodeConfigItem(uint8_t protocolIe, PTR e2NodeCfg)
5557 {
5558    E2nodeComponentConfigurationAck_t *cfgAck =NULLP;
5559    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
5560    E2nodeComponentConfigAdditionAck_Item_t *e2NodeAdditionAckItemIe=NULLP;
5561    E2nodeComponentConfigRemovalAck_Item_t *e2NodeRemovalAckItemIe=NULLP;
5562    E2nodeComponentConfigUpdateAck_Item_t *e2NodeUpdateAckItemIe=NULLP;
5563    
5564     /* Extracting the component interface and configuration ack information from
5565      * e2NodeCfg based on the protocol id */
5566    switch(protocolIe)
5567    {
5568       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
5569       {
5570          e2NodeAdditionAckItemIe= (E2nodeComponentConfigAdditionAck_Item_t*)e2NodeCfg;
5571          switch(e2NodeAdditionAckItemIe->e2nodeComponentInterfaceType)
5572          {
5573             case E2nodeComponentInterfaceType_f1:
5574                {
5575                   f1InterfaceInfo = e2NodeAdditionAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
5576                   break;
5577                }
5578             default:
5579                {
5580                   break;
5581                }
5582
5583          }
5584          cfgAck = &e2NodeAdditionAckItemIe->e2nodeComponentConfigurationAck;
5585       }
5586
5587       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
5588       {
5589          e2NodeUpdateAckItemIe = (E2nodeComponentConfigUpdateAck_Item_t*)e2NodeCfg;
5590          switch(e2NodeUpdateAckItemIe->e2nodeComponentInterfaceType)
5591          {
5592             case E2nodeComponentInterfaceType_f1:
5593                {
5594                   f1InterfaceInfo = e2NodeUpdateAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
5595                   break;
5596                }
5597             default:
5598                {
5599                   break;
5600                }
5601          }
5602          cfgAck = &e2NodeUpdateAckItemIe->e2nodeComponentConfigurationAck;
5603       }
5604
5605       case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
5606       {
5607          e2NodeRemovalAckItemIe= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
5608          switch(e2NodeRemovalAckItemIe->e2nodeComponentInterfaceType)
5609          {
5610             case E2nodeComponentInterfaceType_f1:
5611                {
5612                   f1InterfaceInfo = e2NodeRemovalAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
5613                   break;
5614                }
5615             default:
5616                {
5617                   break;
5618                }
5619          }
5620          cfgAck = &e2NodeRemovalAckItemIe->e2nodeComponentConfigurationAck;
5621       }
5622    }
5623    
5624    /* Freeing the memory allocated to component interface and configuration ack */
5625    if(f1InterfaceInfo)
5626    {
5627       RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
5628       RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
5629    }
5630
5631    switch(cfgAck->updateOutcome)
5632    {
5633       case E2nodeComponentConfigurationAck__updateOutcome_success:
5634          break;
5635       case E2nodeComponentConfigurationAck__updateOutcome_failure:
5636          {
5637             RIC_FREE(cfgAck->failureCauseE2, sizeof(CauseE2_t));
5638             break;
5639          }
5640    }
5641
5642 }
5643
5644 /*******************************************************************
5645  *
5646  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
5647  *
5648  * @details
5649  *
5650  *    Function : FreeE2NodeConfigUpdate 
5651  *
5652  *    Functionality:
5653  *       - freeing the memory allocated for E2nodeConfigurationUpdate
5654  *
5655  * @params[in] E2AP_PDU_t *e2apMsg 
5656  * @return ROK     - success
5657  *         RFAILED - failure
5658  *
5659  * ****************************************************************/
5660
5661 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
5662 {
5663    uint8_t arrIdx =0, e2NodeConfigIdx=0;
5664    E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg=NULL;
5665    E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
5666    E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
5667    E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
5668    E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
5669    E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
5670    E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
5671
5672    if(e2apMsg != NULLP)
5673    {
5674       if(e2apMsg->choice.successfulOutcome != NULLP)
5675       {
5676          updateAckMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
5677          if(updateAckMsg->protocolIEs.list.array != NULLP)
5678          {
5679             for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
5680             {
5681                if(updateAckMsg->protocolIEs.list.array[arrIdx])
5682                {
5683                   switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
5684                   {
5685                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
5686                         {
5687                            additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
5688                            if(additionAckList->list.array)
5689                            {
5690                               for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
5691                               {
5692                                  additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
5693                                  if(additionAckItemIte)
5694                                  {
5695                                     freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck,\
5696                                     (PTR)&additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item);
5697                                     RIC_FREE(additionAckItemIte, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
5698                                  }
5699                               }
5700                               RIC_FREE(additionAckList->list.array, additionAckList->list.size);
5701                            }
5702                            break;
5703                         }
5704                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
5705                         {
5706                            updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
5707                            if(updateAckList->list.array)
5708                            {
5709                               for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
5710                               {
5711                                  updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
5712                                  if(updateAckItemIe)
5713                                  {
5714                                     freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck,\
5715                                     (PTR)&updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item);
5716                                     RIC_FREE(updateAckItemIe, sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t));
5717                                  }
5718                               }
5719                               RIC_FREE(updateAckList->list.array, updateAckList->list.size);
5720                            }
5721                            break;
5722                         }
5723                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
5724                         {
5725                            removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
5726                            if(removalAckList->list.array)
5727                            {
5728                               for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
5729                               {
5730                                  removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
5731                                  if(removalAckItemIe)
5732                                  {
5733                                     freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck,\
5734                                     (PTR)&removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item);
5735                                     RIC_FREE(removalAckItemIe, sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t));
5736                                  }
5737                               }
5738                               RIC_FREE(removalAckList->list.array, removalAckList->list.size);
5739                            }
5740                            break;
5741                         }
5742                   }
5743                   RIC_FREE(updateAckMsg->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
5744                }
5745             }
5746             RIC_FREE(updateAckMsg->protocolIEs.list.array, updateAckMsg->protocolIEs.list.size);
5747          }
5748          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
5749       }
5750       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5751    }
5752 }
5753
5754 /*******************************************************************
5755  *
5756  * @brief Build E2node Component config Removal ack list
5757  *
5758  * @details
5759  *
5760  *    Function :  BuildE2nodeComponentConfigRemovalAck
5761  *
5762  *    Functionality: Build the e2 node remove ack 
5763  *
5764  * @params[in] 
5765  *    E2nodeComponentConfigRemovalAck_List_t to be filled
5766  *    Count of e2 node to be removed
5767  *    list of e2 node cfg to be removed
5768  *
5769  * @return ROK - success
5770  *         RFAILED - failure
5771  * ****************************************************************/
5772
5773 uint8_t BuildE2nodeComponentConfigRemovalAck(E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList,\
5774 uint16_t removalE2NodeCount, E2NodeConfigItem *removaldE2Node)
5775 {
5776    uint8_t arrIdx = 0;
5777    E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULL;
5778    
5779    /* Filling the e2 node config removal ack list */
5780    e2NodeConfigRemovalAckList->list.count = removalE2NodeCount;
5781    e2NodeConfigRemovalAckList->list.size = e2NodeConfigRemovalAckList->list.count * sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t*);
5782    RIC_ALLOC(e2NodeConfigRemovalAckList->list.array, e2NodeConfigRemovalAckList->list.size);
5783    if(e2NodeConfigRemovalAckList->list.array == NULLP)
5784    {
5785       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigRemovalAck %d",__LINE__);
5786       return RFAILED;
5787    }
5788
5789    for(arrIdx = 0; arrIdx< e2NodeConfigRemovalAckList->list.count; arrIdx++)
5790    {
5791       RIC_ALLOC(e2NodeConfigRemovalAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t));
5792       if(e2NodeConfigRemovalAckList->list.array[arrIdx] == NULLP)
5793       {
5794          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigRemovalAck %d",__LINE__);
5795          return RFAILED;
5796       }
5797       e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[arrIdx];
5798       e2NodeRemovalAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck_Item;
5799       e2NodeRemovalAckItem->criticality = CriticalityE2_reject;
5800       e2NodeRemovalAckItem->value.present = E2nodeComponentConfigRemovalAck_ItemIEs__value_PR_E2nodeComponentConfigRemovalAck_Item;
5801       
5802       /* Filling the e2 node config removal ack item */
5803       fillE2NodeConfigAck((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck,\
5804       &removaldE2Node[arrIdx].componentInfo, removaldE2Node[arrIdx].isSuccessful);
5805    }
5806    return ROK;  
5807 }
5808
5809 /*******************************************************************
5810  *
5811  * @brief Build E2node Component config update ack list
5812  *
5813  * @details
5814  *
5815  *    Function :  BuildE2nodeComponentConfigUpdateAck
5816  *
5817  *    Functionality: Build E2node Component config update ack list 
5818  *
5819  * @params[in] 
5820  *    E2nodeComponentConfigUpdateAck_List to be filled
5821  *    Count of e2 node to be update
5822  *    list of e2 node cfg to be update
5823  *
5824  * @return ROK - success
5825  *         RFAILED - failure
5826  * ****************************************************************/
5827
5828 uint8_t BuildE2nodeComponentConfigUpdateAck(E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList,\
5829 uint16_t updatedE2NodeCount, E2NodeConfigItem *updatedE2Node)
5830 {
5831    uint8_t arrIdx = 0;
5832    E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULL;
5833    
5834    /* Filling the e2 node config update ack list */
5835    e2NodeConfigUpdateAckList->list.count = updatedE2NodeCount;
5836    e2NodeConfigUpdateAckList->list.size = e2NodeConfigUpdateAckList->list.count * sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t*);
5837    RIC_ALLOC(e2NodeConfigUpdateAckList->list.array, e2NodeConfigUpdateAckList->list.size);
5838    if(e2NodeConfigUpdateAckList->list.array == NULLP)
5839    {
5840       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
5841       return RFAILED;
5842    }
5843
5844    for(arrIdx = 0; arrIdx< e2NodeConfigUpdateAckList->list.count; arrIdx++)
5845    {
5846       RIC_ALLOC(e2NodeConfigUpdateAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t));
5847       if(e2NodeConfigUpdateAckList->list.array[arrIdx] == NULLP)
5848       {
5849          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
5850          return RFAILED;
5851       }
5852       e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[arrIdx];
5853       e2NodeUpdateAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck_Item;
5854       e2NodeUpdateAckItem->criticality = CriticalityE2_reject;
5855       e2NodeUpdateAckItem->value.present = E2nodeComponentConfigUpdateAck_ItemIEs__value_PR_E2nodeComponentConfigUpdateAck_Item;
5856       
5857       /* Filling the e2 node config update ack item */
5858       fillE2NodeConfigAck((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck,\
5859       &updatedE2Node[arrIdx].componentInfo, updatedE2Node[arrIdx].isSuccessful);
5860
5861    }
5862    return ROK;  
5863 }
5864
5865 /*******************************************************************
5866  *
5867  * @brief Buld and send the E2 node config update ack msg 
5868  *
5869  * @details
5870  *
5871  *    Function : BuildAndSendE2NodeConfigUpdateAck 
5872  *
5873  *    Functionality:
5874  *         - Buld and send the E2 node config update ack msg
5875  * @params[in] 
5876  *    DU databse 
5877  *    transId 
5878  *    list of E2 node cfg which needs to fill in IEs
5879  * @return ROK     - success
5880  *         RFAILED - failure
5881  *
5882  * ****************************************************************/
5883
5884 uint8_t BuildAndSendE2NodeConfigUpdateAck(DuDb *duDb, uint16_t transId,  E2NodeConfigList *e2NodeList)
5885 {
5886    uint8_t ret = RFAILED;
5887    uint8_t arrIdx = 0,elementCnt = 0;
5888    E2AP_PDU_t        *e2apMsg = NULLP;
5889    asn_enc_rval_t     encRetVal;       
5890    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
5891
5892    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
5893    do
5894    {
5895       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5896       if(e2apMsg == NULLP)
5897       {
5898          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5899          break;
5900       }
5901       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
5902       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
5903       if(e2apMsg->choice.successfulOutcome == NULLP)
5904       {
5905          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5906          break;
5907       }
5908       
5909       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
5910       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
5911       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
5912       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
5913       
5914       elementCnt =1;
5915       if(e2NodeList->addedE2NodeCount)
5916          elementCnt++;
5917       if(e2NodeList->updatedE2NodeCount)
5918          elementCnt++;
5919       if(e2NodeList->removedE2NodeCount)
5920          elementCnt++;
5921
5922       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
5923       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
5924       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
5925       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
5926       {
5927          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5928          break;
5929       }
5930       
5931       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
5932       {
5933          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
5934          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
5935          {
5936             
5937             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5938             break;
5939          }
5940       }
5941       
5942       if(arrIdx<elementCnt)
5943          break;
5944
5945       arrIdx = 0;
5946       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5947       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5948       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
5949       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5950       
5951       if(e2NodeList->addedE2NodeCount)
5952       {
5953          arrIdx++;
5954          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
5955          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5956          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigAdditionAck_List;
5957          if(BuildE2nodeComponentConfigAdditionAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List,\
5958                   e2NodeList->addedE2NodeCount, e2NodeList->addedE2Node)!=ROK)
5959
5960          {
5961             DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
5962             break;
5963          }
5964       }
5965       if(e2NodeList->updatedE2NodeCount)
5966       {
5967          arrIdx++;
5968          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck;
5969          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5970          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigUpdateAck_List;
5971          if(BuildE2nodeComponentConfigUpdateAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List,\
5972                   e2NodeList->updatedE2NodeCount, e2NodeList->updatedE2Node)!=ROK)
5973
5974          {
5975             DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config update ack list");
5976             break;
5977          }
5978       }
5979       if(e2NodeList->removedE2NodeCount)
5980       {
5981          arrIdx++;
5982          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck;
5983          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5984          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigRemovalAck_List;
5985          if(BuildE2nodeComponentConfigRemovalAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List,\
5986                   e2NodeList->removedE2NodeCount, e2NodeList->removedE2Node)!=ROK)
5987
5988          {
5989             DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config removal ack list");
5990             break;
5991          }
5992       }      
5993       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5994
5995       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5996       encBufSize = 0;
5997       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
5998             encBuf);
5999       if(encRetVal.encoded == ENCODE_FAIL)
6000       {
6001          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
6002                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6003          break;
6004       }
6005       else
6006       {
6007          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
6008          for(int i=0; i< encBufSize; i++)
6009          {
6010             DU_LOG("%x",encBuf[i]);
6011          } 
6012       }
6013
6014
6015       /* Sending msg */
6016       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
6017       {
6018          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
6019          break;
6020       }
6021       ret = ROK;
6022       break;
6023    }while(true);
6024    
6025    FreeE2NodeConfigUpdateAck(e2apMsg);
6026    return ret;
6027 }
6028
6029
6030 /******************************************************************
6031  *
6032  * @brief Processes the E2 removal failure msg
6033  *
6034  * @details
6035  *
6036  *    Function : procE2RemovalFailure
6037  *
6038  *    Functionality: Processes the E2 removal failure msg
6039  *
6040  * @params[in] 
6041  *       E2 Removal Failure information
6042  *
6043  * @return void
6044  *
6045  * ****************************************************************/
6046 void ProcE2RemovalFailure(E2RemovalFailure_t *e2RemovalFailure) 
6047 {
6048    uint8_t ieIdx = 0;
6049    uint16_t transId=0;
6050    CauseE2_t *cause = NULLP;
6051
6052    if(!e2RemovalFailure)
6053    {
6054       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure pointer is null"); 
6055       return;
6056    }
6057
6058    if(!e2RemovalFailure->protocolIEs.list.array)      
6059    {
6060       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
6061       return;
6062    }
6063    
6064    for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
6065    {
6066       if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
6067       {
6068          switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
6069          {
6070             case ProtocolIE_IDE2_id_TransactionID:
6071                {
6072                   transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
6073                   DU_LOG("\nERROR  -->  E2AP : Received transID %d", transId);
6074                   break;
6075                }
6076             case ProtocolIE_IDE2_id_CauseE2:
6077                {
6078                    cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
6079                    printE2ErrorCause(cause);
6080                    break; 
6081                }
6082             default:
6083                {
6084                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
6085                   break;
6086                }
6087          }
6088       }
6089    }
6090 }
6091 /*******************************************************************
6092  *
6093  * @brief Delete E2 component node list
6094  *
6095  * @details
6096  *
6097  *    Function : deleteE2ComponentNodeList 
6098  *
6099  * Functionality: Delete E2 component node  list
6100  *
6101  * @params[in] E2 component node list
6102  * @return void
6103
6104  *
6105  ******************************************************************/
6106
6107 void deleteE2ComponentNodeList(CmLListCp *componentList)
6108 {
6109    E2NodeComponent *cfgInfo = NULLP;
6110    CmLList *e2ComponentNode = NULLP;
6111
6112    CM_LLIST_FIRST_NODE(componentList, e2ComponentNode);
6113    while(e2ComponentNode)
6114    {
6115       cfgInfo = (E2NodeComponent*)e2ComponentNode->node;
6116       cmLListDelFrm(componentList, e2ComponentNode);
6117       memset(cfgInfo, 0, sizeof(E2NodeComponent));
6118       CM_LLIST_FIRST_NODE(componentList, e2ComponentNode);
6119    }
6120 }
6121
6122 /*******************************************************************
6123  *
6124  * @brief process the E2 node information from ric db
6125  *
6126  * @details
6127  *
6128  *    Function : deleteE2NodeInfo
6129  *
6130  * Functionality: process the E2 node information from ric db
6131  *
6132  * @params[in] 
6133  *       du Id
6134  *      
6135  * @return void
6136  *
6137  ******************************************************************/
6138 void deleteE2NodeInfo(DuDb *duDb)
6139 {
6140    uint16_t ranFuncIdx =0;
6141    RanFunction *ranFuncDb=NULLP;
6142
6143    DU_LOG("\nINFO  -->  E2AP : Removing all the E2 node information");
6144    for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
6145    {
6146       ranFuncDb = &duDb->ranFunction[ranFuncIdx];
6147       if(ranFuncDb->id > 0)
6148       {
6149          deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
6150       }
6151    }
6152    deleteE2ComponentNodeList(&duDb->e2NodeComponent);
6153 }
6154
6155 /*******************************************************************
6156  *
6157  * @brief process the E2 Removal Response
6158  *
6159  * @details
6160  *
6161  *    Function : ProcE2RemovalResponse 
6162  *
6163  * Functionality: Process E2 Removal Response 
6164  *
6165  * @params[in] 
6166  *       du Id
6167  *       Pointer to removal response 
6168  * @return void
6169  *
6170  ******************************************************************/
6171
6172 void ProcE2RemovalResponse(uint32_t duId, E2RemovalResponse_t *removalRsp)
6173 {
6174    uint8_t ieIdx = 0, duIdx =0;
6175    DuDb *duDb = NULLP;
6176
6177    SEARCH_DU_DB(duIdx, duId, duDb);
6178    if(duDb == NULLP)
6179    {
6180       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6181       return;
6182    }
6183
6184    if(!removalRsp)
6185    {
6186       DU_LOG("\nERROR  -->  E2AP : removalRsp pointer is null"); 
6187       return;
6188    }
6189
6190    if(!removalRsp->protocolIEs.list.array)      
6191    {
6192       DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
6193       return;
6194    }
6195
6196    for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
6197    {
6198       if(removalRsp->protocolIEs.list.array[ieIdx])
6199       {
6200          switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
6201          {
6202             case ProtocolIE_IDE2_id_TransactionID:
6203                {
6204                   DU_LOG("\nINFO  -->  E2AP : Sending request to close the sctp connection");
6205                   cmInetClose(&sctpCb.e2LstnSockFd);
6206                   deleteE2NodeInfo(duDb);
6207                   exit(0);
6208                }
6209             default:
6210                {
6211                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
6212                   break;
6213                }
6214          }
6215       }
6216    }
6217 }
6218 /*******************************************************************
6219  *
6220  * @brief Deallocate the memory allocated for E2 Removal Failure
6221  *
6222  * @details
6223  *
6224  *    Function : FreeE2RemovalFailure
6225  *
6226  *    Functionality:
6227  *       - freeing the memory allocated for E2RemovalFailure
6228  *
6229  * @params[in] E2AP_PDU_t *e2apMsg
6230  * @return void
6231  *
6232  * ****************************************************************/
6233 void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
6234 {
6235    uint8_t ieIdx =0;
6236    E2RemovalFailure_t *e2RemovalFailure=NULLP;
6237
6238    if(e2apMsg != NULLP)
6239    {
6240       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
6241       {
6242          e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
6243          if(e2RemovalFailure->protocolIEs.list.array)
6244          {
6245             for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
6246             {
6247                if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
6248                {
6249                   RIC_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
6250                }
6251             }
6252             RIC_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
6253          }
6254          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
6255       }
6256       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6257    }
6258 }
6259
6260 /*******************************************************************
6261  *
6262  * @brief Buld and send the E2 Removal Failure msg
6263  *
6264  * @details
6265  *
6266  *    Function : BuildAndSendE2RemovalFailure
6267  *
6268  *    Functionality:
6269  *         - Buld and send the E2 Removal Failure Message
6270  * @params[in] 
6271  *    DU Id
6272  *    Trans Id 
6273  *    Type of failure 
6274  *    Cause of failure
6275  * @return ROK     - success
6276  *         RFAILED - failure
6277  *
6278  * ****************************************************************/
6279
6280 uint8_t BuildAndSendRemovalFailure(uint32_t duId, uint16_t transId,  CauseE2_PR causePresent, uint8_t reason)
6281 {
6282    uint8_t           ieIdx = 0, elementCnt = 0;
6283    uint8_t           ret = RFAILED;
6284    E2AP_PDU_t        *e2apMsg = NULLP;
6285    E2RemovalFailure_t *e2RemovalFailure=NULLP;
6286    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6287
6288    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Failure Message\n");
6289    do
6290    {
6291       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6292       if(e2apMsg == NULLP)
6293       {
6294          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6295          break;
6296       }
6297       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
6298
6299       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
6300       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
6301       {
6302          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6303          break;
6304       }
6305
6306       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
6307       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
6308       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure;
6309       e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
6310
6311       elementCnt = 2;
6312       e2RemovalFailure->protocolIEs.list.count = elementCnt;
6313       e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *);
6314       RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
6315       if(!e2RemovalFailure->protocolIEs.list.array)
6316       {
6317          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6318          break;
6319       }
6320
6321       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6322       {
6323          RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
6324          if(!e2RemovalFailure->protocolIEs.list.array[ieIdx])
6325          {
6326             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6327             break;
6328          }
6329       }
6330       if(ieIdx < elementCnt)
6331          break;
6332
6333       ieIdx = 0;
6334       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6335       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6336       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID;
6337       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6338
6339       /* Cause */
6340       ieIdx++;
6341       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
6342       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
6343       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
6344       fillE2FailureCause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
6345       
6346       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6347
6348       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6349       encBufSize = 0;
6350       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6351       if(encRetVal.encoded == ENCODE_FAIL)
6352       {
6353          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal failure structure (at %s)\n",\
6354                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6355          break;
6356       }
6357       else
6358       {
6359          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Failure \n");
6360          for(int i=0; i< encBufSize; i++)
6361          {
6362             DU_LOG("%x",encBuf[i]);
6363          }
6364       }
6365
6366       /* Sending msg */
6367       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6368       {
6369          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Failure");
6370          break;
6371       }
6372
6373       ret = ROK;
6374       break;
6375    }while(true);
6376
6377    FreeE2RemovalFailure(e2apMsg);
6378    return ret;
6379 }
6380
6381 /*******************************************************************
6382  *
6383  * @brief Deallocate the memory allocated for E2 Removal Response
6384  *
6385  * @details
6386  *
6387  *    Function : FreeE2RemovalResponse
6388  *
6389  *    Functionality:
6390  *       - freeing the memory allocated for E2RemovalResponse
6391  *
6392  * @params[in] E2AP_PDU_t *e2apMsg
6393  * @return ROK     - success
6394  *         RFAILED - failure
6395  *
6396  * ****************************************************************/
6397 void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
6398 {
6399    uint8_t ieIdx =0;
6400    E2RemovalResponse_t *e2RemovalResponse=NULLP;
6401
6402    if(e2apMsg != NULLP)
6403    {
6404       if(e2apMsg->choice.successfulOutcome != NULLP)
6405       {
6406          e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
6407          if(e2RemovalResponse->protocolIEs.list.array)
6408          {
6409             for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++)
6410             {
6411                if(e2RemovalResponse->protocolIEs.list.array[ieIdx])
6412                {
6413                   RIC_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
6414                }
6415             }
6416             RIC_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
6417          }
6418          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6419       }
6420       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6421    }
6422 }
6423
6424 /*******************************************************************
6425  *
6426  * @brief Buld and send the E2 Removal Response msg
6427  *
6428  * @details
6429  *
6430  *    Function : BuildAndSendE2RemovalResponse
6431  *
6432  *    Functionality:
6433  *         - Buld and send the E2 Removal Response Message
6434  * @params[in] 
6435  *    Du Id
6436  *    Trans Id 
6437  * @return ROK     - success
6438  *         RFAILED - failure
6439  *
6440  * ****************************************************************/
6441 uint8_t BuildAndSendRemovalResponse(uint32_t duId, uint16_t transId)
6442 {
6443    uint8_t ieIdx = 0, elementCnt = 0;
6444    uint8_t ret = RFAILED, duIdx =0;
6445    E2AP_PDU_t *e2apMsg = NULLP;
6446    DuDb *duDb = NULLP;
6447    E2RemovalResponse_t *e2RemovalResponse=NULLP;
6448    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6449
6450    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Response Message\n");
6451    do
6452    {
6453       SEARCH_DU_DB(duIdx, duId, duDb);
6454       if(duDb == NULLP)
6455       {
6456          DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6457          return RFAILED;
6458       }
6459    
6460       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6461       if(e2apMsg == NULLP)
6462       {
6463          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6464          break;
6465       }
6466       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6467
6468       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6469       if(e2apMsg->choice.successfulOutcome == NULLP)
6470       {
6471          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6472          break;
6473       }
6474
6475       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
6476       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6477       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse;
6478       e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
6479
6480       elementCnt = 1;
6481       e2RemovalResponse->protocolIEs.list.count = elementCnt;
6482       e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *);
6483       RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
6484       if(!e2RemovalResponse->protocolIEs.list.array)
6485       {
6486          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6487          break;
6488       }
6489
6490       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6491       {
6492          RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
6493          if(!e2RemovalResponse->protocolIEs.list.array[ieIdx])
6494          {
6495             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6496             break;
6497          }
6498       }
6499       if(ieIdx < elementCnt)
6500          break;
6501
6502       ieIdx = 0;
6503       e2RemovalResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6504       e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6505       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID;
6506       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6507
6508       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6509
6510       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6511       encBufSize = 0;
6512       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6513       if(encRetVal.encoded == ENCODE_FAIL)
6514       {
6515          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal response structure (at %s)\n",\
6516                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6517          break;
6518       }
6519       else
6520       {
6521          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Response \n");
6522          for(int i=0; i< encBufSize; i++)
6523          {
6524             DU_LOG("%x",encBuf[i]);
6525          }
6526       }
6527
6528       /* Sending msg */
6529       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6530       {
6531          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Response");
6532          break;
6533       }
6534
6535       ret = ROK;
6536       break;
6537    }while(true);
6538
6539    FreeE2RemovalResponse(e2apMsg);
6540    return ret;
6541 }
6542
6543 /*******************************************************************
6544  *
6545  * @brief Process Removal req received from RIC
6546  *
6547  * @details
6548  *
6549  *    Function : procE2RemovalRequest
6550  *
6551  * Functionality: Process Removal req received from RIC
6552  *
6553  * @param  
6554  *    DU id
6555  *    E2 Removal Request 
6556  * @return void
6557  *
6558  ******************************************************************/
6559
6560 void procE2RemovalRequest(uint32_t duId, E2RemovalRequest_t *removalReq)
6561 {
6562    uint8_t arrIdx =0;
6563    uint16_t transId =0;
6564
6565    DU_LOG("\nINFO   -->  E2AP : E2 Removal request received");
6566    
6567    for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
6568    {
6569       switch(removalReq->protocolIEs.list.array[arrIdx]->id)
6570       {
6571          case ProtocolIE_IDE2_id_TransactionID:
6572             {
6573                transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
6574                break;
6575             }
6576          default:
6577             {
6578                DU_LOG("\nERROR  -->  E2AP : Invalid IE recevied [%d]", transId);
6579                break;
6580             }
6581       }
6582    }
6583    
6584    if(transId>=0 && transId<=255)
6585    {
6586       if(BuildAndSendRemovalResponse(duId, transId) != ROK)
6587       {
6588          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
6589       }
6590    }
6591    else
6592    {
6593       if(BuildAndSendRemovalFailure(duId, transId, CauseE2_PR_protocol, CauseE2Protocol_abstract_syntax_error_falsely_constructed_message) != ROK)
6594       {
6595          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
6596       }
6597    }
6598 }
6599
6600 /*******************************************************************
6601  *
6602  * @brief fill E2 connection update item
6603  *
6604  * @details
6605  *
6606  *    Function : fillE2connectionUpdateItem 
6607  *
6608  *    Functionality: fill E2 connection update item
6609  *
6610  * @params[in]
6611  *    E2connectionUpdate Item to be filled
6612  *    Protocol Id
6613  * @return ROK - success
6614  *         RFAILED - failure
6615  * ****************************************************************/
6616
6617 uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId)
6618 {
6619    E2connectionUpdateRemove_Item_t *connectionRemoveITem=NULLP;
6620    E2connectionUpdate_Item_t *connectionModifyItem=NULLP;
6621    TNLinformation_t *tnlInformation = NULLP;
6622    TNLusage_t  *tnlUsage=NULLP;
6623
6624    switch(protocolId)
6625    {
6626       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
6627       {
6628          connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo;
6629          tnlInformation = &connectionModifyItem->tnlInformation;
6630          tnlUsage = &connectionModifyItem->tnlUsage;
6631          break;
6632       }
6633
6634       case ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item:
6635       {
6636          connectionRemoveITem = (E2connectionUpdateRemove_Item_t*)connectionInfo;
6637          tnlInformation= &connectionRemoveITem->tnlInformation;
6638          break;
6639       }
6640    }
6641    
6642    tnlInformation->tnlAddress.size =  4*sizeof(uint8_t);
6643    RIC_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size);
6644    if(!tnlInformation->tnlAddress.buf)
6645    {
6646       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6647       return RFAILED;
6648    }
6649    
6650    tnlInformation->tnlAddress.buf[3] =  ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr & 0xFF; 
6651    tnlInformation->tnlAddress.buf[2] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 8) & 0xFF;
6652    tnlInformation->tnlAddress.buf[1] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 16) & 0xFF;
6653    tnlInformation->tnlAddress.buf[0] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 24) & 0xFF;
6654    tnlInformation->tnlAddress.bits_unused = 0;
6655    if(protocolId == ProtocolIE_IDE2_id_E2connectionUpdate_Item)
6656    {
6657       *tnlUsage = TNLusage_support_function; 
6658    }
6659    return ROK;
6660 }
6661
6662 /*******************************************************************
6663  *
6664  * @brief Build E2 connection modification list
6665  *
6666  * @details
6667  *
6668  *    Function : BuildE2ConnectionModifyList
6669  *
6670  *    Functionality: Build E2 connection modification list
6671  *
6672  * @params[in]
6673  *    E2 connection modification list to be filled
6674  *
6675  * @return ROK - success
6676  *         RFAILED - failure
6677  * ****************************************************************/
6678
6679 uint8_t BuildE2ConnectionModifyList(E2connectionUpdate_List_t *connectionToBeModifyList)
6680 {
6681    uint8_t arrIdx = 0;
6682    E2connectionUpdate_ItemIEs_t *connectionModify=NULL;
6683
6684    connectionToBeModifyList->list.count = 1;
6685  
6686    connectionToBeModifyList->list.size = connectionToBeModifyList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*);
6687    RIC_ALLOC(connectionToBeModifyList->list.array, connectionToBeModifyList->list.size);
6688    if(connectionToBeModifyList->list.array)
6689    {
6690       for(arrIdx = 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++)
6691       {
6692          RIC_ALLOC(connectionToBeModifyList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
6693          if(connectionToBeModifyList->list.array[arrIdx] == NULLP)
6694          {
6695             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6696             return RFAILED;
6697          }
6698          connectionModify = (E2connectionUpdate_ItemIEs_t*)connectionToBeModifyList->list.array[arrIdx];
6699          connectionModify->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item;
6700          connectionModify->criticality= CriticalityE2_ignore;
6701          connectionModify->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item;
6702          if(fillE2connectionUpdateItem((PTR)&connectionModify->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item) != ROK)
6703          {
6704             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
6705             return RFAILED;
6706          }
6707          
6708       }
6709    }
6710    else
6711    {
6712       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6713       return RFAILED;
6714    }
6715    return ROK;
6716 }
6717
6718 /*******************************************************************
6719  *
6720  * @brief Build E2 connection remove list
6721  *
6722  * @details
6723  *
6724  *    Function : BuildE2ConnectionRemoveList
6725  *
6726  *    Functionality: Build E2 connection remove list
6727  *
6728  * @params[in]
6729  *    E2 connection remove list to be filled
6730  *
6731  * @return ROK - success
6732  *         RFAILED - failure
6733  * ****************************************************************/
6734
6735 uint8_t BuildE2ConnectionRemoveList(E2connectionUpdateRemove_List_t *connectionToBeRemoveList)
6736 {
6737    uint8_t arrIdx = 0;
6738    E2connectionUpdateRemove_ItemIEs_t *connectionRemove=NULL;
6739
6740    connectionToBeRemoveList->list.count = 1;
6741  
6742    connectionToBeRemoveList->list.size = connectionToBeRemoveList->list.count*sizeof(E2connectionUpdateRemove_ItemIEs_t*);
6743    RIC_ALLOC(connectionToBeRemoveList->list.array, connectionToBeRemoveList->list.size);
6744    if(connectionToBeRemoveList->list.array)
6745    {
6746       for(arrIdx = 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++)
6747       {
6748          RIC_ALLOC(connectionToBeRemoveList->list.array[arrIdx], sizeof(E2connectionUpdateRemove_ItemIEs_t));
6749          if(connectionToBeRemoveList->list.array[arrIdx] == NULLP)
6750          {
6751             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6752             return RFAILED;
6753          }
6754          connectionRemove = (E2connectionUpdateRemove_ItemIEs_t*)connectionToBeRemoveList->list.array[arrIdx];
6755          connectionRemove->id = ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item;
6756          connectionRemove->criticality= CriticalityE2_ignore;
6757          connectionRemove->value.present = E2connectionUpdateRemove_ItemIEs__value_PR_E2connectionUpdateRemove_Item;
6758          if(fillE2connectionUpdateItem((PTR)&connectionRemove->value.choice.E2connectionUpdateRemove_Item, ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item) != ROK)
6759          {
6760             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
6761             return RFAILED;
6762          }
6763          
6764       }
6765    }
6766    else
6767    {
6768       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6769       return RFAILED;
6770    }
6771    return ROK;
6772 }
6773
6774 /*******************************************************************
6775  *
6776  * @brief Deallocate the memory allocated for E2ConnectionUpdate msg
6777  *
6778  * @details
6779  *
6780  *    Function : FreeE2ConnectionUpdate
6781  *
6782  *    Functionality:
6783  *       - freeing the memory allocated for E2ConnectionUpdate
6784  *
6785  * @params[in] E2AP_PDU_t *e2apMsg
6786  * @return ROK     - success
6787  *         RFAILED - failure
6788  *
6789  * ****************************************************************/
6790 void FreeE2ConnectionUpdate(E2AP_PDU_t *e2apMsg)
6791 {
6792    uint8_t ieIdx =0, arrIdx=0;
6793    E2connectionUpdate_t  *connectionUpdate = NULLP;
6794    E2connectionUpdate_List_t *connectionToBeModifyList = NULLP;
6795    E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP;
6796
6797    if(e2apMsg != NULLP)
6798    {
6799       if(e2apMsg->choice.initiatingMessage != NULLP)
6800       {
6801          connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
6802          if(connectionUpdate->protocolIEs.list.array)
6803          {
6804             for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
6805             {
6806                if(connectionUpdate->protocolIEs.list.array[ieIdx])
6807                {
6808                   switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
6809                   {
6810                      case ProtocolIE_IDE2_id_TransactionID:
6811                         break;
6812
6813                      case ProtocolIE_IDE2_id_E2connectionUpdateModify:
6814                         {
6815                            connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
6816                            if(connectionToBeModifyList->list.array)
6817                            {
6818                               for(arrIdx = 0; arrIdx < connectionToBeModifyList->list.count; arrIdx++)
6819                               {
6820                                  RIC_FREE(connectionToBeModifyList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
6821                               }
6822                               RIC_FREE(connectionToBeModifyList->list.array, connectionToBeModifyList->list.size);
6823                            }
6824                            break;
6825                         }
6826
6827                      case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
6828                         {
6829                            connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List;
6830                            if(connectionToBeRemoveList->list.array)
6831                            {
6832                               for(arrIdx = 0; arrIdx < connectionToBeRemoveList->list.count; arrIdx++)
6833                               {
6834                                  RIC_FREE(connectionToBeRemoveList->list.array[arrIdx], sizeof(E2connectionUpdateRemove_ItemIEs_t));
6835                               }
6836                               RIC_FREE(connectionToBeRemoveList->list.array, connectionToBeRemoveList->list.size);
6837                            }
6838                            break;
6839                         }
6840                   }
6841                   RIC_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdate_IEs_t));
6842                }
6843             }
6844             RIC_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size);
6845          }
6846          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6847       }
6848       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6849    }
6850 }
6851
6852 /*******************************************************************
6853  *
6854  * @brief Buld and send the E2 Connection Update msg
6855  *
6856  * @details
6857  *
6858  *    Function : BuildAndSendE2ConnectionUpdate
6859  *
6860  *    Functionality:
6861  *         - Buld and send the E2 Connection Update Message
6862  * @params[in] 
6863  *    Du Id
6864  *    E2 connection to be modify or delete
6865  * @return ROK     - success
6866  *         RFAILED - failure
6867  *
6868  * ****************************************************************/
6869
6870 uint8_t BuildAndSendE2ConnectionUpdate(uint32_t duId, E2Connection connectionInfo)
6871 {
6872    uint8_t ieIdx = 0, elementCnt = 0;
6873    uint8_t ret = RFAILED, duIdx =0;
6874    DuDb    *duDb = NULLP;
6875    E2AP_PDU_t *e2apMsg = NULLP;
6876    E2connectionUpdate_t *e2ConnectionUpdate=NULLP;
6877    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6878
6879    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Message\n");
6880    do
6881    {
6882       SEARCH_DU_DB(duIdx, duId, duDb);
6883       if(duDb == NULLP)
6884       {
6885          DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6886          return RFAILED;
6887       }
6888    
6889       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6890       if(e2apMsg == NULLP)
6891       {
6892          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6893          break;
6894       }
6895       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6896
6897       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6898       if(e2apMsg->choice.initiatingMessage == NULLP)
6899       {
6900          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6901          break;
6902       }
6903
6904       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
6905       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6906       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2connectionUpdate;
6907       e2ConnectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
6908
6909       elementCnt = 1;
6910       if(connectionInfo == MODIFY_CONNECTION) 
6911          elementCnt++;
6912       if(connectionInfo == REMOVE_CONNECTION)
6913          elementCnt++;
6914
6915       e2ConnectionUpdate->protocolIEs.list.count = elementCnt;
6916       e2ConnectionUpdate->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdate_IEs_t*);
6917       RIC_ALLOC(e2ConnectionUpdate->protocolIEs.list.array, e2ConnectionUpdate->protocolIEs.list.size);
6918       if(!e2ConnectionUpdate->protocolIEs.list.array)
6919       {
6920          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6921          break;
6922       }
6923
6924       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6925       {
6926          RIC_ALLOC(e2ConnectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdate_IEs_t));
6927          if(!e2ConnectionUpdate->protocolIEs.list.array[ieIdx])
6928          {
6929             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6930             break;
6931          }
6932       }
6933       if(ieIdx < elementCnt)
6934          break;
6935
6936       ieIdx = 0;
6937       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6938       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6939       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_TransactionID;
6940       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = assignTransactionId(duDb);
6941
6942       if(connectionInfo == MODIFY_CONNECTION)
6943       {
6944          ieIdx++;
6945          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionUpdateModify;
6946          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6947          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_E2connectionUpdate_List;
6948          if(BuildE2ConnectionModifyList(&e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List) != ROK)
6949          {
6950             DU_LOG("\nERROR  -->  E2AP : Failed to build the connection update modify list");
6951             break;
6952          }
6953       }
6954       
6955       if(connectionInfo == REMOVE_CONNECTION)
6956       {
6957          ieIdx++;
6958          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionUpdateRemove;
6959          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6960          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_E2connectionUpdateRemove_List;
6961          if(BuildE2ConnectionRemoveList(&e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List) != ROK)
6962          {
6963             DU_LOG("\nERROR  -->  E2AP : Failed to build the connection update modify list");
6964             break;
6965          }
6966       }
6967
6968       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6969
6970       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6971       encBufSize = 0;
6972       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6973       if(encRetVal.encoded == ENCODE_FAIL)
6974       {
6975          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update structure (at %s)\n",\
6976                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6977          break;
6978       }
6979       else
6980       {
6981          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update \n");
6982          for(int i=0; i< encBufSize; i++)
6983          {
6984             DU_LOG("%x",encBuf[i]);
6985          }
6986       }
6987
6988       /* Sending msg */
6989       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6990       {
6991          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update");
6992          break;
6993       }
6994
6995       ret = ROK;
6996       break;
6997    }while(true);
6998    
6999    FreeE2ConnectionUpdate(e2apMsg);
7000    return ret;
7001 }
7002
7003 /******************************************************************
7004  *
7005  * @brief Processes the E2 connection update failure msg
7006  *
7007  * @details
7008  *
7009  *    Function : procE2connectionUpdateFailure
7010  *
7011  *    Functionality: Processes the E2 connection update failure msg
7012  *
7013  * @params[in] 
7014  *       E2 connection update failure information
7015  *
7016  * @return void
7017  *
7018  * ****************************************************************/
7019 void ProcE2connectionUpdateFailure(E2connectionUpdateFailure_t *updateFailure) 
7020 {
7021    uint8_t ieIdx = 0;
7022    uint16_t transId=0;
7023    CauseE2_t *cause = NULLP;
7024
7025    if(!updateFailure)
7026    {
7027       DU_LOG("\nERROR  -->  E2AP : updateFailure pointer is null"); 
7028       return;
7029    }
7030
7031    if(!updateFailure->protocolIEs.list.array)      
7032    {
7033       DU_LOG("\nERROR  -->  E2AP : updateFailure array pointer is null");
7034       return;
7035    }
7036    
7037    for(ieIdx=0; ieIdx < updateFailure->protocolIEs.list.count; ieIdx++)
7038    {
7039       if(updateFailure->protocolIEs.list.array[ieIdx])
7040       {
7041          switch(updateFailure->protocolIEs.list.array[ieIdx]->id)
7042          {
7043             case ProtocolIE_IDE2_id_TransactionID:
7044                {
7045                   transId = updateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
7046                   DU_LOG("\nERROR  -->  E2AP : Received transID %d", transId);
7047                   break;
7048                }
7049             case ProtocolIE_IDE2_id_CauseE2:
7050                {
7051                    cause = &updateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
7052                    printE2ErrorCause(cause);
7053                    break; 
7054                }
7055             default:
7056                {
7057                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", updateFailure->protocolIEs.list.array[ieIdx]->id);
7058                   break;
7059                }
7060          }
7061       }
7062    }
7063 }
7064
7065 /*******************************************************************
7066  *
7067  * @brief process the E2 Connection update ack
7068  *
7069  * @details
7070  *
7071  *    Function : ProcE2ConnectionUpdateAck 
7072  *
7073  * Functionality: Process E2 Connection update ack 
7074  *
7075  * @params[in] 
7076  *       du Id
7077  *       Pointer to Connection update ack 
7078  * @return void
7079  *
7080  ******************************************************************/
7081
7082 void ProcE2ConnectionUpdateAck(uint32_t duId, E2connectionUpdateAcknowledge_t *connectionUpdateAck)
7083 {
7084    uint16_t transId =0;
7085    uint32_t ipAddress=0;
7086    DuDb *duDb = NULLP;
7087    uint8_t ieIdx = 0, duIdx =0, arrIdx=0;
7088    E2connectionUpdate_Item_t *connectionSetupItem=NULLP;
7089    E2connectionUpdate_ItemIEs_t *connectionSetupItemIe=NULLP;
7090    E2connectionUpdate_List_t *connectionSetupList=NULLP;
7091    E2connectionSetupFailed_Item_t *setupFailedItem =NULLP;
7092    E2connectionSetupFailed_List_t *setupFailedList=NULLP;
7093    E2connectionSetupFailed_ItemIEs_t *setupFailedItemIe =NULLP;
7094
7095    SEARCH_DU_DB(duIdx, duId, duDb);
7096    if(duDb == NULLP)
7097    {
7098       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
7099       return;
7100    }
7101
7102    if(!connectionUpdateAck)
7103    {
7104       DU_LOG("\nERROR  -->  E2AP : connectionUpdateAck pointer is null"); 
7105       return;
7106    }
7107
7108    if(!connectionUpdateAck->protocolIEs.list.array)      
7109    {
7110       DU_LOG("\nERROR  -->  E2AP : connectionUpdateAck array pointer is null");
7111       return;
7112    }
7113
7114    for(ieIdx=0; ieIdx < connectionUpdateAck->protocolIEs.list.count; ieIdx++)
7115    {
7116       if(connectionUpdateAck->protocolIEs.list.array[ieIdx])
7117       {
7118          switch(connectionUpdateAck->protocolIEs.list.array[ieIdx]->id)
7119          {
7120             case ProtocolIE_IDE2_id_TransactionID:
7121                {
7122                   transId = connectionUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
7123                   if(transId>255)
7124                   {
7125                      DU_LOG("\nERROR  -->  E2AP : Received invalid trans id %d ",transId);
7126                      return;
7127                   }
7128                   break;
7129                }
7130             case ProtocolIE_IDE2_id_E2connectionSetup:
7131                {
7132                   connectionSetupList=&connectionUpdateAck->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
7133                   if(connectionSetupList->list.array)
7134                   {
7135                      for(arrIdx = 0; arrIdx< connectionSetupList->list.count; arrIdx++)
7136                      {
7137                         connectionSetupItemIe = (E2connectionUpdate_ItemIEs_t*)connectionSetupList->list.array[arrIdx];
7138                         connectionSetupItem = &connectionSetupItemIe->value.choice.E2connectionUpdate_Item;
7139                         bitStringToInt(&connectionSetupItem->tnlInformation.tnlAddress, &ipAddress);
7140                         if(ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr == ipAddress)
7141                         {
7142                             ricCb.ricCfgParams.sctpParams.usage = connectionSetupItem->tnlUsage;
7143                         }
7144                      }
7145                   }
7146                   break;
7147                }
7148
7149             case ProtocolIE_IDE2_id_E2connectionSetupFailed:
7150                {
7151                   setupFailedList=&connectionUpdateAck->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List;
7152                   if(setupFailedList->list.array)
7153                   {
7154                      for(arrIdx = 0; arrIdx< setupFailedList->list.count; arrIdx++)
7155                      {
7156                         setupFailedItemIe = (E2connectionSetupFailed_ItemIEs_t*)setupFailedList->list.array[arrIdx];
7157                         setupFailedItem = &setupFailedItemIe->value.choice.E2connectionSetupFailed_Item;
7158                         printE2ErrorCause(&setupFailedItem->cause);
7159                      }
7160                   }
7161                   break;
7162                }
7163             default:
7164                {
7165                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", connectionUpdateAck->protocolIEs.list.array[ieIdx]->id);
7166                   break;
7167                }
7168          }
7169       }
7170    }
7171 }
7172
7173 /******************************************************************
7174  *
7175  * @brief Processes the Ric Subs delete failure msg
7176  *
7177  * @details
7178  *
7179  *    Function : procRicSubsDeleteFailure
7180  *
7181  *    Functionality: Processes the Ric Subs delete failure msg
7182  *
7183  * @params[in]
7184  *       Ric Subs delete failure information
7185  *
7186  * @return void
7187  *
7188  * ****************************************************************/
7189 void ProcRicSubsDeleteFailure(RICsubscriptionDeleteFailure_t *ricSubsDeleteFail)
7190 {
7191    uint8_t ieIdx = 0;
7192    uint16_t ranFuncId=0;
7193    CauseE2_t *cause = NULLP;
7194    RICrequestID_t  ricRequestID;
7195
7196    if(!ricSubsDeleteFail)
7197    {
7198       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteFail pointer is null");
7199       return;
7200    }
7201
7202    if(!ricSubsDeleteFail->protocolIEs.list.array)
7203    {
7204       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteFail array pointer is null");
7205       return;
7206    }
7207
7208    for(ieIdx=0; ieIdx < ricSubsDeleteFail->protocolIEs.list.count; ieIdx++)
7209    {
7210       if(ricSubsDeleteFail->protocolIEs.list.array[ieIdx])
7211       {
7212          switch(ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->id)
7213          {
7214             case ProtocolIE_IDE2_id_RICrequestID:
7215                {
7216                   memcpy(&ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID, &ricRequestID, sizeof(RICrequestID_t));
7217                   DU_LOG("\nERROR  -->  E2AP : Received RicReqId %ld and InstanceId %ld", ricRequestID.ricRequestorID, ricRequestID.ricInstanceID);
7218                   break;
7219                }
7220             case ProtocolIE_IDE2_id_RANfunctionID:
7221                {
7222                   ranFuncId = ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
7223                   DU_LOG("\nERROR  -->  E2AP : Received ranfuncId %d", ranFuncId);
7224                   break;
7225                }
7226             case ProtocolIE_IDE2_id_CauseE2:
7227                {
7228                    cause = &ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
7229                    printE2ErrorCause(cause);
7230                    break;
7231                }
7232             default:
7233                {
7234                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->id);
7235                   break;
7236                }
7237          }
7238       }
7239    }
7240 }
7241
7242
7243 /******************************************************************
7244  *
7245  * @brief Processes the Ric Subs delete rsp msg
7246  *
7247  * @details
7248  *
7249  *    Function : ProcRicSubsDeleteRsp
7250  *
7251  *    Functionality: Processes the Ric Subs delete rsp msg
7252  *
7253  * @params[in]
7254  *       Ric Subs delete rsp information
7255  *
7256  * @return void
7257  *
7258  * ****************************************************************/
7259 void ProcRicSubsDeleteRsp(uint32_t duId, RICsubscriptionDeleteResponse_t *ricSubsDeleteRsp)
7260 {
7261    uint8_t ieIdx = 0;
7262    uint8_t duIdx= 0;
7263    uint16_t ranFuncId=0;
7264    RanFunction *ranFuncDb = NULLP;
7265    RicRequestId ricReqId;
7266    DuDb    *duDb = NULLP;
7267    RicSubscription *ricSubs = NULLP;
7268    CmLList *ricSubsNode = NULLP;
7269
7270    SEARCH_DU_DB(duIdx, duId, duDb);
7271    if(duDb == NULLP)
7272    {
7273       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
7274       return;
7275    }
7276
7277    if(!ricSubsDeleteRsp)
7278    {
7279       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteRsp pointer is null");
7280       return;
7281    }
7282
7283    if(!ricSubsDeleteRsp->protocolIEs.list.array)
7284    {
7285       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteRsp array pointer is null");
7286       return;
7287    }
7288    for(ieIdx=0; ieIdx < ricSubsDeleteRsp->protocolIEs.list.count; ieIdx++)
7289    {
7290       if(ricSubsDeleteRsp->protocolIEs.list.array[ieIdx])
7291       {
7292          switch(ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->id)
7293          {
7294             case ProtocolIE_IDE2_id_RICrequestID:
7295                {
7296                   ricReqId.requestorId = ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricRequestorID;
7297                   ricReqId.instanceId = ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricInstanceID;
7298                   break;
7299                }
7300             case ProtocolIE_IDE2_id_RANfunctionID:
7301                {
7302                   ranFuncId = ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
7303                   ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
7304                   if(!ranFuncDb)
7305                   {
7306                      DU_LOG("\nERROR  -->  E2AP : Invalid Ran Function id %d received",ranFuncId);
7307                      return;
7308                   }
7309
7310                   ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
7311                   if(ricSubs)
7312                   {
7313                      deleteRicSubscriptionNode(ricSubsNode);
7314                      DU_LOG("\nINFO  -->  E2AP : Ric subscription node deleted successfully");
7315                   }
7316                   else
7317                   {
7318                      DU_LOG("\nERROR  -->  E2AP : Ric subscription node is not present ");
7319                      return;
7320                   }
7321                   break;
7322                }
7323          }
7324       }
7325    }
7326 }
7327
7328
7329  /******************************************************************
7330   *
7331   * @brief Processes the Ric Subs modification failure msg
7332   *
7333   * @details
7334   *
7335   *    Function : procRicSubsModificationFailure
7336   *
7337   *    Functionality: Processes the Ric Subs modification failure msg
7338   *
7339   * @params[in]
7340   *       Ric Subs modification failure information
7341   *
7342   * @return void
7343   *
7344   * ****************************************************************/
7345  void ProcRicSubsModificationFailure(RICsubscriptionModificationFailure_t *ricSubsModificationFail)
7346  {
7347     uint8_t ieIdx = 0;
7348     uint16_t ranFuncId=0;
7349     CauseE2_t *cause = NULLP;
7350     RICrequestID_t  ricRequestID;
7351
7352     DU_LOG("\nINFO  -->  E2AP : Ric subscription modification failure received");
7353
7354     if(!ricSubsModificationFail)
7355     {
7356        DU_LOG("\nERROR  -->  E2AP : ricSubsModificationFail pointer is null");
7357        return;
7358     }
7359
7360     if(!ricSubsModificationFail->protocolIEs.list.array)
7361     {
7362        DU_LOG("\nERROR  -->  E2AP : ricSubsModificationFail array pointer is null");
7363        return;
7364     }
7365
7366     for(ieIdx=0; ieIdx < ricSubsModificationFail->protocolIEs.list.count; ieIdx++)
7367     {
7368        if(ricSubsModificationFail->protocolIEs.list.array[ieIdx])
7369        {
7370           switch(ricSubsModificationFail->protocolIEs.list.array[ieIdx]->id)
7371           {
7372              case ProtocolIE_IDE2_id_RICrequestID:
7373                 {
7374                    memcpy(&ricSubsModificationFail->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID, &ricRequestID, sizeof(RICrequestID_t));
7375                    DU_LOG("\nERROR  -->  E2AP : Received RicReqId %ld and InstanceId %ld", ricRequestID.ricRequestorID, ricRequestID.ricInstanceID);
7376                    break;
7377                 }
7378              case ProtocolIE_IDE2_id_RANfunctionID:
7379                 {
7380                    ranFuncId = ricSubsModificationFail->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
7381                    DU_LOG("\nERROR  -->  E2AP : Received ranfuncId %d", ranFuncId);
7382                    break;
7383                 }
7384              case ProtocolIE_IDE2_id_CauseE2:
7385                 {
7386                     cause = &ricSubsModificationFail->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
7387                     printE2ErrorCause(cause);
7388                     break;
7389                 }
7390              default:
7391                 {
7392                    DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubsModificationFail->protocolIEs.list.array[ieIdx]->id);
7393                    break;
7394                 }
7395           }
7396        }
7397     }
7398  }
7399
7400 /*******************************************************************
7401  *
7402  * @brief Free RIC Subscription  action to be added list
7403  *
7404  * @details
7405  *
7406  *    Function : FreeRicSubsActionToBeAdded
7407  *
7408  *    Functionality: Free the RIC Subscription action to be added list
7409  *
7410  * @params[in] RICactions_ToBeAddedForModification_List_t *subsDetails
7411  * @return void
7412  *
7413  * ****************************************************************/
7414 void FreeRicSubsActionToBeAdded(RICactions_ToBeAddedForModification_List_t *subsDetails)
7415 {
7416    uint8_t elementIdx = 0;
7417    RICaction_ToBeAddedForModification_ItemIEs_t *addedActionItemIe=NULLP;
7418
7419    if(subsDetails->list.array)
7420    {
7421       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
7422       {
7423          if(subsDetails->list.array[elementIdx])
7424          {
7425             addedActionItemIe = (RICaction_ToBeAddedForModification_ItemIEs_t*)subsDetails->list.array[elementIdx];
7426             RIC_FREE(addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition.buf, \
7427             addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition.size);
7428             RIC_FREE(subsDetails->list.array[elementIdx], sizeof(RICaction_ToBeAddedForModification_ItemIEs_t));
7429          }
7430       }
7431       RIC_FREE(subsDetails->list.array, subsDetails->list.size);
7432    }
7433 }
7434
7435 /*******************************************************************
7436  *
7437  * @brief Free RIC Subscription  action to be removed list
7438  *
7439  * @details
7440  *
7441  *    Function : FreeRicSubsActionToBeRemoved
7442  *
7443  *    Functionality: Free the RIC Subscription action to be removed list
7444  *
7445  * @params[in] RICactions_ToBeRemovedForModification_List_t *subsDetails
7446  * @return void
7447  *
7448  * ****************************************************************/
7449 void FreeRicSubsActionToBeRemoved(RICactions_ToBeRemovedForModification_List_t *subsDetails)
7450 {
7451    uint8_t elementIdx = 0;
7452
7453    if(subsDetails->list.array)
7454    {
7455       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
7456       {
7457          RIC_FREE(subsDetails->list.array[elementIdx], sizeof(RICaction_ToBeRemovedForModification_ItemIEs_t));
7458       }
7459       RIC_FREE(subsDetails->list.array, subsDetails->list.size);
7460    }
7461 }
7462
7463 /*******************************************************************
7464  *
7465  * @brief Free RIC Subscription action to be modify
7466  *
7467  * @details
7468  *
7469  *    Function : FreeRicSubsActionToBeModified
7470  *
7471  *    Functionality: Free the RIC Subscription action to be modify
7472  *
7473  * @params[in] RICactions_ToBeModifiedForModification_List_t List
7474  * @return void
7475  *
7476  * ****************************************************************/
7477 void FreeRicSubsActionToBeModified(RICactions_ToBeModifiedForModification_List_t *subsDetails)
7478 {
7479    uint8_t elementIdx = 0;
7480    RICaction_ToBeModifiedForModification_ItemIEs_t *actionItem = NULLP;
7481
7482    if(subsDetails->list.array)
7483    {
7484       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
7485       {
7486          if(subsDetails->list.array[elementIdx])
7487          {
7488             actionItem = (RICaction_ToBeModifiedForModification_ItemIEs_t *)subsDetails->list.array[elementIdx];
7489             if(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition)
7490             {
7491                RIC_FREE(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition->buf, \
7492                   actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition->size);
7493                RIC_FREE(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
7494             }
7495             RIC_FREE(subsDetails->list.array[elementIdx], sizeof(RICaction_ToBeModifiedForModification_ItemIEs_t))
7496          }
7497       }
7498       RIC_FREE(subsDetails->list.array, subsDetails->list.size);
7499    }
7500 }
7501
7502 /*******************************************************************
7503  *
7504  * @brief Free RIC Subscription modification Request
7505  *
7506  * @details
7507  *
7508  *    Function :FreeRicSubscriptionModReq
7509  *
7510  * Functionality : Free RIC Subscription modification Request
7511  *
7512  * @params[in] E2AP_PDU
7513  * @return void
7514  *
7515  ******************************************************************/
7516 void FreeRicSubscriptionModReq(E2AP_PDU_t *e2apRicMsg)
7517 {
7518    uint8_t idx = 0;
7519    RICsubscriptionModificationRequest_t   *ricSubscriptionModReq =NULLP;
7520    RICsubscriptionModificationRequest_IEs_t *ricSubscriptionModReqIe=NULLP;
7521
7522    if(e2apRicMsg)
7523    {
7524       if(e2apRicMsg->choice.initiatingMessage)
7525       {
7526          ricSubscriptionModReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest;
7527          if(ricSubscriptionModReq->protocolIEs.list.array)
7528          {
7529             for(idx=0; idx < ricSubscriptionModReq->protocolIEs.list.count; idx++)
7530             {
7531                if(ricSubscriptionModReq->protocolIEs.list.array[idx])
7532                {
7533                   ricSubscriptionModReqIe = ricSubscriptionModReq->protocolIEs.list.array[idx];
7534                   switch(ricSubscriptionModReq->protocolIEs.list.array[idx]->id)
7535                   {
7536                      case ProtocolIE_IDE2_id_RICrequestID:
7537                         break;
7538                      case ProtocolIE_IDE2_id_RANfunctionID:
7539                         break;
7540                      case ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List:
7541                         {
7542                            FreeRicSubsActionToBeRemoved(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeRemovedForModification_List));
7543                            break;
7544                         }
7545                      case ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List:
7546                         {
7547                            FreeRicSubsActionToBeModified(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeModifiedForModification_List));
7548                            break;
7549                         }
7550                      case ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List:
7551                         {
7552                            FreeRicSubsActionToBeAdded(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeAddedForModification_List));
7553                            break;
7554                         }
7555                      default:
7556                         {
7557                            DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubscriptionModReq->protocolIEs.list.array[idx]->id);
7558                            break;
7559                         }
7560
7561                   }
7562
7563                   RIC_FREE(ricSubscriptionModReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionModificationRequest_IEs_t));
7564                }
7565             }
7566             RIC_FREE(ricSubscriptionModReq->protocolIEs.list.array, ricSubscriptionModReq->protocolIEs.list.size);
7567          }
7568          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7569       }
7570       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
7571    }
7572 }
7573
7574 /*******************************************************************
7575 *
7576 * @brief Build Ric subscription action to be modify list
7577 *
7578 * @details
7579 *
7580 *    Function : BuildRicSubsActionToBeModify
7581 *
7582 *    Functionality: Build Ric subscription action to be modify list
7583 *
7584 * @params[in]
7585 *    RICactions_ToBeModifiedForModification_List_t to be filled
7586 *    Num of action to be modify
7587 *    List of action to be modify
7588 *
7589 * @return ROK     - success
7590 *         RFAILED - failure
7591 *
7592 ******************************************************************/
7593
7594 uint8_t BuildRicSubsActionToBeModify(RICactions_ToBeModifiedForModification_List_t *modifyActionList, uint8_t numOfActionToBeModify, ActionInfo *actionToBeModify)
7595 {
7596    uint8_t arrIdx=0;
7597    RICaction_ToBeModifiedForModification_ItemIEs_t *modifiedActionItemIe=NULLP;
7598
7599    modifyActionList->list.count = numOfActionToBeModify;
7600    modifyActionList->list.size = modifyActionList->list.count *  sizeof(RICaction_ToBeModifiedForModification_ItemIEs_t*);
7601    RIC_ALLOC(modifyActionList->list.array, modifyActionList->list.size);
7602    if(!modifyActionList->list.array)
7603    {
7604       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7605       return RFAILED;
7606    }
7607
7608    for(arrIdx = 0; arrIdx< modifyActionList->list.count; arrIdx++)
7609    {
7610       RIC_ALLOC(modifyActionList->list.array[arrIdx], sizeof(RICaction_ToBeModifiedForModification_ItemIEs_t));
7611       if(!modifyActionList->list.array[arrIdx])
7612       {
7613          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7614          return RFAILED;
7615       }
7616       modifiedActionItemIe = (RICaction_ToBeModifiedForModification_ItemIEs_t*)modifyActionList->list.array[arrIdx];
7617       modifiedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item;
7618       modifiedActionItemIe->criticality = CriticalityE2_ignore;
7619       modifiedActionItemIe->value.present = RICaction_ToBeModifiedForModification_ItemIEs__value_PR_RICaction_ToBeModifiedForModification_Item;
7620       modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionID = actionToBeModify[arrIdx].actionId;
7621
7622       /* RIC Action Definition */
7623       RIC_ALLOC(modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
7624       if(!modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition)
7625       {
7626          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7627          break;
7628       }
7629
7630       if(fillRicActionDef(modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition,\
7631                actionToBeModify[arrIdx].actionId, CONFIG_MOD) != ROK)
7632       {
7633          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7634          break;
7635       }
7636
7637    }
7638    return ROK;
7639 }
7640
7641 /*******************************************************************
7642 *
7643 * @brief Build Ric subscription action to be removed list
7644 *
7645 * @details
7646 *
7647 *    Function : BuildRicSubsActionToBeRemoved
7648 *
7649 *    Functionality: Build Ric subscription action to be removed list
7650 *
7651 * @params[in]
7652 *    RICactions_ToBeRemovedForModification_List_t to be filled
7653 *    Num Of Action To Be Remove 
7654 *    Action remove list
7655 *
7656 * @return ROK     - success
7657 *         RFAILED - failure
7658 *
7659 ******************************************************************/
7660
7661 uint8_t BuildRicSubsActionToBeRemoved(RICactions_ToBeRemovedForModification_List_t *removeActionList, uint8_t numOfActionToBeRemove, ActionInfo *actionToBeRemove)
7662 {
7663    uint8_t arrIdx=0;
7664    RICaction_ToBeRemovedForModification_ItemIEs_t *removeActionItemIe=NULLP;
7665
7666    removeActionList->list.count = numOfActionToBeRemove;
7667    removeActionList->list.size = removeActionList->list.count *  sizeof(RICaction_ToBeRemovedForModification_ItemIEs_t*);
7668    RIC_ALLOC(removeActionList->list.array, removeActionList->list.size);
7669    if(!removeActionList->list.array)
7670    {
7671       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7672       return RFAILED;
7673    }
7674
7675    for(arrIdx = 0; arrIdx< removeActionList->list.count; arrIdx++)
7676    {
7677       RIC_ALLOC(removeActionList->list.array[arrIdx], sizeof(RICaction_ToBeRemovedForModification_ItemIEs_t));
7678       if(!removeActionList->list.array[arrIdx])
7679       {
7680          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7681          return RFAILED;
7682       }
7683       removeActionItemIe = (RICaction_ToBeRemovedForModification_ItemIEs_t*)removeActionList->list.array[arrIdx];
7684       removeActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ToBeRemovedForModification_Item;
7685       removeActionItemIe->criticality = CriticalityE2_ignore;
7686       removeActionItemIe->value.present = RICaction_ToBeRemovedForModification_ItemIEs__value_PR_RICaction_ToBeRemovedForModification_Item;
7687       removeActionItemIe->value.choice.RICaction_ToBeRemovedForModification_Item.ricActionID = actionToBeRemove[arrIdx].actionId;
7688    }
7689    return ROK;
7690 }
7691
7692 /*******************************************************************
7693 *
7694 * @brief Build Ric subscription action to be added list
7695 *
7696 * @details
7697 *
7698 *    Function : BuildRicSubsActionToBeAdded 
7699 *
7700 *    Functionality: Build Ric subscription action to be added list
7701 *
7702 * @params[in]
7703 *    RICactions_ToBeAddedForModification_List_t to be filled
7704 *    Num Of Action To Be added 
7705 *    Action add list
7706 *
7707 * @return ROK     - success
7708 *         RFAILED - failure
7709 *
7710 ******************************************************************/
7711
7712 uint8_t BuildRicSubsActionToBeAdded(RICactions_ToBeAddedForModification_List_t *addedActionList, RicSubscription **ricSubsInfo, uint8_t numOfActionToBeAdded, ActionInfo *actionToBeAdded)
7713 {
7714    uint8_t arrIdx=0;
7715    CmLList *actionNode=NULLP;
7716    RICaction_ToBeAddedForModification_ItemIEs_t *addedActionItemIe;
7717
7718    addedActionList->list.count = numOfActionToBeAdded;
7719    addedActionList->list.size = addedActionList->list.count *  sizeof(RICaction_ToBeAddedForModification_ItemIEs_t*);
7720    RIC_ALLOC(addedActionList->list.array, addedActionList->list.size);
7721    if(!addedActionList->list.array)
7722    {
7723       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7724       return RFAILED;
7725    }
7726
7727    for(arrIdx = 0; arrIdx< addedActionList->list.count; arrIdx++)
7728    {
7729       RIC_ALLOC(addedActionList->list.array[arrIdx], sizeof(RICaction_ToBeAddedForModification_ItemIEs_t));
7730       if(!addedActionList->list.array[arrIdx])
7731       {
7732          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7733          return RFAILED;
7734       }
7735       addedActionItemIe = (RICaction_ToBeAddedForModification_ItemIEs_t*)addedActionList->list.array[arrIdx];
7736       addedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item;
7737       addedActionItemIe->criticality = CriticalityE2_ignore;
7738       addedActionItemIe->value.present = RICaction_ToBeAddedForModification_ItemIEs__value_PR_RICaction_ToBeAddedForModification_Item;
7739       addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionID = actionToBeAdded[arrIdx].actionId;
7740       
7741       addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionType = RICactionType_report;
7742
7743       if(fillRicActionDef(&addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition, \
7744       actionToBeAdded[arrIdx].actionId, CONFIG_ADD) != ROK)
7745       {
7746          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7747          break;
7748       }
7749       
7750       actionNode = addRicSubsAction((*ricSubsInfo)->actionSequence.count, &(*ricSubsInfo)->actionSequence);
7751       if(actionNode == NULLP)
7752       {
7753          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7754          return RFAILED;
7755       }
7756    }
7757    return ROK;
7758 }
7759
7760 /*******************************************************************
7761  *
7762  * @brief Builds and Send the RicSubscriptionModReq
7763  *
7764  * @details
7765  *
7766  *    Function : BuildAndSendRicSubscriptionModReq
7767  *
7768  * Functionality:Builds and Send the RicSubscriptionModReq
7769  *
7770  * @params[in]
7771  *    Du databse
7772  *    Ric subs information
7773  *    List of ric subs action which needs to modify/add/remove
7774  * @return ROK     - success
7775  *         RFAILED - failure
7776  *
7777  ******************************************************************/
7778
7779 uint8_t BuildAndSendRicSubscriptionModReq(DuDb *duDb, RicSubscription **ricSubsInfo, RicSubsModReq ricSubsModReq)
7780 {
7781    uint8_t         ret = RFAILED;
7782    uint8_t         elementCnt = 0;
7783    uint8_t         idx = 0;
7784    asn_enc_rval_t  encRetVal;        /* Encoder return value */
7785    E2AP_PDU_t                 *e2apRicMsg = NULL;
7786    RICsubscriptionModificationRequest_t   *ricSubscriptionModReq;
7787    
7788    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
7789
7790    while(true)
7791    {
7792       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
7793       if(e2apRicMsg == NULLP)
7794       {
7795          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7796          break;
7797       }
7798
7799       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
7800       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7801       if(e2apRicMsg->choice.initiatingMessage == NULLP)
7802       {
7803          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7804          break;
7805       }
7806       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModification;
7807       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7808       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequest;
7809
7810       ricSubscriptionModReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest;
7811
7812       /* Increasing the elment count based on the number of configured action to  be add, mod, delete */
7813       elementCnt = 2;
7814       if(ricSubsModReq.numOfActionToBeAdded)
7815          elementCnt++;
7816       if(ricSubsModReq.numOfActionToBeModify)
7817          elementCnt++;
7818       if(ricSubsModReq.numOfActionToBeRemove)
7819          elementCnt++;
7820
7821       ricSubscriptionModReq->protocolIEs.list.count = elementCnt;
7822       ricSubscriptionModReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionModificationRequest_IEs_t);
7823
7824       /* Initialize the subscription members */
7825       RIC_ALLOC(ricSubscriptionModReq->protocolIEs.list.array, ricSubscriptionModReq->protocolIEs.list.size);
7826       if(ricSubscriptionModReq->protocolIEs.list.array == NULLP)
7827       {
7828          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7829          break;
7830       }
7831
7832       for(idx=0; idx<elementCnt; idx++)
7833       {
7834          RIC_ALLOC(ricSubscriptionModReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionModificationRequest_IEs_t));
7835          if(ricSubscriptionModReq->protocolIEs.list.array[idx] == NULLP)
7836          {
7837             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7838             break;
7839          }
7840       }
7841       if(idx < elementCnt)
7842          break;
7843
7844       /* Filling RIC Request Id */
7845       idx = 0;
7846       ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
7847       ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
7848       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present =\
7849                                                                       RICsubscriptionModificationRequest_IEs__value_PR_RICrequestID;
7850       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = (*ricSubsInfo)->requestId.requestorId;
7851       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =  (*ricSubsInfo)->requestId.instanceId;
7852
7853       /* Filling RAN Function Id */
7854       idx++;
7855       ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
7856       ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
7857       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present =\
7858                                                                       RICsubscriptionModificationRequest_IEs__value_PR_RANfunctionID;
7859       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = (*ricSubsInfo)->ranFuncId;
7860
7861       if(ricSubsModReq.numOfActionToBeRemove)
7862       {
7863          /* Filling RIC Subscription action to be removed */
7864          idx++;
7865          ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List;
7866          ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_ignore;
7867          ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present = RICsubscriptionModificationRequest_IEs__value_PR_RICactions_ToBeRemovedForModification_List;
7868          if(BuildRicSubsActionToBeRemoved(&ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICactions_ToBeRemovedForModification_List,\
7869                   ricSubsModReq.numOfActionToBeRemove, ricSubsModReq.actionToBeRemove) != ROK)
7870          {
7871             DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7872             break;
7873          }
7874       }
7875       if(ricSubsModReq.numOfActionToBeModify)
7876       {
7877          /* Filling RIC Subscription action to be modified */
7878          idx++;
7879          ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List;
7880          ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_ignore;
7881          ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present = RICsubscriptionModificationRequest_IEs__value_PR_RICactions_ToBeModifiedForModification_List;
7882          if(BuildRicSubsActionToBeModify(&ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICactions_ToBeModifiedForModification_List,\
7883                   ricSubsModReq.numOfActionToBeModify, ricSubsModReq.actionToBeModify) != ROK)
7884          {
7885             DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7886             break;
7887          }
7888       }
7889
7890       if(ricSubsModReq.numOfActionToBeAdded)
7891       {
7892          /* Filling RIC Subscription action to be added */
7893          idx++;
7894          ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List;
7895          ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_ignore;
7896          ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present = RICsubscriptionModificationRequest_IEs__value_PR_RICactions_ToBeAddedForModification_List;
7897          if(BuildRicSubsActionToBeAdded(&ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICactions_ToBeAddedForModification_List,\
7898          ricSubsInfo, ricSubsModReq.numOfActionToBeAdded, ricSubsModReq.actionToBeAdded) != ROK)
7899          {
7900             DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7901             break;
7902          }
7903       }
7904
7905       /* Prints the Msg formed */
7906       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
7907
7908       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7909       encBufSize = 0;
7910       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
7911       if(encRetVal.encoded == ENCODE_FAIL)
7912       {
7913          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionModRequest structure (at %s)\n",\
7914                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7915          break;
7916       }
7917       else
7918       {
7919          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionModRequest\n");
7920          for(int i=0; i< encBufSize; i++)
7921          {
7922             DU_LOG("%x",encBuf[i]);
7923          }
7924       }
7925
7926       /* Sending msg */
7927       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
7928       {
7929          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
7930          break;
7931       }
7932
7933       ret = ROK;
7934       break;
7935    }
7936
7937    FreeRicSubscriptionModReq(e2apRicMsg);
7938    return ret;
7939 }
7940
7941 /*******************************************************************
7942  *
7943  * @brief Builds RicSubscriptionModReq
7944  *
7945  * @details
7946  *
7947  *    Function : BuildRicSubscriptionModReq
7948  *
7949  * Functionality:Builds the RicSubscriptionModReq
7950  *
7951  * @params[in]
7952  *    Du databse
7953  * @return void
7954  *
7955  * ****************************************************************/
7956
7957 void BuildRicSubsModificationReq(DuDb *duDb, RicSubscription *ricSubsInfo)
7958 {
7959    CmLList *actionNode=NULLP;
7960    uint8_t actionToBeAdded =0;
7961    uint8_t actionIdx =0, tmpActionIdx=0;
7962    ActionInfo *actionInfoDb = NULLP;
7963    RicSubsModReq ricSubsModReq;
7964
7965    if(ricSubsInfo)
7966    {
7967       memset(&ricSubsModReq, 0, sizeof(RicSubsModReq));
7968       
7969
7970       CM_LLIST_FIRST_NODE(&ricSubsInfo->actionSequence, actionNode);
7971       while(actionNode)
7972       {
7973          actionInfoDb = (ActionInfo*)(actionNode->node);
7974          /* Change the condition based on the action required to be modiified or removed */
7975          if(((actionInfoDb->actionId+1)%2) == 0)
7976          {
7977             tmpActionIdx = ricSubsModReq.numOfActionToBeModify; 
7978             ricSubsModReq.actionToBeModify[tmpActionIdx].actionId = actionInfoDb->actionId;
7979             ricSubsModReq.numOfActionToBeModify++;
7980          }
7981          else
7982          {
7983             tmpActionIdx = ricSubsModReq.numOfActionToBeRemove; 
7984             ricSubsModReq.actionToBeRemove[tmpActionIdx].actionId = actionInfoDb->actionId;
7985             ricSubsModReq.numOfActionToBeRemove++;
7986          }
7987          actionNode= actionNode->next;
7988       }
7989       /* Change the value of actionToBeAdded based on the number of action required to be added */
7990       actionToBeAdded =1;
7991       tmpActionIdx = ricSubsInfo->actionSequence.count;
7992       for(actionIdx=0; actionIdx<actionToBeAdded; actionIdx++)
7993       {
7994          ricSubsModReq.actionToBeAdded[actionIdx].actionId = tmpActionIdx;
7995          ricSubsModReq.numOfActionToBeAdded++;
7996          tmpActionIdx++;
7997       }
7998
7999       if(BuildAndSendRicSubscriptionModReq(duDb, &ricSubsInfo, ricSubsModReq) != ROK)
8000       {
8001          DU_LOG("\nERROR  -->  E2AP : failed to build and send RIC Subscription Modification");
8002          return ;
8003       }
8004    }
8005 }
8006
8007 /****************************************************************
8008  *
8009  * @brief Processing RIC Subscription action modified list
8010  *
8011  * @details
8012  *
8013  *    Function :ProcessingRicSubsActionModified 
8014  *
8015  *    Functionality: Processing the RIC Subscription action modified list
8016  *
8017  * @params[in] RICactions_AddedForModification_List_t
8018  * @return void
8019  *
8020  * ****************************************************************/
8021 void ProcessingRicSubsActionModified(RICactions_ModifiedForModification_List_t *actionModifiedList)
8022 {
8023    uint8_t actionId=0;
8024    uint8_t elementIdx = 0;
8025    RICaction_ModifiedForModification_ItemIEs_t *modifiedActionItemIe =NULLP;
8026
8027    if(actionModifiedList->list.array)
8028    {
8029       for(elementIdx = 0; elementIdx < actionModifiedList->list.count; elementIdx++)
8030       {
8031          if(actionModifiedList->list.array[elementIdx])
8032          {
8033             modifiedActionItemIe=(RICaction_ModifiedForModification_ItemIEs_t*)actionModifiedList->list.array[elementIdx];
8034             actionId = modifiedActionItemIe->value.choice.RICaction_ModifiedForModification_Item.ricActionID;
8035             DU_LOG("\nInfo  -->  E2AP : Action id %d modified successfully",  actionId);
8036          }
8037
8038       }
8039
8040    }
8041 }
8042
8043 /****************************************************************
8044  *
8045  * @brief Processing RIC Subscription action added list
8046  *
8047  * @details
8048  *
8049  *    Function : ProcessingRicSubsActionAdded
8050  *
8051  *    Functionality: Processing RIC Subscription action added  list
8052  *
8053  * @params[in] RICactions_AddedForModification_List_t
8054  * @return void
8055  *
8056  * ****************************************************************/
8057 void ProcessingRicSubsActionAdded(RICactions_AddedForModification_List_t *actionAddedList)
8058 {
8059    uint8_t actionId=0;
8060    uint8_t elementIdx = 0;
8061    RICaction_AddedForModification_ItemIEs_t *addedActionItemIe =NULLP;
8062
8063    if(actionAddedList->list.array)
8064    {
8065       for(elementIdx = 0; elementIdx < actionAddedList->list.count; elementIdx++)
8066       {
8067          if(actionAddedList->list.array[elementIdx])
8068          {
8069             addedActionItemIe=(RICaction_AddedForModification_ItemIEs_t*)actionAddedList->list.array[elementIdx];
8070             actionId = addedActionItemIe->value.choice.RICaction_AddedForModification_Item.ricActionID;
8071             DU_LOG("\nInfo  -->  E2AP : Action id %d added successfully",  actionId);
8072          }
8073
8074       }
8075
8076    }
8077 }
8078
8079 /****************************************************************
8080  *
8081  * @brief Processing RIC Subscription action deleted list
8082  *
8083  * @details
8084  *
8085  *    Function : ProcessingRicSubsActionRemoved
8086  *
8087  *    Functionality: Processing RIC Subscription action deleted list
8088  *
8089  * @params[in] RICactions_RemovedForModification_List_t
8090  *             Ric Subscription info
8091  * @return void
8092  *
8093  * ****************************************************************/
8094 void ProcessingRicSubsActionRemoved(RICactions_RemovedForModification_List_t *actionRemovedList, RicSubscription *ricSubs)
8095 {
8096    uint8_t actionId=0;
8097    uint8_t elementIdx = 0;
8098    ActionInfo *action=NULLP;
8099    CmLList *actionNode =NULLP;
8100    RICaction_RemovedForModification_ItemIEs_t *removedActionItemIe =NULLP;
8101
8102    if(actionRemovedList->list.array)
8103    {
8104       for(elementIdx = 0; elementIdx < actionRemovedList->list.count; elementIdx++)
8105       {
8106          if(actionRemovedList->list.array[elementIdx])
8107          {
8108             removedActionItemIe=(RICaction_RemovedForModification_ItemIEs_t*)actionRemovedList->list.array[elementIdx];
8109             actionId = removedActionItemIe->value.choice.RICaction_RemovedForModification_Item.ricActionID;
8110             action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
8111             if(action)
8112             {
8113                cmLListDelFrm(&ricSubs->actionSequence, actionNode);
8114                deleteActionSequence(actionNode);
8115                DU_LOG("\nInfo  -->  E2AP : Action id %d removed successfully",  actionId);
8116             }
8117          }
8118
8119       }
8120
8121    }
8122 }
8123
8124 /*******************************************************************
8125  *
8126  * @brief Processing RIC Subscription action failed to be
8127  * removed list
8128  *
8129  * @details
8130  *
8131  *    Function : ProcessingRicSubsActionFailedToBeRemoved
8132  *
8133  *    Functionality: Processing the RIC Subscription action failed
8134  *    to be removed list
8135  *
8136  * @params[in] RICactions_FailedToBeRemovedForModification_List_t 
8137  * @return void
8138  *
8139  * ****************************************************************/
8140 void ProcessingRicSubsActionFailedToBeRemoved(RICactions_FailedToBeRemovedForModification_List_t *actionFailedToBeRemoved)
8141 {
8142    uint8_t actionId=0;
8143    uint8_t elementIdx = 0;
8144    RICaction_FailedToBeRemovedForModification_ItemIEs_t *failedToBeRemovedActionItemIe =NULLP;
8145
8146    if(actionFailedToBeRemoved->list.array)
8147    {
8148       for(elementIdx = 0; elementIdx < actionFailedToBeRemoved->list.count; elementIdx++)
8149       {
8150          if(actionFailedToBeRemoved->list.array[elementIdx])
8151          {
8152             failedToBeRemovedActionItemIe=(RICaction_FailedToBeRemovedForModification_ItemIEs_t*)actionFailedToBeRemoved->list.array[elementIdx];
8153             actionId = failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.ricActionID;
8154             DU_LOG("\nERROR  -->  E2AP : Failed to remove action id %d in %s", actionId, __func__);
8155             printE2ErrorCause(&failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.cause);
8156          }
8157
8158       }
8159
8160    }
8161 }
8162
8163 /****************************************************************
8164  *
8165  * @brief Processing RIC Subscription action failed to be
8166  * add list
8167  *
8168  * @details
8169  *
8170  *    Function : ProcessingRicSubsActionFailedToBeAdded
8171  *
8172  *    Functionality: Processing the RIC Subscription action failed
8173  *    to be add list
8174  *
8175  * @params[in] RICactions_FailedToBeAddedForModification_List_t 
8176  * @return void
8177  *
8178  * ****************************************************************/
8179 void ProcessingRicSubsActionFailedToBeAdded(RICactions_FailedToBeAddedForModification_List_t *actionfailedToBeAddedList, RicSubscription *ricSubs)
8180 {
8181    uint8_t actionId=0;
8182    uint8_t elementIdx = 0;
8183    ActionInfo *action=NULLP;
8184    CmLList *actionNode =NULLP;
8185    RICaction_FailedToBeAddedForModification_ItemIEs_t *failedToBeAddedActionItemIe =NULLP;
8186
8187    if(actionfailedToBeAddedList->list.array)
8188    {
8189       for(elementIdx = 0; elementIdx < actionfailedToBeAddedList->list.count; elementIdx++)
8190       {
8191          if(actionfailedToBeAddedList->list.array[elementIdx])
8192          {
8193             failedToBeAddedActionItemIe=(RICaction_FailedToBeAddedForModification_ItemIEs_t*)actionfailedToBeAddedList->list.array[elementIdx];
8194             actionId = failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.ricActionID;
8195             action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
8196             if(action)
8197             {
8198                cmLListDelFrm(&ricSubs->actionSequence, actionNode);
8199                deleteActionSequence(actionNode);
8200             }
8201             DU_LOG("\nERROR  -->  E2AP : Failed to remove action id %d in %s", actionId,__func__);
8202             printE2ErrorCause(&failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.cause);
8203          }
8204
8205       }
8206
8207    }
8208 }
8209
8210 /*******************************************************************
8211  *
8212  * @brief Processing RIC Subscription action failed to be
8213  * modified list
8214  *
8215  * @details
8216  *
8217  *    Function :ProcessingRicSubsActionFailedToBeModified 
8218  *
8219  *    Functionality: Processing the RIC Subscription action failed
8220  *    to be modified list
8221  *
8222  * @params[in] RICactions_FailedToBeModifiedForModification_List_t 
8223  * @return void
8224  *
8225  * ****************************************************************/
8226 void ProcessingRicSubsActionFailedToBeModified(RICactions_FailedToBeModifiedForModification_List_t *actionFailedToBeModifiedList)
8227 {
8228    uint8_t actionId=0;
8229    uint8_t elementIdx = 0;
8230    RICaction_FailedToBeModifiedForModification_ItemIEs_t *failedToBeModifiedActionItemIe =NULLP;
8231
8232    if(actionFailedToBeModifiedList->list.array)
8233    {
8234       for(elementIdx = 0; elementIdx < actionFailedToBeModifiedList->list.count; elementIdx++)
8235       {
8236          if(actionFailedToBeModifiedList->list.array[elementIdx])
8237          {
8238             failedToBeModifiedActionItemIe=(RICaction_FailedToBeModifiedForModification_ItemIEs_t*)actionFailedToBeModifiedList->list.array[elementIdx];
8239             actionId = failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.ricActionID;
8240             DU_LOG("\nERROR  -->  E2AP : Failed to remove action id %d in %s", actionId,__func__);
8241             printE2ErrorCause(&failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.cause);
8242          }
8243
8244       }
8245
8246    }
8247 }
8248
8249 /******************************************************************
8250  *
8251  * @brief Processes the Ric Subs modification rsp msg
8252  *
8253  * @details
8254  *
8255  *    Function : ProcRicSubsModificationRsp
8256  *
8257  *    Functionality: Processes the Ric Subs modification rsp msg
8258  *
8259  * @params[in]
8260  *       Ric Subs modification rsp information
8261  *
8262  * @return void
8263  *
8264  * ****************************************************************/
8265 void ProcRicSubsModificationRsp(uint32_t duId, RICsubscriptionModificationResponse_t *ricSubsModificationRsp)
8266 {
8267    uint8_t ieIdx = 0;
8268    uint8_t duIdx= 0;
8269    uint16_t ranFuncId=0;
8270    RanFunction *ranFuncDb = NULLP;
8271    RicRequestId ricReqId;
8272    DuDb    *duDb = NULLP;
8273    RicSubscription *ricSubs = NULLP;
8274    CmLList *ricSubsNode = NULLP;
8275
8276    SEARCH_DU_DB(duIdx, duId, duDb);
8277    if(duDb == NULLP)
8278    {
8279       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
8280       return;
8281    }
8282
8283    if(!ricSubsModificationRsp)
8284    {
8285       DU_LOG("\nERROR  -->  E2AP : ricSubsModificationRsp pointer is null");
8286       return;
8287    }
8288
8289    if(!ricSubsModificationRsp->protocolIEs.list.array)
8290    {
8291       DU_LOG("\nERROR  -->  E2AP : ricSubsModificationRsp array pointer is null");
8292       return;
8293    }
8294
8295    for(ieIdx=0; ieIdx < ricSubsModificationRsp->protocolIEs.list.count; ieIdx++)
8296    {
8297       if(ricSubsModificationRsp->protocolIEs.list.array[ieIdx])
8298       {
8299          switch(ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->id)
8300          {
8301             case ProtocolIE_IDE2_id_RICrequestID:
8302                {
8303                   ricReqId.requestorId = ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricRequestorID;
8304                   ricReqId.instanceId = ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricInstanceID;
8305                   break;
8306                }
8307             case ProtocolIE_IDE2_id_RANfunctionID:
8308                {
8309                   ranFuncId = ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
8310                   ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
8311                   if(!ranFuncDb)
8312                   {
8313                      DU_LOG("\nERROR  -->  E2AP : Invalid Ran Function id %d received",ranFuncId);
8314                      return;
8315                   }
8316
8317                   ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
8318                   if(!ricSubs)
8319                   {
8320                      DU_LOG("\nERROR  -->  E2AP : Ric subscription node is not present ");
8321                      return;
8322                   }
8323                   break;
8324                }
8325             case ProtocolIE_IDE2_id_RICactionsRemovedForModification_List:
8326                {
8327                   ProcessingRicSubsActionRemoved(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_RemovedForModification_List, ricSubs);
8328                   break;
8329                }
8330             case ProtocolIE_IDE2_id_RICactionsFailedToBeRemovedForModification_List:
8331                {
8332                   ProcessingRicSubsActionFailedToBeRemoved(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeRemovedForModification_List);
8333                   break;
8334                }
8335             case ProtocolIE_IDE2_id_RICactionsModifiedForModification_List:
8336                {
8337                   ProcessingRicSubsActionModified(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_ModifiedForModification_List);
8338                   break;
8339                }
8340             case ProtocolIE_IDE2_id_RICactionsFailedToBeModifiedForModification_List:
8341                {
8342                   ProcessingRicSubsActionFailedToBeModified(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeModifiedForModification_List);
8343                   break;
8344                }
8345             case ProtocolIE_IDE2_id_RICactionsAddedForModification_List:
8346                {
8347                   ProcessingRicSubsActionAdded(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_AddedForModification_List);
8348                   break;
8349                }
8350             case ProtocolIE_IDE2_id_RICactionsFailedToBeAddedForModification_List:
8351                {
8352                   ProcessingRicSubsActionFailedToBeAdded(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeAddedForModification_List, ricSubs);
8353                   break;
8354                }
8355             default:
8356                {
8357                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->id);
8358                   break;
8359                }
8360          }
8361       }
8362    }
8363 }
8364
8365 /*******************************************************************
8366 *
8367 * @brief Handles received E2AP message and sends back response  
8368 *
8369 * @details
8370 *
8371 *    Function : E2APMsgHdlr
8372 *
8373 *    Functionality:
8374 *         - Decodes received E2AP control message
8375 *         - Prepares response message, encodes and sends to SCTP
8376 *
8377 * @params[in] 
8378 * @return ROK     - success
8379 *         RFAILED - failure
8380 *
8381 * ****************************************************************/
8382 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
8383 {
8384    int             i;
8385    char            *recvBuf;
8386    MsgLen          copyCnt;
8387    MsgLen          recvBufLen;
8388    E2AP_PDU_t      *e2apMsg;
8389    asn_dec_rval_t  rval; /* Decoder return value */
8390    E2AP_PDU_t      e2apasnmsg ;
8391  
8392    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
8393    ODU_PRINT_MSG(mBuf, 0,0);
8394  
8395    /* Copy mBuf into char array to decode it */
8396    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
8397    RIC_ALLOC(recvBuf, (Size)recvBufLen);
8398
8399    if(recvBuf == NULLP)
8400    {
8401       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
8402       return;
8403    }
8404    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
8405    {
8406       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
8407       return;
8408    }
8409
8410    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
8411    for(i=0; i< recvBufLen; i++)
8412    {
8413         DU_LOG("%x",recvBuf[i]);
8414    }
8415
8416    /* Decoding flat buffer into E2AP messsage */
8417    e2apMsg = &e2apasnmsg;
8418    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
8419
8420    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
8421    RIC_FREE(recvBuf, (Size)recvBufLen);
8422
8423    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
8424    {
8425       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
8426       return;
8427    }
8428    DU_LOG("\n");
8429    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8430
8431    switch(e2apMsg->present)
8432    {
8433       case E2AP_PDU_PR_initiatingMessage:
8434          {
8435             switch(e2apMsg->choice.initiatingMessage->value.present)
8436             {
8437                case InitiatingMessageE2__value_PR_E2setupRequest:
8438                   {
8439                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
8440                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
8441                      break;
8442                   }
8443                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
8444                   {
8445                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
8446                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
8447                      break;
8448                   }
8449                case InitiatingMessageE2__value_PR_ResetRequestE2:
8450                   {
8451                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
8452                      ProcResetRequest(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
8453                      break;
8454                   }
8455                case InitiatingMessageE2__value_PR_RICindication:
8456                   {
8457                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
8458                      break;
8459                   }
8460                case InitiatingMessageE2__value_PR_RICserviceUpdate:
8461                   {
8462                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
8463                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
8464                      break;
8465                   }
8466                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
8467                   {
8468                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
8469                      ProcRicSubsModReqd(*duId, \
8470                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
8471                      break;
8472                   }
8473                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
8474                   {
8475                       DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
8476                       ProcRicSubsDeleteReqd(*duId, \
8477                          &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
8478                       break;
8479                   }
8480
8481                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
8482                   {
8483                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
8484                      break;
8485                   }
8486                case InitiatingMessageE2__value_PR_E2RemovalRequest:
8487                   {
8488                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
8489                      procE2RemovalRequest(*duId,\
8490                      &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest);
8491                      break;
8492                   }
8493                default:
8494                   {
8495                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
8496                         e2apMsg->choice.initiatingMessage->value.present);
8497                      return;
8498                   }
8499             }/* End of switch(initiatingMessage) */
8500             break;
8501          }
8502       case E2AP_PDU_PR_successfulOutcome: 
8503          {
8504             switch(e2apMsg->choice.successfulOutcome->value.present)
8505             {
8506                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
8507                   {
8508                      DU_LOG("\nINFO  -->  E2AP : Reset response received");
8509                      ProcResetResponse(*duId,  &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2);
8510                      break;
8511                   }
8512                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
8513                   {
8514                      ProcRicSubscriptionResponse(*duId, \
8515                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
8516                      break;
8517                   }
8518                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
8519                   {
8520                      ProcE2RemovalResponse(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse);
8521                      break;
8522                   }
8523                case SuccessfulOutcomeE2__value_PR_E2connectionUpdateAcknowledge:
8524                   {
8525                      ProcE2ConnectionUpdateAck(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge);
8526                      break;
8527                   }
8528                case SuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteResponse:
8529                   {
8530                      ProcRicSubsDeleteRsp(*duId, &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse);
8531                      break;
8532                   }
8533                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationResponse:
8534                   {
8535                      ProcRicSubsModificationRsp(*duId, &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationResponse);
8536                      break;
8537                   }
8538                default:
8539                   {
8540                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
8541                         e2apMsg->choice.successfulOutcome->value.present);
8542                      return;
8543                   }
8544                   break;
8545             }
8546             break; 
8547          }
8548          case E2AP_PDU_PR_unsuccessfulOutcome:
8549          {
8550             switch(e2apMsg->choice.successfulOutcome->value.present)
8551             {
8552                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
8553                   {
8554                      ProcRicSubscriptionFailure(*duId, \
8555                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
8556                      break;
8557                   }
8558                case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
8559                   {
8560                      ProcE2RemovalFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure);
8561                      break;
8562                   }
8563                case UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure:
8564                   {
8565                      ProcE2connectionUpdateFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure);
8566                      break;
8567                   }
8568                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteFailure:
8569                   {
8570                      ProcRicSubsDeleteFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure);
8571                      break;
8572                   }
8573                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationFailure:
8574                   {
8575                      ProcRicSubsModificationFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationFailure);
8576                      break;
8577                   }
8578                default:
8579                   {
8580                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
8581                         e2apMsg->choice.unsuccessfulOutcome->value.present);
8582                      return;
8583                   }
8584             }
8585             break;
8586          }
8587       default:
8588          {
8589             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
8590             return;
8591          }
8592
8593    }/* End of switch(e2apMsg->present) */
8594 } /* End of E2APMsgHdlr */
8595
8596
8597 /**********************************************************************
8598   End of file
8599  **********************************************************************/