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