[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-533] Implementation of E2 Node Connection...
[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  *
5989  * @brief process the E2 node information from ric db
5990  *
5991  * @details
5992  *
5993  *    Function : deleteE2NodeInfo
5994  *
5995  * Functionality: process the E2 node information from ric db
5996  *
5997  * @params[in] 
5998  *       du Id
5999  *      
6000  * @return void
6001  *
6002  ******************************************************************/
6003 void deleteE2NodeInfo(DuDb *duDb)
6004 {
6005    uint16_t ranFuncIdx =0;
6006    RanFunction *ranFuncDb=NULLP;
6007
6008    DU_LOG("\nINFO  -->  E2AP : Removing all the E2 node information");
6009    for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
6010    {
6011       ranFuncDb = &duDb->ranFunction[ranFuncIdx];
6012       if(ranFuncDb->id > 0)
6013       {
6014          deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
6015       }
6016    }
6017
6018    cmInetClose(&sctpCb.e2LstnSockFd);
6019 }
6020
6021 /*******************************************************************
6022  *
6023  * @brief process the E2 Removal Response
6024  *
6025  * @details
6026  *
6027  *    Function : ProcE2RemovalResponse 
6028  *
6029  * Functionality: Process E2 Removal Response 
6030  *
6031  * @params[in] 
6032  *       du Id
6033  *       Pointer to removal response 
6034  * @return void
6035  *
6036  ******************************************************************/
6037
6038 void ProcE2RemovalResponse(uint32_t duId, E2RemovalResponse_t *removalRsp)
6039 {
6040    uint8_t ieIdx = 0, duIdx =0;
6041    DuDb *duDb = NULLP;
6042
6043    SEARCH_DU_DB(duIdx, duId, duDb);
6044    if(duDb == NULLP)
6045    {
6046       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6047       return;
6048    }
6049
6050    if(!removalRsp)
6051    {
6052       DU_LOG("\nERROR  -->  E2AP : removalRsp pointer is null"); 
6053       return;
6054    }
6055
6056    if(!removalRsp->protocolIEs.list.array)      
6057    {
6058       DU_LOG("\nERROR  -->  E2AP : removalRsp array pointer is null");
6059       return;
6060    }
6061
6062    for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++)
6063    {
6064       if(removalRsp->protocolIEs.list.array[ieIdx])
6065       {
6066          switch(removalRsp->protocolIEs.list.array[ieIdx]->id)
6067          {
6068             case ProtocolIE_IDE2_id_TransactionID:
6069                {
6070                   deleteE2NodeInfo(duDb);
6071                   break;
6072                }
6073             default:
6074                {
6075                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id);
6076                   break;
6077                }
6078          }
6079       }
6080    }
6081 }
6082 /*******************************************************************
6083  *
6084  * @brief Deallocate the memory allocated for E2 Removal Failure
6085  *
6086  * @details
6087  *
6088  *    Function : FreeE2RemovalFailure
6089  *
6090  *    Functionality:
6091  *       - freeing the memory allocated for E2RemovalFailure
6092  *
6093  * @params[in] E2AP_PDU_t *e2apMsg
6094  * @return void
6095  *
6096  * ****************************************************************/
6097 void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg)
6098 {
6099    uint8_t ieIdx =0;
6100    E2RemovalFailure_t *e2RemovalFailure=NULLP;
6101
6102    if(e2apMsg != NULLP)
6103    {
6104       if(e2apMsg->choice.unsuccessfulOutcome != NULLP)
6105       {
6106          e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
6107          if(e2RemovalFailure->protocolIEs.list.array)
6108          {
6109             for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++)
6110             {
6111                if(e2RemovalFailure->protocolIEs.list.array[ieIdx])
6112                {
6113                   RIC_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
6114                }
6115             }
6116             RIC_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
6117          }
6118          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
6119       }
6120       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6121    }
6122 }
6123
6124 /*******************************************************************
6125  *
6126  * @brief Buld and send the E2 Removal Failure msg
6127  *
6128  * @details
6129  *
6130  *    Function : BuildAndSendE2RemovalFailure
6131  *
6132  *    Functionality:
6133  *         - Buld and send the E2 Removal Failure Message
6134  * @params[in] 
6135  *    DU Id
6136  *    Trans Id 
6137  *    Type of failure 
6138  *    Cause of failure
6139  * @return ROK     - success
6140  *         RFAILED - failure
6141  *
6142  * ****************************************************************/
6143
6144 uint8_t BuildAndSendRemovalFailure(uint32_t duId, uint16_t transId,  CauseE2_PR causePresent, uint8_t reason)
6145 {
6146    uint8_t           ieIdx = 0, elementCnt = 0;
6147    uint8_t           ret = RFAILED;
6148    E2AP_PDU_t        *e2apMsg = NULLP;
6149    E2RemovalFailure_t *e2RemovalFailure=NULLP;
6150    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6151
6152    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Failure Message\n");
6153    do
6154    {
6155       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6156       if(e2apMsg == NULLP)
6157       {
6158          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6159          break;
6160       }
6161       e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome;
6162
6163       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
6164       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
6165       {
6166          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6167          break;
6168       }
6169
6170       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
6171       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
6172       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure;
6173       e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure;
6174
6175       elementCnt = 2;
6176       e2RemovalFailure->protocolIEs.list.count = elementCnt;
6177       e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *);
6178       RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size);
6179       if(!e2RemovalFailure->protocolIEs.list.array)
6180       {
6181          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6182          break;
6183       }
6184
6185       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6186       {
6187          RIC_ALLOC(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t));
6188          if(!e2RemovalFailure->protocolIEs.list.array[ieIdx])
6189          {
6190             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6191             break;
6192          }
6193       }
6194       if(ieIdx < elementCnt)
6195          break;
6196
6197       ieIdx = 0;
6198       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6199       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6200       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID;
6201       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6202
6203       /* Cause */
6204       ieIdx++;
6205       e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
6206       e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
6207       e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
6208       fillE2FailureCause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
6209       
6210       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6211
6212       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6213       encBufSize = 0;
6214       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6215       if(encRetVal.encoded == ENCODE_FAIL)
6216       {
6217          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal failure structure (at %s)\n",\
6218                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6219          break;
6220       }
6221       else
6222       {
6223          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Failure \n");
6224          for(int i=0; i< encBufSize; i++)
6225          {
6226             DU_LOG("%x",encBuf[i]);
6227          }
6228       }
6229
6230       /* Sending msg */
6231       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6232       {
6233          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Failure");
6234          break;
6235       }
6236
6237       ret = ROK;
6238       break;
6239    }while(true);
6240
6241    FreeE2RemovalFailure(e2apMsg);
6242    return ret;
6243 }
6244
6245 /*******************************************************************
6246  *
6247  * @brief Deallocate the memory allocated for E2 Removal Response
6248  *
6249  * @details
6250  *
6251  *    Function : FreeE2RemovalResponse
6252  *
6253  *    Functionality:
6254  *       - freeing the memory allocated for E2RemovalResponse
6255  *
6256  * @params[in] E2AP_PDU_t *e2apMsg
6257  * @return ROK     - success
6258  *         RFAILED - failure
6259  *
6260  * ****************************************************************/
6261 void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg)
6262 {
6263    uint8_t ieIdx =0;
6264    E2RemovalResponse_t *e2RemovalResponse=NULLP;
6265
6266    if(e2apMsg != NULLP)
6267    {
6268       if(e2apMsg->choice.successfulOutcome != NULLP)
6269       {
6270          e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
6271          if(e2RemovalResponse->protocolIEs.list.array)
6272          {
6273             for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++)
6274             {
6275                if(e2RemovalResponse->protocolIEs.list.array[ieIdx])
6276                {
6277                   RIC_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
6278                }
6279             }
6280             RIC_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
6281          }
6282          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6283       }
6284       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6285    }
6286 }
6287
6288 /*******************************************************************
6289  *
6290  * @brief Buld and send the E2 Removal Response msg
6291  *
6292  * @details
6293  *
6294  *    Function : BuildAndSendE2RemovalResponse
6295  *
6296  *    Functionality:
6297  *         - Buld and send the E2 Removal Response Message
6298  * @params[in] 
6299  *    Du Id
6300  *    Trans Id 
6301  * @return ROK     - success
6302  *         RFAILED - failure
6303  *
6304  * ****************************************************************/
6305 uint8_t BuildAndSendRemovalResponse(uint32_t duId, uint16_t transId)
6306 {
6307    uint8_t ieIdx = 0, elementCnt = 0;
6308    uint8_t ret = RFAILED, duIdx =0;
6309    E2AP_PDU_t *e2apMsg = NULLP;
6310    DuDb *duDb = NULLP;
6311    E2RemovalResponse_t *e2RemovalResponse=NULLP;
6312    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6313
6314    DU_LOG("\nINFO   -->  E2AP : Building E2 Removal Response Message\n");
6315    do
6316    {
6317       SEARCH_DU_DB(duIdx, duId, duDb);
6318       if(duDb == NULLP)
6319       {
6320          DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6321          return;
6322       }
6323    
6324       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6325       if(e2apMsg == NULLP)
6326       {
6327          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6328          break;
6329       }
6330       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
6331
6332       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
6333       if(e2apMsg->choice.successfulOutcome == NULLP)
6334       {
6335          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6336          break;
6337       }
6338
6339       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal;
6340       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
6341       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse;
6342       e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse;
6343
6344       elementCnt = 1;
6345       e2RemovalResponse->protocolIEs.list.count = elementCnt;
6346       e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *);
6347       RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size);
6348       if(!e2RemovalResponse->protocolIEs.list.array)
6349       {
6350          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6351          break;
6352       }
6353
6354       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6355       {
6356          RIC_ALLOC(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t));
6357          if(!e2RemovalResponse->protocolIEs.list.array[ieIdx])
6358          {
6359             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6360             break;
6361          }
6362       }
6363       if(ieIdx < elementCnt)
6364          break;
6365
6366       ieIdx = 0;
6367       e2RemovalResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6368       e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6369       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID;
6370       e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
6371
6372       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6373
6374       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6375       encBufSize = 0;
6376       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6377       if(encRetVal.encoded == ENCODE_FAIL)
6378       {
6379          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 removal response structure (at %s)\n",\
6380                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6381          break;
6382       }
6383       else
6384       {
6385          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Removal Response \n");
6386          for(int i=0; i< encBufSize; i++)
6387          {
6388             DU_LOG("%x",encBuf[i]);
6389          }
6390       }
6391
6392       /* Sending msg */
6393       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6394       {
6395          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Removal Response");
6396          break;
6397       }
6398
6399       ret = ROK;
6400       break;
6401    }while(true);
6402
6403    FreeE2RemovalResponse(e2apMsg);
6404    deleteE2NodeInfo(duDb);
6405    return ret;
6406 }
6407
6408 /*******************************************************************
6409  *
6410  * @brief Process Removal req received from RIC
6411  *
6412  * @details
6413  *
6414  *    Function : procE2RemovalRequest
6415  *
6416  * Functionality: Process Removal req received from RIC
6417  *
6418  * @param  
6419  *    DU id
6420  *    E2 Removal Request 
6421  * @return void
6422  *
6423  ******************************************************************/
6424
6425 void procE2RemovalRequest(uint32_t duId, E2RemovalRequest_t *removalReq)
6426 {
6427    uint8_t arrIdx =0;
6428    uint16_t transId =0;
6429
6430    DU_LOG("\nINFO   -->  E2AP : E2 Removal request received");
6431    
6432    for(arrIdx=0; arrIdx<removalReq->protocolIEs.list.count; arrIdx++)
6433    {
6434       switch(removalReq->protocolIEs.list.array[arrIdx]->id)
6435       {
6436          case ProtocolIE_IDE2_id_TransactionID:
6437             {
6438                transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
6439                break;
6440             }
6441          default:
6442             {
6443                DU_LOG("\nERROR  -->  E2AP : Invalid IE recevied [%d]", transId);
6444                break;
6445             }
6446       }
6447    }
6448    
6449    if(transId>=0 && transId<=255)
6450    {
6451       if(BuildAndSendRemovalResponse(duId, transId) != ROK)
6452       {
6453          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
6454       }
6455    }
6456    else
6457    {
6458       if(BuildAndSendRemovalFailure(duId, transId, CauseE2_PR_protocol, CauseE2Protocol_abstract_syntax_error_falsely_constructed_message) != ROK)
6459       {
6460          DU_LOG("\nERROR  -->  E2AP : Failed to build and send Removal response");
6461       }
6462    }
6463 }
6464
6465 /*******************************************************************
6466  *
6467  * @brief fill E2 connection update item
6468  *
6469  * @details
6470  *
6471  *    Function : fillE2connectionUpdateItem 
6472  *
6473  *    Functionality: fill E2 connection update item
6474  *
6475  * @params[in]
6476  *    E2connectionUpdate Item to be filled
6477  *    Protocol Id
6478  * @return ROK - success
6479  *         RFAILED - failure
6480  * ****************************************************************/
6481
6482 uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId)
6483 {
6484    E2connectionUpdateRemove_Item_t *connectionRemoveITem=NULLP;
6485    E2connectionUpdate_Item_t *connectionModifyItem=NULLP;
6486    TNLinformation_t *tnlInformation = NULLP;
6487    TNLusage_t  *tnlUsage=NULLP;
6488
6489    switch(protocolId)
6490    {
6491       case ProtocolIE_IDE2_id_E2connectionUpdate_Item:
6492       {
6493          connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo;
6494          tnlInformation = &connectionModifyItem->tnlInformation;
6495          tnlUsage = &connectionModifyItem->tnlUsage;
6496          break;
6497       }
6498
6499       case ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item:
6500       {
6501          connectionRemoveITem = (E2connectionUpdateRemove_Item_t*)connectionInfo;
6502          tnlInformation= &connectionRemoveITem->tnlInformation;
6503          break;
6504       }
6505    }
6506    
6507    tnlInformation->tnlAddress.size =  4*sizeof(uint8_t);
6508    RIC_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size);
6509    if(!tnlInformation->tnlAddress.buf)
6510    {
6511       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6512       return RFAILED;
6513    }
6514    
6515    tnlInformation->tnlAddress.buf[3] =  ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr & 0xFF; 
6516    tnlInformation->tnlAddress.buf[2] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 8) & 0xFF;
6517    tnlInformation->tnlAddress.buf[1] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 16) & 0xFF;
6518    tnlInformation->tnlAddress.buf[0] = (ricCb.ricCfgParams.sctpParams.localIpAddr.ipV4Addr>> 24) & 0xFF;
6519    tnlInformation->tnlAddress.bits_unused = 0;
6520    if(protocolId == ProtocolIE_IDE2_id_E2connectionUpdate_Item)
6521    {
6522       *tnlUsage = TNLusage_support_function; 
6523    }
6524    return ROK;
6525 }
6526
6527 /*******************************************************************
6528  *
6529  * @brief Build E2 connection modification list
6530  *
6531  * @details
6532  *
6533  *    Function : BuildE2ConnectionModifyList
6534  *
6535  *    Functionality: Build E2 connection modification list
6536  *
6537  * @params[in]
6538  *    E2 connection modification list to be filled
6539  *
6540  * @return ROK - success
6541  *         RFAILED - failure
6542  * ****************************************************************/
6543
6544 uint8_t BuildE2ConnectionModifyList(E2connectionUpdate_List_t *connectionToBeModifyList)
6545 {
6546    uint8_t arrIdx = 0;
6547    E2connectionUpdate_ItemIEs_t *connectionModify=NULL;
6548
6549    connectionToBeModifyList->list.count = 1;
6550  
6551    connectionToBeModifyList->list.size = connectionToBeModifyList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*);
6552    RIC_ALLOC(connectionToBeModifyList->list.array, connectionToBeModifyList->list.size);
6553    if(connectionToBeModifyList->list.array)
6554    {
6555       for(arrIdx = 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++)
6556       {
6557          RIC_ALLOC(connectionToBeModifyList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
6558          if(connectionToBeModifyList->list.array[arrIdx] == NULLP)
6559          {
6560             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6561             return RFAILED;
6562          }
6563          connectionModify = (E2connectionUpdate_ItemIEs_t*)connectionToBeModifyList->list.array[arrIdx];
6564          connectionModify->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item;
6565          connectionModify->criticality= CriticalityE2_ignore;
6566          connectionModify->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item;
6567          if(fillE2connectionUpdateItem((PTR)&connectionModify->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item) != ROK)
6568          {
6569             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
6570             return RFAILED;
6571          }
6572          
6573       }
6574    }
6575    else
6576    {
6577       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6578       return RFAILED;
6579    }
6580    return ROK;
6581 }
6582
6583 /*******************************************************************
6584  *
6585  * @brief Build E2 connection remove list
6586  *
6587  * @details
6588  *
6589  *    Function : BuildE2ConnectionRemoveList
6590  *
6591  *    Functionality: Build E2 connection remove list
6592  *
6593  * @params[in]
6594  *    E2 connection remove list to be filled
6595  *
6596  * @return ROK - success
6597  *         RFAILED - failure
6598  * ****************************************************************/
6599
6600 uint8_t BuildE2ConnectionRemoveList(E2connectionUpdateRemove_List_t *connectionToBeRemoveList)
6601 {
6602    uint8_t arrIdx = 0;
6603    E2connectionUpdateRemove_ItemIEs_t *connectionRemove=NULL;
6604
6605    connectionToBeRemoveList->list.count = 1;
6606  
6607    connectionToBeRemoveList->list.size = connectionToBeRemoveList->list.count*sizeof(E2connectionUpdateRemove_ItemIEs_t*);
6608    RIC_ALLOC(connectionToBeRemoveList->list.array, connectionToBeRemoveList->list.size);
6609    if(connectionToBeRemoveList->list.array)
6610    {
6611       for(arrIdx = 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++)
6612       {
6613          RIC_ALLOC(connectionToBeRemoveList->list.array[arrIdx], sizeof(E2connectionUpdateRemove_ItemIEs_t));
6614          if(connectionToBeRemoveList->list.array[arrIdx] == NULLP)
6615          {
6616             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6617             return RFAILED;
6618          }
6619          connectionRemove = (E2connectionUpdateRemove_ItemIEs_t*)connectionToBeRemoveList->list.array[arrIdx];
6620          connectionRemove->id = ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item;
6621          connectionRemove->criticality= CriticalityE2_ignore;
6622          connectionRemove->value.present = E2connectionUpdateRemove_ItemIEs__value_PR_E2connectionUpdateRemove_Item;
6623          if(fillE2connectionUpdateItem((PTR)&connectionRemove->value.choice.E2connectionUpdateRemove_Item, ProtocolIE_IDE2_id_E2connectionUpdateRemove_Item) != ROK)
6624          {
6625             DU_LOG("\nERROR  -->  E2AP : Failed to fill E2 connection update item");
6626             return RFAILED;
6627          }
6628          
6629       }
6630    }
6631    else
6632    {
6633       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6634       return RFAILED;
6635    }
6636    return ROK;
6637 }
6638
6639 /*******************************************************************
6640  *
6641  * @brief Deallocate the memory allocated for E2ConnectionUpdate msg
6642  *
6643  * @details
6644  *
6645  *    Function : FreeE2ConnectionUpdate
6646  *
6647  *    Functionality:
6648  *       - freeing the memory allocated for E2ConnectionUpdate
6649  *
6650  * @params[in] E2AP_PDU_t *e2apMsg
6651  * @return ROK     - success
6652  *         RFAILED - failure
6653  *
6654  * ****************************************************************/
6655 void FreeE2ConnectionUpdate(E2AP_PDU_t *e2apMsg)
6656 {
6657    uint8_t ieIdx =0, arrIdx=0;
6658    E2connectionUpdate_t  *connectionUpdate = NULLP;
6659    E2connectionUpdate_List_t *connectionToBeModifyList = NULLP;
6660    E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP;
6661
6662    if(e2apMsg != NULLP)
6663    {
6664       if(e2apMsg->choice.initiatingMessage != NULLP)
6665       {
6666          connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
6667          if(connectionUpdate->protocolIEs.list.array)
6668          {
6669             for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++)
6670             {
6671                if(connectionUpdate->protocolIEs.list.array[ieIdx])
6672                {
6673                   switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id)
6674                   {
6675                      case ProtocolIE_IDE2_id_TransactionID:
6676                         break;
6677
6678                      case ProtocolIE_IDE2_id_E2connectionUpdateModify:
6679                         {
6680                            connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List;
6681                            if(connectionToBeModifyList->list.array)
6682                            {
6683                               for(arrIdx = 0; arrIdx < connectionToBeModifyList->list.count; arrIdx++)
6684                               {
6685                                  RIC_FREE(connectionToBeModifyList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t));
6686                               }
6687                               RIC_FREE(connectionToBeModifyList->list.array, connectionToBeModifyList->list.size);
6688                            }
6689                            break;
6690                         }
6691
6692                      case ProtocolIE_IDE2_id_E2connectionUpdateRemove:
6693                         {
6694                            connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List;
6695                            if(connectionToBeRemoveList->list.array)
6696                            {
6697                               for(arrIdx = 0; arrIdx < connectionToBeRemoveList->list.count; arrIdx++)
6698                               {
6699                                  RIC_FREE(connectionToBeRemoveList->list.array[arrIdx], sizeof(E2connectionUpdateRemove_ItemIEs_t));
6700                               }
6701                               RIC_FREE(connectionToBeRemoveList->list.array, connectionToBeRemoveList->list.size);
6702                            }
6703                            break;
6704                         }
6705                   }
6706                   RIC_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdate_IEs_t));
6707                }
6708             }
6709             RIC_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size);
6710          }
6711          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6712       }
6713       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
6714    }
6715 }
6716
6717 /*******************************************************************
6718  *
6719  * @brief Buld and send the E2 Connection Update msg
6720  *
6721  * @details
6722  *
6723  *    Function : BuildAndSendE2ConnectionUpdate
6724  *
6725  *    Functionality:
6726  *         - Buld and send the E2 Connection Update Message
6727  * @params[in] 
6728  *    Du Id
6729  *    E2 connection to be modify or delete
6730  * @return ROK     - success
6731  *         RFAILED - failure
6732  *
6733  * ****************************************************************/
6734
6735 uint8_t BuildAndSendE2ConnectionUpdate(uint32_t duId, E2Connection connectionInfo)
6736 {
6737    uint8_t ieIdx = 0, elementCnt = 0;
6738    uint8_t ret = RFAILED, duIdx =0;
6739    DuDb    *duDb = NULLP;
6740    E2AP_PDU_t *e2apMsg = NULLP;
6741    E2connectionUpdate_t *e2ConnectionUpdate=NULLP;
6742    asn_enc_rval_t    encRetVal;       /* Encoder return value */
6743
6744    DU_LOG("\nINFO   -->  E2AP : Building E2 Connection Update Message\n");
6745    do
6746    {
6747       SEARCH_DU_DB(duIdx, duId, duDb);
6748       if(duDb == NULLP)
6749       {
6750          DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
6751          return RFAILED;
6752       }
6753    
6754       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
6755       if(e2apMsg == NULLP)
6756       {
6757          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6758          break;
6759       }
6760       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
6761
6762       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
6763       if(e2apMsg->choice.initiatingMessage == NULLP)
6764       {
6765          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6766          break;
6767       }
6768
6769       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2connectionUpdate;
6770       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
6771       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2connectionUpdate;
6772       e2ConnectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate;
6773
6774       elementCnt = 1;
6775       if(connectionInfo == MODIFY_CONNECTION) 
6776          elementCnt++;
6777       if(connectionInfo == REMOVE_CONNECTION)
6778          elementCnt++;
6779
6780       e2ConnectionUpdate->protocolIEs.list.count = elementCnt;
6781       e2ConnectionUpdate->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdate_IEs_t*);
6782       RIC_ALLOC(e2ConnectionUpdate->protocolIEs.list.array, e2ConnectionUpdate->protocolIEs.list.size);
6783       if(!e2ConnectionUpdate->protocolIEs.list.array)
6784       {
6785          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6786          break;
6787       }
6788
6789       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
6790       {
6791          RIC_ALLOC(e2ConnectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdate_IEs_t));
6792          if(!e2ConnectionUpdate->protocolIEs.list.array[ieIdx])
6793          {
6794             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__);
6795             break;
6796          }
6797       }
6798       if(ieIdx < elementCnt)
6799          break;
6800
6801       ieIdx = 0;
6802       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
6803       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6804       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_TransactionID;
6805       e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = assignTransactionId(duDb);
6806
6807       if(connectionInfo == MODIFY_CONNECTION)
6808       {
6809          ieIdx++;
6810          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionUpdateModify;
6811          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6812          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_E2connectionUpdate_List;
6813          if(BuildE2ConnectionModifyList(&e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List) != ROK)
6814          {
6815             DU_LOG("\nERROR  -->  E2AP : Failed to build the connection update modify list");
6816             break;
6817          }
6818       }
6819       
6820       if(connectionInfo == REMOVE_CONNECTION)
6821       {
6822          ieIdx++;
6823          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_E2connectionUpdateRemove;
6824          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
6825          e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdate_IEs__value_PR_E2connectionUpdateRemove_List;
6826          if(BuildE2ConnectionRemoveList(&e2ConnectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List) != ROK)
6827          {
6828             DU_LOG("\nERROR  -->  E2AP : Failed to build the connection update modify list");
6829             break;
6830          }
6831       }
6832
6833       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6834
6835       memset(encBuf, 0, ENC_BUF_MAX_LEN);
6836       encBufSize = 0;
6837       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
6838       if(encRetVal.encoded == ENCODE_FAIL)
6839       {
6840          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 connection update structure (at %s)\n",\
6841                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
6842          break;
6843       }
6844       else
6845       {
6846          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Connection Update \n");
6847          for(int i=0; i< encBufSize; i++)
6848          {
6849             DU_LOG("%x",encBuf[i]);
6850          }
6851       }
6852
6853       /* Sending msg */
6854       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
6855       {
6856          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Connection Update");
6857          break;
6858       }
6859
6860       ret = ROK;
6861       break;
6862    }while(true);
6863    
6864    FreeE2ConnectionUpdate(e2apMsg);
6865    return ret;
6866 }
6867
6868 /******************************************************************
6869  *
6870  * @brief Processes the E2 connection update failure msg
6871  *
6872  * @details
6873  *
6874  *    Function : procE2connectionUpdateFailure
6875  *
6876  *    Functionality: Processes the E2 connection update failure msg
6877  *
6878  * @params[in] 
6879  *       E2 connection update failure information
6880  *
6881  * @return void
6882  *
6883  * ****************************************************************/
6884 void ProcE2connectionUpdateFailure(E2connectionUpdateFailure_t *updateFailure) 
6885 {
6886    uint8_t ieIdx = 0;
6887    uint16_t transId=0;
6888    CauseE2_t *cause = NULLP;
6889
6890    if(!updateFailure)
6891    {
6892       DU_LOG("\nERROR  -->  E2AP : updateFailure pointer is null"); 
6893       return;
6894    }
6895
6896    if(!updateFailure->protocolIEs.list.array)      
6897    {
6898       DU_LOG("\nERROR  -->  E2AP : updateFailure array pointer is null");
6899       return;
6900    }
6901    
6902    for(ieIdx=0; ieIdx < updateFailure->protocolIEs.list.count; ieIdx++)
6903    {
6904       if(updateFailure->protocolIEs.list.array[ieIdx])
6905       {
6906          switch(updateFailure->protocolIEs.list.array[ieIdx]->id)
6907          {
6908             case ProtocolIE_IDE2_id_TransactionID:
6909                {
6910                   transId = updateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
6911                   DU_LOG("\nERROR  -->  E2AP : Received transID %d", transId);
6912                   break;
6913                }
6914             case ProtocolIE_IDE2_id_CauseE2:
6915                {
6916                    cause = &updateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2;
6917                    printE2ErrorCause(cause);
6918                    break; 
6919                }
6920             default:
6921                {
6922                   DU_LOG("\nERROR  -->  E2AP : Received Invalid Ie [%d]", updateFailure->protocolIEs.list.array[ieIdx]->id);
6923                   break;
6924                }
6925          }
6926       }
6927    }
6928 }
6929
6930 /*******************************************************************
6931 *
6932 * @brief Handles received E2AP message and sends back response  
6933 *
6934 * @details
6935 *
6936 *    Function : E2APMsgHdlr
6937 *
6938 *    Functionality:
6939 *         - Decodes received E2AP control message
6940 *         - Prepares response message, encodes and sends to SCTP
6941 *
6942 * @params[in] 
6943 * @return ROK     - success
6944 *         RFAILED - failure
6945 *
6946 * ****************************************************************/
6947 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
6948 {
6949    int             i;
6950    char            *recvBuf;
6951    MsgLen          copyCnt;
6952    MsgLen          recvBufLen;
6953    E2AP_PDU_t      *e2apMsg;
6954    asn_dec_rval_t  rval; /* Decoder return value */
6955    E2AP_PDU_t      e2apasnmsg ;
6956  
6957    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
6958    ODU_PRINT_MSG(mBuf, 0,0);
6959  
6960    /* Copy mBuf into char array to decode it */
6961    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
6962    RIC_ALLOC(recvBuf, (Size)recvBufLen);
6963
6964    if(recvBuf == NULLP)
6965    {
6966       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
6967       return;
6968    }
6969    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
6970    {
6971       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
6972       return;
6973    }
6974
6975    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
6976    for(i=0; i< recvBufLen; i++)
6977    {
6978         DU_LOG("%x",recvBuf[i]);
6979    }
6980
6981    /* Decoding flat buffer into E2AP messsage */
6982    e2apMsg = &e2apasnmsg;
6983    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
6984
6985    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
6986    RIC_FREE(recvBuf, (Size)recvBufLen);
6987
6988    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
6989    {
6990       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
6991       return;
6992    }
6993    DU_LOG("\n");
6994    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
6995
6996    switch(e2apMsg->present)
6997    {
6998       case E2AP_PDU_PR_initiatingMessage:
6999          {
7000             switch(e2apMsg->choice.initiatingMessage->value.present)
7001             {
7002                case InitiatingMessageE2__value_PR_E2setupRequest:
7003                   {
7004                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
7005                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
7006                      break;
7007                   }
7008                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
7009                   {
7010                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
7011                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
7012                      break;
7013                   }
7014                case InitiatingMessageE2__value_PR_ResetRequestE2:
7015                   {
7016                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
7017                      ProcResetRequest(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
7018                      break;
7019                   }
7020                case InitiatingMessageE2__value_PR_RICindication:
7021                   {
7022                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
7023                      break;
7024                   }
7025                case InitiatingMessageE2__value_PR_RICserviceUpdate:
7026                   {
7027                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
7028                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
7029                      break;
7030                   }
7031                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
7032                   {
7033                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
7034                      ProcRicSubsModReqd(*duId, \
7035                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
7036                      break;
7037                   }
7038                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
7039                   {
7040                       DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
7041                       ProcRicSubsDeleteReqd(*duId, \
7042                          &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
7043                       break;
7044                   }
7045
7046                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
7047                   {
7048                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
7049                      break;
7050                   }
7051                case InitiatingMessageE2__value_PR_E2RemovalRequest:
7052                   {
7053                      DU_LOG("\nINFO  -->  E2AP : E2 Removal request received");
7054                      procE2RemovalRequest(*duId,\
7055                      &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest);
7056                      break;
7057                   }
7058                default:
7059                   {
7060                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
7061                         e2apMsg->choice.initiatingMessage->value.present);
7062                      return;
7063                   }
7064             }/* End of switch(initiatingMessage) */
7065             break;
7066          }
7067       case E2AP_PDU_PR_successfulOutcome: 
7068          {
7069             switch(e2apMsg->choice.successfulOutcome->value.present)
7070             {
7071                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
7072                   {
7073                      DU_LOG("\nINFO  -->  E2AP : Reset response received");
7074                      ProcResetResponse(*duId,  &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2);
7075                      break;
7076                   }
7077                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
7078                   {
7079                      ProcRicSubscriptionResponse(*duId, \
7080                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
7081                      break;
7082                   }
7083                case SuccessfulOutcomeE2__value_PR_E2RemovalResponse:
7084                   {
7085                      ProcE2RemovalResponse(*duId, &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse);
7086                      break;
7087                   }
7088                default:
7089                   {
7090                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
7091                         e2apMsg->choice.successfulOutcome->value.present);
7092                      return;
7093                   }
7094                   break;
7095             }
7096             break; 
7097          }
7098          case E2AP_PDU_PR_unsuccessfulOutcome:
7099          {
7100             switch(e2apMsg->choice.successfulOutcome->value.present)
7101             {
7102                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
7103                   {
7104                      ProcRicSubscriptionFailure(*duId, \
7105                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
7106                      break;
7107                   }
7108                case UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure:
7109                   {
7110                      ProcE2RemovalFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure);
7111                      break;
7112                   }
7113                case UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure:
7114                   {
7115                      ProcE2connectionUpdateFailure(&e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure);
7116                      break;
7117                   }
7118                default:
7119                   {
7120                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
7121                         e2apMsg->choice.unsuccessfulOutcome->value.present);
7122                      return;
7123                   }
7124             }
7125             break;
7126          }
7127       default:
7128          {
7129             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
7130             return;
7131          }
7132
7133    }/* End of switch(e2apMsg->present) */
7134 } /* End of E2APMsgHdlr */
7135
7136
7137 /**********************************************************************
7138   End of file
7139  **********************************************************************/