[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-530] RIC Subscription Modification Response
[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       cmLListDelFrm(&ricSubsDb->actionSequence, actionNode);
2000       deleteActionSequence(actionNode);
2001    }
2002    return RFAILED;
2003 }
2004
2005 /*******************************************************************
2006  *
2007  * @brief Free Event Trigger Definition
2008  *
2009  * @details
2010  *
2011  *    Function : FreeEventTriggerDef
2012  *
2013  *    Functionality: Free Event Trigger Definition
2014  *
2015  * @params[in] E2SM-KPM Event Trigger Definition
2016  * @return void
2017  *
2018  * ****************************************************************/
2019 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
2020 {
2021    if(eventTiggerDef)
2022    {
2023       switch(eventTiggerDef->eventDefinition_formats.present)
2024       {
2025          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
2026             break;
2027          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
2028             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
2029                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
2030             break;                  
2031       }         
2032    }
2033 }
2034
2035 /*******************************************************************
2036  *
2037  * @brief Fill Event Trigger Definition
2038  *
2039  * @details
2040  *
2041  *    Function : fillEventTriggerDef
2042  *
2043  *    Functionality: Fill Event Trigger Definition
2044  *
2045  * @params[in] RIC Event Trigger Definition
2046  * @return ROK
2047  *         RFAILED
2048  *
2049  * ****************************************************************/
2050 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
2051 {
2052    uint8_t ret = RFAILED;
2053    asn_enc_rval_t  encRetVal;
2054    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
2055
2056    while(true)
2057    {
2058       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
2059       eventTiggerDef.eventDefinition_formats.present = \
2060        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
2061
2062       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
2063             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
2064       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
2065       {
2066          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2067          break;
2068       }
2069
2070       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
2071
2072       /* Prints the Msg formed */
2073       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
2074
2075       /* Encode E2SM-KPM Event Trigger Definition */
2076       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2077       encBufSize = 0;
2078       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
2079       if(encRetVal.encoded == ENCODE_FAIL)
2080       {
2081          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
2082                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2083          break;
2084       }
2085
2086       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
2087       ricEventTriggerDef->size = encBufSize;
2088       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
2089       if(ricEventTriggerDef->buf == NULLP)
2090       {
2091          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2092          break;
2093       }
2094       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
2095
2096       ret = ROK;
2097       break;
2098    }
2099
2100    FreeEventTriggerDef(&eventTiggerDef);
2101    return ret;
2102 }
2103
2104 /*******************************************************************
2105  *
2106  * @brief builds RIC Subscription Details
2107  *
2108  * @details
2109  *
2110  *    Function : BuildsRicSubsDetails
2111  *
2112  *    Functionality: Builds the RIC Subscription Details
2113  *
2114  * @params[in] RIC Subscription details to be filled
2115  *             RIC subscriotion DB
2116  * @return ROK     - success
2117  *         RFAILED - failure
2118  *
2119  * ****************************************************************/
2120
2121 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsInfo)
2122 {
2123    uint8_t elementCnt = 0;
2124    uint8_t elementIdx = 0;
2125
2126    if(subsDetails == NULLP)
2127    {
2128       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
2129       return RFAILED;
2130    }
2131
2132    while(true)
2133    {
2134       /* RIC Event Trigger Definition */
2135       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
2136       {
2137          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
2138          break;
2139       }
2140
2141       /* RIC Actions To Be Setup List */
2142       elementCnt = 1;
2143       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
2144       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
2145       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
2146       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
2147       {
2148          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
2149          break;
2150       } 
2151
2152       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
2153       {
2154          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
2155          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
2156          {
2157             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2158             break;
2159          }
2160       }
2161       if(elementIdx < elementCnt)
2162          break;
2163
2164
2165       elementIdx = 0;
2166       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
2167          ricSubsInfo) != ROK)
2168       {
2169          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
2170          break;
2171       }
2172
2173       return ROK;
2174    }
2175    return RFAILED;
2176 }
2177
2178 /*******************************************************************
2179  *
2180  * @brief Builds and Send the RicSubscriptionReq
2181  *
2182  * @details
2183  *
2184  *    Function : BuildAndSendRicSubscriptionReq
2185  *
2186  * Functionality:Fills the RicSubscriptionReq
2187  *
2188  * @return ROK     - success
2189  *         RFAILED - failure
2190  *
2191  ******************************************************************/
2192 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
2193 {
2194    uint8_t         ret = RFAILED;
2195    uint8_t         elementCnt = 0;
2196    uint8_t         idx = 0;
2197    uint8_t         actionIdx = 0;
2198    asn_enc_rval_t  encRetVal;        /* Encoder return value */
2199    E2AP_PDU_t                 *e2apRicMsg = NULL;
2200    RICsubscriptionRequest_t   *ricSubscriptionReq;
2201    RanFunction  *ranFuncDb = &duDb->ranFunction[0];
2202    CmLList *ricSubsNode = NULLP;
2203    RicSubscription *ricSubsInfo = NULLP;
2204
2205    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
2206
2207    /* Allocate memory to store RIC subscription info in RIC DB */
2208    RIC_ALLOC(ricSubsInfo, sizeof(RicSubscription));
2209    if(!ricSubsInfo)
2210    {
2211       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2212       return RFAILED;
2213    }
2214
2215    while(true)
2216    {
2217       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
2218       if(e2apRicMsg == NULLP)
2219       {
2220          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2221          break;
2222       }
2223
2224       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
2225       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2226       if(e2apRicMsg->choice.initiatingMessage == NULLP)
2227       {
2228          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2229          break;
2230       }
2231       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
2232       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2233       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
2234
2235       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
2236
2237       elementCnt = 3;
2238       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
2239       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
2240
2241       /* Initialize the subscription members */
2242       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
2243       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
2244       {
2245          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2246          break;
2247       }
2248
2249       for(idx=0; idx<elementCnt; idx++)
2250       {
2251          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
2252          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
2253          {
2254             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2255             break;
2256          }
2257       }
2258       if(idx < elementCnt)
2259          break;
2260
2261       /* Filling RIC Request Id */
2262       idx = 0;
2263       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
2264       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2265       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2266                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
2267       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
2268          &ricSubsInfo->requestId) != ROK)
2269       {
2270          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
2271          break;
2272       }
2273
2274
2275       /* Filling RAN Function Id */
2276       idx++;
2277       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
2278       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2279       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2280                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
2281       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
2282       ricSubsInfo->ranFuncId = ranFuncDb->id;
2283
2284       /* Filling RIC Subscription Details */
2285       idx++;
2286       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
2287       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2288       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2289                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
2290       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
2291          ricSubsInfo) != ROK)
2292       {
2293          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
2294          break;
2295       }
2296
2297       /* Prints the Msg formed */
2298       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
2299
2300       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2301       encBufSize = 0;
2302       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
2303       if(encRetVal.encoded == ENCODE_FAIL)
2304       {
2305          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
2306                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2307          break;               
2308       }
2309       else
2310       {
2311          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
2312          for(int i=0; i< encBufSize; i++)
2313          {
2314             DU_LOG("%x",encBuf[i]);
2315          } 
2316       }
2317
2318       /* Sending msg */
2319       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2320       {
2321          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
2322          break;
2323       }
2324
2325       /* Add RIC Subscription Info to RAN Function's RIC Subscription List */
2326       RIC_ALLOC(ricSubsNode , sizeof(CmLList));
2327       if(!ricSubsNode)
2328       {
2329          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2330          break;
2331       }
2332       ricSubsNode->node = (PTR)ricSubsInfo;
2333       cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubsNode);
2334
2335       ret = ROK;
2336       break;
2337    }
2338
2339    if(ret == RFAILED)
2340    {
2341       RIC_FREE(ricSubsInfo, sizeof(RicSubscription));
2342       RIC_FREE(ricSubsNode , sizeof(CmLList));
2343    }
2344
2345    FreeRicSubscriptionReq(e2apRicMsg);
2346    return ret;
2347 }
2348
2349 /*******************************************************************
2350  *
2351  * @brief Process RicSubscriptionResponse
2352  *
2353  * @details
2354  *
2355  *    Function : ProcRicSubscriptionRsp
2356  *
2357  * Functionality: Processes RicSubscriptionRsp
2358  *
2359  * @return ROK     - void
2360  *
2361  ******************************************************************/
2362
2363 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
2364 {
2365    uint8_t duIdx = 0, ieIdx = 0, notAdmitIdx = 0;
2366    uint8_t ranFuncId = 0, actionId = 0;
2367    DuDb *duDb = NULLP;
2368    bool ricReqIdDecoded = false;
2369    RicRequestId ricReqId;
2370    RanFunction  *ranFuncDb = NULLP;
2371    RicSubscription *ricSubs = NULLP;
2372    CmLList *ricSubsNode = NULLP;
2373    CmLList *actionNode = NULLP;
2374    ActionInfo *action = NULLP;
2375    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
2376    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
2377
2378    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
2379
2380    /* Fetch DU DB */
2381    SEARCH_DU_DB(duIdx, duId, duDb);
2382    if(duDb == NULLP)
2383    {
2384       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2385       return;
2386    }
2387
2388    memset(&ricReqId, 0, sizeof(RicRequestId));
2389    if(ricSubscriptionRsp)
2390    {
2391       if(ricSubscriptionRsp->protocolIEs.list.array)
2392       {
2393          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
2394          {
2395             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
2396             {
2397                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2398                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
2399                {
2400                   case ProtocolIE_IDE2_id_RICrequestID:
2401                      {
2402                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
2403                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
2404                         ricReqIdDecoded = true;
2405                         break;
2406                      }
2407                   case ProtocolIE_IDE2_id_RANfunctionID:
2408                      {
2409                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
2410                         ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
2411                         if(!ranFuncDb)
2412                         {
2413                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
2414                            return;
2415                         }
2416                         break; 
2417                      }
2418                   case ProtocolIE_IDE2_id_RICactions_Admitted:
2419                      {
2420                         break;
2421                      }
2422                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
2423                      {
2424                         if(!(ranFuncDb && ricReqIdDecoded))
2425                            return;
2426
2427                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
2428                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
2429                         {
2430                            actionNode=NULLP;
2431                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
2432                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
2433
2434                            /* Remove action from RAN Function's subscription list */
2435                            ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
2436                            if(ricSubs)
2437                            {
2438                               action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
2439                               if(action)
2440                               {
2441                                  cmLListDelFrm(&ricSubs->actionSequence, actionNode);
2442                                  deleteActionSequence(actionNode);
2443                               }
2444                            }
2445                         }
2446                         break;
2447                      }
2448                }
2449             }
2450          }
2451       }
2452    } 
2453 }
2454
2455 /*******************************************************************
2456  *
2457  * @brief deallocate the memory allocated in E2SetupFailure
2458  *
2459  * @details
2460  *
2461  *    Function : FreeE2SetupFailure 
2462  *
2463  *    Functionality: deallocate the memory allocated in E2SetupFailure 
2464  *
2465  * @params[in] E2AP_PDU_t *e2apMsg
2466  *
2467  * @return void
2468  * ****************************************************************/
2469 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
2470 {
2471    uint8_t arrIdx = 0;
2472    E2setupFailure_t  *e2SetupFail;
2473
2474    if(e2apMsg)
2475    {
2476       if(e2apMsg->choice.unsuccessfulOutcome)
2477       {
2478          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2479          if(e2SetupFail->protocolIEs.list.array)
2480          {
2481             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
2482             {
2483                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
2484             }
2485             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
2486          }
2487          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2488       }
2489       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2490    }
2491 }
2492
2493 /*******************************************************************
2494  *
2495  * @brief Buld and send the E2 Setup failure
2496  *
2497  * @details
2498  *
2499  *    Function : BuildAndSendE2SetupFailure
2500  *
2501  *    Functionality:
2502  *         - Buld and send the E2 Setup failure
2503  * @return ROK     - success
2504  *         RFAILED - failure
2505  *
2506  * ****************************************************************/
2507
2508 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
2509 {
2510    uint8_t            ret = RFAILED;
2511    E2AP_PDU_t         *e2apMsg = NULL;
2512    E2setupFailure_t   *e2SetupFailure;
2513    asn_enc_rval_t     encRetVal;
2514    uint8_t            arrIdx;
2515    uint8_t            elementCnt;
2516    bool  memAllocFailed = false;
2517
2518    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
2519    while(true)
2520    {
2521       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2522       if(e2apMsg == NULLP)
2523       {
2524          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2525          break;
2526       }
2527       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2528       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2529       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2530       {
2531          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2532          break;
2533       }
2534
2535       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
2536       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2537       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
2538       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2539
2540       elementCnt = 3;
2541       e2SetupFailure->protocolIEs.list.count = elementCnt;
2542       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
2543
2544       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
2545       if(e2SetupFailure->protocolIEs.list.array == NULLP)
2546       {
2547          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2548          break;
2549       }
2550
2551       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2552       {
2553          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
2554          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
2555          {
2556             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2557             memAllocFailed = true;
2558             break;
2559          }
2560       }
2561
2562       if(memAllocFailed == true)
2563       {
2564           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2565           break;
2566       }
2567
2568       /* Trans Id */
2569       arrIdx = 0;
2570       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2571       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2572       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
2573       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2574
2575       arrIdx++;
2576       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2577       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2578       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
2579       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
2580       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
2581
2582       arrIdx++;
2583       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2584       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2585       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
2586       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2587
2588       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2589       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2590       encBufSize = 0;
2591       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2592
2593       /* Check encode results */
2594       if(encRetVal.encoded == ENCODE_FAIL)
2595       {
2596          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
2597                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2598          break;
2599       }
2600       else
2601       {
2602          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
2603          for(int i=0; i< encBufSize; i++)
2604          {
2605             DU_LOG("%x",encBuf[i]);
2606          }
2607       }
2608
2609       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2610       {
2611          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
2612          break;
2613       }
2614
2615       ret = ROK;
2616       break;
2617    }
2618
2619    FreeE2SetupFailure(e2apMsg);
2620    return ret;
2621 }
2622
2623 /*******************************************************************
2624  *
2625  * @brief process the e2setup request 
2626  *
2627  * @details
2628  *
2629  *    Function : ProcE2SetupReq
2630  *
2631  * Functionality: process the e2setup request
2632  *
2633  * @return void
2634  *
2635  ******************************************************************/
2636
2637 void ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
2638 {
2639    uint8_t arrIdx = 0, duIdx = 0, transId =0;
2640    uint16_t ranFuncIdx=0, e2NodeAddListIdx =0;
2641    E2NodeConfigList tmpE2NodeList;
2642    DuDb    *duDb = NULLP;
2643    bool ieProcessingFailed = false;
2644    E2nodeComponentConfigAddition_List_t *e2NodeAddList=NULLP;
2645    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem=NULLP;
2646    RANfunction_ItemIEs_t *ranFuncItemIe=NULLP;
2647    RANfunction_Item_t  *ranFunItem=NULLP;
2648    RANfunctions_List_t *ranFunctionsList=NULLP;
2649
2650    memset(&tmpE2NodeList, 0, sizeof(E2NodeConfigList));
2651    if(!e2SetupReq)
2652    {
2653       DU_LOG("\nERROR  -->  E2AP : e2SetupReq pointer is null");
2654       return;
2655    }
2656    if(!e2SetupReq->protocolIEs.list.array)
2657    {
2658       DU_LOG("\nERROR  -->  E2AP : e2SetupReq array pointer is null");
2659       return;
2660    }
2661
2662    for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
2663    {
2664       if(e2SetupReq->protocolIEs.list.array[arrIdx])
2665       {
2666          switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
2667          {
2668             case ProtocolIE_IDE2_id_TransactionID:
2669                {
2670                   transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
2671                   break;
2672                }
2673             case ProtocolIE_IDE2_id_GlobalE2node_ID:
2674                {
2675                   if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
2676                   {
2677                      *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
2678
2679                      SEARCH_DU_DB(duIdx, *duId, duDb); 
2680                      if(duDb == NULLP)
2681                      {
2682                         duDb = &ricCb.duInfo[ricCb.numDu];
2683                         ricCb.numDu++;
2684                      }
2685                      memset(duDb, 0, sizeof(DuDb));
2686                      duDb->duId = *duId;
2687                   }
2688                   break;
2689                }
2690             case ProtocolIE_IDE2_id_RANfunctionsAdded:
2691                {
2692                   ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2693
2694                   if(ranFunctionsList->list.array)
2695                   {
2696                      for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
2697                      {
2698                         ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
2699                         ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2700                         duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
2701                         duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
2702                         cmLListInit(&duDb->ranFunction[ranFunItem->ranFunctionID-1].subscriptionList);
2703                         duDb->numOfRanFunction++;
2704                      }
2705                   }
2706                   break;
2707                }
2708             case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
2709                {
2710                   e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
2711                   if(e2NodeAddList->list.array)
2712                   {
2713                      for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
2714                      {
2715                         if(e2NodeAddList->list.array[e2NodeAddListIdx])
2716                         {
2717                            /* Storing the E2 node information in DB */
2718                            e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
2719                            if(handleE2NodeComponentAction(duDb, (PTR)&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item,\
2720                                     ProtocolIE_IDE2_id_E2nodeComponentConfigAddition, &tmpE2NodeList.addedE2Node[tmpE2NodeList.addedE2NodeCount++]) != ROK)
2721                            {
2722                               DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",e2NodeAddListIdx);
2723                            }
2724
2725                         }
2726                      }
2727                   }
2728                   break;
2729                }
2730             default:
2731                break;
2732          }
2733       }
2734    }
2735    
2736    if(BuildAndSendE2SetupRsp(duDb, transId, tmpE2NodeList) !=ROK)
2737    {
2738       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
2739    }
2740 }
2741 /*******************************************************************
2742  *
2743  * @brief Deallocate the memory allocated for E2 Reset Response
2744  *
2745  * @details
2746  *
2747  *    Function : FreeE2ResetResponse
2748  *
2749  *    Functionality:
2750  *       - freeing the memory allocated for E2ResetResponse
2751  *
2752  * @params[in] E2AP_PDU_t *e2apMsg
2753  * @return ROK     - success
2754  *         RFAILED - failure
2755  *
2756  * ****************************************************************/
2757 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
2758 {
2759    uint8_t ieIdx =0;
2760    ResetResponseE2_t *resetResponse =NULLP;
2761
2762    if(e2apMsg != NULLP)
2763    {
2764       if(e2apMsg->choice.successfulOutcome != NULLP)
2765       {
2766          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2767          if(resetResponse->protocolIEs.list.array)
2768          {
2769             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2770             {
2771                if(resetResponse->protocolIEs.list.array[ieIdx])
2772                {
2773                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2774                }
2775             }
2776             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2777          }
2778          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2779       }
2780       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2781    }
2782 }
2783
2784 /*******************************************************************
2785  *
2786  * @brief Buld and send the Reset Response msg
2787  *
2788  * @details
2789  *
2790  *    Function : BuildAndSendResetResponse 
2791  *
2792  *    Functionality:
2793  *         - Buld and send the Reset Response Message
2794  *
2795  * @params[in] 
2796  *    DU id
2797  *    TransId Id
2798  * @return ROK     - success
2799  *         RFAILED - failure
2800  *
2801  * ****************************************************************/
2802 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
2803 {
2804    uint8_t           ieIdx = 0, elementCnt = 0;
2805    uint8_t           ret = RFAILED;
2806    E2AP_PDU_t        *e2apMsg = NULLP;
2807    ResetResponseE2_t *resetResponse=NULL;
2808    asn_enc_rval_t    encRetVal;       /* Encoder return value */
2809
2810    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
2811    do
2812    {
2813       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2814       if(e2apMsg == NULLP)
2815       {
2816          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
2817          break;
2818       }
2819       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
2820
2821       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2822       if(e2apMsg->choice.successfulOutcome == NULLP)
2823       {
2824          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
2825          break;
2826       }
2827  
2828       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
2829       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2830       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
2831       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2832
2833       elementCnt = 1;
2834       resetResponse->protocolIEs.list.count = elementCnt;
2835       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
2836       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2837       if(!resetResponse->protocolIEs.list.array)
2838       {
2839          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
2840          break;
2841       }
2842
2843       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
2844       {
2845          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2846          if(!resetResponse->protocolIEs.list.array[ieIdx])
2847          {
2848             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
2849             break;
2850          }
2851       }
2852       if(ieIdx < elementCnt)
2853          break;
2854
2855       ieIdx = 0; 
2856       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
2857       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2858       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
2859       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2860
2861       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2862
2863       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2864       encBufSize = 0;
2865       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2866       if(encRetVal.encoded == ENCODE_FAIL)
2867       {
2868          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
2869                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2870          break;
2871       }
2872       else
2873       {
2874          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
2875          for(int i=0; i< encBufSize; i++)
2876          {
2877             DU_LOG("%x",encBuf[i]);
2878          }
2879       }
2880
2881       /* Sending msg */
2882       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2883       {
2884          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
2885          break;
2886       }
2887
2888       ret = ROK;
2889       break;
2890    }while(true);
2891
2892    FreeE2ResetResponse(e2apMsg);
2893    return ret;
2894 }
2895
2896 /*******************************************************************
2897  *
2898  * @brief deallocate the memory allocated in building the
2899  *    Service Query message
2900  *
2901  * @details
2902  *
2903  *    Function : FreeRicServiceQuery 
2904  *
2905  *    Functionality: deallocate the memory allocated in building
2906  *    Ric Service Query message
2907  *
2908  * @params[in] E2AP_PDU_t *e2apMsg
2909  *
2910  * @return void
2911  * ****************************************************************/
2912
2913 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2914 {
2915    uint8_t arrIdx = 0, ranFuncIdx=0;
2916    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2917    RICserviceQuery_t *ricServiceQuery=NULL;
2918    
2919    if(e2apMsg)
2920    {
2921       if(e2apMsg->choice.initiatingMessage)
2922       {
2923          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2924          if(ricServiceQuery->protocolIEs.list.array)
2925          {
2926             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2927             {
2928                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2929                {
2930                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2931                   {
2932                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2933                         {
2934                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2935                            if(ranFuncAcceptedList->list.array)
2936                            {
2937                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2938                               {
2939                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2940                               }
2941                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2942                            }
2943                            break;
2944                         }
2945                      case RICserviceQuery_IEs__value_PR_TransactionID:
2946                         {
2947                            break;
2948                         }
2949                   }
2950                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2951                }
2952             }
2953             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2954          }
2955          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2956       }
2957       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2958    }
2959 }
2960
2961 /*******************************************************************
2962  *
2963  * @brief build and send the ric service Query 
2964  *
2965  * @details
2966  *
2967  *    Function : BuildAndSendRicServiceQuery
2968  *
2969  * Functionality: build and send the ric service Query 
2970  * @return ROK     - success
2971  *         RFAILED - Acknowledge
2972  *
2973  ******************************************************************/
2974
2975 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2976 {
2977    uint8_t arrIdx;
2978    uint8_t elementCnt;
2979    uint8_t ret = RFAILED;
2980    bool  memAllocFailed = false;
2981    E2AP_PDU_t     *e2apMsg = NULL;
2982    asn_enc_rval_t encRetVal;
2983    RICserviceQuery_t *ricServiceQuery;
2984
2985    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2986    while(true)
2987    {
2988       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2989       if(e2apMsg == NULLP)
2990       {
2991          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2992          break;
2993       }
2994       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2995       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2996       if(e2apMsg->choice.initiatingMessage == NULLP)
2997       {
2998          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2999          break;
3000       }
3001
3002       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
3003       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
3004       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
3005       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
3006
3007       elementCnt = 1;
3008       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
3009       if(duDb->numOfRanFunction)
3010          elementCnt++;
3011
3012       ricServiceQuery->protocolIEs.list.count = elementCnt;
3013       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
3014
3015       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
3016       if(ricServiceQuery->protocolIEs.list.array == NULLP)
3017       {
3018          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
3019          break;
3020       }
3021
3022       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3023       {
3024          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
3025          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
3026          {
3027             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
3028             memAllocFailed = true;
3029             break;
3030          }
3031       }
3032       if(memAllocFailed == true)
3033       {
3034          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
3035          break;
3036       }
3037
3038       /* Trans Id */
3039       arrIdx = 0;
3040       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3041       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3042       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
3043       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
3044       
3045       if(duDb->numOfRanFunction)
3046       {
3047          /* Accepted RAN function Id */
3048          arrIdx++;
3049          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
3050          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3051          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
3052          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
3053          {
3054             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
3055             break;         
3056          }
3057       }
3058       
3059       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3060       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3061       encBufSize = 0;
3062       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3063
3064       /* Check encode results */
3065       if(encRetVal.encoded == ENCODE_FAIL)
3066       {
3067          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
3068                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3069          break;
3070       }
3071       else
3072       {
3073          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
3074          for(int i=0; i< encBufSize; i++)
3075          {
3076             DU_LOG("%x",encBuf[i]);
3077          }
3078       }
3079
3080       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
3081       {
3082          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
3083          break;
3084       }
3085
3086       ret =ROK;
3087       break;
3088    }
3089    FreeRicServiceQuery(e2apMsg);
3090    return ret;
3091 }
3092
3093 /*******************************************************************
3094  *
3095  * @brief deallocate the memory allocated in RicServiceUpdateFailure
3096  *
3097  * @details
3098  *
3099  *    Function : FreeRicServiceUpdateFailure 
3100  *
3101  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
3102  *
3103  * @params[in] E2AP_PDU_t *e2apMsg
3104  *
3105  * @return void
3106  * ****************************************************************/
3107
3108 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
3109 {
3110    uint8_t arrIdx = 0;
3111    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
3112    
3113    if(e2apMsg)
3114    {
3115       if(e2apMsg->choice.unsuccessfulOutcome)
3116       {
3117          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
3118          if(ricServiceUpdateFailure->protocolIEs.list.array)
3119          {
3120             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
3121             {
3122                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
3123             }
3124             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
3125          }
3126          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
3127       }
3128       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3129    }
3130 }
3131
3132 /*******************************************************************
3133  *
3134  * @brief build and send the ric service update failure 
3135  *
3136  * @details
3137  *
3138  *    Function : BuildAndSendRicServiceUpdateFailure
3139  *
3140  * Functionality: build and send the ric service update failure 
3141  * @return ROK     - success
3142  *         RFAILED - failure
3143  *
3144  ******************************************************************/
3145
3146 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
3147 {
3148
3149    E2AP_PDU_t         *e2apMsg = NULL;
3150    asn_enc_rval_t     encRetVal;
3151    uint8_t            ret = RFAILED;
3152    uint8_t            arrIdx=0;
3153    uint8_t            elementCnt=0;
3154    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
3155
3156    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
3157    while(true)
3158    {
3159       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3160       if(e2apMsg == NULLP)
3161       {
3162          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3163          break;
3164       }
3165       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3166       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
3167       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3168       {
3169          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3170          break;
3171       }
3172
3173       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3174       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3175       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
3176       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
3177
3178       elementCnt = 3;
3179       ricServiceFailure->protocolIEs.list.count = elementCnt;
3180       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
3181
3182       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
3183       if(ricServiceFailure->protocolIEs.list.array == NULLP)
3184       {
3185          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
3186          break;
3187       }
3188
3189       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3190       {
3191          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
3192          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
3193          {
3194             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
3195             break;
3196          }
3197       }
3198       if(arrIdx<elementCnt)
3199       {
3200          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
3201          break;
3202       }
3203
3204       /* Trans Id */
3205       arrIdx = 0;
3206       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3207       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3208       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
3209       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
3210
3211       arrIdx++;
3212       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
3213       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3214       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
3215       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
3216
3217       arrIdx++;
3218       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
3219       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
3220       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
3221       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
3222
3223       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3224       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3225       encBufSize = 0;
3226       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3227
3228       /* Check encode results */
3229       if(encRetVal.encoded == ENCODE_FAIL)
3230       {
3231          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
3232                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3233          break;
3234       }
3235       else
3236       {
3237          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
3238          for(int i=0; i< encBufSize; i++)
3239          {
3240             DU_LOG("%x",encBuf[i]);
3241          }
3242       }
3243
3244       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3245       {
3246          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
3247          break;
3248       }
3249       ret = ROK;
3250       break;
3251    }
3252
3253    FreeRicServiceUpdateFailure(e2apMsg);
3254    return ret;
3255 }
3256
3257
3258 /*******************************************************************
3259  *
3260  * @brief deallocate the memory allocated in RicServiceUpdateAck(
3261  *
3262  * @details
3263  *
3264  *    Function : FreeRicServiceUpdateAck 
3265  *
3266  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
3267  *
3268  * @params[in] E2AP_PDU_t *e2apMsg
3269  *
3270  * @return void
3271  * ****************************************************************/
3272
3273 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
3274 {
3275    uint8_t arrIdx = 0, ranFuncIdx=0;
3276    RANfunctionsID_List_t *acceptedList=NULL;
3277    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
3278    RANfunctionsIDcause_List_t  *rejectedList=NULL;
3279
3280    if(e2apMsg)
3281    {
3282       if(e2apMsg->choice.successfulOutcome)
3283       {
3284          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3285          if(ricServiceUpdateAck->protocolIEs.list.array)
3286          {
3287             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
3288             {
3289                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
3290                {
3291                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
3292                   {
3293                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3294                         {
3295                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3296                            if(acceptedList->list.array)
3297                            {
3298                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
3299                               {
3300                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
3301                               }
3302                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
3303                            }
3304                            break;
3305                         }
3306
3307                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
3308                         {
3309                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
3310                            if(rejectedList->list.array)
3311                            {
3312                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
3313                               {
3314                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
3315                               }
3316                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
3317                            }
3318                            break;
3319                         }
3320                   }
3321                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
3322                }
3323             }
3324             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
3325          }
3326          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
3327       }
3328       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3329    }
3330 }
3331
3332 /*******************************************************************
3333  *
3334  * @brief Build RAN function rejected list
3335  *
3336  * @details
3337  *
3338  *    Function : BuildRanFunctionRejectedList
3339  *
3340  *    Functionality: Build RAN function rejected list 
3341  *
3342  * @params[in] 
3343  *    Count of ran functions to be rejected in the list 
3344  *    Received list of RAN functions
3345  *
3346  * @return ROK - success
3347  *         RFAILED - failure
3348  * ****************************************************************/
3349
3350 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
3351 {
3352    uint8_t ranFuncIdx = 0;
3353    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
3354    
3355    ranFuncRejectedList->list.count = count;
3356    
3357    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
3358    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
3359    if(ranFuncRejectedList->list.array == NULLP)
3360    {
3361       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
3362       return RFAILED;
3363    }
3364    
3365    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
3366    {
3367       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
3368       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
3369       {
3370          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
3371          return RFAILED;
3372       }
3373       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
3374       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
3375       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
3376       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
3377       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
3378       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
3379             CauseE2RICservice_ran_function_not_supported);
3380    }
3381    
3382    return ROK;
3383 }
3384
3385 /*******************************************************************
3386  *
3387  * @brief build and send the ric service update Acknowledge 
3388  *
3389  * @details
3390  *
3391  *    Function : BuildAndSendRicServiceUpdateAcknowledge
3392  *
3393  * Functionality: build and send the ric service update Acknowledge 
3394  * @return ROK     - success
3395  *         RFAILED - Acknowledge
3396  *
3397  ******************************************************************/
3398
3399 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
3400 {
3401    E2AP_PDU_t         *e2apMsg = NULL;
3402    asn_enc_rval_t     encRetVal;
3403    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
3404    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
3405
3406    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
3407    while(true)
3408    {
3409       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3410       if(e2apMsg == NULLP)
3411       {
3412          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3413          break;
3414       }
3415       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
3416       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
3417       if(e2apMsg->choice.successfulOutcome == NULLP)
3418       {
3419          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3420          break;
3421       }
3422
3423       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3424       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
3425       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
3426       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3427
3428       elementCnt = 1;
3429       if(ricRanFuncList.numOfRanFunAccepted)
3430          elementCnt++;
3431       if(ricRanFuncList.numOfRanFuneRejected)
3432          elementCnt++;
3433       
3434
3435       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
3436       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
3437
3438       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
3439       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
3440       {
3441          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3442          break;
3443       }
3444
3445       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3446       {
3447          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
3448          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
3449          {
3450             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3451             break;
3452          }
3453       }
3454       if(arrIdx<elementCnt)
3455       {
3456          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3457          break;
3458       }
3459
3460       /* Trans Id */
3461       arrIdx = 0;
3462       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3463       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3464       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
3465       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
3466
3467       if(ricRanFuncList.numOfRanFunAccepted)
3468       {
3469          /* Accepted RAN function List */
3470          arrIdx++;
3471          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
3472          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3473          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
3474          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
3475          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
3476          {
3477             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
3478             break;         
3479          }
3480       }
3481       
3482       if(ricRanFuncList.numOfRanFuneRejected)
3483       {
3484          /* RAN Functions Rejected List */
3485          arrIdx++;
3486          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
3487          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3488          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
3489          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
3490          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
3491          {
3492             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
3493             break;         
3494          }
3495       }
3496       
3497       
3498       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3499       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3500       encBufSize = 0;
3501       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3502
3503       /* Check encode results */
3504       if(encRetVal.encoded == ENCODE_FAIL)
3505       {
3506          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
3507                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3508          break;
3509       }
3510       else
3511       {
3512          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
3513          for(int i=0; i< encBufSize; i++)
3514          {
3515             DU_LOG("%x",encBuf[i]);
3516          }
3517       }
3518
3519       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
3520       {
3521          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
3522          break;
3523       }
3524       ret =ROK;
3525       break;
3526    }
3527    FreeRicServiceUpdateAck(e2apMsg);
3528    return ret; 
3529 }
3530
3531 /*******************************************************************
3532  *
3533  * @brief process the RIC service update 
3534  *
3535  * @details
3536  *
3537  *    Function : ProcRicserviceUpdate 
3538  *
3539  * Functionality: process the RIC service update 
3540  *
3541  * @return ROK     - success
3542  *         RFAILED - failure
3543  *
3544  ******************************************************************/
3545
3546 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
3547 {
3548    RicTmpRanFunList ricRanFuncList;
3549    DuDb    *duDb = NULLP;
3550    int8_t transId =-1;
3551    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
3552    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
3553    RanFunction *ranFuncDb = NULLP;
3554    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
3555    RANfunction_Item_t  *ranFuncItem =NULL;
3556    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
3557    RANfunctions_List_t *ranFuncList=NULL;
3558    RANfunctionsID_List_t *deleteList=NULL;
3559    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
3560
3561    SEARCH_DU_DB(duIdx, duId, duDb); 
3562    if(duDb == NULLP)
3563    {
3564       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3565       return;
3566    }
3567    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
3568
3569    if(!ricServiceUpdate)
3570    {
3571       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
3572       return;
3573    }
3574
3575    if(!ricServiceUpdate->protocolIEs.list.array)      
3576    {
3577       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
3578       return;
3579    }
3580    elementCnt = ricServiceUpdate->protocolIEs.list.count;
3581    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
3582    {
3583       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
3584       {
3585          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
3586          return;
3587       }
3588
3589       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
3590       {
3591          case ProtocolIE_IDE2_id_TransactionID:
3592             {
3593                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3594
3595                if(transId < 0 || transId > 255)
3596                {
3597                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
3598                   return;
3599                }
3600                break;
3601             }
3602
3603          case ProtocolIE_IDE2_id_RANfunctionsAdded:
3604             {
3605                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
3606
3607                if(ranFuncList->list.array)
3608                {
3609                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
3610                   {
3611                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
3612                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3613
3614                      /* Adding the ran function in temporary list */
3615                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
3616                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
3617                      ricRanFuncList.numOfRanFunAccepted++;
3618
3619                      /* Adding the new ran function in DB*/
3620                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
3621                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
3622                      duDb->numOfRanFunction++;
3623
3624                      /* Calculating total number of ran fuctions which are received for addition */
3625                      recvdRanFuncCount++;
3626                   }
3627                }
3628                break;
3629             }
3630
3631          case ProtocolIE_IDE2_id_RANfunctionsModified:
3632             {
3633
3634                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
3635                if(ranFuncList->list.array)
3636                {
3637                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
3638                   {
3639                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
3640                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3641                      if(fetchRanFuncFromRanFuncId(duDb, ranFuncItem->ranFunctionID) == NULLP)
3642                      {
3643                         /* Calculating total number of ran fuctions which are not present */
3644                         failedRanFuncCount++;
3645
3646                         /* Adding the ran function in temporary list */
3647                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
3648                         ricRanFuncList.numOfRanFuneRejected++;
3649                      }
3650                      else
3651                      {
3652
3653                         /* Adding the ran function in temporary list */
3654                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
3655                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
3656                         ricRanFuncList.numOfRanFunAccepted++;
3657
3658                         /* Updating the new ran function in DB*/
3659                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
3660                      }
3661                      /* Calculating total number of ran fuctions which are received for modification */
3662                      recvdRanFuncCount++;
3663                   }
3664                }
3665                break;
3666             }
3667          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
3668             {
3669
3670                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
3671                if(deleteList->list.array)
3672                {
3673                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
3674                   {
3675                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
3676                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
3677                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncIdItem->ranFunctionID);
3678                      if(ranFuncDb)
3679                      {
3680                         memset(ranFuncDb, 0, sizeof(RanFunction));
3681                         duDb->numOfRanFunction--; 
3682                      }
3683
3684                      /* Calculating total number of ran fuctions which are received for deletion */
3685                      recvdRanFuncCount++;
3686                   }
3687                }
3688                break;
3689             }
3690
3691          default:
3692             {
3693                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
3694                break;
3695             }
3696       }
3697    }
3698    
3699    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
3700     * Else sending RIC Service Update Acknowledge */  
3701    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
3702    {
3703       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
3704       {
3705          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
3706          return;
3707       }
3708    }
3709    else
3710    {
3711       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
3712       {
3713          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
3714          return;
3715       }
3716    }
3717 }
3718
3719 /*******************************************************************
3720  *
3721  * @brief Processing RIC subscription failure from DU
3722  *
3723  * @details
3724  *
3725  *    Function : ProcRicSubscriptionFailure
3726  *
3727  * Functionality: Processing RIC subscription failure from DU
3728  *
3729  * @param  ID of DU from which message was sent
3730  *         RIC Subscription failure message
3731  * @return ROK     - success
3732  *         RFAILED - failure
3733  *
3734  ******************************************************************/
3735 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
3736 {
3737    uint8_t ieIdx = 0, duIdx = 0;
3738    uint8_t ranFuncId = 0;
3739    DuDb    *duDb = NULLP;
3740    RanFunction *ranFuncDb = NULLP;
3741    RicSubscription *ricSubs = NULLP;
3742    CmLList *ricSubsNode = NULLP;
3743    RicRequestId ricReqId;
3744    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3745
3746    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
3747
3748    SEARCH_DU_DB(duIdx, duId, duDb);
3749    if(duDb == NULLP)
3750    {
3751       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3752       return RFAILED;
3753    }
3754
3755    memset(&ricReqId, 0, sizeof(RicRequestId));
3756    if(ricSubscriptionFailure)
3757    {
3758       if(ricSubscriptionFailure->protocolIEs.list.array)
3759       {
3760          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
3761          {
3762             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
3763             {
3764                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
3765                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
3766                {
3767                   case ProtocolIE_IDE2_id_RICrequestID:
3768                   {
3769                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
3770                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
3771                      break;
3772                   }
3773                   case ProtocolIE_IDE2_id_RANfunctionID:
3774                   {
3775                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
3776                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3777                      if(!ranFuncDb)
3778                      {
3779                         DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionFailure : RAN Function Id [%d] not found", ranFuncId);
3780                         return RFAILED;
3781                      }
3782                      else
3783                      {
3784                         /* Remove subscription entry from RAN Function */
3785                         ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3786                         if(ricSubs)
3787                         {
3788                            cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
3789                            deleteRicSubscriptionNode(ricSubsNode);
3790                         }
3791                      }
3792                      break; 
3793                   }
3794                   case ProtocolIE_IDE2_id_CauseE2:
3795                   default:
3796                      /* No handling required as of now since this is a stub */
3797                      break;
3798                }
3799             }
3800          }
3801       }
3802    }
3803    return ROK;
3804 }
3805
3806 /*******************************************************************
3807  *
3808  * @brief Free RIC Subscription Modification Refuse
3809  *
3810  * @details
3811  *
3812  *    Function : FreeRicSubsModRefuse
3813  *
3814  * Functionality: Free RIC Subscription Modification Refuse
3815  *
3816  * @param  E2AP Message PDU to be freed
3817  * @return void
3818  *
3819  ******************************************************************/
3820 void FreeRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
3821 {
3822    uint8_t ieIdx =0;
3823    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3824
3825    if(e2apMsg)
3826    {
3827       if(e2apMsg->choice.unsuccessfulOutcome)
3828       {
3829          ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3830          if(ricSubsModRefuse->protocolIEs.list.array)
3831          {
3832             for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
3833             {
3834                RIC_FREE(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3835             }
3836             RIC_FREE(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3837          }
3838          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3839       }
3840       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3841    }
3842 }
3843
3844 /*******************************************************************
3845  *
3846  * @brief Build And Send RIC Subscription Modification Refuse
3847  *
3848  * @details
3849  *
3850  *    Function : BuildAndSendRicSubsModRefuse
3851  *
3852  * Functionality: Build And Send RIC Subscription Modification Refuse
3853  *
3854  * @param DU ID
3855  *        RIC Request ID of subscription
3856  *        RAN Function ID
3857  *        Type of failure
3858  *        Cause of failure
3859  * @return ROK - success
3860  *         RFAILED - failure
3861  *
3862  ******************************************************************/
3863 uint8_t BuildAndSendRicSubsModRefuse(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, CauseE2_PR causeType, \
3864    uint8_t cause)
3865 {
3866    uint8_t ieIdx = 0, elementCnt = 0;
3867    uint8_t ret = RFAILED;
3868    E2AP_PDU_t *e2apMsg = NULL;
3869    asn_enc_rval_t encRetVal;
3870    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3871    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
3872
3873    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Refuse\n");
3874    while(true)
3875    {
3876       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3877       if(e2apMsg == NULLP)
3878       {
3879          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3880          break;
3881       }
3882       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3883       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3884       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3885       {
3886          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3887          break;
3888       }
3889
3890       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3891       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3892       e2apMsg->choice.unsuccessfulOutcome->value.present = \
3893          UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse;
3894       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3895
3896       elementCnt = 3;
3897       ricSubsModRefuse->protocolIEs.list.count = elementCnt;
3898       ricSubsModRefuse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRefuse_IEs_t *);
3899       RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3900       if(!ricSubsModRefuse->protocolIEs.list.array)
3901       {
3902          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3903          break;
3904       }
3905
3906       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3907       {
3908          RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3909          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
3910          {
3911             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3912             break;
3913          }
3914       }
3915       
3916       /* RIC Request ID */
3917       ieIdx = 0;
3918       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3919       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RICrequestID;
3920       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3921       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RICrequestID;
3922       ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3923       ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3924
3925       /* RAN Function ID */
3926       ieIdx++;
3927       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3928       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3929       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3930       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RANfunctionID;
3931       ricSubsModRefuseIe->value.choice.RANfunctionID = ranFuncId;
3932
3933       /* Cause */
3934       ieIdx++;
3935       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3936       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_CauseE2;
3937       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3938       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_CauseE2;
3939       fillE2FailureCause(&ricSubsModRefuseIe->value.choice.CauseE2, causeType, cause); 
3940
3941       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3942       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3943       encBufSize = 0;
3944       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3945
3946       /* Check encode results */
3947       if(encRetVal.encoded == ENCODE_FAIL)
3948       {
3949          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification refuse (at %s)\n",\
3950                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3951          break;
3952       }
3953       else
3954       {
3955          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification refuse\n");
3956          for(int i=0; i< encBufSize; i++)
3957          {
3958             DU_LOG("%x",encBuf[i]);
3959          }
3960       }
3961
3962       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3963       {
3964          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Refused");
3965          break;
3966       }
3967
3968       ret =ROK;
3969       break;
3970    }
3971    FreeRicSubsModRefuse(e2apMsg);
3972    return ret;
3973 }
3974
3975 /*******************************************************************
3976  *
3977  * @brief Free memory for RIC Subscription Modification Confirm
3978  *
3979  * @details
3980  *
3981  *    Function : FreeRicSubsModConfirm
3982  *
3983  * Functionality: Free memory for RIC subscription modification
3984  *    confirm
3985  *
3986  * @param E2AP Message PDU to be freed
3987  * @return Void
3988  *
3989  ******************************************************************/
3990 void FreeRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
3991 {
3992    uint8_t ieIdx = 0, arrIdx=0;
3993    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3994    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3995    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
3996    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
3997    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
3998    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
3999
4000    if(e2apMsg)
4001    {
4002       if(e2apMsg->choice.successfulOutcome)
4003       {
4004          ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
4005          if(ricSubsModCfm->protocolIEs.list.array)
4006          {
4007             for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
4008             {
4009                if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
4010                {
4011                   ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4012                   switch(ricSubsModCfmIe->id)
4013                   {
4014                      case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
4015                         {
4016                            modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
4017                            if(modCfmList->list.array)
4018                            {
4019                               for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
4020                               {
4021                                  RIC_FREE(modCfmList->list.array[arrIdx], \
4022                                     sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
4023                               }
4024                               RIC_FREE(modCfmList->list.array,  modCfmList->list.size);
4025                            }
4026                            break;
4027                         }
4028
4029                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
4030                         {
4031                            modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
4032                            if(modRefusedList->list.array)
4033                            {
4034                               for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
4035                               {
4036                                  RIC_FREE(modRefusedList->list.array[arrIdx], \
4037                                        sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
4038                               }
4039                               RIC_FREE(modRefusedList->list.array,  modRefusedList->list.size);
4040                            }
4041                            break;
4042                         }
4043
4044                      case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
4045                         {
4046                            rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
4047                            if(rmvCfmList->list.array)
4048                            {
4049                               for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
4050                               {
4051                                  RIC_FREE(rmvCfmList->list.array[arrIdx], \
4052                                        sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
4053                               }
4054                               RIC_FREE(rmvCfmList->list.array,  rmvCfmList->list.size);
4055                            }
4056                            break;
4057                         }
4058
4059                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
4060                         {
4061                            rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
4062                            if(rmvFailList->list.array)
4063                            {
4064                               for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
4065                               {
4066                                  RIC_ALLOC(rmvFailList->list.array[arrIdx], \
4067                                     sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
4068                               }
4069                               RIC_FREE(rmvFailList->list.array,  rmvFailList->list.size);
4070                            }
4071                            break;
4072                         }
4073
4074                      default:
4075                         break;
4076
4077                   }
4078                   RIC_FREE(ricSubsModCfmIe, sizeof(RICsubscriptionModificationConfirm_IEs_t));
4079                }
4080             }
4081             RIC_FREE(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
4082          }
4083          RIC_FREE(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
4084       }
4085       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4086    }
4087 }
4088
4089 /*******************************************************************
4090  *
4091  * @brief Fill the list of actions confirmed for modification
4092  *
4093  * @details
4094  *
4095  *    Function : fillActionModConfirmedList
4096  *
4097  * Functionality: Fill the list of actions confirmed for modification
4098  *
4099  * @param List to be filled
4100  *        Number of actions
4101  *        Source list of actions
4102  * @return ROK - success
4103  *         RFAILED - failure
4104  *
4105  ******************************************************************/
4106 uint8_t fillActionModConfirmedList(RICactions_ConfirmedForModification_List_t *modCfmList, uint8_t numActions, \
4107    uint8_t *actionModifiedList)
4108 {
4109    uint8_t arrIdx = 0;
4110    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
4111
4112    modCfmList->list.count = numActions;
4113    modCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForModification_ItemIEs_t *);
4114    RIC_ALLOC(modCfmList->list.array,  modCfmList->list.size);
4115    if(!modCfmList->list.array)
4116    {
4117       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4118       return RFAILED;
4119    }
4120
4121    for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
4122    {
4123       RIC_ALLOC(modCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
4124       if(!modCfmList->list.array[arrIdx])
4125       {
4126          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4127          return RFAILED;
4128       }
4129
4130       modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
4131       modCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForModification_Item;
4132       modCfmListItem->criticality = CriticalityE2_ignore;
4133       modCfmListItem->value.present = \
4134          RICaction_ConfirmedForModification_ItemIEs__value_PR_RICaction_ConfirmedForModification_Item;
4135       modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID = actionModifiedList[arrIdx];
4136    }
4137
4138    return ROK;
4139 }
4140
4141 /*******************************************************************
4142  *
4143  * @brief Fill the list of actions refused to be modified
4144  *
4145  * @details
4146  *
4147  *    Function : fillActionModRefusedList
4148  *
4149  * Functionality: Fill the list of actions refused to be modified
4150  *
4151  * @param List to be filled
4152  *        Number of list
4153  *        Source list of actions refused tobe modified
4154  * @return ROK - success
4155  *         RFAILED - failure
4156  *
4157  ******************************************************************/
4158 uint8_t fillActionModRefusedList(RICactions_RefusedToBeModified_List_t *modRefusedList, uint8_t numActions, \
4159    ActionFailed *actionModFailedList)
4160 {
4161    uint8_t arrIdx = 0;
4162    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
4163
4164    modRefusedList->list.count = numActions;
4165    modRefusedList->list.size = numActions * sizeof(RICaction_RefusedToBeModified_ItemIEs_t *);
4166    RIC_ALLOC(modRefusedList->list.array,  modRefusedList->list.size);
4167    if(!modRefusedList->list.array)
4168    {
4169       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4170       return RFAILED;
4171    }
4172
4173    for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
4174    {
4175       RIC_ALLOC(modRefusedList->list.array[arrIdx], sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
4176       if(!modRefusedList->list.array[arrIdx])
4177       {
4178          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4179          return RFAILED;
4180       }
4181
4182       modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
4183       modRefusedListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeModified_Item;
4184       modRefusedListItem->criticality = CriticalityE2_ignore;
4185       modRefusedListItem->value.present = \
4186          RICaction_RefusedToBeModified_ItemIEs__value_PR_RICaction_RefusedToBeModified_Item;
4187       modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID = \
4188          actionModFailedList[arrIdx].actionId;
4189       fillE2FailureCause(&modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.cause, \
4190          actionModFailedList[arrIdx].failureType, actionModFailedList[arrIdx].cause);
4191    }
4192
4193    return ROK;
4194 }
4195
4196 /*******************************************************************
4197  *
4198  * @brief Fill the list of action confirmed for removal
4199  *
4200  * @details
4201  *
4202  *    Function : fillActionRemovalConfirmedList
4203  *
4204  * Functionality: Fill the list of action confirmed for removal
4205  *
4206  * @param List to be filled
4207  *        Number of actions
4208  *        Source list of actions removed
4209  * @return ROK - success
4210  *         RFAILED - failure
4211  *
4212  ******************************************************************/
4213 uint8_t fillActionRemovalConfirmedList(RICactions_ConfirmedForRemoval_List_t *rmvCfmList, uint8_t numActions, \
4214    uint8_t *actionRemovedList)
4215 {
4216    uint8_t arrIdx = 0;
4217    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
4218
4219    rmvCfmList->list.count = numActions;
4220    rmvCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t *);
4221    RIC_ALLOC(rmvCfmList->list.array,  rmvCfmList->list.size);
4222    if(!rmvCfmList->list.array)
4223    {
4224       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4225       return RFAILED;
4226    }
4227
4228    for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
4229    {
4230       RIC_ALLOC(rmvCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
4231       if(!rmvCfmList->list.array[arrIdx])
4232       {
4233          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4234          return RFAILED;
4235       }
4236
4237       rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
4238       rmvCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForRemoval_Item;
4239       rmvCfmListItem->criticality = CriticalityE2_ignore;
4240       rmvCfmListItem->value.present = \
4241          RICaction_ConfirmedForRemoval_ItemIEs__value_PR_RICaction_ConfirmedForRemoval_Item;
4242       rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID = actionRemovedList[arrIdx];
4243    }
4244
4245    return ROK;
4246 }
4247
4248 /*******************************************************************
4249  *
4250  * @brief Fill the list of actions refused to be removed
4251  *
4252  * @details
4253  *
4254  *    Function : fillActionRemovalRefusedList
4255  *
4256  * Functionality: Fill the list of actions refused to be removed
4257  *
4258  * @param List to be filled
4259  *        Number of list
4260  *        Source list of actions refused to be removed
4261  * @return ROK - success
4262  *         RFAILED - failure
4263  *
4264  ******************************************************************/
4265 uint8_t fillActionRemovalRefusedList(RICactions_RefusedToBeRemoved_List_t *rmvFailList, \
4266    uint8_t numActions, ActionFailed *actionRmvlFailList)
4267 {
4268    uint8_t arrIdx = 0;
4269    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
4270
4271    rmvFailList->list.count = numActions;
4272    rmvFailList->list.size = numActions * sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t *);
4273    RIC_ALLOC(rmvFailList->list.array,  rmvFailList->list.size);
4274    if(!rmvFailList->list.array)
4275    {
4276       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4277       return RFAILED;
4278    }
4279
4280    for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
4281    {
4282       RIC_ALLOC(rmvFailList->list.array[arrIdx], sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
4283       if(!rmvFailList->list.array[arrIdx])
4284       {
4285          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4286          return RFAILED;
4287       }
4288
4289       rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
4290       rmvFailListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeRemoved_Item;
4291       rmvFailListItem->criticality = CriticalityE2_ignore;
4292       rmvFailListItem->value.present = \
4293          RICaction_RefusedToBeRemoved_ItemIEs__value_PR_RICaction_RefusedToBeRemoved_Item;
4294       rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID = actionRmvlFailList[arrIdx].actionId;
4295       fillE2FailureCause(&rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.cause, \
4296          actionRmvlFailList[arrIdx].failureType, actionRmvlFailList[arrIdx].cause);
4297    }
4298
4299    return ROK;
4300
4301 }
4302
4303 /*******************************************************************
4304  *
4305  * @brief Build And Send RIC Subscription Modification Confirm
4306  *
4307  * @details
4308  *
4309  *    Function : BuildAndSendRicSubsModConfirm
4310  *
4311  * Functionality: Build And Send RIC Subscription Modification Confirm
4312  *
4313  * @param DU ID
4314  *        RIC Request ID of subscription
4315  *        RAN Function ID
4316  *        Temporary source action list
4317  * @return ROK - success
4318  *         RFAILED - failure
4319  *
4320  ******************************************************************/
4321 uint8_t BuildAndSendRicSubsModConfirm(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, RicTmpActionList tmpActionList)
4322 {
4323    uint8_t ieIdx = 0, elementCnt = 0;
4324    uint8_t ret = RFAILED;
4325    E2AP_PDU_t *e2apMsg = NULLP;
4326    asn_enc_rval_t encRetVal;
4327    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
4328    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
4329
4330    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Confirm\n");
4331    while(true)
4332    {
4333       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4334       if(e2apMsg == NULLP)
4335       {
4336          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4337          break;
4338       }
4339
4340       /* Successful Outcome */
4341       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
4342       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
4343       if(e2apMsg->choice.successfulOutcome == NULLP)
4344       {
4345          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4346          break;
4347       }
4348
4349       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
4350       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
4351       e2apMsg->choice.successfulOutcome->value.present = \
4352          SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm;
4353       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
4354
4355       elementCnt = 2;
4356       if(tmpActionList.numActionModified)
4357          elementCnt++;
4358       if(tmpActionList.numActionModFailed)
4359          elementCnt++;
4360       if(tmpActionList.numActionRemoved)
4361          elementCnt++;
4362       if(tmpActionList.numActionRemovalFailed)
4363          elementCnt++;
4364
4365       ricSubsModCfm->protocolIEs.list.count = elementCnt;
4366       ricSubsModCfm->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationConfirm_IEs_t *);
4367       RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
4368       if(!ricSubsModCfm->protocolIEs.list.array)
4369       {
4370          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4371          break;
4372       }
4373
4374       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4375       {
4376          RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationConfirm_IEs_t));
4377          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
4378          {
4379             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4380             break;
4381          }
4382       }
4383       
4384       /* RIC Request ID */
4385       ieIdx = 0;
4386       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4387       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICrequestID;
4388       ricSubsModCfmIe->criticality = CriticalityE2_reject;
4389       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RICrequestID;
4390       ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
4391       ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
4392
4393       /* RAN Function ID */
4394       ieIdx++;
4395       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4396       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RANfunctionID;
4397       ricSubsModCfmIe->criticality = CriticalityE2_reject;
4398       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RANfunctionID;
4399       ricSubsModCfmIe->value.choice.RANfunctionID = ranFuncId;
4400
4401       /* RIC Actions List confirmed for modification */
4402       if(tmpActionList.numActionModified)
4403       {
4404          ieIdx++;
4405          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4406          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List;
4407          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4408          ricSubsModCfmIe->value.present = \
4409             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForModification_List;
4410          if(fillActionModConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List, \
4411             tmpActionList.numActionModified, tmpActionList.actionModifiedList) != ROK)
4412          {
4413             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Modification List", __func__);
4414             break;
4415          }
4416       }
4417
4418       /* RIC Actions List refured to be modified */
4419       if(tmpActionList.numActionModFailed)
4420       {
4421          ieIdx++;
4422          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4423          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List;
4424          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4425          ricSubsModCfmIe->value.present = \
4426             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeModified_List;
4427          if(fillActionModRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List, \
4428             tmpActionList.numActionModFailed, tmpActionList.actionModFailedList) != ROK)
4429          {
4430             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Refused to be Modified List", __func__);
4431             break;
4432          }
4433       }
4434
4435       /* RIC Actions List confirmed for removal */
4436       if(tmpActionList.numActionRemoved)
4437       {
4438          ieIdx++;
4439          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4440          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List;
4441          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4442          ricSubsModCfmIe->value.present = \
4443             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForRemoval_List;
4444          if(fillActionRemovalConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List, \
4445             tmpActionList.numActionRemoved, tmpActionList.actionRemovedList) != ROK)
4446          {
4447             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Removal List", __func__);
4448             break;
4449          }
4450       }
4451
4452       /* RIC Actions List Refused to be removed */
4453       if(tmpActionList.numActionRemovalFailed)
4454       {
4455          ieIdx++;
4456          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4457          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List;
4458          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4459          ricSubsModCfmIe->value.present = \
4460             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeRemoved_List;
4461          if(fillActionRemovalRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List, \
4462             tmpActionList.numActionRemovalFailed, tmpActionList.actionRemovalFailedList) != ROK)
4463          {
4464             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Failed to be Removed List", __func__);
4465             break;
4466          }
4467       }
4468
4469       /* Print and encode E2AP Message PDU */
4470       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4471       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4472       encBufSize = 0;
4473       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4474
4475       /* Check encode results */
4476       if(encRetVal.encoded == ENCODE_FAIL)
4477       {
4478          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification confirm (at %s)\n",\
4479                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4480          break;
4481       }
4482       else
4483       {
4484          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification confirm\n");
4485          for(int i=0; i< encBufSize; i++)
4486          {
4487             DU_LOG("%x",encBuf[i]);
4488          }
4489       }
4490
4491       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4492       {
4493          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Confirm");
4494          break;
4495       }
4496
4497       ret =ROK;
4498       break;
4499    }
4500
4501    FreeRicSubsModConfirm(e2apMsg);
4502    return ret;
4503 }
4504
4505 /*******************************************************************
4506  *
4507  * @brief Processing of RIC Subscription Modification Required
4508  *
4509  * @details
4510  *
4511  *    Function : ProcRicSubsModReqd
4512  *
4513  * Functionality: Processing of RIC Subscription Modification Required
4514  *    As of now, we do not identify any scenario where this message
4515  *    shall be sent by DU. Hence, bare minimum handling has been
4516  *    done here.
4517  *
4518  * @param  DU ID
4519  *         RIC Subscription Modification Required IEs
4520  * @return ROK-success
4521  *         RFAILED-failure
4522  *
4523  ******************************************************************/
4524 uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t *ricSubsModReqd)
4525 {
4526    uint8_t ieIdx = 0, actionIdx = 0, duIdx = 0;
4527    DuDb    *duDb = NULLP;
4528    uint16_t ranFuncId;
4529    uint16_t actionId;
4530    RicRequestId ricReqId;
4531    RanFunction *ranFuncDb = NULLP;
4532    RicSubscription *ricSubs = NULLP;
4533    CmLList *ricSubsNode = NULLP;
4534    CmLList *actionNode = NULLP;
4535    ActionInfo *action = NULLP;
4536    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
4537    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
4538    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
4539    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULLP;
4540    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULLP;
4541    RicTmpActionList tmpActionList;
4542
4543    memset(&ricReqId, 0, sizeof(RicRequestId));
4544    memset(&tmpActionList, 0, sizeof(RicTmpActionList));
4545
4546    SEARCH_DU_DB(duIdx, duId, duDb);
4547    if(duDb == NULLP)
4548    {
4549       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4550       return RFAILED;
4551    }
4552
4553    for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
4554    {
4555       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
4556       switch(ricSubsModReqdIe->id)
4557       {
4558          case ProtocolIE_IDE2_id_RICrequestID:
4559             {
4560                ricReqId.requestorId = ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID;
4561                ricReqId.instanceId = ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID;
4562                break;
4563             }
4564          case ProtocolIE_IDE2_id_RANfunctionID:
4565             {
4566                ranFuncId = ricSubsModReqdIe->value.choice.RANfunctionID;
4567                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
4568                if(!ranFuncDb)
4569                {
4570                   /* If RIC Subscription not found, send RIC Subscription modification refuse to DU */
4571                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RIC Subscription not found");
4572                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
4573                      CauseE2RICrequest_ran_function_id_invalid);
4574                   return RFAILED;
4575                }
4576
4577                ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
4578                if(!ricSubs)
4579                {
4580                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
4581                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RAN Function ID [%d] not found",ranFuncId);
4582                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, \
4583                      CauseE2_PR_ricRequest, CauseE2RICrequest_request_id_unknown);
4584                   return RFAILED; 
4585                }
4586                break;
4587             }
4588          case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
4589             {
4590                actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
4591                for(actionIdx = 0; actionIdx < actionToBeModList->list.count; actionIdx++)
4592                {
4593                   actionNode=NULLP;
4594                   actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[actionIdx];
4595                   actionId = actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID;
4596                   action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
4597                   if(action)
4598                   {
4599                      /* No modification required as of now, hence directly adding to the list */
4600                      tmpActionList.actionModifiedList[tmpActionList.numActionModified++] = actionId;
4601                   }
4602                   else
4603                   {
4604                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].actionId = actionId;
4605                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].failureType = \
4606                         CauseE2_PR_ricRequest;
4607                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].cause = \
4608                         CauseE2RICrequest_action_not_supported;
4609                      tmpActionList.numActionModFailed++;
4610                   }
4611                }
4612                break;
4613             }
4614          case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
4615             {
4616                actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
4617                for(actionIdx = 0; actionIdx < actionToBeRmvList->list.count; actionIdx++)
4618                {
4619                   actionNode=NULLP;
4620                   actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[actionIdx];
4621                   actionId = actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID;
4622                   action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
4623                   if(action)
4624                   {
4625                      tmpActionList.actionRemovedList[tmpActionList.numActionRemoved++] = actionId;
4626                      cmLListDelFrm(&ricSubs->actionSequence, actionNode);
4627                      deleteActionSequence(actionNode);
4628                   }
4629                }
4630                break;
4631             }
4632          default:
4633             break;
4634       }
4635    }
4636
4637    /* If none of the action modification/removal is supported, 
4638     *   send RIC Subscription Modification Refuse
4639     * Else
4640     *   send RIC Subscription Modification Confirm
4641     */
4642    if(tmpActionList.numActionModified || tmpActionList.numActionRemoved)
4643    {
4644       BuildAndSendRicSubsModConfirm(duId, ricReqId, ranFuncId, tmpActionList);
4645    }
4646    else
4647    {
4648       BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
4649             CauseE2RICrequest_action_not_supported);
4650    }
4651    
4652    return ROK;
4653 }
4654
4655 /*******************************************************************
4656  *
4657  * @brief Free the ErrorIndication Message
4658  *
4659  * @details
4660  *
4661  *    Function : FreeRicIndication
4662  *
4663  * Functionality: Free the ErrorIndication Message
4664  *
4665  * @return void
4666  *
4667  *
4668  ******************************************************************/
4669 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
4670 {
4671    uint8_t arrIdx = 0;
4672    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
4673
4674    if(e2apMsg != NULLP)
4675    {
4676       if(e2apMsg->choice.initiatingMessage != NULLP)
4677       {
4678          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4679          if(errorIndicationMsg!= NULLP)
4680          {
4681             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
4682             {
4683                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
4684                {
4685                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
4686                }
4687                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
4688             }
4689          }
4690          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4691       }
4692       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4693    }
4694 }
4695
4696
4697 /*******************************************************************
4698  *
4699  * @brief Builds and Send the ErrorIndication Message
4700  *
4701  * @details
4702  *
4703  *    Function : BuildAndSendErrorIndication
4704  *
4705  * Functionality:Fills the ErrorIndication Message
4706  *
4707  * @params[in] 
4708  *    DU id
4709  *    Trans id
4710  *    Ric req id
4711  *    Ran function id
4712  *    Reason of failure
4713  * @return ROK     - success
4714  *         RFAILED - failure
4715  *
4716  ******************************************************************/
4717
4718 uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
4719 {
4720    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
4721    E2AP_PDU_t         *e2apMsg = NULLP;
4722    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
4723    asn_enc_rval_t     encRetVal;        /* Encoder return value */
4724
4725    while(true)
4726    {
4727       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
4728
4729       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4730       if(e2apMsg == NULLP)
4731       {
4732          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4733          break;
4734       }
4735
4736       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4737       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4738       if(e2apMsg->choice.initiatingMessage == NULLP)
4739       {
4740          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4741          break;
4742       }
4743       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
4744       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4745       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
4746
4747       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4748
4749       /* Element count is 2 for TransactionID/RICrequestID and Cause.
4750        * If the RAN function id is present, the count will be increased.*/
4751       elementCnt = 2;
4752       if(ranFuncId>0)
4753          elementCnt++;
4754
4755       errorIndicationMsg->protocolIEs.list.count = elementCnt;
4756       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
4757
4758       /* Initialize the E2Setup members */
4759       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
4760       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
4761       {
4762          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
4763          break;
4764       }
4765       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
4766       {
4767          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
4768          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
4769          {
4770             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
4771             break;
4772          }
4773       }
4774       if(arrIdx < elementCnt)
4775          break;
4776
4777       arrIdx = 0;
4778
4779       if(transId >=0 && transId<=255)
4780       {
4781          /* TransactionID */
4782          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4783          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4784          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
4785          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4786       }
4787       else
4788       {
4789          /* RICrequestID */
4790          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
4791          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4792          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
4793          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
4794          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
4795       }
4796       
4797       if(ranFuncId>0)
4798       {
4799          /* RAN Function ID */
4800          arrIdx++;
4801          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4802          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4803          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
4804          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
4805       }
4806      
4807       /* Cause */
4808       arrIdx++;
4809       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4810       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
4811       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
4812       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
4813
4814
4815       /* Prints the Msg formed */
4816       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4817       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4818       encBufSize = 0;
4819       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4820             encBuf);
4821       if(encRetVal.encoded == ENCODE_FAIL)
4822       {
4823          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
4824                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4825          break;
4826       }
4827       else
4828       {
4829          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
4830 #ifdef DEBUG_ASN_PRINT
4831          for(int i=0; i< encBufSize; i++)
4832          {
4833             printf("%x",encBuf[i]);
4834          }
4835 #endif
4836       }
4837
4838       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4839       {
4840          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
4841
4842       }
4843       ret = ROK;
4844       break;
4845    }
4846    FreeErrorIndication(e2apMsg);
4847    return ret;
4848 }
4849
4850 /*******************************************************************
4851  *
4852  * @brief Deallocate the memory allocated for ResetRequest msg
4853  *
4854  * @details
4855  *
4856  *    Function : FreeResetRequest
4857  *
4858  *    Functionality:
4859  *       - freeing the memory allocated for ResetRequest
4860  *
4861  * @params[in] E2AP_PDU_t *e2apMsg
4862  * @return ROK     - success
4863  *         RFAILED - failure
4864  *
4865  * ****************************************************************/
4866 void FreeResetRequest(E2AP_PDU_t *e2apMsg)
4867 {
4868    uint8_t ieIdx =0;
4869    ResetRequestE2_t  *resetReq = NULLP;
4870
4871    if(e2apMsg != NULLP)
4872    {
4873       if(e2apMsg->choice.initiatingMessage != NULLP)
4874       {
4875          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4876          if(resetReq->protocolIEs.list.array)
4877          {
4878             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4879             {
4880                RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4881             }
4882             RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4883          }
4884          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4885       }
4886       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4887    }
4888 }
4889
4890 /*******************************************************************
4891  *
4892  * @brief Build and send the reset request msg
4893  *
4894  * @details
4895  *
4896  *    Function : BuildAndSendResetRequest
4897  *
4898  *    Functionality:
4899  *         - Buld and send the reset request msg to E2 node
4900  *
4901  * @params[in]
4902  *    DU database
4903  *    Type of failure 
4904  *    Cause of failure
4905  * @return ROK     - success
4906  *         RFAILED - failure
4907  *
4908  * ****************************************************************/
4909 uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
4910 {
4911    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4912    uint8_t ret = RFAILED;
4913    E2AP_PDU_t        *e2apMsg = NULLP;
4914    ResetRequestE2_t  *resetReq = NULLP;
4915    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4916
4917    DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
4918
4919    do
4920    {
4921       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4922       if(e2apMsg == NULLP)
4923       {
4924          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
4925          break;
4926       }
4927
4928       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4929       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4930       if(e2apMsg->choice.initiatingMessage == NULLP)
4931       {
4932          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
4933          break;
4934       }
4935
4936       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4937       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4938       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4939       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4940
4941       elementCnt = 2;
4942       resetReq->protocolIEs.list.count = elementCnt;
4943       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4944
4945       RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4946       if(!resetReq->protocolIEs.list.array)
4947       {
4948          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4949                Reset Request IE array");
4950          break;
4951       }
4952
4953       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4954       {
4955          RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4956          if(!resetReq->protocolIEs.list.array[ieIdx])
4957          {
4958             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4959                   Reset Request IE array element");
4960             break;
4961          }
4962       }
4963
4964       /* In case of failure */
4965       if(ieIdx < elementCnt)
4966          break;
4967
4968       ieIdx = 0;
4969       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4970       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4971       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4972       transId = assignTransactionId(duDb);
4973       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4974
4975       ieIdx++;
4976       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4977       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4978       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4979       fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
4980
4981       /* Prints the Msg formed */
4982       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4983
4984       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4985       encBufSize = 0;
4986       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4987             encBuf);
4988       if(encRetVal.encoded == ENCODE_FAIL)
4989       {
4990          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
4991                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4992          break;
4993       }
4994       else
4995       {
4996          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
4997 #ifdef DEBUG_ASN_PRINT
4998          for(int i=0; i< encBufSize; i++)
4999          {
5000             printf("%x",encBuf[i]);
5001          }
5002 #endif
5003       }
5004       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
5005       {
5006          DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
5007          break;
5008       }
5009
5010
5011       ret = ROK;
5012       break;
5013    }while(true);
5014
5015    /* Free all memory */
5016    FreeResetRequest(e2apMsg);
5017    return ret;
5018 }
5019
5020 /******************************************************************
5021  *
5022  * @brief Delete Ric subscription action
5023  *
5024  * @details
5025  *
5026  *    Function : deleteActionSequence
5027  *
5028  *    Functionality: Delete Ric subscription action
5029  *
5030  * @params[in] Action info
5031  *
5032  * @return void
5033  *
5034  * ****************************************************************/
5035 void deleteActionSequence(CmLList *actionNode)
5036 {
5037    ActionInfo *action = NULLP;
5038
5039    if(actionNode)
5040    {
5041       action = (ActionInfo*)actionNode->node;
5042       memset(action, 0, sizeof(ActionInfo));
5043       RIC_FREE(actionNode->node, sizeof(ActionInfo));
5044       RIC_FREE(actionNode, sizeof(CmLList));
5045    }
5046 }
5047
5048 /******************************************************************
5049  *
5050  * @brief Delete Ric subscription action list
5051  *
5052  * @details
5053  *
5054  *    Function : deleteActionSequenceList
5055  *
5056  *    Functionality: Delete Ric subscription action list
5057  *
5058  * @params[in] Action info list
5059  *
5060  * @return void
5061  *
5062  * ****************************************************************/
5063 void deleteActionSequenceList(CmLListCp *actionList)
5064 {
5065    CmLList *actionNode=NULLP;
5066
5067    CM_LLIST_FIRST_NODE(actionList, actionNode);
5068    while(actionNode)
5069    {
5070       cmLListDelFrm(actionList, actionNode);
5071       deleteActionSequence(actionNode);
5072       CM_LLIST_FIRST_NODE(actionList, actionNode);
5073    }
5074
5075 }
5076
5077 /******************************************************************
5078  *
5079  * @brief Delete Ric subscription node
5080  *
5081  * @details
5082  *
5083  *    Function : deleteRicSubscriptionNode
5084  *
5085  *    Functionality: Delete Ric subscription node
5086  *
5087  * @params[in] Ric subscription info
5088  *
5089  * @return void
5090  *
5091  * ****************************************************************/
5092 void deleteRicSubscriptionNode(CmLList *subscriptionNode)
5093 {
5094    uint8_t actionIdx=0;
5095    RicSubscription *ricSubscriptionInfo = NULLP;
5096
5097    ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;
5098    
5099    deleteActionSequenceList(&ricSubscriptionInfo->actionSequence);
5100    
5101    memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
5102    RIC_FREE(subscriptionNode->node, sizeof(RicSubscription));
5103    RIC_FREE(subscriptionNode, sizeof(CmLList));
5104 }
5105
5106 /*******************************************************************
5107  *
5108  * @brief Delete RIC subscription List
5109  *
5110  * @details
5111  *
5112  *    Function : deleteRicSubscriptionList 
5113  *
5114  * Functionality: Delete RIC subscription list
5115  *
5116  * @params[in] RIC Subscription list
5117  * @return void
5118
5119  *
5120  ******************************************************************/
5121 void deleteRicSubscriptionList(CmLListCp *subscriptionList)
5122 {
5123    CmLList *subscriptionNode = NULLP;
5124
5125    CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
5126    while(subscriptionNode)
5127    {
5128       cmLListDelFrm(subscriptionList, subscriptionNode);
5129       deleteRicSubscriptionNode(subscriptionNode);
5130       CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
5131    }
5132 }
5133
5134 /*******************************************************************
5135  *
5136  * @brief process the E2 Reset Response
5137  *
5138  * @details
5139  *
5140  *    Function : ProcResetResponse 
5141  *
5142  * Functionality: Process E2 Reset Response 
5143  *
5144  * @params[in] 
5145  *       du Id
5146  *       Pointer to reset response 
5147  * @return void
5148  *
5149  ******************************************************************/
5150
5151 void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
5152 {
5153    uint8_t ieIdx = 0, duIdx =0;
5154    DuDb *duDb = NULLP;
5155    RanFunction *ranFuncDb = NULLP;
5156    uint16_t ranFuncIdx = 0;
5157
5158    SEARCH_DU_DB(duIdx, duId, duDb); 
5159    if(duDb == NULLP)
5160    {
5161       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5162       return;
5163    }
5164    
5165    if(!resetRsp)
5166    {
5167       DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
5168       return;
5169    }
5170
5171    if(!resetRsp->protocolIEs.list.array)      
5172    {
5173       DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
5174       return;
5175    }
5176    
5177    for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
5178    {
5179       if(resetRsp->protocolIEs.list.array[ieIdx])
5180       {
5181          switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
5182          {
5183             case ProtocolIE_IDE2_id_TransactionID:
5184                {
5185                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
5186                   {
5187                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
5188                      if(ranFuncDb->id > 0)
5189                      {
5190                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
5191                      }
5192                   }
5193                   break;
5194                }
5195             case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
5196                {
5197                   break;
5198                }
5199          }
5200       }
5201    }
5202 }
5203
5204
5205 /*******************************************************************
5206  *
5207  * @brief process the E2 Reset Request
5208  *
5209  * @details
5210  *
5211  *    Function : ProcResetRequest 
5212  *
5213  * Functionality: Process E2 Reset Request 
5214  *
5215  * @params[in] 
5216  *       du Id
5217  *       Pointer to reset response 
5218  * @return void
5219  *
5220  ******************************************************************/
5221
5222 void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
5223 {
5224    uint8_t ieIdx = 0, duIdx =0, transId=0;
5225    DuDb *duDb = NULLP;
5226    RanFunction *ranFuncDb = NULLP;
5227    uint16_t ranFuncIdx = 0;
5228
5229    SEARCH_DU_DB(duIdx, duId, duDb); 
5230    if(duDb == NULLP)
5231    {
5232       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5233       return;
5234    }
5235    
5236    if(!resetReq)
5237    {
5238       DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
5239       return;
5240    }
5241
5242    if(!resetReq->protocolIEs.list.array)      
5243    {
5244       DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
5245       return;
5246    }
5247    
5248    for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
5249    {
5250       if(resetReq->protocolIEs.list.array[ieIdx])
5251       {
5252          switch(resetReq->protocolIEs.list.array[ieIdx]->id)
5253          {
5254             case ProtocolIE_IDE2_id_TransactionID:
5255                {
5256                   transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
5257                   break;
5258                }
5259             case ProtocolIE_IDE2_id_CauseE2:
5260                {
5261                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
5262                   {
5263                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
5264                      if(ranFuncDb->id > 0)
5265                      {
5266                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
5267                      }
5268                   }
5269                   break;
5270                }
5271          }
5272       }
5273    }
5274
5275    if(BuildAndSendResetResponse(duId, transId) !=ROK)
5276    {
5277       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
5278    }
5279 }
5280
5281 /*******************************************************************
5282  *
5283  * @brief Free RIC Subscription Delete Request Message
5284  *
5285  * @details
5286  *
5287  *    Function : FreeRicSubscriptionDeleteRequest
5288  *
5289  * Functionality:  Free RIC Subscription Delete Request
5290  *
5291  * @param  E2AP Message PDU
5292  * @return void
5293  *
5294  ******************************************************************/
5295 void FreeRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
5296 {
5297    uint8_t ieIdx = 0, arrIdx = 0;
5298    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
5299
5300    if(e2apMsg)
5301    {
5302       if(e2apMsg->choice.initiatingMessage)
5303       {
5304          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
5305          if(ricSubsDelReq->protocolIEs.list.array)
5306          {
5307             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
5308             {
5309                RIC_FREE(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
5310             }
5311             RIC_FREE(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
5312          }
5313          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5314       }
5315       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
5316    }
5317 }
5318
5319 /*******************************************************************
5320  *
5321  * @brief Builds and Send RIC Subscription delete request
5322  *
5323  * @details
5324  *
5325  *    Function : BuildAndSendRicSubscriptionDeleteRequest
5326  *
5327  * Functionality: Build and send RIC subscription delete request.
5328  *
5329  * @params[in] DU ID
5330  *             RIC subscription info to be deleted
5331  * @return ROK     - success
5332  *         RFAILED - failure
5333  *
5334  ******************************************************************/
5335 uint8_t BuildAndSendRicSubscriptionDeleteRequest(uint32_t duId, RicSubscription *ricSubsDb)
5336 {
5337    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
5338    E2AP_PDU_t         *e2apMsg = NULLP;
5339    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
5340    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
5341    asn_enc_rval_t     encRetVal;        /* Encoder return value */
5342
5343    while(true)
5344    {
5345       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Request Message\n");
5346
5347       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5348       if(e2apMsg == NULLP)
5349       {
5350          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
5351          break;
5352       }
5353
5354       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5355       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5356       if(e2apMsg->choice.initiatingMessage == NULLP)
5357       {
5358          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
5359          break;
5360       }
5361       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
5362       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5363       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest;
5364
5365       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
5366
5367       elementCnt = 2;
5368       ricSubsDelReq->protocolIEs.list.count = elementCnt;
5369       ricSubsDelReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequest_IEs_t *);
5370
5371       RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
5372       if(ricSubsDelReq->protocolIEs.list.array == NULLP)
5373       {
5374          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
5375          break;
5376       }
5377
5378       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5379       {
5380          RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequest_IEs_t));
5381          if(ricSubsDelReq->protocolIEs.list.array[ieIdx] == NULLP)
5382          {
5383             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
5384                   __func__, ieIdx, __LINE__);
5385             break;
5386          }
5387       }
5388       if(ieIdx < elementCnt)
5389          break;
5390       
5391       /* RIC Request ID */
5392       ieIdx = 0;
5393       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
5394       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RICrequestID;
5395       ricSubsDelReqIe->criticality = CriticalityE2_reject;
5396       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
5397       ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID = ricSubsDb->requestId.requestorId;
5398       ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID = ricSubsDb->requestId.instanceId;
5399
5400       /* RAN Function ID */
5401       ieIdx++;
5402       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
5403       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RANfunctionID;
5404       ricSubsDelReqIe->criticality = CriticalityE2_reject;
5405       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
5406       ricSubsDelReqIe->value.choice.RANfunctionID = ricSubsDb->ranFuncId;
5407
5408       /* Prints the Msg formed */
5409       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5410       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5411       encBufSize = 0;
5412       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5413       if(encRetVal.encoded == ENCODE_FAIL)
5414       {
5415          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Request Message (at %s)\n",\
5416                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5417          break;
5418       }
5419       else
5420       {
5421          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Request Message \n");
5422 #ifdef DEBUG_ASN_PRINT
5423          for(int i=0; i< encBufSize; i++)
5424          {
5425             printf("%x",encBuf[i]);
5426          } 
5427 #endif
5428       }
5429
5430       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
5431       {
5432          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Request Message");      
5433          break;
5434       }
5435
5436       ret = ROK;
5437       break;
5438    }
5439
5440    FreeRicSubscriptionDeleteRequest(e2apMsg);  
5441    return ret;
5442 }
5443
5444 /*******************************************************************
5445  *
5446  * @brief Processing of RIC Subscription Delete Required
5447  *
5448  * @details
5449  *
5450  *    Function : ProcRicSubsDeleteReqd
5451  *
5452  * Functionality: Processing of RIC Subscription Delete Required
5453  *    When received, RIC stub will initiate the RIC subscription
5454  *    deletion procedure towards DU
5455  *
5456  * @param  DU ID
5457  *         RIC Subscription Delete Required IEs
5458  * @return ROK-success
5459  *         RFAILED-failure
5460  *
5461  ******************************************************************/
5462 uint8_t ProcRicSubsDeleteReqd(uint32_t duId, RICsubscriptionDeleteRequired_t *ricSubsDelRqd)
5463 {
5464    uint8_t ieIdx = 0, duIdx = 0;
5465    uint16_t arrIdx = 0;
5466    DuDb *duDb = NULLP;
5467    RicRequestId ricReqId;
5468    RanFunction *ranFuncDb = NULLP;
5469    RicSubscription *subsDb = NULLP;
5470    CmLList *ricSubsNode = NULLP;
5471
5472    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
5473    RICsubscription_List_withCause_t *ricSubsList = NULLP;
5474    RICsubscription_withCause_Item_t *subsItem = NULLP;
5475
5476    memset(&ricReqId, 0, sizeof(RicRequestId));
5477
5478    if(!ricSubsDelRqd)
5479    {
5480       DU_LOG("\nERROR  -->  E2AP : %s: Received NULL message", __func__);
5481       return RFAILED;
5482    }
5483
5484    SEARCH_DU_DB(duIdx, duId, duDb);
5485    if(duDb == NULLP)
5486    {
5487       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5488       return RFAILED;
5489    }
5490
5491    for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
5492    {
5493       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
5494       switch(ricSubsDelRqdIe->id)
5495       {
5496          case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
5497          {
5498             ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
5499             for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
5500             {
5501                subsItem = &(((RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[arrIdx])->\
5502                   value.choice.RICsubscription_withCause_Item);
5503                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, subsItem->ranFunctionID);
5504                if(!ranFuncDb)
5505                {
5506                   DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%ld] not found", __func__, subsItem->ranFunctionID);
5507                   return RFAILED;
5508                }
5509                
5510                ricReqId.requestorId = subsItem->ricRequestID.ricRequestorID;
5511                ricReqId.instanceId = subsItem->ricRequestID.ricInstanceID;
5512                subsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
5513                if(!subsDb)
5514                {
5515                   DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%ld] Instance_ID [%ld]", \
5516                      __func__, subsItem->ricRequestID.ricRequestorID, subsItem->ricRequestID.ricInstanceID);
5517                   return RFAILED;
5518                }
5519
5520                /* Delete RIC Subcription from RAN Function */
5521                cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
5522                
5523                /* Send RIC Subscription delete request and then free any memory
5524                 * allocated to store subscription info at RIC */
5525                BuildAndSendRicSubscriptionDeleteRequest(duId, (RicSubscription *)ricSubsNode->node);
5526                deleteRicSubscriptionNode(ricSubsNode);
5527             }
5528             
5529             break;
5530          }
5531          default:
5532             break;
5533       }
5534    }  
5535    
5536    return ROK;
5537 }
5538
5539 /*******************************************************************
5540  *
5541  * @brief Deallocate memory allocated for E2nodeConfigurationUpdate 
5542  *
5543  * @details
5544  *
5545  *    Function : freeE2NodeConfigItem 
5546  *
5547  *    Functionality:
5548  *       - freeing the memory allocated for E2nodeConfigurationUpdate
5549  *
5550  * @params[in]
5551  *       uint8_t protocolIe
5552  *       PTR to e2NodeCfg which is to be freed
5553  * @return ROK     - success
5554  *         RFAILED - failure
5555  *
5556  * ****************************************************************/
5557
5558 void freeE2NodeConfigItem(uint8_t protocolIe, PTR e2NodeCfg)
5559 {
5560    E2nodeComponentConfigurationAck_t *cfgAck =NULLP;
5561    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
5562    E2nodeComponentConfigAdditionAck_Item_t *e2NodeAdditionAckItemIe=NULLP;
5563    E2nodeComponentConfigRemovalAck_Item_t *e2NodeRemovalAckItemIe=NULLP;
5564    E2nodeComponentConfigUpdateAck_Item_t *e2NodeUpdateAckItemIe=NULLP;
5565    
5566     /* Extracting the component interface and configuration ack information from
5567      * e2NodeCfg based on the protocol id */
5568    switch(protocolIe)
5569    {
5570       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
5571       {
5572          e2NodeAdditionAckItemIe= (E2nodeComponentConfigAdditionAck_Item_t*)e2NodeCfg;
5573          switch(e2NodeAdditionAckItemIe->e2nodeComponentInterfaceType)
5574          {
5575             case E2nodeComponentInterfaceType_f1:
5576                {
5577                   f1InterfaceInfo = e2NodeAdditionAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
5578                   break;
5579                }
5580             default:
5581                {
5582                   break;
5583                }
5584
5585          }
5586          cfgAck = &e2NodeAdditionAckItemIe->e2nodeComponentConfigurationAck;
5587       }
5588
5589       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
5590       {
5591          e2NodeUpdateAckItemIe = (E2nodeComponentConfigUpdateAck_Item_t*)e2NodeCfg;
5592          switch(e2NodeUpdateAckItemIe->e2nodeComponentInterfaceType)
5593          {
5594             case E2nodeComponentInterfaceType_f1:
5595                {
5596                   f1InterfaceInfo = e2NodeUpdateAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
5597                   break;
5598                }
5599             default:
5600                {
5601                   break;
5602                }
5603          }
5604          cfgAck = &e2NodeUpdateAckItemIe->e2nodeComponentConfigurationAck;
5605       }
5606
5607       case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
5608       {
5609          e2NodeRemovalAckItemIe= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
5610          switch(e2NodeRemovalAckItemIe->e2nodeComponentInterfaceType)
5611          {
5612             case E2nodeComponentInterfaceType_f1:
5613                {
5614                   f1InterfaceInfo = e2NodeRemovalAckItemIe->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
5615                   break;
5616                }
5617             default:
5618                {
5619                   break;
5620                }
5621          }
5622          cfgAck = &e2NodeRemovalAckItemIe->e2nodeComponentConfigurationAck;
5623       }
5624    }
5625    
5626    /* Freeing the memory allocated to component interface and configuration ack */
5627    if(f1InterfaceInfo)
5628    {
5629       RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
5630       RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
5631    }
5632
5633    switch(cfgAck->updateOutcome)
5634    {
5635       case E2nodeComponentConfigurationAck__updateOutcome_success:
5636          break;
5637       case E2nodeComponentConfigurationAck__updateOutcome_failure:
5638          {
5639             RIC_FREE(cfgAck->failureCauseE2, sizeof(CauseE2_t));
5640             break;
5641          }
5642    }
5643
5644 }
5645
5646 /*******************************************************************
5647  *
5648  * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg 
5649  *
5650  * @details
5651  *
5652  *    Function : FreeE2NodeConfigUpdate 
5653  *
5654  *    Functionality:
5655  *       - freeing the memory allocated for E2nodeConfigurationUpdate
5656  *
5657  * @params[in] E2AP_PDU_t *e2apMsg 
5658  * @return ROK     - success
5659  *         RFAILED - failure
5660  *
5661  * ****************************************************************/
5662
5663 void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
5664 {
5665    uint8_t arrIdx =0, e2NodeConfigIdx=0;
5666    E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg=NULL;
5667    E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
5668    E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
5669    E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
5670    E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
5671    E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
5672    E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
5673
5674    if(e2apMsg != NULLP)
5675    {
5676       if(e2apMsg->choice.successfulOutcome != NULLP)
5677       {
5678          updateAckMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
5679          if(updateAckMsg->protocolIEs.list.array != NULLP)
5680          {
5681             for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
5682             {
5683                if(updateAckMsg->protocolIEs.list.array[arrIdx])
5684                {
5685                   switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
5686                   {
5687                      case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
5688                         {
5689                            additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
5690                            if(additionAckList->list.array)
5691                            {
5692                               for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
5693                               {
5694                                  additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
5695                                  if(additionAckItemIte)
5696                                  {
5697                                     freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck,\
5698                                     (PTR)&additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item);
5699                                     RIC_FREE(additionAckItemIte, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
5700                                  }
5701                               }
5702                               RIC_FREE(additionAckList->list.array, additionAckList->list.size);
5703                            }
5704                            break;
5705                         }
5706                      case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
5707                         {
5708                            updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
5709                            if(updateAckList->list.array)
5710                            {
5711                               for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
5712                               {
5713                                  updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
5714                                  if(updateAckItemIe)
5715                                  {
5716                                     freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck,\
5717                                     (PTR)&updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item);
5718                                     RIC_FREE(updateAckItemIe, sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t));
5719                                  }
5720                               }
5721                               RIC_FREE(updateAckList->list.array, updateAckList->list.size);
5722                            }
5723                            break;
5724                         }
5725                      case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
5726                         {
5727                            removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
5728                            if(removalAckList->list.array)
5729                            {
5730                               for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
5731                               {
5732                                  removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
5733                                  if(removalAckItemIe)
5734                                  {
5735                                     freeE2NodeConfigItem(ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck,\
5736                                     (PTR)&removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item);
5737                                     RIC_FREE(removalAckItemIe, sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t));
5738                                  }
5739                               }
5740                               RIC_FREE(removalAckList->list.array, removalAckList->list.size);
5741                            }
5742                            break;
5743                         }
5744                   }
5745                   RIC_FREE(updateAckMsg->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
5746                }
5747             }
5748             RIC_FREE(updateAckMsg->protocolIEs.list.array, updateAckMsg->protocolIEs.list.size);
5749          }
5750          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
5751       }
5752       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
5753    }
5754 }
5755
5756 /*******************************************************************
5757  *
5758  * @brief Build E2node Component config Removal ack list
5759  *
5760  * @details
5761  *
5762  *    Function :  BuildE2nodeComponentConfigRemovalAck
5763  *
5764  *    Functionality: Build the e2 node remove ack 
5765  *
5766  * @params[in] 
5767  *    E2nodeComponentConfigRemovalAck_List_t to be filled
5768  *    Count of e2 node to be removed
5769  *    list of e2 node cfg to be removed
5770  *
5771  * @return ROK - success
5772  *         RFAILED - failure
5773  * ****************************************************************/
5774
5775 uint8_t BuildE2nodeComponentConfigRemovalAck(E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList,\
5776 uint16_t removalE2NodeCount, E2NodeConfigItem *removaldE2Node)
5777 {
5778    uint8_t arrIdx = 0;
5779    E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULL;
5780    
5781    /* Filling the e2 node config removal ack list */
5782    e2NodeConfigRemovalAckList->list.count = removalE2NodeCount;
5783    e2NodeConfigRemovalAckList->list.size = e2NodeConfigRemovalAckList->list.count * sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t*);
5784    RIC_ALLOC(e2NodeConfigRemovalAckList->list.array, e2NodeConfigRemovalAckList->list.size);
5785    if(e2NodeConfigRemovalAckList->list.array == NULLP)
5786    {
5787       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigRemovalAck %d",__LINE__);
5788       return RFAILED;
5789    }
5790
5791    for(arrIdx = 0; arrIdx< e2NodeConfigRemovalAckList->list.count; arrIdx++)
5792    {
5793       RIC_ALLOC(e2NodeConfigRemovalAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemovalAck_ItemIEs_t));
5794       if(e2NodeConfigRemovalAckList->list.array[arrIdx] == NULLP)
5795       {
5796          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigRemovalAck %d",__LINE__);
5797          return RFAILED;
5798       }
5799       e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[arrIdx];
5800       e2NodeRemovalAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck_Item;
5801       e2NodeRemovalAckItem->criticality = CriticalityE2_reject;
5802       e2NodeRemovalAckItem->value.present = E2nodeComponentConfigRemovalAck_ItemIEs__value_PR_E2nodeComponentConfigRemovalAck_Item;
5803       
5804       /* Filling the e2 node config removal ack item */
5805       fillE2NodeConfigAck((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck,\
5806       &removaldE2Node[arrIdx].componentInfo, removaldE2Node[arrIdx].isSuccessful);
5807    }
5808    return ROK;  
5809 }
5810
5811 /*******************************************************************
5812  *
5813  * @brief Build E2node Component config update ack list
5814  *
5815  * @details
5816  *
5817  *    Function :  BuildE2nodeComponentConfigUpdateAck
5818  *
5819  *    Functionality: Build E2node Component config update ack list 
5820  *
5821  * @params[in] 
5822  *    E2nodeComponentConfigUpdateAck_List to be filled
5823  *    Count of e2 node to be update
5824  *    list of e2 node cfg to be update
5825  *
5826  * @return ROK - success
5827  *         RFAILED - failure
5828  * ****************************************************************/
5829
5830 uint8_t BuildE2nodeComponentConfigUpdateAck(E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList,\
5831 uint16_t updatedE2NodeCount, E2NodeConfigItem *updatedE2Node)
5832 {
5833    uint8_t arrIdx = 0;
5834    E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULL;
5835    
5836    /* Filling the e2 node config update ack list */
5837    e2NodeConfigUpdateAckList->list.count = updatedE2NodeCount;
5838    e2NodeConfigUpdateAckList->list.size = e2NodeConfigUpdateAckList->list.count * sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t*);
5839    RIC_ALLOC(e2NodeConfigUpdateAckList->list.array, e2NodeConfigUpdateAckList->list.size);
5840    if(e2NodeConfigUpdateAckList->list.array == NULLP)
5841    {
5842       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
5843       return RFAILED;
5844    }
5845
5846    for(arrIdx = 0; arrIdx< e2NodeConfigUpdateAckList->list.count; arrIdx++)
5847    {
5848       RIC_ALLOC(e2NodeConfigUpdateAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdateAck_ItemIEs_t));
5849       if(e2NodeConfigUpdateAckList->list.array[arrIdx] == NULLP)
5850       {
5851          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
5852          return RFAILED;
5853       }
5854       e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[arrIdx];
5855       e2NodeUpdateAckItem->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck_Item;
5856       e2NodeUpdateAckItem->criticality = CriticalityE2_reject;
5857       e2NodeUpdateAckItem->value.present = E2nodeComponentConfigUpdateAck_ItemIEs__value_PR_E2nodeComponentConfigUpdateAck_Item;
5858       
5859       /* Filling the e2 node config update ack item */
5860       fillE2NodeConfigAck((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck,\
5861       &updatedE2Node[arrIdx].componentInfo, updatedE2Node[arrIdx].isSuccessful);
5862
5863    }
5864    return ROK;  
5865 }
5866
5867 /*******************************************************************
5868  *
5869  * @brief Buld and send the E2 node config update ack msg 
5870  *
5871  * @details
5872  *
5873  *    Function : BuildAndSendE2NodeConfigUpdateAck 
5874  *
5875  *    Functionality:
5876  *         - Buld and send the E2 node config update ack msg
5877  * @params[in] 
5878  *    DU databse 
5879  *    transId 
5880  *    list of E2 node cfg which needs to fill in IEs
5881  * @return ROK     - success
5882  *         RFAILED - failure
5883  *
5884  * ****************************************************************/
5885
5886 uint8_t BuildAndSendE2NodeConfigUpdateAck(DuDb *duDb, uint8_t transId,  E2NodeConfigList *e2NodeList)
5887 {
5888    uint8_t ret = RFAILED;
5889    uint8_t arrIdx = 0,elementCnt = 0;
5890    E2AP_PDU_t        *e2apMsg = NULLP;
5891    asn_enc_rval_t     encRetVal;       
5892    E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP;
5893
5894    DU_LOG("\nINFO   -->  E2AP : Building E2 Node config update Ack Message\n");
5895    do
5896    {
5897       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5898       if(e2apMsg == NULLP)
5899       {
5900          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5901          break;
5902       }
5903       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
5904       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
5905       if(e2apMsg->choice.successfulOutcome == NULLP)
5906       {
5907          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5908          break;
5909       }
5910       
5911       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
5912       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate;
5913       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge;
5914       e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
5915       
5916       elementCnt =1;
5917       if(e2NodeList->addedE2NodeCount)
5918          elementCnt++;
5919       if(e2NodeList->updatedE2NodeCount)
5920          elementCnt++;
5921       if(e2NodeList->removedE2NodeCount)
5922          elementCnt++;
5923
5924       e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt;
5925       e2NodeConfigUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*);
5926       RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size);
5927       if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP)
5928       {
5929          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5930          break;
5931       }
5932       
5933       for(arrIdx =0; arrIdx<elementCnt; arrIdx++)
5934       {
5935          RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t));
5936          if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
5937          {
5938             
5939             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__,__LINE__);
5940             break;
5941          }
5942       }
5943       
5944       if(arrIdx<elementCnt)
5945          break;
5946
5947       arrIdx = 0;
5948       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
5949       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5950       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID;
5951       e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
5952       
5953       if(e2NodeList->addedE2NodeCount)
5954       {
5955          arrIdx++;
5956          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
5957          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5958          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigAdditionAck_List;
5959          if(BuildE2nodeComponentConfigAdditionAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List,\
5960                   e2NodeList->addedE2NodeCount, e2NodeList->addedE2Node)!=ROK)
5961
5962          {
5963             DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
5964             break;
5965          }
5966       }
5967       if(e2NodeList->updatedE2NodeCount)
5968       {
5969          arrIdx++;
5970          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck;
5971          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5972          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigUpdateAck_List;
5973          if(BuildE2nodeComponentConfigUpdateAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List,\
5974                   e2NodeList->updatedE2NodeCount, e2NodeList->updatedE2Node)!=ROK)
5975
5976          {
5977             DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config update ack list");
5978             break;
5979          }
5980       }
5981       if(e2NodeList->removedE2NodeCount)
5982       {
5983          arrIdx++;
5984          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck;
5985          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
5986          e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_E2nodeComponentConfigRemovalAck_List;
5987          if(BuildE2nodeComponentConfigRemovalAck(&e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List,\
5988                   e2NodeList->removedE2NodeCount, e2NodeList->removedE2Node)!=ROK)
5989
5990          {
5991             DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config removal ack list");
5992             break;
5993          }
5994       }      
5995       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5996
5997       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5998       encBufSize = 0;
5999       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
6000             encBuf);
6001       if(encRetVal.encoded == ENCODE_FAIL)
6002       {
6003          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\
6004                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6005          break;
6006       }
6007       else
6008       {
6009          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Node config update ack \n");
6010          for(int i=0; i< encBufSize; i++)
6011          {
6012             DU_LOG("%x",encBuf[i]);
6013          } 
6014       }
6015
6016
6017       /* Sending msg */
6018       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
6019       {
6020          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Node config update ack ");
6021          break;
6022       }
6023       ret = ROK;
6024       break;
6025    }while(true);
6026    
6027    FreeE2NodeConfigUpdateAck(e2apMsg);
6028    return ret;
6029 }
6030
6031
6032 /******************************************************************
6033  *
6034  * @brief Processes the E2 removal failure msg
6035  *
6036  * @details
6037  *
6038  *    Function : procE2RemovalFailure
6039  *
6040  *    Functionality: Processes the E2 removal failure msg
6041  *
6042  * @params[in] 
6043  *       E2 Removal Failure information
6044  *
6045  * @return void
6046  *
6047  * ****************************************************************/
6048 void ProcE2RemovalFailure(E2RemovalFailure_t *e2RemovalFailure) 
6049 {
6050    uint8_t ieIdx = 0, transId=0;
6051    CauseE2_t *cause = NULLP;
6052
6053    if(!e2RemovalFailure)
6054    {
6055       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure pointer is null"); 
6056       return;
6057    }
6058
6059    if(!e2RemovalFailure->protocolIEs.list.array)      
6060    {
6061       DU_LOG("\nERROR  -->  E2AP : e2RemovalFailure array pointer is null");
6062       return;
6063    }
6064    
6065    for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
6066    {
6067       if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
6068       {
6069          switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id)
6070          {
6071             case ProtocolIE_IDE2_id_TransactionID:
6072                {
6073                   transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
6074                   DU_LOG("\nERROR  -->  E2AP : Received transID %d", transId);
6075                   break;
6076                }
6077             case ProtocolIE_IDE2_id_CauseE2:
6078                {
6079                    cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
6080                    printE2ErrorCause(cause);
6081                    break; 
6082                }
6083             default:
6084                {
6085                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%d]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id);
6086                   break;
6087                }
6088          }
6089       }
6090    }
6091 }
6092 /*******************************************************************
6093  *
6094  * @brief Delete E2 component node list
6095  *
6096  * @details
6097  *
6098  *    Function : deleteE2ComponentNodeList 
6099  *
6100  * Functionality: Delete E2 component node  list
6101  *
6102  * @params[in] E2 component node list
6103  * @return void
6104
6105  *
6106  ******************************************************************/
6107
6108 void deleteE2ComponentNodeList(CmLListCp *componentList)
6109 {
6110    E2NodeComponent *cfgInfo = NULLP;
6111    CmLList *e2ComponentNode = NULLP;
6112
6113    CM_LLIST_FIRST_NODE(componentList, e2ComponentNode);
6114    while(e2ComponentNode)
6115    {
6116       cfgInfo = (E2NodeComponent*)e2ComponentNode->node;
6117       cmLListDelFrm(componentList, e2ComponentNode);
6118       memset(cfgInfo, 0, sizeof(E2NodeComponent));
6119       CM_LLIST_FIRST_NODE(componentList, e2ComponentNode);
6120    }
6121 }
6122
6123 /*******************************************************************
6124  *
6125  * @brief process the E2 node information from ric db
6126  *
6127  * @details
6128  *
6129  *    Function : deleteE2NodeInfo
6130  *
6131  * Functionality: process the E2 node information from ric db
6132  *
6133  * @params[in] 
6134  *       du Id
6135  *      
6136  * @return void
6137  *
6138  ******************************************************************/
6139 void deleteE2NodeInfo(DuDb *duDb)
6140 {
6141    uint16_t ranFuncIdx =0;
6142    RanFunction *ranFuncDb=NULLP;
6143
6144    DU_LOG("\nINFO  -->  E2AP : Removing all the E2 node information");
6145    for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
6146    {
6147       ranFuncDb = &duDb->ranFunction[ranFuncIdx];
6148       if(ranFuncDb->id > 0)
6149       {
6150          deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
6151       }
6152    }
6153    deleteE2ComponentNodeList(&duDb->e2NodeComponent);
6154 }
6155
6156 /*******************************************************************
6157  *
6158  * @brief process the E2 Removal Response
6159  *
6160  * @details
6161  *
6162  *    Function : ProcE2RemovalResponse 
6163  *
6164  * Functionality: Process E2 Removal Response 
6165  *
6166  * @params[in] 
6167  *       du Id
6168  *       Pointer to removal response 
6169  * @return void
6170  *
6171  ******************************************************************/
6172
6173 void ProcE2RemovalResponse(uint32_t duId, E2RemovalResponse_t *removalRsp)
6174 {
6175    uint8_t ieIdx = 0, duIdx =0;
6176    DuDb *duDb = NULLP;
6177
6178    SEARCH_DU_DB(duIdx, duId, duDb);
6179    if(duDb == NULLP)
6180    {
6181       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6182       return;
6183    }
6184
6185    if(!removalRsp)
6186    {
6187       DU_LOG("\nERROR  -->  E2AP : removalRsp pointer is null"); 
6188       return;
6189    }
6190
6191    if(!removalRsp->protocolIEs.list.array)      
6192    {
6193       DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
6194       return;
6195    }
6196
6197    for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
6198    {
6199       if(removalRsp->protocolIEs.list.array[ieIdx])
6200       {
6201          switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
6202          {
6203             case ProtocolIE_IDE2_id_TransactionID:
6204                {
6205                   DU_LOG("\nINFO  -->  E2AP : Sending request to close the sctp connection");
6206                   cmInetClose(&sctpCb.e2LstnSockFd);
6207                   deleteE2NodeInfo(duDb);
6208                   exit(0);
6209                }
6210             default:
6211                {
6212                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
6213                   break;
6214                }
6215          }
6216       }
6217    }
6218 }
6219 /*******************************************************************
6220  *
6221  * @brief Deallocate the memory allocated for E2 Removal Failure
6222  *
6223  * @details
6224  *
6225  *    Function : FreeE2RemovalFailure
6226  *
6227  *    Functionality:
6228  *       - freeing the memory allocated for E2RemovalFailure
6229  *
6230  * @params[in] E2AP_PDU_t *e2apMsg
6231  * @return void
6232  *
6233  * ****************************************************************/
6234 void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
6235 {
6236    uint8_t ieIdx =0;
6237    E2RemovalFailure_t *e2RemovalFailure=NULLP;
6238
6239    if(e2apMsg != NULLP)
6240    {
6241       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
6242       {
6243          e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
6244          if(e2RemovalFailure->protocolIEs.list.array)
6245          {
6246             for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
6247             {
6248                if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
6249                {
6250                   RIC_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
6251                }
6252             }
6253             RIC_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
6254          }
6255          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
6256       }
6257       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6258    }
6259 }
6260
6261 /*******************************************************************
6262  *
6263  * @brief Buld and send the E2 Removal Failure msg
6264  *
6265  * @details
6266  *
6267  *    Function : BuildAndSendE2RemovalFailure
6268  *
6269  *    Functionality:
6270  *         - Buld and send the E2 Removal Failure Message
6271  * @params[in] 
6272  *    DU Id
6273  *    Trans Id 
6274  *    Type of failure 
6275  *    Cause of failure
6276  * @return ROK     - success
6277  *         RFAILED - failure
6278  *
6279  * ****************************************************************/
6280
6281 uint8_t BuildAndSendRemovalFailure(uint32_t duId, uint16_t transId,  CauseE2_PR causePresent, uint8_t reason)
6282 {
6283    uint8_t           ieIdx = 0, elementCnt = 0;
6284    uint8_t           ret = RFAILED;
6285    E2AP_PDU_t        *e2apMsg = NULLP;
6286    E2RemovalFailure_t *e2RemovalFailure=NULLP;
6287    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6288
6289    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Failure Message\n");
6290    do
6291    {
6292       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6293       if(e2apMsg == NULLP)
6294       {
6295          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6296          break;
6297       }
6298       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
6299
6300       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
6301       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
6302       {
6303          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6304          break;
6305       }
6306
6307       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
6308       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
6309       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure;
6310       e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
6311
6312       elementCnt = 2;
6313       e2RemovalFailure->protocolIEs.list.count = elementCnt;
6314       e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *);
6315       RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
6316       if(!e2RemovalFailure->protocolIEs.list.array)
6317       {
6318          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6319          break;
6320       }
6321
6322       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6323       {
6324          RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
6325          if(!e2RemovalFailure->protocolIEs.list.array[ieIdx])
6326          {
6327             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6328             break;
6329          }
6330       }
6331       if(ieIdx < elementCnt)
6332          break;
6333
6334       ieIdx = 0;
6335       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6336       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6337       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID;
6338       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6339
6340       /* Cause */
6341       ieIdx++;
6342       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
6343       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
6344       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
6345       fillE2FailureCause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
6346       
6347       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6348
6349       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6350       encBufSize = 0;
6351       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6352       if(encRetVal.encoded == ENCODE_FAIL)
6353       {
6354          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal failure structure (at %s)\n",\
6355                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6356          break;
6357       }
6358       else
6359       {
6360          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Failure \n");
6361          for(int i=0; i< encBufSize; i++)
6362          {
6363             DU_LOG("%x",encBuf[i]);
6364          }
6365       }
6366
6367       /* Sending msg */
6368       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6369       {
6370          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Failure");
6371          break;
6372       }
6373
6374       ret = ROK;
6375       break;
6376    }while(true);
6377
6378    FreeE2RemovalFailure(e2apMsg);
6379    return ret;
6380 }
6381
6382 /*******************************************************************
6383  *
6384  * @brief Deallocate the memory allocated for E2 Removal Response
6385  *
6386  * @details
6387  *
6388  *    Function : FreeE2RemovalResponse
6389  *
6390  *    Functionality:
6391  *       - freeing the memory allocated for E2RemovalResponse
6392  *
6393  * @params[in] E2AP_PDU_t *e2apMsg
6394  * @return ROK     - success
6395  *         RFAILED - failure
6396  *
6397  * ****************************************************************/
6398 void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
6399 {
6400    uint8_t ieIdx =0;
6401    E2RemovalResponse_t *e2RemovalResponse=NULLP;
6402
6403    if(e2apMsg != NULLP)
6404    {
6405       if(e2apMsg->choice.successfulOutcome != NULLP)
6406       {
6407          e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
6408          if(e2RemovalResponse->protocolIEs.list.array)
6409          {
6410             for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++)
6411             {
6412                if(e2RemovalResponse->protocolIEs.list.array[ieIdx])
6413                {
6414                   RIC_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
6415                }
6416             }
6417             RIC_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
6418          }
6419          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6420       }
6421       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6422    }
6423 }
6424
6425 /*******************************************************************
6426  *
6427  * @brief Buld and send the E2 Removal Response msg
6428  *
6429  * @details
6430  *
6431  *    Function : BuildAndSendE2RemovalResponse
6432  *
6433  *    Functionality:
6434  *         - Buld and send the E2 Removal Response Message
6435  * @params[in] 
6436  *    Du Id
6437  *    Trans Id 
6438  * @return ROK     - success
6439  *         RFAILED - failure
6440  *
6441  * ****************************************************************/
6442 uint8_t BuildAndSendRemovalResponse(uint32_t duId, uint16_t transId)
6443 {
6444    uint8_t ieIdx = 0, elementCnt = 0;
6445    uint8_t ret = RFAILED, duIdx =0;
6446    E2AP_PDU_t *e2apMsg = NULLP;
6447    DuDb *duDb = NULLP;
6448    E2RemovalResponse_t *e2RemovalResponse=NULLP;
6449    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6450
6451    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Response Message\n");
6452    do
6453    {
6454       SEARCH_DU_DB(duIdx, duId, duDb);
6455       if(duDb == NULLP)
6456       {
6457          DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6458          return;
6459       }
6460    
6461       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6462       if(e2apMsg == NULLP)
6463       {
6464          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6465          break;
6466       }
6467       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6468
6469       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6470       if(e2apMsg->choice.successfulOutcome == NULLP)
6471       {
6472          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6473          break;
6474       }
6475
6476       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
6477       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6478       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse;
6479       e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
6480
6481       elementCnt = 1;
6482       e2RemovalResponse->protocolIEs.list.count = elementCnt;
6483       e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *);
6484       RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
6485       if(!e2RemovalResponse->protocolIEs.list.array)
6486       {
6487          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6488          break;
6489       }
6490
6491       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6492       {
6493          RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
6494          if(!e2RemovalResponse->protocolIEs.list.array[ieIdx])
6495          {
6496             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6497             break;
6498          }
6499       }
6500       if(ieIdx < elementCnt)
6501          break;
6502
6503       ieIdx = 0;
6504       e2RemovalResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6505       e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6506       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID;
6507       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6508
6509       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6510
6511       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6512       encBufSize = 0;
6513       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6514       if(encRetVal.encoded == ENCODE_FAIL)
6515       {
6516          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal response structure (at %s)\n",\
6517                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6518          break;
6519       }
6520       else
6521       {
6522          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Response \n");
6523          for(int i=0; i< encBufSize; i++)
6524          {
6525             DU_LOG("%x",encBuf[i]);
6526          }
6527       }
6528
6529       /* Sending msg */
6530       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6531       {
6532          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Response");
6533          break;
6534       }
6535
6536       ret = ROK;
6537       break;
6538    }while(true);
6539
6540    FreeE2RemovalResponse(e2apMsg);
6541    return ret;
6542 }
6543
6544 /*******************************************************************
6545  *
6546  * @brief Process Removal req received from RIC
6547  *
6548  * @details
6549  *
6550  *    Function : procE2RemovalRequest
6551  *
6552  * Functionality: Process Removal req received from RIC
6553  *
6554  * @param  
6555  *    DU id
6556  *    E2 Removal Request 
6557  * @return void
6558  *
6559  ******************************************************************/
6560
6561 void procE2RemovalRequest(uint32_t duId, E2RemovalRequest_t *removalReq)
6562 {
6563    uint8_t arrIdx =0;
6564    uint16_t transId =0;
6565
6566    DU_LOG("\nINFO   -->  E2AP : E2 Removal request received");
6567    
6568    for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
6569    {
6570       switch(removalReq->protocolIEs.list.array[arrIdx]->id)
6571       {
6572          case ProtocolIE_IDE2_id_TransactionID:
6573             {
6574                transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
6575                break;
6576             }
6577          default:
6578             {
6579                DU_LOG("\nERROR  -->  E2AP : Invalid IE recevied [%d]", transId);
6580                break;
6581             }
6582       }
6583    }
6584    
6585    if(transId>=0 && transId<=255)
6586    {
6587       if(BuildAndSendRemovalResponse(duId, transId) != ROK)
6588       {
6589          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
6590       }
6591    }
6592    else
6593    {
6594       if(BuildAndSendRemovalFailure(duId, transId, CauseE2_PR_protocol, CauseE2Protocol_abstract_syntax_error_falsely_constructed_message) != ROK)
6595       {
6596          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
6597       }
6598    }
6599 }
6600
6601 /*******************************************************************
6602  *
6603  * @brief fill E2 connection update item
6604  *
6605  * @details
6606  *
6607  *    Function : fillE2connectionUpdateItem 
6608  *
6609  *    Functionality: fill E2 connection update item
6610  *
6611  * @params[in]
6612  *    E2connectionUpdate Item to be filled
6613  *    Protocol Id
6614  * @return ROK - success
6615  *         RFAILED - failure
6616  * ****************************************************************/
6617
6618 uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId)
6619 {
6620    E2connectionUpdateRemove_Item_t *connectionRemoveITem=NULLP;
6621    E2connectionUpdate_Item_t *connectionModifyItem=NULLP;
6622    TNLinformation_t *tnlInformation = NULLP;
6623    TNLusage_t  *tnlUsage=NULLP;
6624
6625    switch(protocolId)
6626    {
6627       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
6628       {
6629          connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo;
6630          tnlInformation = &connectionModifyItem->tnlInformation;
6631          tnlUsage = &connectionModifyItem->tnlUsage;
6632          break;
6633       }
6634
6635       case ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item:
6636       {
6637          connectionRemoveITem = (E2connectionUpdateRemove_Item_t*)connectionInfo;
6638          tnlInformation= &connectionRemoveITem->tnlInformation;
6639          break;
6640       }
6641    }
6642    
6643    tnlInformation->tnlAddress.size =  4*sizeof(uint8_t);
6644    RIC_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size);
6645    if(!tnlInformation->tnlAddress.buf)
6646    {
6647       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6648       return RFAILED;
6649    }
6650    
6651    tnlInformation->tnlAddress.buf[3] =  ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr & 0xFF; 
6652    tnlInformation->tnlAddress.buf[2] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 8) & 0xFF;
6653    tnlInformation->tnlAddress.buf[1] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 16) & 0xFF;
6654    tnlInformation->tnlAddress.buf[0] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 24) & 0xFF;
6655    tnlInformation->tnlAddress.bits_unused = 0;
6656    if(protocolId == ProtocolIE_IDE2_id_E2connectionUpdate_Item)
6657    {
6658       *tnlUsage = TNLusage_support_function; 
6659    }
6660    return ROK;
6661 }
6662
6663 /*******************************************************************
6664  *
6665  * @brief Build E2 connection modification list
6666  *
6667  * @details
6668  *
6669  *    Function : BuildE2ConnectionModifyList
6670  *
6671  *    Functionality: Build E2 connection modification list
6672  *
6673  * @params[in]
6674  *    E2 connection modification list to be filled
6675  *
6676  * @return ROK - success
6677  *         RFAILED - failure
6678  * ****************************************************************/
6679
6680 uint8_t BuildE2ConnectionModifyList(E2connectionUpdate_List_t *connectionToBeModifyList)
6681 {
6682    uint8_t arrIdx = 0;
6683    E2connectionUpdate_ItemIEs_t *connectionModify=NULL;
6684
6685    connectionToBeModifyList->list.count = 1;
6686  
6687    connectionToBeModifyList->list.size = connectionToBeModifyList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*);
6688    RIC_ALLOC(connectionToBeModifyList->list.array, connectionToBeModifyList->list.size);
6689    if(connectionToBeModifyList->list.array)
6690    {
6691       for(arrIdx = 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++)
6692       {
6693          RIC_ALLOC(connectionToBeModifyList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
6694          if(connectionToBeModifyList->list.array[arrIdx] == NULLP)
6695          {
6696             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6697             return RFAILED;
6698          }
6699          connectionModify = (E2connectionUpdate_ItemIEs_t*)connectionToBeModifyList->list.array[arrIdx];
6700          connectionModify->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item;
6701          connectionModify->criticality= CriticalityE2_ignore;
6702          connectionModify->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item;
6703          if(fillE2connectionUpdateItem((PTR)&connectionModify->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item) != ROK)
6704          {
6705             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
6706             return RFAILED;
6707          }
6708          
6709       }
6710    }
6711    else
6712    {
6713       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6714       return RFAILED;
6715    }
6716    return ROK;
6717 }
6718
6719 /*******************************************************************
6720  *
6721  * @brief Build E2 connection remove list
6722  *
6723  * @details
6724  *
6725  *    Function : BuildE2ConnectionRemoveList
6726  *
6727  *    Functionality: Build E2 connection remove list
6728  *
6729  * @params[in]
6730  *    E2 connection remove list to be filled
6731  *
6732  * @return ROK - success
6733  *         RFAILED - failure
6734  * ****************************************************************/
6735
6736 uint8_t BuildE2ConnectionRemoveList(E2connectionUpdateRemove_List_t *connectionToBeRemoveList)
6737 {
6738    uint8_t arrIdx = 0;
6739    E2connectionUpdateRemove_ItemIEs_t *connectionRemove=NULL;
6740
6741    connectionToBeRemoveList->list.count = 1;
6742  
6743    connectionToBeRemoveList->list.size = connectionToBeRemoveList->list.count*sizeof(E2connectionUpdateRemove_ItemIEs_t*);
6744    RIC_ALLOC(connectionToBeRemoveList->list.array, connectionToBeRemoveList->list.size);
6745    if(connectionToBeRemoveList->list.array)
6746    {
6747       for(arrIdx = 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++)
6748       {
6749          RIC_ALLOC(connectionToBeRemoveList->list.array[arrIdx], sizeof(E2connectionUpdateRemove_ItemIEs_t));
6750          if(connectionToBeRemoveList->list.array[arrIdx] == NULLP)
6751          {
6752             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6753             return RFAILED;
6754          }
6755          connectionRemove = (E2connectionUpdateRemove_ItemIEs_t*)connectionToBeRemoveList->list.array[arrIdx];
6756          connectionRemove->id = ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item;
6757          connectionRemove->criticality= CriticalityE2_ignore;
6758          connectionRemove->value.present = E2connectionUpdateRemove_ItemIEs__value_PR_E2connectionUpdateRemove_Item;
6759          if(fillE2connectionUpdateItem((PTR)&connectionRemove->value.choice.E2connectionUpdateRemove_Item, ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item) != ROK)
6760          {
6761             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
6762             return RFAILED;
6763          }
6764          
6765       }
6766    }
6767    else
6768    {
6769       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6770       return RFAILED;
6771    }
6772    return ROK;
6773 }
6774
6775 /*******************************************************************
6776  *
6777  * @brief Deallocate the memory allocated for E2ConnectionUpdate msg
6778  *
6779  * @details
6780  *
6781  *    Function : FreeE2ConnectionUpdate
6782  *
6783  *    Functionality:
6784  *       - freeing the memory allocated for E2ConnectionUpdate
6785  *
6786  * @params[in] E2AP_PDU_t *e2apMsg
6787  * @return ROK     - success
6788  *         RFAILED - failure
6789  *
6790  * ****************************************************************/
6791 void FreeE2ConnectionUpdate(E2AP_PDU_t *e2apMsg)
6792 {
6793    uint8_t ieIdx =0, arrIdx=0;
6794    E2connectionUpdate_t  *connectionUpdate = NULLP;
6795    E2connectionUpdate_List_t *connectionToBeModifyList = NULLP;
6796    E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP;
6797
6798    if(e2apMsg != NULLP)
6799    {
6800       if(e2apMsg->choice.initiatingMessage != NULLP)
6801       {
6802          connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
6803          if(connectionUpdate->protocolIEs.list.array)
6804          {
6805             for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
6806             {
6807                if(connectionUpdate->protocolIEs.list.array[ieIdx])
6808                {
6809                   switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
6810                   {
6811                      case ProtocolIE_IDE2_id_TransactionID:
6812                         break;
6813
6814                      case ProtocolIE_IDE2_id_E2connectionUpdateModify:
6815                         {
6816                            connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
6817                            if(connectionToBeModifyList->list.array)
6818                            {
6819                               for(arrIdx = 0; arrIdx < connectionToBeModifyList->list.count; arrIdx++)
6820                               {
6821                                  RIC_FREE(connectionToBeModifyList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
6822                               }
6823                               RIC_FREE(connectionToBeModifyList->list.array, connectionToBeModifyList->list.size);
6824                            }
6825                            break;
6826                         }
6827
6828                      case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
6829                         {
6830                            connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List;
6831                            if(connectionToBeRemoveList->list.array)
6832                            {
6833                               for(arrIdx = 0; arrIdx < connectionToBeRemoveList->list.count; arrIdx++)
6834                               {
6835                                  RIC_FREE(connectionToBeRemoveList->list.array[arrIdx], sizeof(E2connectionUpdateRemove_ItemIEs_t));
6836                               }
6837                               RIC_FREE(connectionToBeRemoveList->list.array, connectionToBeRemoveList->list.size);
6838                            }
6839                            break;
6840                         }
6841                   }
6842                   RIC_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdate_IEs_t));
6843                }
6844             }
6845             RIC_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size);
6846          }
6847          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6848       }
6849       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6850    }
6851 }
6852
6853 /*******************************************************************
6854  *
6855  * @brief Buld and send the E2 Connection Update msg
6856  *
6857  * @details
6858  *
6859  *    Function : BuildAndSendE2ConnectionUpdate
6860  *
6861  *    Functionality:
6862  *         - Buld and send the E2 Connection Update Message
6863  * @params[in] 
6864  *    Du Id
6865  *    E2 connection to be modify or delete
6866  * @return ROK     - success
6867  *         RFAILED - failure
6868  *
6869  * ****************************************************************/
6870
6871 uint8_t BuildAndSendE2ConnectionUpdate(uint32_t duId, E2Connection connectionInfo)
6872 {
6873    uint8_t ieIdx = 0, elementCnt = 0;
6874    uint8_t ret = RFAILED, duIdx =0;
6875    DuDb    *duDb = NULLP;
6876    E2AP_PDU_t *e2apMsg = NULLP;
6877    E2connectionUpdate_t *e2ConnectionUpdate=NULLP;
6878    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6879
6880    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Message\n");
6881    do
6882    {
6883       SEARCH_DU_DB(duIdx, duId, duDb);
6884       if(duDb == NULLP)
6885       {
6886          DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6887          return RFAILED;
6888       }
6889    
6890       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6891       if(e2apMsg == NULLP)
6892       {
6893          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6894          break;
6895       }
6896       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6897
6898       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6899       if(e2apMsg->choice.initiatingMessage == NULLP)
6900       {
6901          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6902          break;
6903       }
6904
6905       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
6906       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6907       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2connectionUpdate;
6908       e2ConnectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
6909
6910       elementCnt = 1;
6911       if(connectionInfo == MODIFY_CONNECTION) 
6912          elementCnt++;
6913       if(connectionInfo == REMOVE_CONNECTION)
6914          elementCnt++;
6915
6916       e2ConnectionUpdate->protocolIEs.list.count = elementCnt;
6917       e2ConnectionUpdate->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdate_IEs_t*);
6918       RIC_ALLOC(e2ConnectionUpdate->protocolIEs.list.array, e2ConnectionUpdate->protocolIEs.list.size);
6919       if(!e2ConnectionUpdate->protocolIEs.list.array)
6920       {
6921          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6922          break;
6923       }
6924
6925       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6926       {
6927          RIC_ALLOC(e2ConnectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdate_IEs_t));
6928          if(!e2ConnectionUpdate->protocolIEs.list.array[ieIdx])
6929          {
6930             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6931             break;
6932          }
6933       }
6934       if(ieIdx < elementCnt)
6935          break;
6936
6937       ieIdx = 0;
6938       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6939       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6940       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_TransactionID;
6941       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = assignTransactionId(duDb);
6942
6943       if(connectionInfo == MODIFY_CONNECTION)
6944       {
6945          ieIdx++;
6946          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionUpdateModify;
6947          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6948          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_E2connectionUpdate_List;
6949          if(BuildE2ConnectionModifyList(&e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List) != ROK)
6950          {
6951             DU_LOG("\nERROR  -->  E2AP : Failed to build the connection update modify list");
6952             break;
6953          }
6954       }
6955       
6956       if(connectionInfo == REMOVE_CONNECTION)
6957       {
6958          ieIdx++;
6959          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionUpdateRemove;
6960          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6961          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_E2connectionUpdateRemove_List;
6962          if(BuildE2ConnectionRemoveList(&e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List) != ROK)
6963          {
6964             DU_LOG("\nERROR  -->  E2AP : Failed to build the connection update modify list");
6965             break;
6966          }
6967       }
6968
6969       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6970
6971       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6972       encBufSize = 0;
6973       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6974       if(encRetVal.encoded == ENCODE_FAIL)
6975       {
6976          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update structure (at %s)\n",\
6977                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6978          break;
6979       }
6980       else
6981       {
6982          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update \n");
6983          for(int i=0; i< encBufSize; i++)
6984          {
6985             DU_LOG("%x",encBuf[i]);
6986          }
6987       }
6988
6989       /* Sending msg */
6990       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6991       {
6992          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update");
6993          break;
6994       }
6995
6996       ret = ROK;
6997       break;
6998    }while(true);
6999    
7000    FreeE2ConnectionUpdate(e2apMsg);
7001    return ret;
7002 }
7003
7004 /******************************************************************
7005  *
7006  * @brief Processes the E2 connection update failure msg
7007  *
7008  * @details
7009  *
7010  *    Function : procE2connectionUpdateFailure
7011  *
7012  *    Functionality: Processes the E2 connection update failure msg
7013  *
7014  * @params[in] 
7015  *       E2 connection update failure information
7016  *
7017  * @return void
7018  *
7019  * ****************************************************************/
7020 void ProcE2connectionUpdateFailure(E2connectionUpdateFailure_t *updateFailure) 
7021 {
7022    uint8_t ieIdx = 0;
7023    uint16_t transId=0;
7024    CauseE2_t *cause = NULLP;
7025
7026    if(!updateFailure)
7027    {
7028       DU_LOG("\nERROR  -->  E2AP : updateFailure pointer is null"); 
7029       return;
7030    }
7031
7032    if(!updateFailure->protocolIEs.list.array)      
7033    {
7034       DU_LOG("\nERROR  -->  E2AP : updateFailure array pointer is null");
7035       return;
7036    }
7037    
7038    for(ieIdx=0; ieIdx < updateFailure->protocolIEs.list.count; ieIdx++)
7039    {
7040       if(updateFailure->protocolIEs.list.array[ieIdx])
7041       {
7042          switch(updateFailure->protocolIEs.list.array[ieIdx]->id)
7043          {
7044             case ProtocolIE_IDE2_id_TransactionID:
7045                {
7046                   transId = updateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
7047                   DU_LOG("\nERROR  -->  E2AP : Received transID %d", transId);
7048                   break;
7049                }
7050             case ProtocolIE_IDE2_id_CauseE2:
7051                {
7052                    cause = &updateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
7053                    printE2ErrorCause(cause);
7054                    break; 
7055                }
7056             default:
7057                {
7058                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%d]", updateFailure->protocolIEs.list.array[ieIdx]->id);
7059                   break;
7060                }
7061          }
7062       }
7063    }
7064 }
7065
7066 /*******************************************************************
7067  *
7068  * @brief process the E2 Connection update ack
7069  *
7070  * @details
7071  *
7072  *    Function : ProcE2ConnectionUpdateAck 
7073  *
7074  * Functionality: Process E2 Connection update ack 
7075  *
7076  * @params[in] 
7077  *       du Id
7078  *       Pointer to Connection update ack 
7079  * @return void
7080  *
7081  ******************************************************************/
7082
7083 void ProcE2ConnectionUpdateAck(uint32_t duId, E2connectionUpdateAcknowledge_t *connectionUpdateAck)
7084 {
7085    uint16_t transId =0;
7086    uint32_t ipAddress=0;
7087    DuDb *duDb = NULLP;
7088    uint8_t ieIdx = 0, duIdx =0, arrIdx=0;
7089    E2connectionUpdate_Item_t *connectionSetupItem=NULLP;
7090    E2connectionUpdate_ItemIEs_t *connectionSetupItemIe=NULLP;
7091    E2connectionUpdate_List_t *connectionSetupList=NULLP;
7092    E2connectionSetupFailed_Item_t *setupFailedItem =NULLP;
7093    E2connectionSetupFailed_List_t *setupFailedList=NULLP;
7094    E2connectionSetupFailed_ItemIEs_t *setupFailedItemIe =NULLP;
7095
7096    SEARCH_DU_DB(duIdx, duId, duDb);
7097    if(duDb == NULLP)
7098    {
7099       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
7100       return;
7101    }
7102
7103    if(!connectionUpdateAck)
7104    {
7105       DU_LOG("\nERROR  -->  E2AP : connectionUpdateAck pointer is null"); 
7106       return;
7107    }
7108
7109    if(!connectionUpdateAck->protocolIEs.list.array)      
7110    {
7111       DU_LOG("\nERROR  -->  E2AP : connectionUpdateAck array pointer is null");
7112       return;
7113    }
7114
7115    for(ieIdx=0; ieIdx < connectionUpdateAck->protocolIEs.list.count; ieIdx++)
7116    {
7117       if(connectionUpdateAck->protocolIEs.list.array[ieIdx])
7118       {
7119          switch(connectionUpdateAck->protocolIEs.list.array[ieIdx]->id)
7120          {
7121             case ProtocolIE_IDE2_id_TransactionID:
7122                {
7123                   transId = connectionUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
7124                   if(transId>255)
7125                   {
7126                      DU_LOG("\nERROR  -->  E2AP : Received invalid trans id %d ",transId);
7127                      return;
7128                   }
7129                   break;
7130                }
7131             case ProtocolIE_IDE2_id_E2connectionSetup:
7132                {
7133                   connectionSetupList=&connectionUpdateAck->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
7134                   if(connectionSetupList->list.array)
7135                   {
7136                      for(arrIdx = 0; arrIdx< connectionSetupList->list.count; arrIdx++)
7137                      {
7138                         connectionSetupItemIe = (E2connectionUpdate_ItemIEs_t*)connectionSetupList->list.array[arrIdx];
7139                         connectionSetupItem = &connectionSetupItemIe->value.choice.E2connectionUpdate_Item;
7140                         bitStringToInt(&connectionSetupItem->tnlInformation.tnlAddress, &ipAddress);
7141                         if(ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr == ipAddress)
7142                         {
7143                             ricCb.ricCfgParams.sctpParams.usage = connectionSetupItem->tnlUsage;
7144                         }
7145                      }
7146                   }
7147                   break;
7148                }
7149
7150             case ProtocolIE_IDE2_id_E2connectionSetupFailed:
7151                {
7152                   setupFailedList=&connectionUpdateAck->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List;
7153                   if(setupFailedList->list.array)
7154                   {
7155                      for(arrIdx = 0; arrIdx< setupFailedList->list.count; arrIdx++)
7156                      {
7157                         setupFailedItemIe = (E2connectionSetupFailed_ItemIEs_t*)setupFailedList->list.array[arrIdx];
7158                         setupFailedItem = &setupFailedItemIe->value.choice.E2connectionSetupFailed_Item;
7159                         printE2ErrorCause(&setupFailedItem->cause);
7160                      }
7161                   }
7162                   break;
7163                }
7164             default:
7165                {
7166                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", connectionUpdateAck->protocolIEs.list.array[ieIdx]->id);
7167                   break;
7168                }
7169          }
7170       }
7171    }
7172 }
7173
7174 /******************************************************************
7175  *
7176  * @brief Processes the Ric Subs delete failure msg
7177  *
7178  * @details
7179  *
7180  *    Function : procRicSubsDeleteFailure
7181  *
7182  *    Functionality: Processes the Ric Subs delete failure msg
7183  *
7184  * @params[in]
7185  *       Ric Subs delete failure information
7186  *
7187  * @return void
7188  *
7189  * ****************************************************************/
7190 void ProcRicSubsDeleteFailure(RICsubscriptionDeleteFailure_t *ricSubsDeleteFail)
7191 {
7192    uint8_t ieIdx = 0;
7193    uint16_t ranFuncId=0;
7194    CauseE2_t *cause = NULLP;
7195    RICrequestID_t  ricRequestID;
7196
7197    if(!ricSubsDeleteFail)
7198    {
7199       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteFail pointer is null");
7200       return;
7201    }
7202
7203    if(!ricSubsDeleteFail->protocolIEs.list.array)
7204    {
7205       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteFail array pointer is null");
7206       return;
7207    }
7208
7209    for(ieIdx=0; ieIdx < ricSubsDeleteFail->protocolIEs.list.count; ieIdx++)
7210    {
7211       if(ricSubsDeleteFail->protocolIEs.list.array[ieIdx])
7212       {
7213          switch(ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->id)
7214          {
7215             case ProtocolIE_IDE2_id_RICrequestID:
7216                {
7217                   memcpy(&ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID, &ricRequestID, sizeof(RICrequestID_t));
7218                   DU_LOG("\nERROR  -->  E2AP : Received RicReqId %ld and InstanceId %ld", ricRequestID.ricRequestorID, ricRequestID.ricInstanceID);
7219                   break;
7220                }
7221             case ProtocolIE_IDE2_id_RANfunctionID:
7222                {
7223                   ranFuncId = ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
7224                   DU_LOG("\nERROR  -->  E2AP : Received ranfuncId %d", ranFuncId);
7225                   break;
7226                }
7227             case ProtocolIE_IDE2_id_CauseE2:
7228                {
7229                    cause = &ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
7230                    printE2ErrorCause(cause);
7231                    break;
7232                }
7233             default:
7234                {
7235                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubsDeleteFail->protocolIEs.list.array[ieIdx]->id);
7236                   break;
7237                }
7238          }
7239       }
7240    }
7241 }
7242
7243
7244 /******************************************************************
7245  *
7246  * @brief Processes the Ric Subs delete rsp msg
7247  *
7248  * @details
7249  *
7250  *    Function : ProcRicSubsDeleteRsp
7251  *
7252  *    Functionality: Processes the Ric Subs delete rsp msg
7253  *
7254  * @params[in]
7255  *       Ric Subs delete rsp information
7256  *
7257  * @return void
7258  *
7259  * ****************************************************************/
7260 void ProcRicSubsDeleteRsp(uint32_t duId, RICsubscriptionDeleteResponse_t *ricSubsDeleteRsp)
7261 {
7262    uint8_t ieIdx = 0;
7263    uint8_t duIdx= 0;
7264    uint16_t ranFuncId=0;
7265    RanFunction *ranFuncDb = NULLP;
7266    RicRequestId ricReqId;
7267    DuDb    *duDb = NULLP;
7268    RicSubscription *ricSubs = NULLP;
7269    CmLList *ricSubsNode = NULLP;
7270
7271    SEARCH_DU_DB(duIdx, duId, duDb);
7272    if(duDb == NULLP)
7273    {
7274       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
7275       return;
7276    }
7277
7278    if(!ricSubsDeleteRsp)
7279    {
7280       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteRsp pointer is null");
7281       return;
7282    }
7283
7284    if(!ricSubsDeleteRsp->protocolIEs.list.array)
7285    {
7286       DU_LOG("\nERROR  -->  E2AP : ricSubsDeleteRsp array pointer is null");
7287       return;
7288    }
7289    for(ieIdx=0; ieIdx < ricSubsDeleteRsp->protocolIEs.list.count; ieIdx++)
7290    {
7291       if(ricSubsDeleteRsp->protocolIEs.list.array[ieIdx])
7292       {
7293          switch(ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->id)
7294          {
7295             case ProtocolIE_IDE2_id_RICrequestID:
7296                {
7297                   ricReqId.requestorId = ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricRequestorID;
7298                   ricReqId.instanceId = ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricInstanceID;
7299                   break;
7300                }
7301             case ProtocolIE_IDE2_id_RANfunctionID:
7302                {
7303                   ranFuncId = ricSubsDeleteRsp->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
7304                   ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
7305                   if(!ranFuncDb)
7306                   {
7307                      DU_LOG("\nERROR  -->  E2AP : Invalid Ran Function id %d received",ranFuncId);
7308                      return;
7309                   }
7310
7311                   ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
7312                   if(ricSubs)
7313                   {
7314                      deleteRicSubscriptionNode(ricSubsNode);
7315                      DU_LOG("\nINFO  -->  E2AP : Ric subscription node deleted successfully");
7316                   }
7317                   else
7318                   {
7319                      DU_LOG("\nERROR  -->  E2AP : Ric subscription node is not present ");
7320                      return;
7321                   }
7322                   break;
7323                }
7324          }
7325       }
7326    }
7327 }
7328
7329
7330  /******************************************************************
7331   *
7332   * @brief Processes the Ric Subs modification failure msg
7333   *
7334   * @details
7335   *
7336   *    Function : procRicSubsModificationFailure
7337   *
7338   *    Functionality: Processes the Ric Subs modification failure msg
7339   *
7340   * @params[in]
7341   *       Ric Subs modification failure information
7342   *
7343   * @return void
7344   *
7345   * ****************************************************************/
7346  void ProcRicSubsModificationFailure(RICsubscriptionModificationFailure_t *ricSubsModificationFail)
7347  {
7348     uint8_t ieIdx = 0;
7349     uint16_t ranFuncId=0;
7350     CauseE2_t *cause = NULLP;
7351     RICrequestID_t  ricRequestID;
7352
7353     DU_LOG("\nINFO  -->  E2AP : Ric subscription modification failure received");
7354
7355     if(!ricSubsModificationFail)
7356     {
7357        DU_LOG("\nERROR  -->  E2AP : ricSubsModificationFail pointer is null");
7358        return;
7359     }
7360
7361     if(!ricSubsModificationFail->protocolIEs.list.array)
7362     {
7363        DU_LOG("\nERROR  -->  E2AP : ricSubsModificationFail array pointer is null");
7364        return;
7365     }
7366
7367     for(ieIdx=0; ieIdx < ricSubsModificationFail->protocolIEs.list.count; ieIdx++)
7368     {
7369        if(ricSubsModificationFail->protocolIEs.list.array[ieIdx])
7370        {
7371           switch(ricSubsModificationFail->protocolIEs.list.array[ieIdx]->id)
7372           {
7373              case ProtocolIE_IDE2_id_RICrequestID:
7374                 {
7375                    memcpy(&ricSubsModificationFail->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID, &ricRequestID, sizeof(RICrequestID_t));
7376                    DU_LOG("\nERROR  -->  E2AP : Received RicReqId %ld and InstanceId %ld", ricRequestID.ricRequestorID, ricRequestID.ricInstanceID);
7377                    break;
7378                 }
7379              case ProtocolIE_IDE2_id_RANfunctionID:
7380                 {
7381                    ranFuncId = ricSubsModificationFail->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
7382                    DU_LOG("\nERROR  -->  E2AP : Received ranfuncId %d", ranFuncId);
7383                    break;
7384                 }
7385              case ProtocolIE_IDE2_id_CauseE2:
7386                 {
7387                     cause = &ricSubsModificationFail->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
7388                     printE2ErrorCause(cause);
7389                     break;
7390                 }
7391              default:
7392                 {
7393                    DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubsModificationFail->protocolIEs.list.array[ieIdx]->id);
7394                    break;
7395                 }
7396           }
7397        }
7398     }
7399  }
7400
7401 /*******************************************************************
7402  *
7403  * @brief Free RIC Subscription  action to be added list
7404  *
7405  * @details
7406  *
7407  *    Function : FreeRicSubsActionToBeAdded
7408  *
7409  *    Functionality: Free the RIC Subscription action to be added list
7410  *
7411  * @params[in] RICactions_ToBeAddedForModification_List_t *subsDetails
7412  * @return void
7413  *
7414  * ****************************************************************/
7415 void FreeRicSubsActionToBeAdded(RICactions_ToBeAddedForModification_List_t *subsDetails)
7416 {
7417    uint8_t elementIdx = 0;
7418    RICaction_ToBeAddedForModification_ItemIEs_t *addedActionItemIe=NULLP;
7419
7420    if(subsDetails->list.array)
7421    {
7422       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
7423       {
7424          if(subsDetails->list.array[elementIdx])
7425          {
7426             addedActionItemIe = (RICaction_ToBeAddedForModification_ItemIEs_t*)subsDetails->list.array[elementIdx];
7427             RIC_FREE(addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition.buf, \
7428             addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition.size);
7429             RIC_FREE(subsDetails->list.array[elementIdx], sizeof(RICaction_ToBeAddedForModification_ItemIEs_t));
7430          }
7431       }
7432       RIC_FREE(subsDetails->list.array, subsDetails->list.size);
7433    }
7434 }
7435
7436 /*******************************************************************
7437  *
7438  * @brief Free RIC Subscription  action to be removed list
7439  *
7440  * @details
7441  *
7442  *    Function : FreeRicSubsActionToBeRemoved
7443  *
7444  *    Functionality: Free the RIC Subscription action to be removed list
7445  *
7446  * @params[in] RICactions_ToBeRemovedForModification_List_t *subsDetails
7447  * @return void
7448  *
7449  * ****************************************************************/
7450 void FreeRicSubsActionToBeRemoved(RICactions_ToBeRemovedForModification_List_t *subsDetails)
7451 {
7452    uint8_t elementIdx = 0;
7453
7454    if(subsDetails->list.array)
7455    {
7456       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
7457       {
7458          RIC_FREE(subsDetails->list.array[elementIdx], sizeof(RICaction_ToBeRemovedForModification_ItemIEs_t));
7459       }
7460       RIC_FREE(subsDetails->list.array, subsDetails->list.size);
7461    }
7462 }
7463
7464 /*******************************************************************
7465  *
7466  * @brief Free RIC Subscription action to be modify
7467  *
7468  * @details
7469  *
7470  *    Function : FreeRicSubsActionToBeModified
7471  *
7472  *    Functionality: Free the RIC Subscription action to be modify
7473  *
7474  * @params[in] RICactions_ToBeModifiedForModification_List_t List
7475  * @return void
7476  *
7477  * ****************************************************************/
7478 void FreeRicSubsActionToBeModified(RICactions_ToBeModifiedForModification_List_t *subsDetails)
7479 {
7480    uint8_t elementIdx = 0;
7481    RICaction_ToBeModifiedForModification_ItemIEs_t *actionItem = NULLP;
7482
7483    if(subsDetails->list.array)
7484    {
7485       for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++)
7486       {
7487          if(subsDetails->list.array[elementIdx])
7488          {
7489             actionItem = (RICaction_ToBeModifiedForModification_ItemIEs_t *)subsDetails->list.array[elementIdx];
7490             if(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition)
7491             {
7492                RIC_FREE(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition->buf, \
7493                   actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition->size);
7494                RIC_FREE(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
7495             }
7496             RIC_FREE(subsDetails->list.array[elementIdx], sizeof(RICaction_ToBeModifiedForModification_ItemIEs_t))
7497          }
7498       }
7499       RIC_FREE(subsDetails->list.array, subsDetails->list.size);
7500    }
7501 }
7502
7503 /*******************************************************************
7504  *
7505  * @brief Free RIC Subscription modification Request
7506  *
7507  * @details
7508  *
7509  *    Function :FreeRicSubscriptionModReq
7510  *
7511  * Functionality : Free RIC Subscription modification Request
7512  *
7513  * @params[in] E2AP_PDU
7514  * @return void
7515  *
7516  ******************************************************************/
7517 void FreeRicSubscriptionModReq(E2AP_PDU_t *e2apRicMsg)
7518 {
7519    uint8_t idx = 0;
7520    RICsubscriptionModificationRequest_t   *ricSubscriptionModReq =NULLP;
7521    RICsubscriptionModificationRequest_IEs_t *ricSubscriptionModReqIe=NULLP;
7522
7523    if(e2apRicMsg)
7524    {
7525       if(e2apRicMsg->choice.initiatingMessage)
7526       {
7527          ricSubscriptionModReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest;
7528          if(ricSubscriptionModReq->protocolIEs.list.array)
7529          {
7530             for(idx=0; idx < ricSubscriptionModReq->protocolIEs.list.count; idx++)
7531             {
7532                if(ricSubscriptionModReq->protocolIEs.list.array[idx])
7533                {
7534                   ricSubscriptionModReqIe = ricSubscriptionModReq->protocolIEs.list.array[idx];
7535                   switch(ricSubscriptionModReq->protocolIEs.list.array[idx]->id)
7536                   {
7537                      case ProtocolIE_IDE2_id_RICrequestID:
7538                         break;
7539                      case ProtocolIE_IDE2_id_RANfunctionID:
7540                         break;
7541                      case ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List:
7542                         {
7543                            FreeRicSubsActionToBeRemoved(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeRemovedForModification_List));
7544                            break;
7545                         }
7546                      case ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List:
7547                         {
7548                            FreeRicSubsActionToBeModified(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeModifiedForModification_List));
7549                            break;
7550                         }
7551                      case ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List:
7552                         {
7553                            FreeRicSubsActionToBeAdded(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeAddedForModification_List));
7554                            break;
7555                         }
7556                      default:
7557                         {
7558                            DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubscriptionModReq->protocolIEs.list.array[idx]->id);
7559                            break;
7560                         }
7561
7562                   }
7563
7564                   RIC_FREE(ricSubscriptionModReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionModificationRequest_IEs_t));
7565                }
7566             }
7567             RIC_FREE(ricSubscriptionModReq->protocolIEs.list.array, ricSubscriptionModReq->protocolIEs.list.size);
7568          }
7569          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7570       }
7571       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
7572    }
7573 }
7574
7575 /*******************************************************************
7576 *
7577 * @brief Build Ric subscription action to be modify list
7578 *
7579 * @details
7580 *
7581 *    Function : BuildRicSubsActionToBeModify
7582 *
7583 *    Functionality: Build Ric subscription action to be modify list
7584 *
7585 * @params[in]
7586 *    RICactions_ToBeModifiedForModification_List_t to be filled
7587 *    Num of action to be modify
7588 *    List of action to be modify
7589 *
7590 * @return ROK     - success
7591 *         RFAILED - failure
7592 *
7593 ******************************************************************/
7594
7595 uint8_t BuildRicSubsActionToBeModify(RICactions_ToBeModifiedForModification_List_t *modifyActionList, uint8_t numOfActionToBeModify, ActionInfo *actionToBeModify)
7596 {
7597    uint8_t arrIdx=0;
7598    RICaction_ToBeModifiedForModification_ItemIEs_t *modifiedActionItemIe=NULLP;
7599
7600    modifyActionList->list.count = numOfActionToBeModify;
7601    modifyActionList->list.size = modifyActionList->list.count *  sizeof(RICaction_ToBeModifiedForModification_ItemIEs_t*);
7602    RIC_ALLOC(modifyActionList->list.array, modifyActionList->list.size);
7603    if(!modifyActionList->list.array)
7604    {
7605       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7606       return RFAILED;
7607    }
7608
7609    for(arrIdx = 0; arrIdx< modifyActionList->list.count; arrIdx++)
7610    {
7611       RIC_ALLOC(modifyActionList->list.array[arrIdx], sizeof(RICaction_ToBeModifiedForModification_ItemIEs_t));
7612       if(!modifyActionList->list.array[arrIdx])
7613       {
7614          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7615          return RFAILED;
7616       }
7617       modifiedActionItemIe = (RICaction_ToBeModifiedForModification_ItemIEs_t*)modifyActionList->list.array[arrIdx];
7618       modifiedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item;
7619       modifiedActionItemIe->criticality = CriticalityE2_ignore;
7620       modifiedActionItemIe->value.present = RICaction_ToBeModifiedForModification_ItemIEs__value_PR_RICaction_ToBeModifiedForModification_Item;
7621       modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionID = actionToBeModify[arrIdx].actionId;
7622
7623       /* RIC Action Definition */
7624       RIC_ALLOC(modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
7625       if(!modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition)
7626       {
7627          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7628          break;
7629       }
7630
7631       if(fillRicActionDef(modifiedActionItemIe->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition,\
7632                actionToBeModify[arrIdx].actionId, CONFIG_MOD) != ROK)
7633       {
7634          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7635          break;
7636       }
7637
7638    }
7639    return ROK;
7640 }
7641
7642 /*******************************************************************
7643 *
7644 * @brief Build Ric subscription action to be removed list
7645 *
7646 * @details
7647 *
7648 *    Function : BuildRicSubsActionToBeRemoved
7649 *
7650 *    Functionality: Build Ric subscription action to be removed list
7651 *
7652 * @params[in]
7653 *    RICactions_ToBeRemovedForModification_List_t to be filled
7654 *    Num Of Action To Be Remove 
7655 *    Action remove list
7656 *
7657 * @return ROK     - success
7658 *         RFAILED - failure
7659 *
7660 ******************************************************************/
7661
7662 uint8_t BuildRicSubsActionToBeRemoved(RICactions_ToBeRemovedForModification_List_t *removeActionList, uint8_t numOfActionToBeRemove, ActionInfo *actionToBeRemove)
7663 {
7664    uint8_t arrIdx=0;
7665    RICaction_ToBeRemovedForModification_ItemIEs_t *removeActionItemIe=NULLP;
7666
7667    removeActionList->list.count = numOfActionToBeRemove;
7668    removeActionList->list.size = removeActionList->list.count *  sizeof(RICaction_ToBeRemovedForModification_ItemIEs_t*);
7669    RIC_ALLOC(removeActionList->list.array, removeActionList->list.size);
7670    if(!removeActionList->list.array)
7671    {
7672       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7673       return RFAILED;
7674    }
7675
7676    for(arrIdx = 0; arrIdx< removeActionList->list.count; arrIdx++)
7677    {
7678       RIC_ALLOC(removeActionList->list.array[arrIdx], sizeof(RICaction_ToBeRemovedForModification_ItemIEs_t));
7679       if(!removeActionList->list.array[arrIdx])
7680       {
7681          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7682          return RFAILED;
7683       }
7684       removeActionItemIe = (RICaction_ToBeRemovedForModification_ItemIEs_t*)removeActionList->list.array[arrIdx];
7685       removeActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ToBeRemovedForModification_Item;
7686       removeActionItemIe->criticality = CriticalityE2_ignore;
7687       removeActionItemIe->value.present = RICaction_ToBeRemovedForModification_ItemIEs__value_PR_RICaction_ToBeRemovedForModification_Item;
7688       removeActionItemIe->value.choice.RICaction_ToBeRemovedForModification_Item.ricActionID = actionToBeRemove[arrIdx].actionId;
7689    }
7690    return ROK;
7691 }
7692
7693 /*******************************************************************
7694 *
7695 * @brief Build Ric subscription action to be added list
7696 *
7697 * @details
7698 *
7699 *    Function : BuildRicSubsActionToBeAdded 
7700 *
7701 *    Functionality: Build Ric subscription action to be added list
7702 *
7703 * @params[in]
7704 *    RICactions_ToBeAddedForModification_List_t to be filled
7705 *    Num Of Action To Be added 
7706 *    Action add list
7707 *
7708 * @return ROK     - success
7709 *         RFAILED - failure
7710 *
7711 ******************************************************************/
7712
7713 uint8_t BuildRicSubsActionToBeAdded(RICactions_ToBeAddedForModification_List_t *addedActionList, RicSubscription **ricSubsInfo, uint8_t numOfActionToBeAdded, ActionInfo *actionToBeAdded)
7714 {
7715    uint8_t arrIdx=0;
7716    CmLList *actionNode=NULLP;
7717    RICaction_ToBeAddedForModification_ItemIEs_t *addedActionItemIe;
7718
7719    addedActionList->list.count = numOfActionToBeAdded;
7720    addedActionList->list.size = addedActionList->list.count *  sizeof(RICaction_ToBeAddedForModification_ItemIEs_t*);
7721    RIC_ALLOC(addedActionList->list.array, addedActionList->list.size);
7722    if(!addedActionList->list.array)
7723    {
7724       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7725       return RFAILED;
7726    }
7727
7728    for(arrIdx = 0; arrIdx< addedActionList->list.count; arrIdx++)
7729    {
7730       RIC_ALLOC(addedActionList->list.array[arrIdx], sizeof(RICaction_ToBeAddedForModification_ItemIEs_t));
7731       if(!addedActionList->list.array[arrIdx])
7732       {
7733          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7734          return RFAILED;
7735       }
7736       addedActionItemIe = (RICaction_ToBeAddedForModification_ItemIEs_t*)addedActionList->list.array[arrIdx];
7737       addedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item;
7738       addedActionItemIe->criticality = CriticalityE2_ignore;
7739       addedActionItemIe->value.present = RICaction_ToBeAddedForModification_ItemIEs__value_PR_RICaction_ToBeAddedForModification_Item;
7740       addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionID = actionToBeAdded[arrIdx].actionId;
7741       
7742       addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionType = RICactionType_report;
7743
7744       if(fillRicActionDef(&addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition, \
7745       actionToBeAdded[arrIdx].actionId, CONFIG_ADD) != ROK)
7746       {
7747          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7748          break;
7749       }
7750       
7751       actionNode = addRicSubsAction((*ricSubsInfo)->actionSequence.count, &(*ricSubsInfo)->actionSequence);
7752       if(actionNode == NULLP)
7753       {
7754          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7755          return RFAILED;
7756       }
7757    }
7758    return ROK;
7759 }
7760
7761 /*******************************************************************
7762  *
7763  * @brief Builds and Send the RicSubscriptionModReq
7764  *
7765  * @details
7766  *
7767  *    Function : BuildAndSendRicSubscriptionModReq
7768  *
7769  * Functionality:Builds and Send the RicSubscriptionModReq
7770  *
7771  * @params[in]
7772  *    Du databse
7773  *    Ric subs information
7774  *    List of ric subs action which needs to modify/add/remove
7775  * @return ROK     - success
7776  *         RFAILED - failure
7777  *
7778  ******************************************************************/
7779
7780 uint8_t BuildAndSendRicSubscriptionModReq(DuDb *duDb, RicSubscription **ricSubsInfo, RicSubsModReq ricSubsModReq)
7781 {
7782    uint8_t         ret = RFAILED;
7783    uint8_t         elementCnt = 0;
7784    uint8_t         idx = 0, cfgIdx=0;
7785    asn_enc_rval_t  encRetVal;        /* Encoder return value */
7786    E2AP_PDU_t                 *e2apRicMsg = NULL;
7787    RICsubscriptionModificationRequest_t   *ricSubscriptionModReq;
7788    RanFunction  *ranFuncDb = &duDb->ranFunction[0];
7789    CmLList *subscriptionNode = NULLP;
7790    
7791    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
7792
7793    while(true)
7794    {
7795       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
7796       if(e2apRicMsg == NULLP)
7797       {
7798          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7799          break;
7800       }
7801
7802       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
7803       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
7804       if(e2apRicMsg->choice.initiatingMessage == NULLP)
7805       {
7806          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7807          break;
7808       }
7809       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModification;
7810       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
7811       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequest;
7812
7813       ricSubscriptionModReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest;
7814
7815       /* Increasing the elment count based on the number of configured action to  be add, mod, delete */
7816       elementCnt = 2;
7817       if(ricSubsModReq.numOfActionToBeAdded)
7818          elementCnt++;
7819       if(ricSubsModReq.numOfActionToBeModify)
7820          elementCnt++;
7821       if(ricSubsModReq.numOfActionToBeRemove)
7822          elementCnt++;
7823
7824       ricSubscriptionModReq->protocolIEs.list.count = elementCnt;
7825       ricSubscriptionModReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionModificationRequest_IEs_t);
7826
7827       /* Initialize the subscription members */
7828       RIC_ALLOC(ricSubscriptionModReq->protocolIEs.list.array, ricSubscriptionModReq->protocolIEs.list.size);
7829       if(ricSubscriptionModReq->protocolIEs.list.array == NULLP)
7830       {
7831          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7832          break;
7833       }
7834
7835       for(idx=0; idx<elementCnt; idx++)
7836       {
7837          RIC_ALLOC(ricSubscriptionModReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionModificationRequest_IEs_t));
7838          if(ricSubscriptionModReq->protocolIEs.list.array[idx] == NULLP)
7839          {
7840             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
7841             break;
7842          }
7843       }
7844       if(idx < elementCnt)
7845          break;
7846
7847       /* Filling RIC Request Id */
7848       idx = 0;
7849       ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
7850       ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
7851       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present =\
7852                                                                       RICsubscriptionModificationRequest_IEs__value_PR_RICrequestID;
7853       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = (*ricSubsInfo)->requestId.requestorId;
7854       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID =  (*ricSubsInfo)->requestId.instanceId;
7855
7856       /* Filling RAN Function Id */
7857       idx++;
7858       ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
7859       ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
7860       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present =\
7861                                                                       RICsubscriptionModificationRequest_IEs__value_PR_RANfunctionID;
7862       ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = (*ricSubsInfo)->ranFuncId;
7863
7864       if(ricSubsModReq.numOfActionToBeRemove)
7865       {
7866          /* Filling RIC Subscription action to be removed */
7867          idx++;
7868          ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List;
7869          ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_ignore;
7870          ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present = RICsubscriptionModificationRequest_IEs__value_PR_RICactions_ToBeRemovedForModification_List;
7871          if(BuildRicSubsActionToBeRemoved(&ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICactions_ToBeRemovedForModification_List,\
7872                   ricSubsModReq.numOfActionToBeRemove, ricSubsModReq.actionToBeRemove) != ROK)
7873          {
7874             DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7875             break;
7876          }
7877       }
7878       if(ricSubsModReq.numOfActionToBeModify)
7879       {
7880          /* Filling RIC Subscription action to be modified */
7881          idx++;
7882          ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List;
7883          ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_ignore;
7884          ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present = RICsubscriptionModificationRequest_IEs__value_PR_RICactions_ToBeModifiedForModification_List;
7885          if(BuildRicSubsActionToBeModify(&ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICactions_ToBeModifiedForModification_List,\
7886                   ricSubsModReq.numOfActionToBeModify, ricSubsModReq.actionToBeModify) != ROK)
7887          {
7888             DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7889             break;
7890          }
7891       }
7892
7893       if(ricSubsModReq.numOfActionToBeAdded)
7894       {
7895          /* Filling RIC Subscription action to be added */
7896          idx++;
7897          ricSubscriptionModReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List;
7898          ricSubscriptionModReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_ignore;
7899          ricSubscriptionModReq->protocolIEs.list.array[idx]->value.present = RICsubscriptionModificationRequest_IEs__value_PR_RICactions_ToBeAddedForModification_List;
7900          if(BuildRicSubsActionToBeAdded(&ricSubscriptionModReq->protocolIEs.list.array[idx]->value.choice.RICactions_ToBeAddedForModification_List,\
7901          ricSubsInfo, ricSubsModReq.numOfActionToBeAdded, ricSubsModReq.actionToBeAdded) != ROK)
7902          {
7903             DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
7904             break;
7905          }
7906       }
7907
7908       /* Prints the Msg formed */
7909       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
7910
7911       memset(encBuf, 0, ENC_BUF_MAX_LEN);
7912       encBufSize = 0;
7913       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
7914       if(encRetVal.encoded == ENCODE_FAIL)
7915       {
7916          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionModRequest structure (at %s)\n",\
7917                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
7918          break;
7919       }
7920       else
7921       {
7922          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionModRequest\n");
7923          for(int i=0; i< encBufSize; i++)
7924          {
7925             DU_LOG("%x",encBuf[i]);
7926          }
7927       }
7928
7929       /* Sending msg */
7930       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
7931       {
7932          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
7933          break;
7934       }
7935
7936       ret = ROK;
7937       break;
7938    }
7939
7940    FreeRicSubscriptionModReq(e2apRicMsg);
7941    return ret;
7942 }
7943
7944 /*******************************************************************
7945  *
7946  * @brief Builds RicSubscriptionModReq
7947  *
7948  * @details
7949  *
7950  *    Function : BuildRicSubscriptionModReq
7951  *
7952  * Functionality:Builds the RicSubscriptionModReq
7953  *
7954  * @params[in]
7955  *    Du databse
7956  * @return void
7957  *
7958  * ****************************************************************/
7959
7960 void BuildRicSubsModificationReq(DuDb *duDb, RicSubscription *ricSubsInfo)
7961 {
7962    CmLList *actionNode=NULLP;
7963    uint8_t actionToBeAdded =0;
7964    uint8_t actionIdx =0, tmpActionIdx=0;
7965    ActionInfo *actionInfoDb = NULLP;
7966    RicSubsModReq ricSubsModReq;
7967
7968    if(ricSubsInfo)
7969    {
7970       memset(&ricSubsModReq, 0, sizeof(RicSubsModReq));
7971       
7972
7973       CM_LLIST_FIRST_NODE(&ricSubsInfo->actionSequence, actionNode);
7974       while(actionNode)
7975       {
7976          actionInfoDb = (ActionInfo*)(actionNode->node);
7977          /* Change the condition based on the action required to be modiified or removed */
7978          if(((actionInfoDb->actionId+1)%2) == 0)
7979          {
7980             tmpActionIdx = ricSubsModReq.numOfActionToBeModify; 
7981             ricSubsModReq.actionToBeModify[tmpActionIdx].actionId = actionInfoDb->actionId;
7982             ricSubsModReq.numOfActionToBeModify++;
7983          }
7984          else
7985          {
7986             tmpActionIdx = ricSubsModReq.numOfActionToBeRemove; 
7987             ricSubsModReq.actionToBeRemove[tmpActionIdx].actionId = actionInfoDb->actionId;
7988             ricSubsModReq.numOfActionToBeRemove++;
7989          }
7990          actionNode= actionNode->next;
7991       }
7992       /* Change the value of actionToBeAdded based on the number of action required to be added */
7993       actionToBeAdded =1;
7994       tmpActionIdx = ricSubsInfo->actionSequence.count;
7995       for(actionIdx=0; actionIdx<actionToBeAdded; actionIdx++)
7996       {
7997          ricSubsModReq.actionToBeAdded[actionIdx].actionId = tmpActionIdx;
7998          ricSubsModReq.numOfActionToBeAdded++;
7999          tmpActionIdx++;
8000       }
8001
8002       if(BuildAndSendRicSubscriptionModReq(duDb, &ricSubsInfo, ricSubsModReq) != ROK)
8003       {
8004          DU_LOG("\nERROR  -->  E2AP : failed to build and send RIC Subscription Modification");
8005          return ;
8006       }
8007    }
8008 }
8009
8010 /****************************************************************
8011  *
8012  * @brief Processing RIC Subscription action modified list
8013  *
8014  * @details
8015  *
8016  *    Function :ProcessingRicSubsActionModified 
8017  *
8018  *    Functionality: Processing the RIC Subscription action modified list
8019  *
8020  * @params[in] RICactions_AddedForModification_List_t
8021  * @return void
8022  *
8023  * ****************************************************************/
8024 void ProcessingRicSubsActionModified(RICactions_ModifiedForModification_List_t *actionModifiedList)
8025 {
8026    uint8_t actionId=0;
8027    uint8_t elementIdx = 0;
8028    ActionInfo *action=NULLP;
8029    CmLList *actionNode =NULLP;
8030    RICaction_ModifiedForModification_ItemIEs_t *modifiedActionItemIe =NULLP;
8031
8032    if(actionModifiedList->list.array)
8033    {
8034       for(elementIdx = 0; elementIdx < actionModifiedList->list.count; elementIdx++)
8035       {
8036          if(actionModifiedList->list.array[elementIdx])
8037          {
8038             modifiedActionItemIe=(RICaction_ModifiedForModification_ItemIEs_t*)actionModifiedList->list.array[elementIdx];
8039             actionId = modifiedActionItemIe->value.choice.RICaction_ModifiedForModification_Item.ricActionID;
8040             DU_LOG("\nInfo  -->  E2AP : Action id %d modified successfully",  actionId);
8041          }
8042
8043       }
8044
8045    }
8046 }
8047
8048 /****************************************************************
8049  *
8050  * @brief Processing RIC Subscription action added list
8051  *
8052  * @details
8053  *
8054  *    Function : ProcessingRicSubsActionAdded
8055  *
8056  *    Functionality: Processing RIC Subscription action added  list
8057  *
8058  * @params[in] RICactions_AddedForModification_List_t
8059  * @return void
8060  *
8061  * ****************************************************************/
8062 void ProcessingRicSubsActionAdded(RICactions_AddedForModification_List_t *actionAddedList)
8063 {
8064    uint8_t actionId=0;
8065    uint8_t elementIdx = 0;
8066    ActionInfo *action=NULLP;
8067    CmLList *actionNode =NULLP;
8068    RICaction_AddedForModification_ItemIEs_t *addedActionItemIe =NULLP;
8069
8070    if(actionAddedList->list.array)
8071    {
8072       for(elementIdx = 0; elementIdx < actionAddedList->list.count; elementIdx++)
8073       {
8074          if(actionAddedList->list.array[elementIdx])
8075          {
8076             addedActionItemIe=(RICaction_AddedForModification_ItemIEs_t*)actionAddedList->list.array[elementIdx];
8077             actionId = addedActionItemIe->value.choice.RICaction_AddedForModification_Item.ricActionID;
8078             DU_LOG("\nInfo  -->  E2AP : Action id %d added successfully",  actionId);
8079          }
8080
8081       }
8082
8083    }
8084 }
8085
8086 /****************************************************************
8087  *
8088  * @brief Processing RIC Subscription action deleted list
8089  *
8090  * @details
8091  *
8092  *    Function : ProcessingRicSubsActionRemoved
8093  *
8094  *    Functionality: Processing RIC Subscription action deleted list
8095  *
8096  * @params[in] RICactions_RemovedForModification_List_t
8097  *             Ric Subscription info
8098  * @return void
8099  *
8100  * ****************************************************************/
8101 void ProcessingRicSubsActionRemoved(RICactions_RemovedForModification_List_t *actionRemovedList, RicSubscription *ricSubs)
8102 {
8103    uint8_t actionId=0;
8104    uint8_t elementIdx = 0;
8105    ActionInfo *action=NULLP;
8106    CmLList *actionNode =NULLP;
8107    RICaction_RemovedForModification_ItemIEs_t *removedActionItemIe =NULLP;
8108
8109    if(actionRemovedList->list.array)
8110    {
8111       for(elementIdx = 0; elementIdx < actionRemovedList->list.count; elementIdx++)
8112       {
8113          if(actionRemovedList->list.array[elementIdx])
8114          {
8115             removedActionItemIe=(RICaction_RemovedForModification_ItemIEs_t*)actionRemovedList->list.array[elementIdx];
8116             actionId = removedActionItemIe->value.choice.RICaction_RemovedForModification_Item.ricActionID;
8117             action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
8118             if(action)
8119             {
8120                cmLListDelFrm(&ricSubs->actionSequence, actionNode);
8121                deleteActionSequence(actionNode);
8122                DU_LOG("\nInfo  -->  E2AP : Action id %d removed successfully",  actionId);
8123             }
8124          }
8125
8126       }
8127
8128    }
8129 }
8130
8131 /*******************************************************************
8132  *
8133  * @brief Processing RIC Subscription action failed to be
8134  * removed list
8135  *
8136  * @details
8137  *
8138  *    Function : ProcessingRicSubsActionFailedToBeRemoved
8139  *
8140  *    Functionality: Processing the RIC Subscription action failed
8141  *    to be removed list
8142  *
8143  * @params[in] RICactions_FailedToBeRemovedForModification_List_t 
8144  * @return void
8145  *
8146  * ****************************************************************/
8147 void ProcessingRicSubsActionFailedToBeRemoved(RICactions_FailedToBeRemovedForModification_List_t *actionFailedToBeRemoved)
8148 {
8149    uint8_t actionId=0;
8150    uint8_t elementIdx = 0;
8151    RICaction_FailedToBeRemovedForModification_ItemIEs_t *failedToBeRemovedActionItemIe =NULLP;
8152
8153    if(actionFailedToBeRemoved->list.array)
8154    {
8155       for(elementIdx = 0; elementIdx < actionFailedToBeRemoved->list.count; elementIdx++)
8156       {
8157          if(actionFailedToBeRemoved->list.array[elementIdx])
8158          {
8159             failedToBeRemovedActionItemIe=(RICaction_FailedToBeRemovedForModification_ItemIEs_t*)actionFailedToBeRemoved->list.array[elementIdx];
8160             actionId = failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.ricActionID;
8161             DU_LOG("\nERROR  -->  E2AP : Failed to remove action id %d in %s", actionId, __func__);
8162             printE2ErrorCause(&failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.cause);
8163          }
8164
8165       }
8166
8167    }
8168 }
8169
8170 /****************************************************************
8171  *
8172  * @brief Processing RIC Subscription action failed to be
8173  * add list
8174  *
8175  * @details
8176  *
8177  *    Function : ProcessingRicSubsActionFailedToBeAdded
8178  *
8179  *    Functionality: Processing the RIC Subscription action failed
8180  *    to be add list
8181  *
8182  * @params[in] RICactions_FailedToBeAddedForModification_List_t 
8183  * @return void
8184  *
8185  * ****************************************************************/
8186 void ProcessingRicSubsActionFailedToBeAdded(RICactions_FailedToBeAddedForModification_List_t *actionfailedToBeAddedList, RicSubscription *ricSubs)
8187 {
8188    uint8_t actionId=0;
8189    uint8_t elementIdx = 0;
8190    ActionInfo *action=NULLP;
8191    CmLList *actionNode =NULLP;
8192    RICaction_FailedToBeAddedForModification_ItemIEs_t *failedToBeAddedActionItemIe =NULLP;
8193
8194    if(actionfailedToBeAddedList->list.array)
8195    {
8196       for(elementIdx = 0; elementIdx < actionfailedToBeAddedList->list.count; elementIdx++)
8197       {
8198          if(actionfailedToBeAddedList->list.array[elementIdx])
8199          {
8200             failedToBeAddedActionItemIe=(RICaction_FailedToBeAddedForModification_ItemIEs_t*)actionfailedToBeAddedList->list.array[elementIdx];
8201             actionId = failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.ricActionID;
8202             action = fetchActionInfoFromActionId(actionId, ricSubs, &actionNode);
8203             if(action)
8204             {
8205                cmLListDelFrm(&ricSubs->actionSequence, actionNode);
8206                deleteActionSequence(actionNode);
8207             }
8208             DU_LOG("\nERROR  -->  E2AP : Failed to remove action id %d in %s", actionId,__func__);
8209             printE2ErrorCause(&failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.cause);
8210          }
8211
8212       }
8213
8214    }
8215 }
8216
8217 /*******************************************************************
8218  *
8219  * @brief Processing RIC Subscription action failed to be
8220  * modified list
8221  *
8222  * @details
8223  *
8224  *    Function :ProcessingRicSubsActionFailedToBeModified 
8225  *
8226  *    Functionality: Processing the RIC Subscription action failed
8227  *    to be modified list
8228  *
8229  * @params[in] RICactions_FailedToBeModifiedForModification_List_t 
8230  * @return void
8231  *
8232  * ****************************************************************/
8233 void ProcessingRicSubsActionFailedToBeModified(RICactions_FailedToBeModifiedForModification_List_t *actionFailedToBeModifiedList)
8234 {
8235    uint8_t actionId=0;
8236    uint8_t elementIdx = 0;
8237    RICaction_FailedToBeModifiedForModification_ItemIEs_t *failedToBeModifiedActionItemIe =NULLP;
8238
8239    if(actionFailedToBeModifiedList->list.array)
8240    {
8241       for(elementIdx = 0; elementIdx < actionFailedToBeModifiedList->list.count; elementIdx++)
8242       {
8243          if(actionFailedToBeModifiedList->list.array[elementIdx])
8244          {
8245             failedToBeModifiedActionItemIe=(RICaction_FailedToBeModifiedForModification_ItemIEs_t*)actionFailedToBeModifiedList->list.array[elementIdx];
8246             actionId = failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.ricActionID;
8247             DU_LOG("\nERROR  -->  E2AP : Failed to remove action id %d in %s", actionId,__func__);
8248             printE2ErrorCause(&failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.cause);
8249          }
8250
8251       }
8252
8253    }
8254 }
8255
8256 /******************************************************************
8257  *
8258  * @brief Processes the Ric Subs modification rsp msg
8259  *
8260  * @details
8261  *
8262  *    Function : ProcRicSubsModificationRsp
8263  *
8264  *    Functionality: Processes the Ric Subs modification rsp msg
8265  *
8266  * @params[in]
8267  *       Ric Subs modification rsp information
8268  *
8269  * @return void
8270  *
8271  * ****************************************************************/
8272 void ProcRicSubsModificationRsp(uint32_t duId, RICsubscriptionModificationResponse_t *ricSubsModificationRsp)
8273 {
8274    uint8_t ieIdx = 0;
8275    uint8_t duIdx= 0;
8276    uint16_t ranFuncId=0;
8277    RanFunction *ranFuncDb = NULLP;
8278    RicRequestId ricReqId;
8279    DuDb    *duDb = NULLP;
8280    RicSubscription *ricSubs = NULLP;
8281    CmLList *ricSubsNode = NULLP;
8282
8283    SEARCH_DU_DB(duIdx, duId, duDb);
8284    if(duDb == NULLP)
8285    {
8286       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
8287       return;
8288    }
8289
8290    if(!ricSubsModificationRsp)
8291    {
8292       DU_LOG("\nERROR  -->  E2AP : ricSubsModificationRsp pointer is null");
8293       return;
8294    }
8295
8296    if(!ricSubsModificationRsp->protocolIEs.list.array)
8297    {
8298       DU_LOG("\nERROR  -->  E2AP : ricSubsModificationRsp array pointer is null");
8299       return;
8300    }
8301
8302    for(ieIdx=0; ieIdx < ricSubsModificationRsp->protocolIEs.list.count; ieIdx++)
8303    {
8304       if(ricSubsModificationRsp->protocolIEs.list.array[ieIdx])
8305       {
8306          switch(ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->id)
8307          {
8308             case ProtocolIE_IDE2_id_RICrequestID:
8309                {
8310                   ricReqId.requestorId = ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricRequestorID;
8311                   ricReqId.instanceId = ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICrequestID.ricInstanceID;
8312                   break;
8313                }
8314             case ProtocolIE_IDE2_id_RANfunctionID:
8315                {
8316                   ranFuncId = ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RANfunctionID;
8317                   ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
8318                   if(!ranFuncDb)
8319                   {
8320                      DU_LOG("\nERROR  -->  E2AP : Invalid Ran Function id %d received",ranFuncId);
8321                      return;
8322                   }
8323
8324                   ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
8325                   if(!ricSubs)
8326                   {
8327                      DU_LOG("\nERROR  -->  E2AP : Ric subscription node is not present ");
8328                      return;
8329                   }
8330                   break;
8331                }
8332             case ProtocolIE_IDE2_id_RICactionsRemovedForModification_List:
8333                {
8334                   ProcessingRicSubsActionRemoved(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_RemovedForModification_List, ricSubs);
8335                   break;
8336                }
8337             case ProtocolIE_IDE2_id_RICactionsFailedToBeRemovedForModification_List:
8338                {
8339                   ProcessingRicSubsActionFailedToBeRemoved(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeRemovedForModification_List);
8340                   break;
8341                }
8342             case ProtocolIE_IDE2_id_RICactionsModifiedForModification_List:
8343                {
8344                   ProcessingRicSubsActionModified(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_ModifiedForModification_List);
8345                   break;
8346                }
8347             case ProtocolIE_IDE2_id_RICactionsFailedToBeModifiedForModification_List:
8348                {
8349                   ProcessingRicSubsActionFailedToBeModified(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeModifiedForModification_List);
8350                   break;
8351                }
8352             case ProtocolIE_IDE2_id_RICactionsAddedForModification_List:
8353                {
8354                   ProcessingRicSubsActionAdded(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_AddedForModification_List);
8355                   break;
8356                }
8357             case ProtocolIE_IDE2_id_RICactionsFailedToBeAddedForModification_List:
8358                {
8359                   ProcessingRicSubsActionFailedToBeAdded(&ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeAddedForModification_List, ricSubs);
8360                   break;
8361                }
8362             default:
8363                {
8364                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", ricSubsModificationRsp->protocolIEs.list.array[ieIdx]->id);
8365                   break;
8366                }
8367          }
8368       }
8369    }
8370 }
8371
8372 /*******************************************************************
8373 *
8374 * @brief Handles received E2AP message and sends back response  
8375 *
8376 * @details
8377 *
8378 *    Function : E2APMsgHdlr
8379 *
8380 *    Functionality:
8381 *         - Decodes received E2AP control message
8382 *         - Prepares response message, encodes and sends to SCTP
8383 *
8384 * @params[in] 
8385 * @return ROK     - success
8386 *         RFAILED - failure
8387 *
8388 * ****************************************************************/
8389 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
8390 {
8391    int             i;
8392    char            *recvBuf;
8393    MsgLen          copyCnt;
8394    MsgLen          recvBufLen;
8395    E2AP_PDU_t      *e2apMsg;
8396    asn_dec_rval_t  rval; /* Decoder return value */
8397    E2AP_PDU_t      e2apasnmsg ;
8398  
8399    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
8400    ODU_PRINT_MSG(mBuf, 0,0);
8401  
8402    /* Copy mBuf into char array to decode it */
8403    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
8404    RIC_ALLOC(recvBuf, (Size)recvBufLen);
8405
8406    if(recvBuf == NULLP)
8407    {
8408       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
8409       return;
8410    }
8411    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
8412    {
8413       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
8414       return;
8415    }
8416
8417    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
8418    for(i=0; i< recvBufLen; i++)
8419    {
8420         DU_LOG("%x",recvBuf[i]);
8421    }
8422
8423    /* Decoding flat buffer into E2AP messsage */
8424    e2apMsg = &e2apasnmsg;
8425    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
8426
8427    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
8428    RIC_FREE(recvBuf, (Size)recvBufLen);
8429
8430    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
8431    {
8432       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
8433       return;
8434    }
8435    DU_LOG("\n");
8436    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
8437
8438    switch(e2apMsg->present)
8439    {
8440       case E2AP_PDU_PR_initiatingMessage:
8441          {
8442             switch(e2apMsg->choice.initiatingMessage->value.present)
8443             {
8444                case InitiatingMessageE2__value_PR_E2setupRequest:
8445                   {
8446                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
8447                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
8448                      break;
8449                   }
8450                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
8451                   {
8452                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
8453                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
8454                      break;
8455                   }
8456                case InitiatingMessageE2__value_PR_ResetRequestE2:
8457                   {
8458                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
8459                      ProcResetRequest(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
8460                      break;
8461                   }
8462                case InitiatingMessageE2__value_PR_RICindication:
8463                   {
8464                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
8465                      break;
8466                   }
8467                case InitiatingMessageE2__value_PR_RICserviceUpdate:
8468                   {
8469                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
8470                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
8471                      break;
8472                   }
8473                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
8474                   {
8475                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
8476                      ProcRicSubsModReqd(*duId, \
8477                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
8478                      break;
8479                   }
8480                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
8481                   {
8482                       DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
8483                       ProcRicSubsDeleteReqd(*duId, \
8484                          &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
8485                       break;
8486                   }
8487
8488                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
8489                   {
8490                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
8491                      break;
8492                   }
8493                case InitiatingMessageE2__value_PR_E2RemovalRequest:
8494                   {
8495                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
8496                      procE2RemovalRequest(*duId,\
8497                      &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest);
8498                      break;
8499                   }
8500                default:
8501                   {
8502                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
8503                         e2apMsg->choice.initiatingMessage->value.present);
8504                      return;
8505                   }
8506             }/* End of switch(initiatingMessage) */
8507             break;
8508          }
8509       case E2AP_PDU_PR_successfulOutcome: 
8510          {
8511             switch(e2apMsg->choice.successfulOutcome->value.present)
8512             {
8513                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
8514                   {
8515                      DU_LOG("\nINFO  -->  E2AP : Reset response received");
8516                      ProcResetResponse(*duId,  &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2);
8517                      break;
8518                   }
8519                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
8520                   {
8521                      ProcRicSubscriptionResponse(*duId, \
8522                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
8523                      break;
8524                   }
8525                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
8526                   {
8527                      ProcE2RemovalResponse(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse);
8528                      break;
8529                   }
8530                case SuccessfulOutcomeE2__value_PR_E2connectionUpdateAcknowledge:
8531                   {
8532                      ProcE2ConnectionUpdateAck(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge);
8533                      break;
8534                   }
8535                case SuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteResponse:
8536                   {
8537                      ProcRicSubsDeleteRsp(*duId, &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse);
8538                      break;
8539                   }
8540                case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationResponse:
8541                   {
8542                      ProcRicSubsModificationRsp(*duId, &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationResponse);
8543                      break;
8544                   }
8545                default:
8546                   {
8547                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
8548                         e2apMsg->choice.successfulOutcome->value.present);
8549                      return;
8550                   }
8551                   break;
8552             }
8553             break; 
8554          }
8555          case E2AP_PDU_PR_unsuccessfulOutcome:
8556          {
8557             switch(e2apMsg->choice.successfulOutcome->value.present)
8558             {
8559                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
8560                   {
8561                      ProcRicSubscriptionFailure(*duId, \
8562                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
8563                      break;
8564                   }
8565                case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
8566                   {
8567                      ProcE2RemovalFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure);
8568                      break;
8569                   }
8570                case UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure:
8571                   {
8572                      ProcE2connectionUpdateFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure);
8573                      break;
8574                   }
8575                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteFailure:
8576                   {
8577                      ProcRicSubsDeleteFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure);
8578                      break;
8579                   }
8580                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationFailure:
8581                   {
8582                      ProcRicSubsModificationFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationFailure);
8583                      break;
8584                   }
8585                default:
8586                   {
8587                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
8588                         e2apMsg->choice.unsuccessfulOutcome->value.present);
8589                      return;
8590                   }
8591             }
8592             break;
8593          }
8594       default:
8595          {
8596             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
8597             return;
8598          }
8599
8600    }/* End of switch(e2apMsg->present) */
8601 } /* End of E2APMsgHdlr */
8602
8603
8604 /**********************************************************************
8605   End of file
8606  **********************************************************************/