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