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