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