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