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