[Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-527] Processing 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       /* TODO - Raising review next gerrit
820      if(BuildAndSendE2NodeConfigUpdateAck(duDb, transId, &tmpE2NodeList) !=ROK)
821       {
822          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 node config ack");
823          return;
824       }
825       */
826    }
827    else
828    {
829       if(BuildAndSendE2NodeConfigUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
830       {
831          DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 node config Failure");
832          return;
833       }
834    }
835 }
836 /*******************************************************************
837  *
838  * @brief Builds Global RIC Id Params
839  *
840  * @details
841  *
842  *    Function : BuildGlobalRicId
843  *
844  *    Functionality: Building the Plmn and ric id
845  *
846  * @params[in] GlobalRIC_ID_t *ricId
847  * @return ROK     - success
848  *         RFAILED - failure
849  *
850  * ****************************************************************/
851
852 uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId)
853 {
854    uint8_t unused = 4;
855    uint8_t byteSize = 3;
856    uint8_t ricVal= 1;
857    if(ricId != NULLP)
858    {
859       ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t);
860       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
861       buildPlmnId(ricCb.ricCfgParams.plmn , ricId->pLMN_Identity.buf);
862       /* fill ric Id */
863       ricId->ric_ID.size = byteSize * sizeof(uint8_t);
864       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
865       fillBitString(&ricId->ric_ID, unused, byteSize, ricVal);
866    }
867    return ROK;   
868 }
869
870 /*******************************************************************
871  *
872  * @brief deallocate the memory allocated in E2SetupResponse
873  *
874  * @details
875  *
876  *    Function : FreeE2SetupRsp 
877  *
878  *    Functionality: deallocate the memory allocated in E2SetupResponse 
879  *
880  * @params[in] E2AP_PDU_t *e2apMsg
881  *
882  * @return void
883  * ****************************************************************/
884 void FreeE2SetupRsp(E2AP_PDU_t *e2apMsg)
885 {
886    uint8_t arrIdx = 0, e2NodeConfigIdx=0, ranFuncIdx=0;
887    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
888    E2setupResponse_t  *e2SetupRsp=NULL;
889    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULL;
890    E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULL;
891    E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULL;
892    
893    if(e2apMsg)
894    {
895       if(e2apMsg->choice.successfulOutcome)
896       {
897          e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
898          if(e2SetupRsp->protocolIEs.list.array)
899          {
900             for(arrIdx=0; arrIdx<e2SetupRsp->protocolIEs.list.count; arrIdx++)
901             {
902                switch(e2SetupRsp->protocolIEs.list.array[arrIdx]->id)
903                {
904                   case ProtocolIE_IDE2_id_RANfunctionsAccepted:
905                   {
906                      ranFuncAcceptedList= &e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
907                      if(ranFuncAcceptedList->list.array)
908                      {
909                         for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
910                         {
911                            if(ranFuncAcceptedList->list.array[ranFuncIdx])
912                            {
913                               RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
914                            }
915                         }
916                         RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
917                      }
918                      break;
919                   }
920                   case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
921                   {
922                      e2NodeConfigAdditionAckList =&e2SetupRsp->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
923                      if(e2NodeConfigAdditionAckList->list.count)
924                      {
925                         for(e2NodeConfigIdx=0; e2NodeConfigIdx<e2NodeConfigAdditionAckList->list.count; e2NodeConfigIdx++)
926                         {
927                            e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2NodeConfigIdx];
928                            if(e2NodeAddAckItemIe)
929                            {
930                               f1InterfaceInfo = e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; 
931                               if(f1InterfaceInfo)
932                               {
933                                  RIC_FREE(f1InterfaceInfo->gNB_DU_ID.buf, f1InterfaceInfo->gNB_DU_ID.size);
934                                  RIC_FREE(f1InterfaceInfo, sizeof(E2nodeComponentInterfaceF1_t));
935                               }
936                               RIC_FREE(e2NodeAddAckItemIe, sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
937                            }
938                         }
939                         RIC_FREE(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
940                      }
941                      break;
942                   }
943                }
944                RIC_FREE(e2SetupRsp->protocolIEs.list.array[arrIdx], sizeof(E2setupResponseIEs_t)); 
945             }
946             RIC_FREE(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
947          }
948          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
949       }
950       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
951    }
952 }
953
954 /*******************************************************************
955  *
956  * @brief fill e2 node configuration for ack msg 
957  *
958  * @details
959  *
960  *    Function : fillE2NodeConfigAck
961  *
962  *    Functionality:
963  *       - fill e2 node configuration for ack msg
964  *
965  * @params[in] 
966  *    Pointer to e2NodeCfg to be filled
967  *    procedure Code
968  *    E2 Node Component information
969  *    Is successful or failure response
970  * @return ROK     - success
971  *         RFAILED - failure
972  *
973  * ****************************************************************/
974
975 uint8_t fillE2NodeConfigAck(PTR e2NodeCfg, uint8_t procedureCode, E2NodeComponent *componentInfo, bool isSuccessful)
976 {
977    E2nodeComponentID_t *e2nodeComponentID=NULLP;
978    E2nodeComponentInterfaceType_t *e2nodeComponentInterfaceType=NULLP;
979    E2nodeComponentConfigurationAck_t *e2nodeComponentConfigurationAck=NULLP;
980    E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP;
981    E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP;
982    E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP;
983    
984    /* filling the interface type, component id, configuration ack based on the
985     * e2 node configuration add, update, delete type  */
986    switch(procedureCode)
987    {
988       case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
989          {
990             additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg;
991             e2nodeComponentInterfaceType = &((E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg)->e2nodeComponentInterfaceType;
992             e2nodeComponentID = &additionAckItem->e2nodeComponentID;
993             e2nodeComponentConfigurationAck = &additionAckItem->e2nodeComponentConfigurationAck;
994             break;
995          }
996       case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
997          {
998             updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg;
999             e2nodeComponentInterfaceType = &updateAckItem->e2nodeComponentInterfaceType;
1000             e2nodeComponentID = &updateAckItem->e2nodeComponentID;
1001             e2nodeComponentConfigurationAck = &updateAckItem->e2nodeComponentConfigurationAck;
1002             break;
1003          }
1004       case  ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
1005          {
1006             removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg;
1007             e2nodeComponentInterfaceType = &removalAckItem->e2nodeComponentInterfaceType;
1008             e2nodeComponentID = &removalAckItem->e2nodeComponentID;
1009             e2nodeComponentConfigurationAck = &removalAckItem->e2nodeComponentConfigurationAck;
1010             break;
1011          }
1012    }
1013
1014    /* >E2 Node Component interface type */
1015    if(componentInfo->interfaceType>= 0 && componentInfo->interfaceType<=6)
1016    {
1017       *e2nodeComponentInterfaceType = componentInfo->interfaceType;
1018    }
1019    else
1020    {
1021       DU_LOG("\nERROR  --> E2AP: Received an invalid interface value %d",componentInfo->interfaceType);
1022       return RFAILED;
1023    }
1024
1025    if(*e2nodeComponentInterfaceType == E2nodeComponentInterfaceType_f1)
1026    {
1027       /* >E2 Node Component ID */
1028       e2nodeComponentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1;
1029       RIC_ALLOC(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t));
1030       if(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP)
1031       {
1032          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
1033          return RFAILED;
1034       }
1035       e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t);
1036       RIC_ALLOC(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size);
1037
1038       if(e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP)
1039       {
1040          DU_LOG("\nERROR  -->list.  E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
1041          return RFAILED;
1042       }
1043       e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0]  = componentInfo->componentId;
1044    }
1045
1046    if(isSuccessful)
1047    {
1048       /* >E2 Node Component Configuration Acknowledge*/
1049       e2nodeComponentConfigurationAck->updateOutcome = E2nodeComponentConfigurationAck__updateOutcome_success;
1050    }
1051    else
1052    {
1053       /* >E2 Node Component Configuration Acknowledge*/
1054       e2nodeComponentConfigurationAck->updateOutcome = E2nodeComponentConfigurationAck__updateOutcome_failure;
1055       RIC_ALLOC(e2nodeComponentConfigurationAck->failureCauseE2, sizeof(struct CauseE2));
1056       if(e2nodeComponentConfigurationAck->failureCauseE2)
1057       {
1058          fillE2FailureCause(e2nodeComponentConfigurationAck->failureCauseE2, CauseE2_PR_e2Node, CauseE2node_e2node_component_unknown);
1059       }
1060       else
1061       {
1062          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigUpdateAck %d",__LINE__);
1063          return RFAILED;
1064       }
1065    }
1066    return ROK;
1067 }
1068
1069 /*******************************************************************
1070  *
1071  * @brief Build E2node Component config addition ack list
1072  *
1073  * @details
1074  *
1075  *    Function :  BuildE2nodeComponentConfigAdditionAck
1076  *
1077  *    Functionality:  Build E2node Component config addition ack list 
1078  *
1079  * @params[in] 
1080  *    E2nodeComponentConfigAdditionAck_List to be filled
1081  *    Count of e2 node to be added
1082  *    list of e2 node cfg to be added
1083  *
1084  * @return ROK - success
1085  *         RFAILED - failure
1086  * ****************************************************************/
1087
1088 uint8_t BuildE2nodeComponentConfigAdditionAck(E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList, \
1089 uint16_t addedE2NodeCount, E2NodeConfigItem *addedE2Node)
1090 {
1091    E2NodeComponent *e2NodeComponentInfo=NULLP;
1092    CmLList *node=NULLP;
1093    uint16_t arrIdx = 0;
1094    E2nodeComponentConfigAdditionAck_Item_t *e2NodeAddAckItem=NULLP;
1095    E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItemIe=NULLP;
1096   
1097    e2NodeConfigAdditionAckList->list.count = addedE2NodeCount;
1098    
1099    e2NodeConfigAdditionAckList->list.size = e2NodeConfigAdditionAckList->list.count * sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t*);
1100    RIC_ALLOC(e2NodeConfigAdditionAckList->list.array, e2NodeConfigAdditionAckList->list.size);
1101    if(e2NodeConfigAdditionAckList->list.array == NULLP)
1102    {
1103       DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
1104       return RFAILED;
1105    }
1106
1107    for(arrIdx = 0; arrIdx< e2NodeConfigAdditionAckList->list.count; arrIdx++)
1108    {
1109       RIC_ALLOC(e2NodeConfigAdditionAckList->list.array[arrIdx], sizeof(E2nodeComponentConfigAdditionAck_ItemIEs_t));
1110       if(e2NodeConfigAdditionAckList->list.array[arrIdx] == NULLP)
1111       {
1112          DU_LOG("\nERROR  --> E2AP: Memory allocation failed for BuildE2nodeComponentConfigAdditionAck %d",__LINE__);
1113          return RFAILED;
1114       }
1115       e2NodeAddAckItemIe = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[arrIdx];
1116       e2NodeAddAckItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck_Item;
1117       e2NodeAddAckItemIe->criticality = CriticalityE2_reject;
1118       e2NodeAddAckItemIe->value.present = E2nodeComponentConfigAdditionAck_ItemIEs__value_PR_E2nodeComponentConfigAdditionAck_Item;
1119       e2NodeAddAckItem = &e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item;
1120
1121       /* Filling the e2 node config addition ack item */
1122       fillE2NodeConfigAck((PTR)&e2NodeAddAckItemIe->value.choice.E2nodeComponentConfigAdditionAck_Item, ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck,\
1123       &addedE2Node[arrIdx].componentInfo, addedE2Node[arrIdx].isSuccessful);
1124    }
1125    return ROK;  
1126 }
1127
1128 /*******************************************************************
1129  *
1130  * @brief Build RAN function accepted list
1131  *
1132  * @details
1133  *
1134  *    Function : BuildRanFunctionAcceptedList
1135  *
1136  *    Functionality: Build RAN function accepted list 
1137  *     ->For ProcedureCodeE2_id_E2setup or ProcedureCodeE2_id_RICserviceQuery  
1138  *     we add all the RAN Function list which is present in RIC database.
1139  *     ->For any other procedures, we just fill the RAN functions whose ID 
1140  *     is present in the recvList
1141  *
1142  * @params[in] 
1143  *    Stored DU databse 
1144  *    Count of ran functions to be accepted in the list 
1145  *    Received list of RAN functions
1146  *    RAN Function list  
1147  *    Procedure Code 
1148  *
1149  * @return ROK - success
1150  *         RFAILED - failure
1151  * ****************************************************************/
1152
1153 uint8_t BuildRanFunctionAcceptedList(DuDb *duDb, uint8_t count, RanFunction *ranFunAcceptedList, RANfunctionsID_List_t *ranFuncAcceptedList, uint8_t procedureCode)
1154 {
1155    uint16_t ranFuncIdx = 0;
1156    RANfunctionID_ItemIEs_t *ranFuncAcceptedItemIe=NULL;
1157    
1158    /* For ProcedureCodeE2_id_E2setup and ProcedureCodeE2_id_RICserviceQuery, 
1159     * the number of RAN function list items is equal to the number of 
1160     * ran function entries stored in the database.
1161     * For any other procedure, the RAN function list count is equal
1162     * to the count of ran functions obtained from the function's caller */
1163
1164    if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
1165       ranFuncAcceptedList->list.count = duDb->numOfRanFunction;
1166    else
1167       ranFuncAcceptedList->list.count = count;
1168    
1169    ranFuncAcceptedList->list.size = ranFuncAcceptedList->list.count*sizeof(RANfunctionID_ItemIEs_t*);
1170    RIC_ALLOC(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
1171    if(ranFuncAcceptedList->list.array)
1172    {
1173       for(ranFuncIdx = 0; ranFuncIdx< ranFuncAcceptedList->list.count; ranFuncIdx++)
1174       {
1175          RIC_ALLOC(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
1176          if(ranFuncAcceptedList->list.array[ranFuncIdx] == NULLP)
1177          {
1178             DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array item");
1179             return RFAILED;
1180          }
1181          ranFuncAcceptedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAcceptedList->list.array[ranFuncIdx];
1182          ranFuncAcceptedItemIe->id = ProtocolIE_IDE2_id_RANfunctionID_Item;
1183          ranFuncAcceptedItemIe->criticality= CriticalityE2_ignore;
1184          ranFuncAcceptedItemIe->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
1185          if((procedureCode == ProcedureCodeE2_id_RICserviceQuery)||(procedureCode == ProcedureCodeE2_id_E2setup))
1186          {
1187             /* filling the RAN function information with the help of DuDb */
1188             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = duDb->ranFunction[ranFuncIdx].id;
1189             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= duDb->ranFunction[ranFuncIdx].revisionCounter;
1190          }
1191          else
1192          {
1193             /* filling the the RAN function information with the help received list of RAN functions */
1194             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionID = ranFunAcceptedList[ranFuncIdx].id;
1195             ranFuncAcceptedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision= ranFunAcceptedList[ranFuncIdx].revisionCounter;
1196          }
1197       }
1198    }
1199    else
1200    {
1201       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function added list array");
1202       return RFAILED;
1203    }
1204    return ROK;
1205 }
1206
1207 /*******************************************************************
1208  *
1209  * @brief Builds and sends the E2SetupResponse
1210  *
1211  * @details
1212  *
1213  *    Function : BuildAndSendE2SetupRsp
1214  *
1215  *    Functionality: Builds and sends the E2SetupResponse
1216  *
1217  * @params[in] 
1218  *      Du datbase
1219  *      Trans id
1220  *      List of E2node cofniguration which needs to be send
1221  *
1222  * @return ROK     - success
1223  *         RFAILED - failure
1224  *
1225  * ****************************************************************/
1226
1227 uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId, E2NodeConfigList e2NodeList)
1228 {
1229    E2AP_PDU_t         *e2apMsg = NULL;
1230    E2setupResponse_t  *e2SetupRsp;
1231    asn_enc_rval_t     encRetVal; 
1232    uint8_t            idx;
1233    uint8_t            elementCnt;
1234    bool  memAllocFailed = false;
1235  
1236    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup Response\n");
1237    while(true)
1238    {
1239       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
1240       if(e2apMsg == NULLP)
1241       {
1242          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1243          break;
1244       }
1245       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
1246       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
1247       if(e2apMsg->choice.successfulOutcome == NULLP)
1248       {
1249          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
1250          break;  
1251       }
1252
1253       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
1254       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
1255       e2apMsg->choice.successfulOutcome->value.present = \
1256                                                          SuccessfulOutcomeE2__value_PR_E2setupResponse;
1257       e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
1258
1259       elementCnt = 3;
1260       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
1261       if(duDb->numOfRanFunction)
1262          elementCnt++;
1263
1264       e2SetupRsp->protocolIEs.list.count = elementCnt;
1265       e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t*);
1266
1267       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, e2SetupRsp->protocolIEs.list.size);
1268       if(e2SetupRsp->protocolIEs.list.array == NULLP)
1269       {
1270          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
1271          break;  
1272       }
1273
1274       for(idx=0; idx<elementCnt; idx++)
1275       {
1276          RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], sizeof(E2setupResponseIEs_t)); 
1277          if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
1278          { 
1279             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");
1280             memAllocFailed = true;
1281             break;
1282          }    
1283       }
1284       
1285       if(memAllocFailed == true)
1286       {
1287           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2ResponseIEs failed");    
1288           break;
1289       }
1290       /* Trans Id */
1291       idx = 0;
1292       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_TransactionID;
1293       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1294       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_TransactionID; 
1295       e2SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID  = transId;
1296
1297       /* Global RIC ID */
1298       idx++;
1299       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
1300       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1301       e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_GlobalRIC_ID;
1302
1303       if(BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID))!=ROK)
1304       {
1305          DU_LOG("\nERROR  -->  E2AP : Failed to build Global Ric Id");
1306          break;
1307       }
1308       
1309       if(duDb->numOfRanFunction)
1310       {
1311          /* Accepted RAN function Id */
1312          idx++;
1313          e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
1314          e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1315          e2SetupRsp->protocolIEs.list.array[idx]->value.present = E2setupResponseIEs__value_PR_RANfunctionsID_List;
1316          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &e2SetupRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_E2setup)!=ROK)
1317          {
1318             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
1319             break;         
1320          }
1321       }
1322
1323       /* E2 Node Component Configuration Addition Acknowledge List*/
1324       idx++;
1325       e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck;
1326       e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1327       e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
1328          E2setupResponseIEs__value_PR_E2nodeComponentConfigAdditionAck_List;
1329       if(BuildE2nodeComponentConfigAdditionAck(&e2SetupRsp->protocolIEs.list.array[idx]->\
1330          value.choice.E2nodeComponentConfigAdditionAck_List, e2NodeList.addedE2NodeCount, e2NodeList.addedE2Node) != ROK)
1331       {
1332          DU_LOG("\nERROR  -->  E2AP : Failed to build E2Node Component config addition ack list");
1333          break;
1334       }
1335
1336       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
1337       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1338       encBufSize = 0;
1339       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
1340
1341       /* Check encode results */
1342       if(encRetVal.encoded == ENCODE_FAIL)
1343       {
1344          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SetupResponse structure (at %s)\n",\
1345                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1346          break;   
1347       } 
1348       else 
1349       {
1350          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2SetupResponse\n");
1351          for(int i=0; i< encBufSize; i++)
1352          {
1353             DU_LOG("%x",encBuf[i]);
1354          } 
1355       }
1356
1357       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
1358       {
1359          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Response failed");      
1360          break;   
1361       }
1362       break;
1363    }
1364
1365    FreeE2SetupRsp(e2apMsg);
1366    BuildAndSendRicSubscriptionReq(duDb);
1367    return ROK;
1368 }
1369
1370 /*******************************************************************
1371  *
1372  * @brief Free RIC Subscription Details
1373  *
1374  * @details
1375  *
1376  *    Function : FreeRicSubsDetails
1377  *
1378  *    Functionality: Free the RIC Subscription Details
1379  *
1380  * @params[in] RICsubscriptionDetails_t *subsDetails
1381  * @return void
1382  *
1383  * ****************************************************************/
1384 void FreeRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
1385 {
1386    uint8_t elementIdx = 0;
1387    RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP;
1388
1389    RIC_FREE(subsDetails->ricEventTriggerDefinition.buf, subsDetails->ricEventTriggerDefinition.size);
1390
1391    if(subsDetails->ricAction_ToBeSetup_List.list.array)
1392    {
1393       for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++)
1394       {
1395          if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1396          {
1397             actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx];
1398             if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1399             {
1400                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf, \
1401                   actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->size);
1402                RIC_FREE(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
1403             }
1404             RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t))
1405          }
1406       }
1407       RIC_FREE(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1408    }
1409 }
1410
1411 /*******************************************************************
1412  *
1413  * @brief Free RIC Subscription Request
1414  *
1415  * @details
1416  *
1417  *    Function : FreeRicSubscriptionReq
1418  *
1419  * Functionality : Free RIC Subscription Request
1420  *
1421  * @return ROK     - success
1422  *         RFAILED - failure
1423  *
1424  ******************************************************************/
1425 void FreeRicSubscriptionReq(E2AP_PDU_t *e2apRicMsg)
1426 {
1427    uint8_t idx = 0;
1428    RICsubscriptionRequest_t   *ricSubscriptionReq;
1429
1430    if(e2apRicMsg)
1431    {
1432       if(e2apRicMsg->choice.initiatingMessage)
1433       {
1434          ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1435          if(ricSubscriptionReq->protocolIEs.list.array)
1436          {
1437             for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++)
1438             {
1439                switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id)
1440                {
1441                   case ProtocolIE_IDE2_id_RICsubscriptionDetails:
1442                      {
1443                         FreeRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
1444                         break;
1445                      }
1446                }               
1447                RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1448             }
1449             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1450          }
1451          RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1452       }
1453       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
1454    }
1455 }
1456
1457 /*******************************************************************
1458  *
1459  * @brief Builds Ric Request Id
1460  *
1461  * @details
1462  *
1463  *    Function : BuildNewRicRequestId
1464  *
1465  *    Functionality: Assign new Ric Request ID
1466  *
1467  * @params[in] RIC request ID to be sent
1468  *             RIC request ID stored in DB
1469  * @return ROK     - success
1470  *         RFAILED - failure
1471  *
1472  * ****************************************************************/
1473
1474 uint8_t BuildNewRicRequestId(RICrequestID_t *ricReqId, RicRequestId *reqIdDb)
1475 {
1476    static uint16_t requestorId = 0;
1477    static uint16_t instanceId = 0;
1478
1479    if(ricReqId != NULLP)
1480    {
1481       ricReqId->ricRequestorID = ++requestorId;
1482       ricReqId->ricInstanceID  = ++instanceId;
1483
1484       reqIdDb->requestorId = ricReqId->ricRequestorID;
1485       reqIdDb->instanceId = ricReqId->ricInstanceID;
1486    }
1487    return ROK;
1488 }
1489
1490 /*******************************************************************
1491  *
1492  * @brief Free RIC Action Definition
1493  *
1494  * @details
1495  *
1496  *    Function : FreeRicActionDefinition
1497  *
1498  *    Functionality: Free RIC Action Definition
1499  *
1500  * @params[in] E2SM-KPM Action definition
1501  * @return void
1502  *
1503  * ****************************************************************/
1504 void  FreeRicActionDefinition(E2SM_KPM_ActionDefinition_t actionDef)
1505 {
1506    uint8_t  elementIdx = 0;
1507    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1508    MeasurementInfoItem_t *measItem = NULLP;
1509
1510    switch(actionDef.actionDefinition_formats.present)
1511    {
1512       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1:
1513          {
1514             if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1)
1515             {
1516                actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1517                if(actionFormat1->measInfoList.list.array)
1518                {
1519                   for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++)
1520                   {
1521                      if(actionFormat1->measInfoList.list.array[elementIdx])
1522                      {
1523                         measItem = actionFormat1->measInfoList.list.array[elementIdx];
1524                         switch(measItem->measType.present)
1525                         {
1526                            case MeasurementType_PR_NOTHING:
1527                            case MeasurementType_PR_measID:
1528                               break;
1529                            case MeasurementType_PR_measName:
1530                            {
1531                               RIC_FREE(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size)
1532                               break;
1533                            }
1534                         }
1535                         RIC_FREE(measItem, sizeof(MeasurementInfoItem_t));
1536                      }
1537                   }
1538                   RIC_FREE(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1539                }
1540                RIC_FREE(actionFormat1, sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1541             }
1542             break;
1543          }
1544
1545       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2:
1546       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3:
1547       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4:
1548       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5:
1549       case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_NOTHING:
1550          break;
1551    }
1552 }
1553
1554 /*******************************************************************
1555  *
1556  * @brief Fill RIC Action Definition
1557  *
1558  * @details
1559  *
1560  *    Function : fillRicActionDef
1561  *
1562  *    Functionality: Fill RIC Action Definition
1563  *
1564  * @params[in] RIC Action definition
1565  * @return ROK 
1566  *         RFAILED
1567  *
1568  * ****************************************************************/
1569 uint8_t fillRicActionDef(RICactionDefinition_t *ricActionDef)
1570 {
1571    uint8_t ret = RFAILED;
1572    asn_enc_rval_t  encRetVal;
1573    uint8_t elementCnt = 0, elementIdx = 0;
1574    char    *measurementTypeName[] = {"RRU.PrbTotDl", "RRU.PrbTotUl"};
1575    E2SM_KPM_ActionDefinition_t actionDef;
1576    E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP;
1577    MeasurementInfoItem_t *measItem = NULLP;
1578    
1579    while(true)
1580    {
1581       /* Fill E2SM-KPM Action Definition Format 1 */
1582
1583       /* RIC Stype Type */
1584       actionDef.ric_Style_Type = RIC_STYLE_TYPE;
1585
1586       /* RIC Action Definition Format 1 */
1587       actionDef.actionDefinition_formats.present = \
1588            E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1;
1589
1590       RIC_ALLOC(actionDef.actionDefinition_formats.choice.actionDefinition_Format1, \
1591             sizeof(E2SM_KPM_ActionDefinition_Format1_t));
1592       if(actionDef.actionDefinition_formats.choice.actionDefinition_Format1 == NULLP)
1593       {
1594          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1595          break;
1596       }
1597       actionFormat1 = actionDef.actionDefinition_formats.choice.actionDefinition_Format1;
1598
1599       /* Measurement Info List */
1600       elementCnt = 2;
1601       actionFormat1->measInfoList.list.count = elementCnt;
1602       actionFormat1->measInfoList.list.size = elementCnt * sizeof(MeasurementInfoItem_t *);
1603       RIC_ALLOC(actionFormat1->measInfoList.list.array, actionFormat1->measInfoList.list.size);
1604       if(actionFormat1->measInfoList.list.array == NULL)
1605       {
1606          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1607          break;
1608       }
1609
1610       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1611       {
1612          RIC_ALLOC(actionFormat1->measInfoList.list.array[elementIdx], sizeof(MeasurementInfoItem_t));
1613          if(actionFormat1->measInfoList.list.array[elementIdx] == NULLP)
1614          {
1615             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1616             break;
1617          }
1618
1619          measItem = actionFormat1->measInfoList.list.array[elementIdx];
1620          measItem->measType.present = MeasurementType_PR_measName;
1621
1622          measItem->measType.choice.measName.size = strlen(measurementTypeName[elementIdx]);
1623          RIC_ALLOC(measItem->measType.choice.measName.buf, measItem->measType.choice.measName.size);
1624          if(measItem->measType.choice.measName.buf == NULLP)
1625          {
1626             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1627             break;
1628          }
1629          memcpy(measItem->measType.choice.measName.buf, measurementTypeName[elementIdx], measItem->measType.choice.measName.size);
1630       }
1631       if(elementIdx < elementCnt)
1632          break;
1633
1634       /* Granularity Period */
1635       actionFormat1->granulPeriod = RIC_ACTION_GRANULARITY_PERIOD; /* In ms */
1636
1637       /* Prints the Msg formed */
1638       xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, &actionDef);
1639
1640       /* Encode E2SM-KPM RIC Action Definition */
1641       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1642       encBufSize = 0;
1643       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_ActionDefinition, 0, &actionDef, PrepFinalEncBuf, encBuf);
1644       if(encRetVal.encoded == ENCODE_FAIL)
1645       {
1646          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM action definition structure (at %s)\n",\
1647                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1648          break;
1649       }
1650
1651       /* Copty encoded E2SM-KPM RIC action definition to E2AP octet string buffer */
1652       ricActionDef->size = encBufSize;
1653       RIC_ALLOC(ricActionDef->buf, encBufSize);
1654       if(ricActionDef->buf == NULLP)
1655       {
1656          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1657          break;
1658       }
1659       memcpy(ricActionDef->buf, encBuf, encBufSize);
1660
1661       ret = ROK;
1662       break;
1663    }
1664
1665    FreeRicActionDefinition(actionDef);
1666    return ret;
1667 }
1668
1669 /*******************************************************************
1670  *
1671  * @brief Fills RIC Action To Be Setup Item
1672  *
1673  * @details
1674  *
1675  *    Function : fillActionToBeSetup
1676  *
1677  *    Functionality: Fill the RIC Action To Be Setup Ite,
1678  *                   RIC subscription DB
1679  *
1680  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
1681  * @return ROK     - success
1682  *         RFAILED - failure
1683  *
1684  * ****************************************************************/
1685 uint8_t fillActionToBeSetup(RICaction_ToBeSetup_ItemIEs_t *actionItem, RicSubscription *ricSubsDb)
1686 {
1687    static uint8_t ricActionId = 0;
1688
1689    if(actionItem == NULLP)
1690    {
1691       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1692       return RFAILED;
1693    }
1694
1695    while(true)
1696    {
1697       actionItem->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
1698       actionItem->criticality   =  CriticalityE2_ignore;
1699       actionItem->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
1700       
1701       /* RIC Action ID */
1702       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID = ricActionId;
1703       ricSubsDb->actionSequence[ricActionId].actionId = \
1704          actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID;
1705       ricActionId++;
1706
1707       /* RIC Action Type */
1708       actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
1709
1710       /* RIC Action Definition */
1711       RIC_ALLOC(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, sizeof(RICactionDefinition_t));
1712       if(!actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition)
1713       {
1714          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1715          break;
1716       }
1717       if(fillRicActionDef(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) != ROK)
1718       {
1719          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1720          break;
1721       }
1722       
1723       ricSubsDb->numOfActions++;
1724       return ROK;
1725    }
1726
1727    memset(&ricSubsDb->actionSequence[ricActionId], 0, sizeof(ActionInfo));
1728    ricSubsDb->actionSequence[ricActionId].actionId = -1;
1729    return RFAILED;
1730 }
1731
1732 /*******************************************************************
1733  *
1734  * @brief Free Event Trigger Definition
1735  *
1736  * @details
1737  *
1738  *    Function : FreeEventTriggerDef
1739  *
1740  *    Functionality: Free Event Trigger Definition
1741  *
1742  * @params[in] E2SM-KPM Event Trigger Definition
1743  * @return void
1744  *
1745  * ****************************************************************/
1746 void  FreeEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef)
1747 {
1748    if(eventTiggerDef)
1749    {
1750       switch(eventTiggerDef->eventDefinition_formats.present)
1751       {
1752          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING:
1753             break;
1754          case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: 
1755             RIC_FREE(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1, \
1756                   sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1757             break;                  
1758       }         
1759    }
1760 }
1761
1762 /*******************************************************************
1763  *
1764  * @brief Fill Event Trigger Definition
1765  *
1766  * @details
1767  *
1768  *    Function : fillEventTriggerDef
1769  *
1770  *    Functionality: Fill Event Trigger Definition
1771  *
1772  * @params[in] RIC Event Trigger Definition
1773  * @return ROK
1774  *         RFAILED
1775  *
1776  * ****************************************************************/
1777 uint8_t fillEventTriggerDef(RICeventTriggerDefinition_t *ricEventTriggerDef)
1778 {
1779    uint8_t ret = RFAILED;
1780    asn_enc_rval_t  encRetVal;
1781    E2SM_KPM_EventTriggerDefinition_t eventTiggerDef;
1782
1783    while(true)
1784    {
1785       /* Fill E2SM-KPM Event Trigger Definition Format 1 */
1786       eventTiggerDef.eventDefinition_formats.present = \
1787        E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1;
1788
1789       RIC_ALLOC(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1, \
1790             sizeof(E2SM_KPM_EventTriggerDefinition_Format1_t));
1791       if(eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1 == NULLP)
1792       {
1793          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1794          break;
1795       }
1796
1797       eventTiggerDef.eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod = 1000; /* In ms */
1798
1799       /* Prints the Msg formed */
1800       xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, &eventTiggerDef);
1801
1802       /* Encode E2SM-KPM Event Trigger Definition */
1803       memset(encBuf, 0, ENC_BUF_MAX_LEN);
1804       encBufSize = 0;
1805       encRetVal = aper_encode(&asn_DEF_E2SM_KPM_EventTriggerDefinition, 0, &eventTiggerDef, PrepFinalEncBuf, encBuf);
1806       if(encRetVal.encoded == ENCODE_FAIL)
1807       {
1808          DU_LOG("\nERROR  -->  E2AP : Could not encode E2SM-KPM event trigger definition structure (at %s)\n",\
1809                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
1810          break;
1811       }
1812
1813       /* Copy encoded E2SM-KPM event trigger definition to E2AP octet string buffer */
1814       ricEventTriggerDef->size = encBufSize;
1815       RIC_ALLOC(ricEventTriggerDef->buf, encBufSize);
1816       if(ricEventTriggerDef->buf == NULLP)
1817       {
1818          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1819          break;
1820       }
1821       memcpy(ricEventTriggerDef->buf, encBuf, encBufSize);
1822
1823       ret = ROK;
1824       break;
1825    }
1826
1827    FreeEventTriggerDef(&eventTiggerDef);
1828    return ret;
1829 }
1830
1831 /*******************************************************************
1832  *
1833  * @brief builds RIC Subscription Details
1834  *
1835  * @details
1836  *
1837  *    Function : BuildsRicSubsDetails
1838  *
1839  *    Functionality: Builds the RIC Subscription Details
1840  *
1841  * @params[in] RIC Subscription details to be filled
1842  *             RIC subscriotion DB
1843  * @return ROK     - success
1844  *         RFAILED - failure
1845  *
1846  * ****************************************************************/
1847
1848 uint8_t BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails, RicSubscription *ricSubsInfo)
1849 {
1850    uint8_t elementCnt = 0;
1851    uint8_t elementIdx = 0;
1852
1853    if(subsDetails == NULLP)
1854    {
1855       DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1856       return RFAILED;
1857    }
1858
1859    while(true)
1860    {
1861       /* RIC Event Trigger Definition */
1862       if(fillEventTriggerDef(&subsDetails->ricEventTriggerDefinition) != ROK)
1863       {
1864          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1865          break;
1866       }
1867
1868       /* RIC Actions To Be Setup List */
1869       elementCnt = 1;
1870       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
1871       subsDetails->ricAction_ToBeSetup_List.list.size = elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t *);
1872       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, subsDetails->ricAction_ToBeSetup_List.list.size);
1873       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
1874       {
1875          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RICactionToBeSetup Items failed");
1876          break;
1877       } 
1878
1879       for(elementIdx = 0; elementIdx < elementCnt; elementIdx++)
1880       {
1881          RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], sizeof(RICaction_ToBeSetup_ItemIEs_t));
1882          if(!subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx])
1883          {
1884             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1885             break;
1886          }
1887       }
1888       if(elementIdx < elementCnt)
1889          break;
1890
1891
1892       elementIdx = 0;
1893       if(fillActionToBeSetup((RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx], \
1894          ricSubsInfo) != ROK)
1895       {
1896          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : line [%d]", __func__, __LINE__);
1897          break;
1898       }
1899
1900       return ROK;
1901    }
1902    return RFAILED;
1903 }
1904
1905 /*******************************************************************
1906  *
1907  * @brief Builds and Send the RicSubscriptionReq
1908  *
1909  * @details
1910  *
1911  *    Function : BuildAndSendRicSubscriptionReq
1912  *
1913  * Functionality:Fills the RicSubscriptionReq
1914  *
1915  * @return ROK     - success
1916  *         RFAILED - failure
1917  *
1918  ******************************************************************/
1919 uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb)
1920 {
1921    uint8_t         ret = RFAILED;
1922    uint8_t         elementCnt = 0;
1923    uint8_t         idx = 0;
1924    uint8_t         actionIdx = 0;
1925    asn_enc_rval_t  encRetVal;        /* Encoder return value */
1926    E2AP_PDU_t                 *e2apRicMsg = NULL;
1927    RICsubscriptionRequest_t   *ricSubscriptionReq;
1928    RanFunction  *ranFuncDb = &duDb->ranFunction[0];
1929    CmLList *ricSubsNode = NULLP;
1930    RicSubscription *ricSubsInfo = NULLP;
1931
1932    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Request\n");
1933
1934    /* Allocate memory to store RIC subscription info in RIC DB */
1935    RIC_ALLOC(ricSubsInfo, sizeof(RicSubscription));
1936    if(!ricSubsInfo)
1937    {
1938       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1939       return RFAILED;
1940    }
1941    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
1942    {
1943       ricSubsInfo->actionSequence[actionIdx].actionId = -1;
1944    }
1945
1946    while(true)
1947    {
1948       RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
1949       if(e2apRicMsg == NULLP)
1950       {
1951          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1952          break;
1953       }
1954
1955       e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
1956       RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
1957       if(e2apRicMsg->choice.initiatingMessage == NULLP)
1958       {
1959          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1960          break;
1961       }
1962       e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
1963       e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
1964       e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
1965
1966       ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
1967
1968       elementCnt = 3;
1969       ricSubscriptionReq->protocolIEs.list.count = elementCnt;
1970       ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
1971
1972       /* Initialize the subscription members */
1973       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, ricSubscriptionReq->protocolIEs.list.size);
1974       if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
1975       {
1976          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1977          break;
1978       }
1979
1980       for(idx=0; idx<elementCnt; idx++)
1981       {
1982          RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx], sizeof(RICsubscriptionRequest_IEs_t));
1983          if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
1984          {
1985             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
1986             break;
1987          }
1988       }
1989       if(idx < elementCnt)
1990          break;
1991
1992       /* Filling RIC Request Id */
1993       idx = 0;
1994       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
1995       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
1996       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
1997                                                                       RICsubscriptionRequest_IEs__value_PR_RICrequestID;
1998       if(BuildNewRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID, \
1999          &ricSubsInfo->requestId) != ROK)
2000       {
2001          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
2002          break;
2003       }
2004
2005
2006       /* Filling RAN Function Id */
2007       idx++;
2008       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
2009       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2010       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2011                                                                       RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
2012       ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ranFuncDb->id;
2013       ricSubsInfo->ranFuncId = ranFuncDb->id;
2014
2015       /* Filling RIC Subscription Details */
2016       idx++;
2017       ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
2018       ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
2019       ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
2020                                                                       RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
2021       if(BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails),\
2022          ricSubsInfo) != ROK)
2023       {
2024          DU_LOG("\nERROR  -->  E2AP : Failed at [%s] : Line [%d]", __func__, __LINE__);
2025          break;
2026       }
2027
2028       /* Prints the Msg formed */
2029       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
2030
2031       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2032       encBufSize = 0;
2033       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf);
2034       if(encRetVal.encoded == ENCODE_FAIL)
2035       {
2036          DU_LOG("\nERROR  -->  E2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
2037                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2038          break;               
2039       }
2040       else
2041       {
2042          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
2043          for(int i=0; i< encBufSize; i++)
2044          {
2045             DU_LOG("%x",encBuf[i]);
2046          } 
2047       }
2048
2049       /* Sending msg */
2050       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2051       {
2052          DU_LOG("\nERROR  -->  E2AP : Sending RIC subscription Request failed");
2053          break;
2054       }
2055
2056       /* Add RIC Subscription Info to RAN Function's RIC Subscription List */
2057       RIC_ALLOC(ricSubsNode , sizeof(CmLList));
2058       if(!ricSubsNode)
2059       {
2060          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__);
2061          break;
2062       }
2063       ricSubsNode->node = (PTR)ricSubsInfo;
2064       cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubsNode);
2065
2066       ret = ROK;
2067       break;
2068    }
2069
2070    if(ret == RFAILED)
2071    {
2072       RIC_FREE(ricSubsInfo, sizeof(RicSubscription));
2073       RIC_FREE(ricSubsNode , sizeof(CmLList));
2074    }
2075
2076    FreeRicSubscriptionReq(e2apRicMsg);
2077    return ret;
2078 }
2079
2080 /*******************************************************************
2081  *
2082  * @brief Process RicSubscriptionResponse
2083  *
2084  * @details
2085  *
2086  *    Function : ProcRicSubscriptionRsp
2087  *
2088  * Functionality: Processes RicSubscriptionRsp
2089  *
2090  * @return ROK     - void
2091  *
2092  ******************************************************************/
2093
2094 void ProcRicSubscriptionResponse(uint32_t duId, RICsubscriptionResponse_t  *ricSubscriptionRsp)
2095 {
2096    uint8_t duIdx = 0, ieIdx = 0, notAdmitIdx = 0;
2097    uint8_t ranFuncId = 0, actionId = 0;
2098    DuDb *duDb = NULLP;
2099    bool ricReqIdDecoded = false;
2100    RicRequestId ricReqId;
2101    RanFunction  *ranFuncDb = NULLP;
2102    RicSubscription *ricSubs = NULLP;
2103    CmLList *ricSubsNode = NULLP;
2104    ActionInfo *action = NULLP;
2105    RICsubscriptionResponse_IEs_t *ricSubsRspIe = NULLP;
2106    RICaction_NotAdmitted_List_t *notAdmitList = NULLP;
2107
2108    DU_LOG("\nINFO  -->  E2AP : RIC Subscription Response received");
2109
2110    /* Fetch DU DB */
2111    SEARCH_DU_DB(duIdx, duId, duDb);
2112    if(duDb == NULLP)
2113    {
2114       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
2115       return;
2116    }
2117
2118    memset(&ricReqId, 0, sizeof(RicRequestId));
2119    if(ricSubscriptionRsp)
2120    {
2121       if(ricSubscriptionRsp->protocolIEs.list.array)
2122       {
2123          for(ieIdx=0; ieIdx<ricSubscriptionRsp->protocolIEs.list.count; ieIdx++)
2124          {
2125             if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx])
2126             {
2127                ricSubsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx];
2128                switch(ricSubscriptionRsp->protocolIEs.list.array[ieIdx]->id)
2129                {
2130                   case ProtocolIE_IDE2_id_RICrequestID:
2131                      {
2132                         ricReqId.requestorId = ricSubsRspIe->value.choice.RICrequestID.ricRequestorID;
2133                         ricReqId.instanceId = ricSubsRspIe->value.choice.RICrequestID.ricInstanceID;
2134                         ricReqIdDecoded = true;
2135                         break;
2136                      }
2137                   case ProtocolIE_IDE2_id_RANfunctionID:
2138                      {
2139                         ranFuncId = ricSubsRspIe->value.choice.RANfunctionID;
2140                         ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
2141                         if(!ranFuncDb)
2142                         {
2143                            DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionResponse: RAN Function ID [%d] not found", ranFuncId);
2144                            return;
2145                         }
2146                         break; 
2147                      }
2148                   case ProtocolIE_IDE2_id_RICactions_Admitted:
2149                      {
2150                         break;
2151                      }
2152                   case ProtocolIE_IDE2_id_RICactions_NotAdmitted:
2153                      {
2154                         if(!(ranFuncDb && ricReqIdDecoded))
2155                            return;
2156
2157                         notAdmitList = &ricSubsRspIe->value.choice.RICaction_NotAdmitted_List;
2158                         for(notAdmitIdx = 0; notAdmitIdx < notAdmitList->list.count; notAdmitIdx++)
2159                         {
2160                            actionId = ((RICaction_NotAdmitted_ItemIEs_t *)(notAdmitList->list.array[notAdmitIdx]))->\
2161                               value.choice.RICaction_NotAdmitted_Item.ricActionID;
2162
2163                            /* Remove action from RAN Function's subscription list */
2164                            ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
2165                            if(ricSubs)
2166                            {
2167                               action = fetchActionInfoFromActionId(actionId, ricSubs);
2168                               if(action)
2169                               {
2170                                  memset(action, 0, sizeof(ActionInfo));
2171                                  ricSubs->actionSequence[actionId].actionId = -1;
2172                                  ricSubs->numOfActions--;
2173                               }
2174                            }
2175                         }
2176                         break;
2177                      }
2178                }
2179             }
2180          }
2181       }
2182    } 
2183 }
2184
2185 /*******************************************************************
2186  *
2187  * @brief deallocate the memory allocated in E2SetupFailure
2188  *
2189  * @details
2190  *
2191  *    Function : FreeE2SetupFailure 
2192  *
2193  *    Functionality: deallocate the memory allocated in E2SetupFailure 
2194  *
2195  * @params[in] E2AP_PDU_t *e2apMsg
2196  *
2197  * @return void
2198  * ****************************************************************/
2199 void FreeE2SetupFailure(E2AP_PDU_t *e2apMsg)
2200 {
2201    uint8_t arrIdx = 0;
2202    E2setupFailure_t  *e2SetupFail;
2203
2204    if(e2apMsg)
2205    {
2206       if(e2apMsg->choice.unsuccessfulOutcome)
2207       {
2208          e2SetupFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2209          if(e2SetupFail->protocolIEs.list.array)
2210          {
2211             for(arrIdx=0; arrIdx<e2SetupFail->protocolIEs.list.count; arrIdx++)
2212             {
2213                RIC_FREE(e2SetupFail->protocolIEs.list.array[arrIdx], sizeof(E2setupFailureIEs_t)); 
2214             }
2215             RIC_FREE(e2SetupFail->protocolIEs.list.array, e2SetupFail->protocolIEs.list.size);
2216          }
2217          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2218       }
2219       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2220    }
2221 }
2222
2223 /*******************************************************************
2224  *
2225  * @brief Buld and send the E2 Setup failure
2226  *
2227  * @details
2228  *
2229  *    Function : BuildAndSendE2SetupFailure
2230  *
2231  *    Functionality:
2232  *         - Buld and send the E2 Setup failure
2233  * @return ROK     - success
2234  *         RFAILED - failure
2235  *
2236  * ****************************************************************/
2237
2238 uint8_t BuildAndSendE2SetupFailure(uint32_t duId, uint8_t transId)
2239 {
2240    uint8_t            ret = RFAILED;
2241    E2AP_PDU_t         *e2apMsg = NULL;
2242    E2setupFailure_t   *e2SetupFailure;
2243    asn_enc_rval_t     encRetVal;
2244    uint8_t            arrIdx;
2245    uint8_t            elementCnt;
2246    bool  memAllocFailed = false;
2247
2248    DU_LOG("\nINFO   -->  E2AP : Building E2 Setup failure\n");
2249    while(true)
2250    {
2251       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2252       if(e2apMsg == NULLP)
2253       {
2254          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2255          break;
2256       }
2257       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2258       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2259       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2260       {
2261          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2262          break;
2263       }
2264
2265       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
2266       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2267       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2setupFailure;
2268       e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure;
2269
2270       elementCnt = 3;
2271       e2SetupFailure->protocolIEs.list.count = elementCnt;
2272       e2SetupFailure->protocolIEs.list.size  = elementCnt * sizeof(struct E2setupFailureIEs *);
2273
2274       RIC_ALLOC(e2SetupFailure->protocolIEs.list.array, e2SetupFailure->protocolIEs.list.size);
2275       if(e2SetupFailure->protocolIEs.list.array == NULLP)
2276       {
2277          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2278          break;
2279       }
2280
2281       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2282       {
2283          RIC_ALLOC(e2SetupFailure->protocolIEs.list.array[arrIdx], sizeof(struct E2setupFailureIEs));
2284          if(e2SetupFailure->protocolIEs.list.array[arrIdx] == NULLP)
2285          {
2286             DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2287             memAllocFailed = true;
2288             break;
2289          }
2290       }
2291
2292       if(memAllocFailed == true)
2293       {
2294           DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2FailureIEs failed");
2295           break;
2296       }
2297
2298       /* Trans Id */
2299       arrIdx = 0;
2300       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2301       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2302       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID;
2303       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2304
2305       arrIdx++;
2306       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2307       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2308       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2;
2309       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = CauseE2_PR_protocol;
2310       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.protocol = CauseE2Protocol_unspecified;
2311
2312       arrIdx++;
2313       e2SetupFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2314       e2SetupFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2315       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2;
2316       e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2317
2318       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2319       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2320       encBufSize = 0;
2321       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2322
2323       /* Check encode results */
2324       if(encRetVal.encoded == ENCODE_FAIL)
2325       {
2326          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 Setup failure structure (at %s)\n",\
2327                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2328          break;
2329       }
2330       else
2331       {
2332          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Setup Failure\n");
2333          for(int i=0; i< encBufSize; i++)
2334          {
2335             DU_LOG("%x",encBuf[i]);
2336          }
2337       }
2338
2339       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2340       {
2341          DU_LOG("\nERROR  -->  E2AP : Sending E2 Setup Failure failed");
2342          break;
2343       }
2344
2345       ret = ROK;
2346       break;
2347    }
2348
2349    FreeE2SetupFailure(e2apMsg);
2350    return ret;
2351 }
2352
2353 /*******************************************************************
2354  *
2355  * @brief process the e2setup request 
2356  *
2357  * @details
2358  *
2359  *    Function : ProcE2SetupReq
2360  *
2361  * Functionality: process the e2setup request
2362  *
2363  * @return void
2364  *
2365  ******************************************************************/
2366
2367 void ProcE2SetupReq(uint32_t *duId, E2setupRequest_t  *e2SetupReq)
2368 {
2369    uint8_t arrIdx = 0, duIdx = 0, transId =0;
2370    uint16_t ranFuncIdx=0, e2NodeAddListIdx =0;
2371    E2NodeConfigList tmpE2NodeList;
2372    DuDb    *duDb = NULLP;
2373    bool ieProcessingFailed = false;
2374    E2nodeComponentConfigAddition_List_t *e2NodeAddList=NULLP;
2375    E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem=NULLP;
2376    RANfunction_ItemIEs_t *ranFuncItemIe=NULLP;
2377    RANfunction_Item_t  *ranFunItem=NULLP;
2378    RANfunctions_List_t *ranFunctionsList=NULLP;
2379
2380    memset(&tmpE2NodeList, 0, sizeof(E2NodeConfigList));
2381    if(!e2SetupReq)
2382    {
2383       DU_LOG("\nERROR  -->  E2AP : e2SetupReq pointer is null");
2384       return;
2385    }
2386    if(!e2SetupReq->protocolIEs.list.array)
2387    {
2388       DU_LOG("\nERROR  -->  E2AP : e2SetupReq array pointer is null");
2389       return;
2390    }
2391
2392    for(arrIdx=0; arrIdx<e2SetupReq->protocolIEs.list.count; arrIdx++)
2393    {
2394       if(e2SetupReq->protocolIEs.list.array[arrIdx])
2395       {
2396          switch(e2SetupReq->protocolIEs.list.array[arrIdx]->id)
2397          {
2398             case ProtocolIE_IDE2_id_TransactionID:
2399                {
2400                   transId = e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; 
2401                   break;
2402                }
2403             case ProtocolIE_IDE2_id_GlobalE2node_ID:
2404                {
2405                   if(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID)
2406                   {
2407                      *duId =e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.GlobalE2node_ID.choice.gNB->gNB_DU_ID->buf[0];
2408
2409                      SEARCH_DU_DB(duIdx, *duId, duDb); 
2410                      if(duDb == NULLP)
2411                      {
2412                         duDb = &ricCb.duInfo[ricCb.numDu];
2413                         ricCb.numDu++;
2414                      }
2415                      memset(duDb, 0, sizeof(DuDb));
2416                      duDb->duId = *duId;
2417                   }
2418                   break;
2419                }
2420             case ProtocolIE_IDE2_id_RANfunctionsAdded:
2421                {
2422                   ranFunctionsList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
2423
2424                   if(ranFunctionsList->list.array)
2425                   {
2426                      for(ranFuncIdx=0;ranFuncIdx<ranFunctionsList->list.count; ranFuncIdx++)
2427                      {
2428                         ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; 
2429                         ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item;
2430                         duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; 
2431                         duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; 
2432                         cmLListInit(&duDb->ranFunction[ranFunItem->ranFunctionID-1].subscriptionList);
2433                         duDb->numOfRanFunction++;
2434                      }
2435                   }
2436                   break;
2437                }
2438             case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition:
2439                {
2440                   e2NodeAddList = &e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List;      
2441                   if(e2NodeAddList->list.array)
2442                   {
2443                      for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++)
2444                      {
2445                         if(e2NodeAddList->list.array[e2NodeAddListIdx])
2446                         {
2447                            /* Storing the E2 node information in DB */
2448                            e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *)e2NodeAddList->list.array[e2NodeAddListIdx];
2449                            if(handleE2NodeComponentAction(duDb, (PTR)&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item,\
2450                                     ProtocolIE_IDE2_id_E2nodeComponentConfigAddition, &tmpE2NodeList.addedE2Node[tmpE2NodeList.addedE2NodeCount++]) != ROK)
2451                            {
2452                               DU_LOG("\nERROR  -->  E2AP : Processing of E2 node component idx %d failed",e2NodeAddListIdx);
2453                            }
2454
2455                         }
2456                      }
2457                   }
2458                   break;
2459                }
2460             default:
2461                break;
2462          }
2463       }
2464    }
2465    
2466    if(BuildAndSendE2SetupRsp(duDb, transId, tmpE2NodeList) !=ROK)
2467    {
2468       DU_LOG("\nERROR  -->  E2AP : Failed to build and send E2 setup response");
2469    }
2470 }
2471 /*******************************************************************
2472  *
2473  * @brief Deallocate the memory allocated for E2 Reset Response
2474  *
2475  * @details
2476  *
2477  *    Function : FreeE2ResetResponse
2478  *
2479  *    Functionality:
2480  *       - freeing the memory allocated for E2ResetResponse
2481  *
2482  * @params[in] E2AP_PDU_t *e2apMsg
2483  * @return ROK     - success
2484  *         RFAILED - failure
2485  *
2486  * ****************************************************************/
2487 void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg)
2488 {
2489    uint8_t ieIdx =0;
2490    ResetResponseE2_t *resetResponse =NULLP;
2491
2492    if(e2apMsg != NULLP)
2493    {
2494       if(e2apMsg->choice.successfulOutcome != NULLP)
2495       {
2496          resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2497          if(resetResponse->protocolIEs.list.array)
2498          {
2499             for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++)
2500             {
2501                if(resetResponse->protocolIEs.list.array[ieIdx])
2502                {
2503                   RIC_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2504                }
2505             }
2506             RIC_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2507          }
2508          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2509       }
2510       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2511    }
2512 }
2513
2514 /*******************************************************************
2515  *
2516  * @brief Buld and send the Reset Response msg
2517  *
2518  * @details
2519  *
2520  *    Function : BuildAndSendResetResponse 
2521  *
2522  *    Functionality:
2523  *         - Buld and send the Reset Response Message
2524  *
2525  * @params[in] 
2526  *    DU id
2527  *    TransId Id
2528  * @return ROK     - success
2529  *         RFAILED - failure
2530  *
2531  * ****************************************************************/
2532 uint8_t BuildAndSendResetResponse(uint32_t duId, uint8_t transId)
2533 {
2534    uint8_t           ieIdx = 0, elementCnt = 0;
2535    uint8_t           ret = RFAILED;
2536    E2AP_PDU_t        *e2apMsg = NULLP;
2537    ResetResponseE2_t *resetResponse=NULL;
2538    asn_enc_rval_t    encRetVal;       /* Encoder return value */
2539
2540    DU_LOG("\nINFO   -->  E2AP : Building E2 Reset Response Message\n");
2541    do
2542    {
2543       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2544       if(e2apMsg == NULLP)
2545       {
2546          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed");
2547          break;
2548       }
2549       e2apMsg->present = E2AP_PDU_PR_successfulOutcome;
2550
2551       RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
2552       if(e2apMsg->choice.successfulOutcome == NULLP)
2553       {
2554          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome");
2555          break;
2556       }
2557  
2558       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset;
2559       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
2560       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2;
2561       resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;
2562
2563       elementCnt = 1;
2564       resetResponse->protocolIEs.list.count = elementCnt;
2565       resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *);
2566       RIC_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size);
2567       if(!resetResponse->protocolIEs.list.array)
2568       {
2569          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array");
2570          break;
2571       }
2572
2573       for(ieIdx=0; ieIdx < elementCnt; ieIdx++)
2574       {
2575          RIC_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t));
2576          if(!resetResponse->protocolIEs.list.array[ieIdx])
2577          {
2578             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element");
2579             break;
2580          }
2581       }
2582       if(ieIdx < elementCnt)
2583          break;
2584
2585       ieIdx = 0; 
2586       resetResponse->protocolIEs.list.array[ieIdx]->id =  ProtocolIE_IDE2_id_TransactionID;
2587       resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
2588       resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID;
2589       resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
2590
2591       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2592
2593       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2594       encBufSize = 0;
2595       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2596       if(encRetVal.encoded == ENCODE_FAIL)
2597       {
2598          DU_LOG("\nERROR  -->  E2AP : Could not encode E2 reset response structure (at %s)\n",\
2599                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2600          break;
2601       }
2602       else
2603       {
2604          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for E2 Reset Response \n");
2605          for(int i=0; i< encBufSize; i++)
2606          {
2607             DU_LOG("%x",encBuf[i]);
2608          }
2609       }
2610
2611       /* Sending msg */
2612       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2613       {
2614          DU_LOG("\nERROR  -->  E2AP : Failed to send E2 Reset Response");
2615          break;
2616       }
2617
2618       ret = ROK;
2619       break;
2620    }while(true);
2621
2622    FreeE2ResetResponse(e2apMsg);
2623    return ret;
2624 }
2625
2626 /*******************************************************************
2627  *
2628  * @brief deallocate the memory allocated in building the
2629  *    Service Query message
2630  *
2631  * @details
2632  *
2633  *    Function : FreeRicServiceQuery 
2634  *
2635  *    Functionality: deallocate the memory allocated in building
2636  *    Ric Service Query message
2637  *
2638  * @params[in] E2AP_PDU_t *e2apMsg
2639  *
2640  * @return void
2641  * ****************************************************************/
2642
2643 void FreeRicServiceQuery(E2AP_PDU_t *e2apMsg)
2644 {
2645    uint8_t arrIdx = 0, ranFuncIdx=0;
2646    RANfunctionsID_List_t *ranFuncAcceptedList=NULL;
2647    RICserviceQuery_t *ricServiceQuery=NULL;
2648    
2649    if(e2apMsg)
2650    {
2651       if(e2apMsg->choice.initiatingMessage)
2652       {
2653          ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2654          if(ricServiceQuery->protocolIEs.list.array)
2655          {
2656             for(arrIdx=0; arrIdx<ricServiceQuery->protocolIEs.list.count; arrIdx++)
2657             {
2658                if(ricServiceQuery->protocolIEs.list.array[arrIdx])
2659                {
2660                   switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id)
2661                   {
2662                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
2663                         {
2664                            ranFuncAcceptedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
2665                            if(ranFuncAcceptedList->list.array)
2666                            {
2667                               for(ranFuncIdx=0;ranFuncIdx<ranFuncAcceptedList->list.count; ranFuncIdx++)
2668                               {
2669                                  RIC_FREE(ranFuncAcceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
2670                               }
2671                               RIC_FREE(ranFuncAcceptedList->list.array, ranFuncAcceptedList->list.size);
2672                            }
2673                            break;
2674                         }
2675                      case RICserviceQuery_IEs__value_PR_TransactionID:
2676                         {
2677                            break;
2678                         }
2679                   }
2680                   RIC_FREE(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t)); 
2681                }
2682             }
2683             RIC_FREE(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2684          }
2685          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
2686       }
2687       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2688    }
2689 }
2690
2691 /*******************************************************************
2692  *
2693  * @brief build and send the ric service Query 
2694  *
2695  * @details
2696  *
2697  *    Function : BuildAndSendRicServiceQuery
2698  *
2699  * Functionality: build and send the ric service Query 
2700  * @return ROK     - success
2701  *         RFAILED - Acknowledge
2702  *
2703  ******************************************************************/
2704
2705 uint8_t BuildAndSendRicServiceQuery(DuDb *duDb)
2706 {
2707    uint8_t arrIdx;
2708    uint8_t elementCnt;
2709    uint8_t ret = RFAILED;
2710    bool  memAllocFailed = false;
2711    E2AP_PDU_t     *e2apMsg = NULL;
2712    asn_enc_rval_t encRetVal;
2713    RICserviceQuery_t *ricServiceQuery;
2714
2715    DU_LOG("\nINFO   -->  E2AP : Building Ric service Query\n");
2716    while(true)
2717    {
2718       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2719       if(e2apMsg == NULLP)
2720       {
2721          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2722          break;
2723       }
2724       e2apMsg->present =  E2AP_PDU_PR_initiatingMessage;
2725       RIC_ALLOC(e2apMsg->choice.initiatingMessage , sizeof(struct InitiatingMessageE2));
2726       if(e2apMsg->choice.initiatingMessage == NULLP)
2727       {
2728          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2729          break;
2730       }
2731
2732       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceQuery;
2733       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
2734       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceQuery;
2735       ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery;
2736
2737       elementCnt = 1;
2738       /* Fill Accepted RAN function IE If Ran function information is stored in databse */
2739       if(duDb->numOfRanFunction)
2740          elementCnt++;
2741
2742       ricServiceQuery->protocolIEs.list.count = elementCnt;
2743       ricServiceQuery->protocolIEs.list.size  = elementCnt * sizeof(RICserviceQuery_IEs_t*);
2744
2745       RIC_ALLOC(ricServiceQuery->protocolIEs.list.array, ricServiceQuery->protocolIEs.list.size);
2746       if(ricServiceQuery->protocolIEs.list.array == NULLP)
2747       {
2748          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2749          break;
2750       }
2751
2752       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2753       {
2754          RIC_ALLOC(ricServiceQuery->protocolIEs.list.array[arrIdx], sizeof(RICserviceQuery_IEs_t));
2755          if(ricServiceQuery->protocolIEs.list.array[arrIdx] == NULLP)
2756          {
2757             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2758             memAllocFailed = true;
2759             break;
2760          }
2761       }
2762       if(memAllocFailed == true)
2763       {
2764          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceQueryIEs failed");
2765          break;
2766       }
2767
2768       /* Trans Id */
2769       arrIdx = 0;
2770       ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2771       ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2772       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_TransactionID;
2773       ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = assignTransactionId(duDb);
2774       
2775       if(duDb->numOfRanFunction)
2776       {
2777          /* Accepted RAN function Id */
2778          arrIdx++;
2779          ricServiceQuery->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
2780          ricServiceQuery->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2781          ricServiceQuery->protocolIEs.list.array[arrIdx]->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
2782          if(BuildRanFunctionAcceptedList(duDb, 0, NULL, &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceQuery)!=ROK)
2783          {
2784             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
2785             break;         
2786          }
2787       }
2788       
2789       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2790       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2791       encBufSize = 0;
2792       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2793
2794       /* Check encode results */
2795       if(encRetVal.encoded == ENCODE_FAIL)
2796       {
2797          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service Query structure (at %s)\n",\
2798                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2799          break;
2800       }
2801       else
2802       {
2803          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service Query\n");
2804          for(int i=0; i< encBufSize; i++)
2805          {
2806             DU_LOG("%x",encBuf[i]);
2807          }
2808       }
2809
2810       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
2811       {
2812          DU_LOG("\nERROR  -->  E2AP : Sending of RIC service  Query failed");
2813          break;
2814       }
2815
2816       ret =ROK;
2817       break;
2818    }
2819    FreeRicServiceQuery(e2apMsg);
2820    return ret;
2821 }
2822
2823 /*******************************************************************
2824  *
2825  * @brief deallocate the memory allocated in RicServiceUpdateFailure
2826  *
2827  * @details
2828  *
2829  *    Function : FreeRicServiceUpdateFailure 
2830  *
2831  *    Functionality: deallocate the memory allocated in RicServiceUpdatefailure
2832  *
2833  * @params[in] E2AP_PDU_t *e2apMsg
2834  *
2835  * @return void
2836  * ****************************************************************/
2837
2838 void FreeRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg)
2839 {
2840    uint8_t arrIdx = 0;
2841    RICserviceUpdateFailure_t *ricServiceUpdateFailure=NULL;
2842    
2843    if(e2apMsg)
2844    {
2845       if(e2apMsg->choice.unsuccessfulOutcome)
2846       {
2847          ricServiceUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2848          if(ricServiceUpdateFailure->protocolIEs.list.array)
2849          {
2850             for(arrIdx=0; arrIdx<ricServiceUpdateFailure->protocolIEs.list.count; arrIdx++)
2851             {
2852                RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t)); 
2853             }
2854             RIC_FREE(ricServiceUpdateFailure->protocolIEs.list.array, ricServiceUpdateFailure->protocolIEs.list.size);
2855          }
2856          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t));
2857       }
2858       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
2859    }
2860 }
2861
2862 /*******************************************************************
2863  *
2864  * @brief build and send the ric service update failure 
2865  *
2866  * @details
2867  *
2868  *    Function : BuildAndSendRicServiceUpdateFailure
2869  *
2870  * Functionality: build and send the ric service update failure 
2871  * @return ROK     - success
2872  *         RFAILED - failure
2873  *
2874  ******************************************************************/
2875
2876 uint8_t BuildAndSendRicServiceUpdateFailure(uint32_t duId, int8_t transId, CauseE2_PR causePresent, uint8_t reason)
2877 {
2878
2879    E2AP_PDU_t         *e2apMsg = NULL;
2880    asn_enc_rval_t     encRetVal;
2881    uint8_t            ret = RFAILED;
2882    uint8_t            arrIdx=0;
2883    uint8_t            elementCnt=0;
2884    RICserviceUpdateFailure_t *ricServiceFailure=NULL;
2885
2886    DU_LOG("\nINFO   -->  E2AP : Building Ric service update failure\n");
2887    while(true)
2888    {
2889       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
2890       if(e2apMsg == NULLP)
2891       {
2892          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2893          break;
2894       }
2895       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
2896       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2));
2897       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
2898       {
2899          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
2900          break;
2901       }
2902
2903       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
2904       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
2905       e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure;
2906       ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure;
2907
2908       elementCnt = 3;
2909       ricServiceFailure->protocolIEs.list.count = elementCnt;
2910       ricServiceFailure->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateFailure_IEs_t *);
2911
2912       RIC_ALLOC(ricServiceFailure->protocolIEs.list.array, ricServiceFailure->protocolIEs.list.size);
2913       if(ricServiceFailure->protocolIEs.list.array == NULLP)
2914       {
2915          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2916          break;
2917       }
2918
2919       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
2920       {
2921          RIC_ALLOC(ricServiceFailure->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateFailure_IEs_t));
2922          if(ricServiceFailure->protocolIEs.list.array[arrIdx] == NULLP)
2923          {
2924             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2925             break;
2926          }
2927       }
2928       if(arrIdx<elementCnt)
2929       {
2930          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceFailureIEs failed");
2931          break;
2932       }
2933
2934       /* Trans Id */
2935       arrIdx = 0;
2936       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
2937       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2938       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TransactionID;
2939       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
2940
2941       arrIdx++;
2942       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
2943       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
2944       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_CauseE2;
2945       fillE2FailureCause(&ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, causePresent, reason);
2946
2947       arrIdx++;
2948       ricServiceFailure->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2;
2949       ricServiceFailure->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
2950       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateFailure_IEs__value_PR_TimeToWaitE2;
2951       ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s;
2952
2953       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
2954       memset(encBuf, 0, ENC_BUF_MAX_LEN);
2955       encBufSize = 0;
2956       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
2957
2958       /* Check encode results */
2959       if(encRetVal.encoded == ENCODE_FAIL)
2960       {
2961          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update failure structure (at %s)\n",\
2962                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
2963          break;
2964       }
2965       else
2966       {
2967          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Failure\n");
2968          for(int i=0; i< encBufSize; i++)
2969          {
2970             DU_LOG("%x",encBuf[i]);
2971          }
2972       }
2973
2974       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
2975       {
2976          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update failed");
2977          break;
2978       }
2979       ret = ROK;
2980       break;
2981    }
2982
2983    FreeRicServiceUpdateFailure(e2apMsg);
2984    return ret;
2985 }
2986
2987
2988 /*******************************************************************
2989  *
2990  * @brief deallocate the memory allocated in RicServiceUpdateAck(
2991  *
2992  * @details
2993  *
2994  *    Function : FreeRicServiceUpdateAck 
2995  *
2996  *    Functionality: deallocate the memory allocated in RicServiceUpdateAck
2997  *
2998  * @params[in] E2AP_PDU_t *e2apMsg
2999  *
3000  * @return void
3001  * ****************************************************************/
3002
3003 void FreeRicServiceUpdateAck(E2AP_PDU_t *e2apMsg)
3004 {
3005    uint8_t arrIdx = 0, ranFuncIdx=0;
3006    RANfunctionsID_List_t *acceptedList=NULL;
3007    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
3008    RANfunctionsIDcause_List_t  *rejectedList=NULL;
3009
3010    if(e2apMsg)
3011    {
3012       if(e2apMsg->choice.successfulOutcome)
3013       {
3014          ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3015          if(ricServiceUpdateAck->protocolIEs.list.array)
3016          {
3017             for(arrIdx=0; arrIdx<ricServiceUpdateAck->protocolIEs.list.count; arrIdx++)
3018             {
3019                if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx])
3020                {
3021                   switch(ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id)
3022                   {
3023                      case ProtocolIE_IDE2_id_RANfunctionsAccepted:
3024                         {
3025                            acceptedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List;
3026                            if(acceptedList->list.array)
3027                            {
3028                               for(ranFuncIdx=0;ranFuncIdx<acceptedList->list.count; ranFuncIdx++)
3029                               {
3030                                  RIC_FREE(acceptedList->list.array[ranFuncIdx], sizeof(RANfunction_ItemIEs_t));
3031                               }
3032                               RIC_FREE(acceptedList->list.array, acceptedList->list.size);
3033                            }
3034                            break;
3035                         }
3036
3037                      case ProtocolIE_IDE2_id_RANfunctionsRejected:
3038                         {
3039                            rejectedList= &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List;
3040                            if(rejectedList->list.array)
3041                            {
3042                               for(ranFuncIdx=0;ranFuncIdx<rejectedList->list.count; ranFuncIdx++)
3043                               {
3044                                  RIC_FREE(rejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
3045                               }
3046                               RIC_FREE(rejectedList->list.array, rejectedList->list.size);
3047                            }
3048                            break;
3049                         }
3050                   }
3051                   RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t)); 
3052                }
3053             }
3054             RIC_FREE(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
3055          }
3056          RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
3057       }
3058       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3059    }
3060 }
3061
3062 /*******************************************************************
3063  *
3064  * @brief Build RAN function rejected list
3065  *
3066  * @details
3067  *
3068  *    Function : BuildRanFunctionRejectedList
3069  *
3070  *    Functionality: Build RAN function rejected list 
3071  *
3072  * @params[in] 
3073  *    Count of ran functions to be rejected in the list 
3074  *    Received list of RAN functions
3075  *
3076  * @return ROK - success
3077  *         RFAILED - failure
3078  * ****************************************************************/
3079
3080 uint8_t BuildRanFunctionRejectedList(uint8_t count, RanFunction *ranFunRejectedList, RANfunctionsIDcause_List_t *ranFuncRejectedList)
3081 {
3082    uint8_t ranFuncIdx = 0;
3083    RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL;
3084    
3085    ranFuncRejectedList->list.count = count;
3086    
3087    ranFuncRejectedList->list.size = ranFuncRejectedList->list.count*sizeof(RANfunctionIDcause_ItemIEs_t*);
3088    RIC_ALLOC(ranFuncRejectedList->list.array, ranFuncRejectedList->list.size);
3089    if(ranFuncRejectedList->list.array == NULLP)
3090    {
3091       DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array");
3092       return RFAILED;
3093    }
3094    
3095    for(ranFuncIdx = 0; ranFuncIdx< ranFuncRejectedList->list.count; ranFuncIdx++)
3096    {
3097       RIC_ALLOC(ranFuncRejectedList->list.array[ranFuncIdx], sizeof(RANfunctionIDcause_ItemIEs_t));
3098       if(ranFuncRejectedList->list.array[ranFuncIdx] == NULLP)
3099       {
3100          DU_LOG("\nERROR  -->  E2AP : Memory allocation for RAN function rejected list array item");
3101          return RFAILED;
3102       }
3103       ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)ranFuncRejectedList->list.array[ranFuncIdx];
3104       ranFuncRejectedItemIe->id = ProtocolIE_IDE2_id_RANfunctionIEcause_Item;
3105       ranFuncRejectedItemIe->criticality= CriticalityE2_ignore;
3106       ranFuncRejectedItemIe->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
3107       ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID = ranFunRejectedList[ranFuncIdx].id;
3108       fillE2FailureCause(&ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.cause, CauseE2_PR_ricService,\
3109             CauseE2RICservice_ran_function_not_supported);
3110    }
3111    
3112    return ROK;
3113 }
3114
3115 /*******************************************************************
3116  *
3117  * @brief build and send the ric service update Acknowledge 
3118  *
3119  * @details
3120  *
3121  *    Function : BuildAndSendRicServiceUpdateAcknowledge
3122  *
3123  * Functionality: build and send the ric service update Acknowledge 
3124  * @return ROK     - success
3125  *         RFAILED - Acknowledge
3126  *
3127  ******************************************************************/
3128
3129 uint8_t BuildAndSendRicServiceUpdateAcknowledge(DuDb *duDb, int8_t transId, RicTmpRanFunList ricRanFuncList)
3130 {
3131    E2AP_PDU_t         *e2apMsg = NULL;
3132    asn_enc_rval_t     encRetVal;
3133    uint8_t  arrIdx=0, elementCnt=0, ret=RFAILED;;
3134    RICserviceUpdateAcknowledge_t *ricServiceUpdateAck=NULL;
3135
3136    DU_LOG("\nINFO   -->  E2AP : Building Ric service update Acknowledge\n");
3137    while(true)
3138    {
3139       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3140       if(e2apMsg == NULLP)
3141       {
3142          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3143          break;
3144       }
3145       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
3146       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(struct SuccessfulOutcomeE2));
3147       if(e2apMsg->choice.successfulOutcome == NULLP)
3148       {
3149          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed");
3150          break;
3151       }
3152
3153       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICserviceUpdate;
3154       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
3155       e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge;
3156       ricServiceUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge;
3157
3158       elementCnt = 1;
3159       if(ricRanFuncList.numOfRanFunAccepted)
3160          elementCnt++;
3161       if(ricRanFuncList.numOfRanFuneRejected)
3162          elementCnt++;
3163       
3164
3165       ricServiceUpdateAck->protocolIEs.list.count = elementCnt;
3166       ricServiceUpdateAck->protocolIEs.list.size  = elementCnt * sizeof(RICserviceUpdateAcknowledge_IEs_t*);
3167
3168       RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array, ricServiceUpdateAck->protocolIEs.list.size);
3169       if(ricServiceUpdateAck->protocolIEs.list.array == NULLP)
3170       {
3171          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3172          break;
3173       }
3174
3175       for(arrIdx=0; arrIdx<elementCnt; arrIdx++)
3176       {
3177          RIC_ALLOC(ricServiceUpdateAck->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdateAcknowledge_IEs_t));
3178          if(ricServiceUpdateAck->protocolIEs.list.array[arrIdx] == NULLP)
3179          {
3180             DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3181             break;
3182          }
3183       }
3184       if(arrIdx<elementCnt)
3185       {
3186          DU_LOG("\nERROR  -->  E2AP : Memory allocation for ricServiceUpdateAckIEs failed");
3187          break;
3188       }
3189
3190       /* Trans Id */
3191       arrIdx = 0;
3192       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
3193       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3194       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_TransactionID;
3195       ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID  = transId;
3196
3197       if(ricRanFuncList.numOfRanFunAccepted)
3198       {
3199          /* Accepted RAN function List */
3200          arrIdx++;
3201          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAccepted;
3202          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3203          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
3204          if(BuildRanFunctionAcceptedList(duDb, ricRanFuncList.numOfRanFunAccepted, ricRanFuncList.ranFunAcceptedList,\
3205          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List, ProcedureCodeE2_id_RICserviceUpdate)!=ROK)       
3206          {
3207             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function added list");
3208             break;         
3209          }
3210       }
3211       
3212       if(ricRanFuncList.numOfRanFuneRejected)
3213       {
3214          /* RAN Functions Rejected List */
3215          arrIdx++;
3216          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsRejected;
3217          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
3218          ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
3219          if(BuildRanFunctionRejectedList(ricRanFuncList.numOfRanFuneRejected, ricRanFuncList.ranFunRejectedList, \
3220          &ricServiceUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List)!=ROK)       
3221          {
3222             DU_LOG("\nERROR  -->  E2AP : Failed to build Ran function rejected list");
3223             break;         
3224          }
3225       }
3226       
3227       
3228       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3229       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3230       encBufSize = 0;
3231       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3232
3233       /* Check encode results */
3234       if(encRetVal.encoded == ENCODE_FAIL)
3235       {
3236          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC service update Acknowledge structure (at %s)\n",\
3237                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3238          break;
3239       }
3240       else
3241       {
3242          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC service update Acknowledge\n");
3243          for(int i=0; i< encBufSize; i++)
3244          {
3245             DU_LOG("%x",encBuf[i]);
3246          }
3247       }
3248
3249       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
3250       {
3251          DU_LOG("\nERROR  -->  E2AP : Sending RIC service update ack failed");
3252          break;
3253       }
3254       ret =ROK;
3255       break;
3256    }
3257    FreeRicServiceUpdateAck(e2apMsg);
3258    return ret; 
3259 }
3260
3261 /*******************************************************************
3262  *
3263  * @brief process the RIC service update 
3264  *
3265  * @details
3266  *
3267  *    Function : ProcRicserviceUpdate 
3268  *
3269  * Functionality: process the RIC service update 
3270  *
3271  * @return ROK     - success
3272  *         RFAILED - failure
3273  *
3274  ******************************************************************/
3275
3276 void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate)
3277 {
3278    RicTmpRanFunList ricRanFuncList;
3279    DuDb    *duDb = NULLP;
3280    int8_t transId =-1;
3281    uint8_t duIdx = 0, elementCnt =0, arrIdx = 0; 
3282    uint16_t ranFuncIdx = 0, failedRanFuncCount=0, recvdRanFuncCount=0;
3283    RanFunction *ranFuncDb = NULLP;
3284    RANfunction_ItemIEs_t *ranFuncItemIe =NULL;
3285    RANfunction_Item_t  *ranFuncItem =NULL;
3286    RANfunctionID_Item_t  *ranFuncIdItem=NULL;
3287    RANfunctions_List_t *ranFuncList=NULL;
3288    RANfunctionsID_List_t *deleteList=NULL;
3289    RANfunctionID_ItemIEs_t *delRanFuncItem=NULL;
3290
3291    SEARCH_DU_DB(duIdx, duId, duDb); 
3292    if(duDb == NULLP)
3293    {
3294       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3295       return;
3296    }
3297    memset(&ricRanFuncList, 0, sizeof(RicTmpRanFunList)); 
3298
3299    if(!ricServiceUpdate)
3300    {
3301       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate pointer is null"); 
3302       return;
3303    }
3304
3305    if(!ricServiceUpdate->protocolIEs.list.array)      
3306    {
3307       DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array pointer is null");
3308       return;
3309    }
3310    elementCnt = ricServiceUpdate->protocolIEs.list.count;
3311    for(arrIdx=0; arrIdx<ricServiceUpdate->protocolIEs.list.count; arrIdx++)
3312    {
3313       if(!ricServiceUpdate->protocolIEs.list.array[arrIdx])
3314       {
3315          DU_LOG("\nERROR  -->  E2AP : ricServiceUpdate array idx %d pointer is null",arrIdx);
3316          return;
3317       }
3318
3319       switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)
3320       {
3321          case ProtocolIE_IDE2_id_TransactionID:
3322             {
3323                transId = ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID;
3324
3325                if(transId < 0 || transId > 255)
3326                {
3327                   DU_LOG("\nERROR  -->  E2AP : Received invalid transId %d",transId);
3328                   return;
3329                }
3330                break;
3331             }
3332
3333          case ProtocolIE_IDE2_id_RANfunctionsAdded:
3334             {
3335                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List;
3336
3337                if(ranFuncList->list.array)
3338                {
3339                   for(ranFuncIdx=0;ranFuncIdx<ranFuncList->list.count; ranFuncIdx++)
3340                   {
3341                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx]; 
3342                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3343
3344                      /* Adding the ran function in temporary list */
3345                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
3346                      ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
3347                      ricRanFuncList.numOfRanFunAccepted++;
3348
3349                      /* Adding the new ran function in DB*/
3350                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].id = ranFuncItem->ranFunctionID;
3351                      duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
3352                      duDb->numOfRanFunction++;
3353
3354                      /* Calculating total number of ran fuctions which are received for addition */
3355                      recvdRanFuncCount++;
3356                   }
3357                }
3358                break;
3359             }
3360
3361          case ProtocolIE_IDE2_id_RANfunctionsModified:
3362             {
3363
3364                ranFuncList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List; 
3365                if(ranFuncList->list.array)
3366                {
3367                   for(ranFuncIdx = 0; ranFuncIdx< ranFuncList->list.count; ranFuncIdx++)
3368                   {
3369                      ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFuncList->list.array[ranFuncIdx];
3370                      ranFuncItem = &ranFuncItemIe->value.choice.RANfunction_Item;
3371                      if(fetchRanFuncFromRanFuncId(duDb, ranFuncItem->ranFunctionID) == NULLP)
3372                      {
3373                         /* Calculating total number of ran fuctions which are not present */
3374                         failedRanFuncCount++;
3375
3376                         /* Adding the ran function in temporary list */
3377                         ricRanFuncList.ranFunRejectedList[ricRanFuncList.numOfRanFuneRejected].id =  ranFuncItem->ranFunctionID; 
3378                         ricRanFuncList.numOfRanFuneRejected++;
3379                      }
3380                      else
3381                      {
3382
3383                         /* Adding the ran function in temporary list */
3384                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].id =  ranFuncItem->ranFunctionID; 
3385                         ricRanFuncList.ranFunAcceptedList[ricRanFuncList.numOfRanFunAccepted].revisionCounter = ranFuncItem->ranFunctionRevision; 
3386                         ricRanFuncList.numOfRanFunAccepted++;
3387
3388                         /* Updating the new ran function in DB*/
3389                         duDb->ranFunction[ranFuncItem->ranFunctionID-1].revisionCounter = ranFuncItem->ranFunctionRevision;
3390                      }
3391                      /* Calculating total number of ran fuctions which are received for modification */
3392                      recvdRanFuncCount++;
3393                   }
3394                }
3395                break;
3396             }
3397          case ProtocolIE_IDE2_id_RANfunctionsDeleted:
3398             {
3399
3400                deleteList = &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; 
3401                if(deleteList->list.array)
3402                {
3403                   for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++)
3404                   {
3405                      delRanFuncItem  = (RANfunctionID_ItemIEs_t*) deleteList->list.array[ranFuncIdx];
3406                      ranFuncIdItem = &delRanFuncItem->value.choice.RANfunctionID_Item;
3407                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncIdItem->ranFunctionID);
3408                      if(ranFuncDb)
3409                      {
3410                         memset(ranFuncDb, 0, sizeof(RanFunction));
3411                         duDb->numOfRanFunction--; 
3412                      }
3413
3414                      /* Calculating total number of ran fuctions which are received for deletion */
3415                      recvdRanFuncCount++;
3416                   }
3417                }
3418                break;
3419             }
3420
3421          default:
3422             {
3423                DU_LOG("\nERROR  -->  E2AP : IE [%ld] is not supported",ricServiceUpdate->protocolIEs.list.array[arrIdx]->id);
3424                break;
3425             }
3426       }
3427    }
3428    
3429    /* Sending RIC Service Update Failed if all RAN Functions received fail or if any IE processing fails
3430     * Else sending RIC Service Update Acknowledge */  
3431    if((elementCnt > arrIdx) ||((recvdRanFuncCount > 0) && (recvdRanFuncCount == failedRanFuncCount)))
3432    {
3433       if(BuildAndSendRicServiceUpdateFailure(duDb->duId, transId, CauseE2_PR_misc, CauseE2Misc_unspecified) != ROK)
3434       {
3435          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update Failure");
3436          return;
3437       }
3438    }
3439    else
3440    {
3441       if(BuildAndSendRicServiceUpdateAcknowledge(duDb, transId, ricRanFuncList) != ROK)
3442       {
3443          DU_LOG("\nERROR  -->  E2AP : Failed to build and send RIC service update acknowledge");
3444          return;
3445       }
3446    }
3447 }
3448
3449 /*******************************************************************
3450  *
3451  * @brief Processing RIC subscription failure from DU
3452  *
3453  * @details
3454  *
3455  *    Function : ProcRicSubscriptionFailure
3456  *
3457  * Functionality: Processing RIC subscription failure from DU
3458  *
3459  * @param  ID of DU from which message was sent
3460  *         RIC Subscription failure message
3461  * @return ROK     - success
3462  *         RFAILED - failure
3463  *
3464  ******************************************************************/
3465 uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure)
3466 {
3467    uint8_t ieIdx = 0, duIdx = 0;
3468    uint8_t ranFuncId = 0;
3469    DuDb    *duDb = NULLP;
3470    RanFunction *ranFuncDb = NULLP;
3471    RicSubscription *ricSubs = NULLP;
3472    CmLList *ricSubsNode = NULLP;
3473    RicRequestId ricReqId;
3474    RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP;
3475
3476    DU_LOG("\nINFO  -->  E2AP : Received RIC subscription failure");
3477
3478    SEARCH_DU_DB(duIdx, duId, duDb);
3479    if(duDb == NULLP)
3480    {
3481       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
3482       return RFAILED;
3483    }
3484
3485    memset(&ricReqId, 0, sizeof(RicRequestId));
3486    if(ricSubscriptionFailure)
3487    {
3488       if(ricSubscriptionFailure->protocolIEs.list.array)
3489       {
3490          for(ieIdx=0; ieIdx<ricSubscriptionFailure->protocolIEs.list.count; ieIdx++)
3491          {
3492             if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx])
3493             {
3494                ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx];
3495                switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id)
3496                {
3497                   case ProtocolIE_IDE2_id_RICrequestID:
3498                   {
3499                      ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID;
3500                      ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID;
3501                      break;
3502                   }
3503                   case ProtocolIE_IDE2_id_RANfunctionID:
3504                   {
3505                      ranFuncId = ricSubsFailIe->value.choice.RANfunctionID;
3506                      ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
3507                      if(!ranFuncDb)
3508                      {
3509                         DU_LOG("\nERROR  -->  E2AP : ProcRicSubscriptionFailure : RAN Function Id [%d] not found", ranFuncId);
3510                         return RFAILED;
3511                      }
3512                      else
3513                      {
3514                         /* Remove subscription entry from RAN Function */
3515                         ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
3516                         if(ricSubs)
3517                         {
3518                            cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
3519                            deleteRicSubscriptionNode(ricSubsNode);
3520                         }
3521                      }
3522                      break; 
3523                   }
3524                   case ProtocolIE_IDE2_id_CauseE2:
3525                   default:
3526                      /* No handling required as of now since this is a stub */
3527                      break;
3528                }
3529             }
3530          }
3531       }
3532    }
3533    return ROK;
3534 }
3535
3536 /*******************************************************************
3537  *
3538  * @brief Free RIC Subscription Modification Refuse
3539  *
3540  * @details
3541  *
3542  *    Function : FreeRicSubsModRefuse
3543  *
3544  * Functionality: Free RIC Subscription Modification Refuse
3545  *
3546  * @param  E2AP Message PDU to be freed
3547  * @return void
3548  *
3549  ******************************************************************/
3550 void FreeRicSubsModRefuse(E2AP_PDU_t *e2apMsg)
3551 {
3552    uint8_t ieIdx =0;
3553    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3554
3555    if(e2apMsg)
3556    {
3557       if(e2apMsg->choice.unsuccessfulOutcome)
3558       {
3559          ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3560          if(ricSubsModRefuse->protocolIEs.list.array)
3561          {
3562             for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++)
3563             {
3564                RIC_FREE(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3565             }
3566             RIC_FREE(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3567          }
3568          RIC_FREE(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3569       }
3570       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3571    }
3572 }
3573
3574 /*******************************************************************
3575  *
3576  * @brief Build And Send RIC Subscription Modification Refuse
3577  *
3578  * @details
3579  *
3580  *    Function : BuildAndSendRicSubsModRefuse
3581  *
3582  * Functionality: Build And Send RIC Subscription Modification Refuse
3583  *
3584  * @param DU ID
3585  *        RIC Request ID of subscription
3586  *        RAN Function ID
3587  *        Type of failure
3588  *        Cause of failure
3589  * @return ROK - success
3590  *         RFAILED - failure
3591  *
3592  ******************************************************************/
3593 uint8_t BuildAndSendRicSubsModRefuse(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, CauseE2_PR causeType, \
3594    uint8_t cause)
3595 {
3596    uint8_t ieIdx = 0, elementCnt = 0;
3597    uint8_t ret = RFAILED;
3598    E2AP_PDU_t *e2apMsg = NULL;
3599    asn_enc_rval_t encRetVal;
3600    RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP;
3601    RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP;
3602
3603    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Refuse\n");
3604    while(true)
3605    {
3606       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
3607       if(e2apMsg == NULLP)
3608       {
3609          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3610          break;
3611       }
3612       e2apMsg->present =  E2AP_PDU_PR_unsuccessfulOutcome;
3613       RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(UnsuccessfulOutcomeE2_t));
3614       if(e2apMsg->choice.unsuccessfulOutcome == NULLP)
3615       {
3616          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3617          break;
3618       }
3619
3620       e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
3621       e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject;
3622       e2apMsg->choice.unsuccessfulOutcome->value.present = \
3623          UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse;
3624       ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse;
3625
3626       elementCnt = 3;
3627       ricSubsModRefuse->protocolIEs.list.count = elementCnt;
3628       ricSubsModRefuse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRefuse_IEs_t *);
3629       RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array, ricSubsModRefuse->protocolIEs.list.size);
3630       if(!ricSubsModRefuse->protocolIEs.list.array)
3631       {
3632          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3633          break;
3634       }
3635
3636       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
3637       {
3638          RIC_ALLOC(ricSubsModRefuse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRefuse_IEs_t));
3639          if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx])
3640          {
3641             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3642             break;
3643          }
3644       }
3645       
3646       /* RIC Request ID */
3647       ieIdx = 0;
3648       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3649       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RICrequestID;
3650       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3651       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RICrequestID;
3652       ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
3653       ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
3654
3655       /* RAN Function ID */
3656       ieIdx++;
3657       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3658       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_RANfunctionID;
3659       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3660       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_RANfunctionID;
3661       ricSubsModRefuseIe->value.choice.RANfunctionID = ranFuncId;
3662
3663       /* Cause */
3664       ieIdx++;
3665       ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx];
3666       ricSubsModRefuseIe->id = ProtocolIE_IDE2_id_CauseE2;
3667       ricSubsModRefuseIe->criticality = CriticalityE2_reject;
3668       ricSubsModRefuseIe->value.present = RICsubscriptionModificationRefuse_IEs__value_PR_CauseE2;
3669       fillE2FailureCause(&ricSubsModRefuseIe->value.choice.CauseE2, causeType, cause); 
3670
3671       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
3672       memset(encBuf, 0, ENC_BUF_MAX_LEN);
3673       encBufSize = 0;
3674       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
3675
3676       /* Check encode results */
3677       if(encRetVal.encoded == ENCODE_FAIL)
3678       {
3679          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification refuse (at %s)\n",\
3680                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
3681          break;
3682       }
3683       else
3684       {
3685          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification refuse\n");
3686          for(int i=0; i< encBufSize; i++)
3687          {
3688             DU_LOG("%x",encBuf[i]);
3689          }
3690       }
3691
3692       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
3693       {
3694          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Refused");
3695          break;
3696       }
3697
3698       ret =ROK;
3699       break;
3700    }
3701    FreeRicSubsModRefuse(e2apMsg);
3702    return ret;
3703 }
3704
3705 /*******************************************************************
3706  *
3707  * @brief Free memory for RIC Subscription Modification Confirm
3708  *
3709  * @details
3710  *
3711  *    Function : FreeRicSubsModConfirm
3712  *
3713  * Functionality: Free memory for RIC subscription modification
3714  *    confirm
3715  *
3716  * @param E2AP Message PDU to be freed
3717  * @return Void
3718  *
3719  ******************************************************************/
3720 void FreeRicSubsModConfirm(E2AP_PDU_t *e2apMsg)
3721 {
3722    uint8_t ieIdx = 0, arrIdx=0;
3723    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
3724    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
3725    RICactions_ConfirmedForModification_List_t *modCfmList = NULLP;
3726    RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP;
3727    RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP;
3728    RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP;
3729
3730    if(e2apMsg)
3731    {
3732       if(e2apMsg->choice.successfulOutcome)
3733       {
3734          ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
3735          if(ricSubsModCfm->protocolIEs.list.array)
3736          {
3737             for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++)
3738             {
3739                if(ricSubsModCfm->protocolIEs.list.array[ieIdx])
3740                {
3741                   ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
3742                   switch(ricSubsModCfmIe->id)
3743                   {
3744                      case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List:
3745                         {
3746                            modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List;
3747                            if(modCfmList->list.array)
3748                            {
3749                               for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
3750                               {
3751                                  RIC_FREE(modCfmList->list.array[arrIdx], \
3752                                     sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
3753                               }
3754                               RIC_FREE(modCfmList->list.array,  modCfmList->list.size);
3755                            }
3756                            break;
3757                         }
3758
3759                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List:
3760                         {
3761                            modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List;
3762                            if(modRefusedList->list.array)
3763                            {
3764                               for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
3765                               {
3766                                  RIC_FREE(modRefusedList->list.array[arrIdx], \
3767                                        sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
3768                               }
3769                               RIC_FREE(modRefusedList->list.array,  modRefusedList->list.size);
3770                            }
3771                            break;
3772                         }
3773
3774                      case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List:
3775                         {
3776                            rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List;
3777                            if(rmvCfmList->list.array)
3778                            {
3779                               for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
3780                               {
3781                                  RIC_FREE(rmvCfmList->list.array[arrIdx], \
3782                                        sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
3783                               }
3784                               RIC_FREE(rmvCfmList->list.array,  rmvCfmList->list.size);
3785                            }
3786                            break;
3787                         }
3788
3789                      case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List:
3790                         {
3791                            rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List;
3792                            if(rmvFailList->list.array)
3793                            {
3794                               for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
3795                               {
3796                                  RIC_ALLOC(rmvFailList->list.array[arrIdx], \
3797                                     sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
3798                               }
3799                               RIC_FREE(rmvFailList->list.array,  rmvFailList->list.size);
3800                            }
3801                            break;
3802                         }
3803
3804                      default:
3805                         break;
3806
3807                   }
3808                   RIC_FREE(ricSubsModCfmIe, sizeof(RICsubscriptionModificationConfirm_IEs_t));
3809                }
3810             }
3811             RIC_FREE(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
3812          }
3813          RIC_FREE(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
3814       }
3815       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
3816    }
3817 }
3818
3819 /*******************************************************************
3820  *
3821  * @brief Fill the list of actions confirmed for modification
3822  *
3823  * @details
3824  *
3825  *    Function : fillActionModConfirmedList
3826  *
3827  * Functionality: Fill the list of actions confirmed for modification
3828  *
3829  * @param List to be filled
3830  *        Number of actions
3831  *        Source list of actions
3832  * @return ROK - success
3833  *         RFAILED - failure
3834  *
3835  ******************************************************************/
3836 uint8_t fillActionModConfirmedList(RICactions_ConfirmedForModification_List_t *modCfmList, uint8_t numActions, \
3837    uint8_t *actionModifiedList)
3838 {
3839    uint8_t arrIdx = 0;
3840    RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP;
3841
3842    modCfmList->list.count = numActions;
3843    modCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForModification_ItemIEs_t *);
3844    RIC_ALLOC(modCfmList->list.array,  modCfmList->list.size);
3845    if(!modCfmList->list.array)
3846    {
3847       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3848       return RFAILED;
3849    }
3850
3851    for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++)
3852    {
3853       RIC_ALLOC(modCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForModification_ItemIEs_t));
3854       if(!modCfmList->list.array[arrIdx])
3855       {
3856          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3857          return RFAILED;
3858       }
3859
3860       modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx];
3861       modCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForModification_Item;
3862       modCfmListItem->criticality = CriticalityE2_ignore;
3863       modCfmListItem->value.present = \
3864          RICaction_ConfirmedForModification_ItemIEs__value_PR_RICaction_ConfirmedForModification_Item;
3865       modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID = actionModifiedList[arrIdx];
3866    }
3867
3868    return ROK;
3869 }
3870
3871 /*******************************************************************
3872  *
3873  * @brief Fill the list of actions refused to be modified
3874  *
3875  * @details
3876  *
3877  *    Function : fillActionModRefusedList
3878  *
3879  * Functionality: Fill the list of actions refused to be modified
3880  *
3881  * @param List to be filled
3882  *        Number of list
3883  *        Source list of actions refused tobe modified
3884  * @return ROK - success
3885  *         RFAILED - failure
3886  *
3887  ******************************************************************/
3888 uint8_t fillActionModRefusedList(RICactions_RefusedToBeModified_List_t *modRefusedList, uint8_t numActions, \
3889    ActionFailed *actionModFailedList)
3890 {
3891    uint8_t arrIdx = 0;
3892    RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP;
3893
3894    modRefusedList->list.count = numActions;
3895    modRefusedList->list.size = numActions * sizeof(RICaction_RefusedToBeModified_ItemIEs_t *);
3896    RIC_ALLOC(modRefusedList->list.array,  modRefusedList->list.size);
3897    if(!modRefusedList->list.array)
3898    {
3899       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3900       return RFAILED;
3901    }
3902
3903    for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++)
3904    {
3905       RIC_ALLOC(modRefusedList->list.array[arrIdx], sizeof(RICaction_RefusedToBeModified_ItemIEs_t));
3906       if(!modRefusedList->list.array[arrIdx])
3907       {
3908          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3909          return RFAILED;
3910       }
3911
3912       modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx];
3913       modRefusedListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeModified_Item;
3914       modRefusedListItem->criticality = CriticalityE2_ignore;
3915       modRefusedListItem->value.present = \
3916          RICaction_RefusedToBeModified_ItemIEs__value_PR_RICaction_RefusedToBeModified_Item;
3917       modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID = \
3918          actionModFailedList[arrIdx].actionId;
3919       fillE2FailureCause(&modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.cause, \
3920          actionModFailedList[arrIdx].failureType, actionModFailedList[arrIdx].cause);
3921    }
3922
3923    return ROK;
3924 }
3925
3926 /*******************************************************************
3927  *
3928  * @brief Fill the list of action confirmed for removal
3929  *
3930  * @details
3931  *
3932  *    Function : fillActionRemovalConfirmedList
3933  *
3934  * Functionality: Fill the list of action confirmed for removal
3935  *
3936  * @param List to be filled
3937  *        Number of actions
3938  *        Source list of actions removed
3939  * @return ROK - success
3940  *         RFAILED - failure
3941  *
3942  ******************************************************************/
3943 uint8_t fillActionRemovalConfirmedList(RICactions_ConfirmedForRemoval_List_t *rmvCfmList, uint8_t numActions, \
3944    uint8_t *actionRemovedList)
3945 {
3946    uint8_t arrIdx = 0;
3947    RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP;
3948
3949    rmvCfmList->list.count = numActions;
3950    rmvCfmList->list.size = numActions * sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t *);
3951    RIC_ALLOC(rmvCfmList->list.array,  rmvCfmList->list.size);
3952    if(!rmvCfmList->list.array)
3953    {
3954       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3955       return RFAILED;
3956    }
3957
3958    for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++)
3959    {
3960       RIC_ALLOC(rmvCfmList->list.array[arrIdx], sizeof(RICaction_ConfirmedForRemoval_ItemIEs_t));
3961       if(!rmvCfmList->list.array[arrIdx])
3962       {
3963          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
3964          return RFAILED;
3965       }
3966
3967       rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx];
3968       rmvCfmListItem->id = ProtocolIE_IDE2_id_RICaction_ConfirmedForRemoval_Item;
3969       rmvCfmListItem->criticality = CriticalityE2_ignore;
3970       rmvCfmListItem->value.present = \
3971          RICaction_ConfirmedForRemoval_ItemIEs__value_PR_RICaction_ConfirmedForRemoval_Item;
3972       rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID = actionRemovedList[arrIdx];
3973    }
3974
3975    return ROK;
3976 }
3977
3978 /*******************************************************************
3979  *
3980  * @brief Fill the list of actions refused to be removed
3981  *
3982  * @details
3983  *
3984  *    Function : fillActionRemovalRefusedList
3985  *
3986  * Functionality: Fill the list of actions refused to be removed
3987  *
3988  * @param List to be filled
3989  *        Number of list
3990  *        Source list of actions refused to be removed
3991  * @return ROK - success
3992  *         RFAILED - failure
3993  *
3994  ******************************************************************/
3995 uint8_t fillActionRemovalRefusedList(RICactions_RefusedToBeRemoved_List_t *rmvFailList, \
3996    uint8_t numActions, ActionFailed *actionRmvlFailList)
3997 {
3998    uint8_t arrIdx = 0;
3999    RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP;
4000
4001    rmvFailList->list.count = numActions;
4002    rmvFailList->list.size = numActions * sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t *);
4003    RIC_ALLOC(rmvFailList->list.array,  rmvFailList->list.size);
4004    if(!rmvFailList->list.array)
4005    {
4006       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4007       return RFAILED;
4008    }
4009
4010    for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++)
4011    {
4012       RIC_ALLOC(rmvFailList->list.array[arrIdx], sizeof(RICaction_RefusedToBeRemoved_ItemIEs_t));
4013       if(!rmvFailList->list.array[arrIdx])
4014       {
4015          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4016          return RFAILED;
4017       }
4018
4019       rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx];
4020       rmvFailListItem->id = ProtocolIE_IDE2_id_RICaction_RefusedToBeRemoved_Item;
4021       rmvFailListItem->criticality = CriticalityE2_ignore;
4022       rmvFailListItem->value.present = \
4023          RICaction_RefusedToBeRemoved_ItemIEs__value_PR_RICaction_RefusedToBeRemoved_Item;
4024       rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID = actionRmvlFailList[arrIdx].actionId;
4025       fillE2FailureCause(&rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.cause, \
4026          actionRmvlFailList[arrIdx].failureType, actionRmvlFailList[arrIdx].cause);
4027    }
4028
4029    return ROK;
4030
4031 }
4032
4033 /*******************************************************************
4034  *
4035  * @brief Build And Send RIC Subscription Modification Confirm
4036  *
4037  * @details
4038  *
4039  *    Function : BuildAndSendRicSubsModConfirm
4040  *
4041  * Functionality: Build And Send RIC Subscription Modification Confirm
4042  *
4043  * @param DU ID
4044  *        RIC Request ID of subscription
4045  *        RAN Function ID
4046  *        Temporary source action list
4047  * @return ROK - success
4048  *         RFAILED - failure
4049  *
4050  ******************************************************************/
4051 uint8_t BuildAndSendRicSubsModConfirm(uint32_t duId, RicRequestId ricReqId, uint16_t ranFuncId, RicTmpActionList tmpActionList)
4052 {
4053    uint8_t ieIdx = 0, elementCnt = 0;
4054    uint8_t ret = RFAILED;
4055    E2AP_PDU_t *e2apMsg = NULLP;
4056    asn_enc_rval_t encRetVal;
4057    RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP;
4058    RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP;
4059
4060    DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Modification Confirm\n");
4061    while(true)
4062    {
4063       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4064       if(e2apMsg == NULLP)
4065       {
4066          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4067          break;
4068       }
4069
4070       /* Successful Outcome */
4071       e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
4072       RIC_ALLOC(e2apMsg->choice.successfulOutcome , sizeof(SuccessfulOutcomeE2_t));
4073       if(e2apMsg->choice.successfulOutcome == NULLP)
4074       {
4075          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4076          break;
4077       }
4078
4079       e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired;
4080       e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
4081       e2apMsg->choice.successfulOutcome->value.present = \
4082          SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm;
4083       ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm;
4084
4085       elementCnt = 2;
4086       if(tmpActionList.numActionModified)
4087          elementCnt++;
4088       if(tmpActionList.numActionModFailed)
4089          elementCnt++;
4090       if(tmpActionList.numActionRemoved)
4091          elementCnt++;
4092       if(tmpActionList.numActionRemovalFailed)
4093          elementCnt++;
4094
4095       ricSubsModCfm->protocolIEs.list.count = elementCnt;
4096       ricSubsModCfm->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationConfirm_IEs_t *);
4097       RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array, ricSubsModCfm->protocolIEs.list.size);
4098       if(!ricSubsModCfm->protocolIEs.list.array)
4099       {
4100          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4101          break;
4102       }
4103
4104       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4105       {
4106          RIC_ALLOC(ricSubsModCfm->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationConfirm_IEs_t));
4107          if(!ricSubsModCfm->protocolIEs.list.array[ieIdx])
4108          {
4109             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for %s at line %d", __func__, __LINE__);
4110             break;
4111          }
4112       }
4113       
4114       /* RIC Request ID */
4115       ieIdx = 0;
4116       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4117       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICrequestID;
4118       ricSubsModCfmIe->criticality = CriticalityE2_reject;
4119       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RICrequestID;
4120       ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId;
4121       ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId;
4122
4123       /* RAN Function ID */
4124       ieIdx++;
4125       ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4126       ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RANfunctionID;
4127       ricSubsModCfmIe->criticality = CriticalityE2_reject;
4128       ricSubsModCfmIe->value.present = RICsubscriptionModificationConfirm_IEs__value_PR_RANfunctionID;
4129       ricSubsModCfmIe->value.choice.RANfunctionID = ranFuncId;
4130
4131       /* RIC Actions List confirmed for modification */
4132       if(tmpActionList.numActionModified)
4133       {
4134          ieIdx++;
4135          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4136          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List;
4137          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4138          ricSubsModCfmIe->value.present = \
4139             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForModification_List;
4140          if(fillActionModConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List, \
4141             tmpActionList.numActionModified, tmpActionList.actionModifiedList) != ROK)
4142          {
4143             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Modification List", __func__);
4144             break;
4145          }
4146       }
4147
4148       /* RIC Actions List refured to be modified */
4149       if(tmpActionList.numActionModFailed)
4150       {
4151          ieIdx++;
4152          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4153          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List;
4154          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4155          ricSubsModCfmIe->value.present = \
4156             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeModified_List;
4157          if(fillActionModRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List, \
4158             tmpActionList.numActionModFailed, tmpActionList.actionModFailedList) != ROK)
4159          {
4160             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Refused to be Modified List", __func__);
4161             break;
4162          }
4163       }
4164
4165       /* RIC Actions List confirmed for removal */
4166       if(tmpActionList.numActionRemoved)
4167       {
4168          ieIdx++;
4169          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4170          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List;
4171          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4172          ricSubsModCfmIe->value.present = \
4173             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_ConfirmedForRemoval_List;
4174          if(fillActionRemovalConfirmedList(&ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List, \
4175             tmpActionList.numActionRemoved, tmpActionList.actionRemovedList) != ROK)
4176          {
4177             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Confirmed for Removal List", __func__);
4178             break;
4179          }
4180       }
4181
4182       /* RIC Actions List Refused to be removed */
4183       if(tmpActionList.numActionRemovalFailed)
4184       {
4185          ieIdx++;
4186          ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx];
4187          ricSubsModCfmIe->id = ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List;
4188          ricSubsModCfmIe->criticality = CriticalityE2_ignore;
4189          ricSubsModCfmIe->value.present = \
4190             RICsubscriptionModificationConfirm_IEs__value_PR_RICactions_RefusedToBeRemoved_List;
4191          if(fillActionRemovalRefusedList(&ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List, \
4192             tmpActionList.numActionRemovalFailed, tmpActionList.actionRemovalFailedList) != ROK)
4193          {
4194             DU_LOG("\nERROR  -->  E2AP : %s: Failed to fill RIC Actions Failed to be Removed List", __func__);
4195             break;
4196          }
4197       }
4198
4199       /* Print and encode E2AP Message PDU */
4200       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4201       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4202       encBufSize = 0;
4203       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
4204
4205       /* Check encode results */
4206       if(encRetVal.encoded == ENCODE_FAIL)
4207       {
4208          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC subscription modification confirm (at %s)\n",\
4209                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4210          break;
4211       }
4212       else
4213       {
4214          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC subscription modification confirm\n");
4215          for(int i=0; i< encBufSize; i++)
4216          {
4217             DU_LOG("%x",encBuf[i]);
4218          }
4219       }
4220
4221       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4222       {
4223          DU_LOG("\nERROR  -->  E2AP : Failed to send RIC Subscription Modification Confirm");
4224          break;
4225       }
4226
4227       ret =ROK;
4228       break;
4229    }
4230
4231    FreeRicSubsModConfirm(e2apMsg);
4232    return ret;
4233 }
4234
4235 /*******************************************************************
4236  *
4237  * @brief Processing of RIC Subscription Modification Required
4238  *
4239  * @details
4240  *
4241  *    Function : ProcRicSubsModReqd
4242  *
4243  * Functionality: Processing of RIC Subscription Modification Required
4244  *    As of now, we do not identify any scenario where this message
4245  *    shall be sent by DU. Hence, bare minimum handling has been
4246  *    done here.
4247  *
4248  * @param  DU ID
4249  *         RIC Subscription Modification Required IEs
4250  * @return ROK-success
4251  *         RFAILED-failure
4252  *
4253  ******************************************************************/
4254 uint8_t ProcRicSubsModReqd(uint32_t duId, RICsubscriptionModificationRequired_t *ricSubsModReqd)
4255 {
4256    uint8_t ieIdx = 0, actionIdx = 0, duIdx = 0;
4257    DuDb    *duDb = NULLP;
4258    uint16_t ranFuncId;
4259    uint16_t actionId;
4260    RicRequestId ricReqId;
4261    RanFunction *ranFuncDb = NULLP;
4262    RicSubscription *ricSubs = NULLP;
4263    CmLList *ricSubsNode = NULLP;
4264    ActionInfo *action = NULLP;
4265    RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP;
4266    RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP;
4267    RICactions_RequiredToBeRemoved_List_t  *actionToBeRmvList = NULLP;
4268    RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULLP;
4269    RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULLP;
4270    RicTmpActionList tmpActionList;
4271
4272    memset(&ricReqId, 0, sizeof(RicRequestId));
4273    memset(&tmpActionList, 0, sizeof(RicTmpActionList));
4274
4275    SEARCH_DU_DB(duIdx, duId, duDb);
4276    if(duDb == NULLP)
4277    {
4278       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4279       return RFAILED;
4280    }
4281
4282    for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++)
4283    {
4284       ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx];
4285       switch(ricSubsModReqdIe->id)
4286       {
4287          case ProtocolIE_IDE2_id_RICrequestID:
4288             {
4289                ricReqId.requestorId = ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID;
4290                ricReqId.instanceId = ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID;
4291                break;
4292             }
4293          case ProtocolIE_IDE2_id_RANfunctionID:
4294             {
4295                ranFuncId = ricSubsModReqdIe->value.choice.RANfunctionID;
4296                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, ranFuncId);
4297                if(!ranFuncDb)
4298                {
4299                   /* If RIC Subscription not found, send RIC Subscription modification refuse to DU */
4300                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RIC Subscription not found");
4301                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
4302                      CauseE2RICrequest_ran_function_id_invalid);
4303                   return RFAILED;
4304                }
4305
4306                ricSubs = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
4307                if(!ricSubs)
4308                {
4309                   /* If RAN Function not found, send RIC Subscription modification refuse to DU */
4310                   DU_LOG("\nERROR  -->  E2AP : ProcRicSubsModReqd: RAN Function ID [%d] not found",ranFuncId);
4311                   BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, \
4312                      CauseE2_PR_ricRequest, CauseE2RICrequest_request_id_unknown);
4313                   return RFAILED; 
4314                }
4315                break;
4316             }
4317          case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List:
4318             {
4319                actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List;
4320                for(actionIdx = 0; actionIdx < actionToBeModList->list.count; actionIdx++)
4321                {
4322                   actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[actionIdx];
4323                   actionId = actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID;
4324                   action = fetchActionInfoFromActionId(actionId, ricSubs);
4325                   if(action)
4326                   {
4327                      /* No modification required as of now, hence directly adding to the list */
4328                      tmpActionList.actionModifiedList[tmpActionList.numActionModified++] = actionId;
4329                   }
4330                   else
4331                   {
4332                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].actionId = actionId;
4333                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].failureType = \
4334                         CauseE2_PR_ricRequest;
4335                      tmpActionList.actionModFailedList[tmpActionList.numActionModFailed].cause = \
4336                         CauseE2RICrequest_action_not_supported;
4337                      tmpActionList.numActionModFailed++;
4338                   }
4339                }
4340                break;
4341             }
4342          case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List:
4343             {
4344                actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List;
4345                for(actionIdx = 0; actionIdx < actionToBeRmvList->list.count; actionIdx++)
4346                {
4347                   actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[actionIdx];
4348                   actionId = actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID;
4349                   action = fetchActionInfoFromActionId(actionId, ricSubs);
4350                   if(action)
4351                   {
4352                      tmpActionList.actionRemovedList[tmpActionList.numActionRemoved++] = actionId;
4353                      memset(action, 0, sizeof(ActionInfo));
4354                      action->actionId = -1;
4355                      ricSubs->numOfActions--;
4356                   }
4357                }
4358                break;
4359             }
4360          default:
4361             break;
4362       }
4363    }
4364
4365    /* If none of the action modification/removal is supported, 
4366     *   send RIC Subscription Modification Refuse
4367     * Else
4368     *   send RIC Subscription Modification Confirm
4369     */
4370    if(tmpActionList.numActionModified || tmpActionList.numActionRemoved)
4371    {
4372       BuildAndSendRicSubsModConfirm(duId, ricReqId, ranFuncId, tmpActionList);
4373    }
4374    else
4375    {
4376       BuildAndSendRicSubsModRefuse(duId, ricReqId, ranFuncId, CauseE2_PR_ricRequest, \
4377             CauseE2RICrequest_action_not_supported);
4378    }
4379    
4380    return ROK;
4381 }
4382
4383 /*******************************************************************
4384  *
4385  * @brief Free the ErrorIndication Message
4386  *
4387  * @details
4388  *
4389  *    Function : FreeRicIndication
4390  *
4391  * Functionality: Free the ErrorIndication Message
4392  *
4393  * @return void
4394  *
4395  *
4396  ******************************************************************/
4397 void FreeErrorIndication(E2AP_PDU_t  *e2apMsg)
4398 {
4399    uint8_t arrIdx = 0;
4400    ErrorIndicationE2_t *errorIndicationMsg= NULLP;
4401
4402    if(e2apMsg != NULLP)
4403    {
4404       if(e2apMsg->choice.initiatingMessage != NULLP)
4405       {
4406          errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4407          if(errorIndicationMsg!= NULLP)
4408          {
4409             if(errorIndicationMsg->protocolIEs.list.array != NULLP)
4410             {
4411                for(arrIdx=0; arrIdx<errorIndicationMsg->protocolIEs.list.count; arrIdx++)
4412                {
4413                   RIC_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t));
4414                }
4415                RIC_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size);
4416             }
4417          }
4418          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4419       }
4420       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4421    }
4422 }
4423
4424
4425 /*******************************************************************
4426  *
4427  * @brief Builds and Send the ErrorIndication Message
4428  *
4429  * @details
4430  *
4431  *    Function : BuildAndSendErrorIndication
4432  *
4433  * Functionality:Fills the ErrorIndication Message
4434  *
4435  * @params[in] 
4436  *    DU id
4437  *    Trans id
4438  *    Ric req id
4439  *    Ran function id
4440  *    Reason of failure
4441  * @return ROK     - success
4442  *         RFAILED - failure
4443  *
4444  ******************************************************************/
4445
4446 uint8_t BuildAndSendErrorIndication(uint32_t duId, int8_t transId, RicRequestId requestId, uint16_t ranFuncId, uint8_t reason)
4447 {
4448    uint8_t elementCnt =0, arrIdx=0, ret = RFAILED;
4449    E2AP_PDU_t         *e2apMsg = NULLP;
4450    ErrorIndicationE2_t *errorIndicationMsg=NULLP;
4451    asn_enc_rval_t     encRetVal;        /* Encoder return value */
4452
4453    while(true)
4454    {
4455       DU_LOG("\nINFO   -->  E2AP : Building Error Indication Message\n");
4456
4457       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4458       if(e2apMsg == NULLP)
4459       {
4460          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4461          break;
4462       }
4463
4464       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4465       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4466       if(e2apMsg->choice.initiatingMessage == NULLP)
4467       {
4468          DU_LOG("\nERROR  -->  E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__);
4469          break;
4470       }
4471       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2;
4472       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4473       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2;
4474
4475       errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2;
4476
4477       /* Element count is 2 for TransactionID/RICrequestID and Cause.
4478        * If the RAN function id is present, the count will be increased.*/
4479       elementCnt = 2;
4480       if(ranFuncId>0)
4481          elementCnt++;
4482
4483       errorIndicationMsg->protocolIEs.list.count = elementCnt;
4484       errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*);
4485
4486       /* Initialize the E2Setup members */
4487       RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size);
4488       if(errorIndicationMsg->protocolIEs.list.array == NULLP)
4489       {
4490          DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__);
4491          break;
4492       }
4493       for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++)
4494       {
4495          RIC_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t));
4496          if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP)
4497          {
4498             DU_LOG("\nERROR  -->  E2AP : Memory allocation failed for array Idx %d in %s at line %d",arrIdx,__func__, __LINE__);
4499             break;
4500          }
4501       }
4502       if(arrIdx < elementCnt)
4503          break;
4504
4505       arrIdx = 0;
4506
4507       if(transId >=0 && transId<=255)
4508       {
4509          /* TransactionID */
4510          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4511          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4512          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID;
4513          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId;
4514       }
4515       else
4516       {
4517          /* RICrequestID */
4518          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID;
4519          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4520          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID;
4521          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId;
4522          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId;
4523       }
4524       
4525       if(ranFuncId>0)
4526       {
4527          /* RAN Function ID */
4528          arrIdx++;
4529          errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID;
4530          errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject;
4531          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID;
4532          errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId;
4533       }
4534      
4535       /* Cause */
4536       arrIdx++;
4537       errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4538       errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore;
4539       errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2;
4540       fillE2FailureCause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, CauseE2_PR_misc, reason);
4541
4542
4543       /* Prints the Msg formed */
4544       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4545       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4546       encBufSize = 0;
4547       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4548             encBuf);
4549       if(encRetVal.encoded == ENCODE_FAIL)
4550       {
4551          DU_LOG("\nERROR  -->  E2AP : Could not encode Error Indication Message (at %s)\n",\
4552                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4553          break;
4554       }
4555       else
4556       {
4557          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for Error Indication Message \n");
4558 #ifdef DEBUG_ASN_PRINT
4559          for(int i=0; i< encBufSize; i++)
4560          {
4561             printf("%x",encBuf[i]);
4562          }
4563 #endif
4564       }
4565
4566       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
4567       {
4568          DU_LOG("\nINFO   -->  E2AP : Sending Error Indication Message");
4569
4570       }
4571       ret = ROK;
4572       break;
4573    }
4574    FreeErrorIndication(e2apMsg);
4575    return ret;
4576 }
4577
4578 /*******************************************************************
4579  *
4580  * @brief Deallocate the memory allocated for ResetRequest msg
4581  *
4582  * @details
4583  *
4584  *    Function : FreeResetRequest
4585  *
4586  *    Functionality:
4587  *       - freeing the memory allocated for ResetRequest
4588  *
4589  * @params[in] E2AP_PDU_t *e2apMsg
4590  * @return ROK     - success
4591  *         RFAILED - failure
4592  *
4593  * ****************************************************************/
4594 void FreeResetRequest(E2AP_PDU_t *e2apMsg)
4595 {
4596    uint8_t ieIdx =0;
4597    ResetRequestE2_t  *resetReq = NULLP;
4598
4599    if(e2apMsg != NULLP)
4600    {
4601       if(e2apMsg->choice.initiatingMessage != NULLP)
4602       {
4603          resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4604          if(resetReq->protocolIEs.list.array)
4605          {
4606             for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4607             {
4608                RIC_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4609             }
4610             RIC_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4611          }
4612          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4613       }
4614       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
4615    }
4616 }
4617
4618 /*******************************************************************
4619  *
4620  * @brief Build and send the reset request msg
4621  *
4622  * @details
4623  *
4624  *    Function : BuildAndSendResetRequest
4625  *
4626  *    Functionality:
4627  *         - Buld and send the reset request msg to E2 node
4628  *
4629  * @params[in]
4630  *    DU database
4631  *    Type of failure 
4632  *    Cause of failure
4633  * @return ROK     - success
4634  *         RFAILED - failure
4635  *
4636  * ****************************************************************/
4637 uint8_t BuildAndSendResetRequest(DuDb *duDb, CauseE2_PR causePresent, uint8_t reason)
4638 {
4639    uint8_t ieIdx = 0, elementCnt = 0, transId = 0;
4640    uint8_t ret = RFAILED;
4641    E2AP_PDU_t        *e2apMsg = NULLP;
4642    ResetRequestE2_t  *resetReq = NULLP;
4643    asn_enc_rval_t     encRetVal;       /* Encoder return value */
4644
4645    DU_LOG("\nINFO   -->  E2AP : Building Reset Request\n");
4646
4647    do
4648    {
4649       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
4650       if(e2apMsg == NULLP)
4651       {
4652          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for E2AP-PDU failed");
4653          break;
4654       }
4655
4656       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
4657       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4658       if(e2apMsg->choice.initiatingMessage == NULLP)
4659       {
4660          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation for initiatingMessage");
4661          break;
4662       }
4663
4664       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset;
4665       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
4666       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2;
4667       resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2;
4668
4669       elementCnt = 2;
4670       resetReq->protocolIEs.list.count = elementCnt;
4671       resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *);
4672
4673       RIC_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size);
4674       if(!resetReq->protocolIEs.list.array)
4675       {
4676          DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4677                Reset Request IE array");
4678          break;
4679       }
4680
4681       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
4682       {
4683          RIC_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t));
4684          if(!resetReq->protocolIEs.list.array[ieIdx])
4685          {
4686             DU_LOG("\nERROR  -->  E2AP : BuildAndSendResetRequest(): Memory allocation failed for \
4687                   Reset Request IE array element");
4688             break;
4689          }
4690       }
4691
4692       /* In case of failure */
4693       if(ieIdx < elementCnt)
4694          break;
4695
4696       ieIdx = 0;
4697       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID;
4698       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject;
4699       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID;
4700       transId = assignTransactionId(duDb);
4701       resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId;
4702
4703       ieIdx++;
4704       resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2;
4705       resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore;
4706       resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2;
4707       fillE2FailureCause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, causePresent, reason);
4708
4709       /* Prints the Msg formed */
4710       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
4711
4712       memset(encBuf, 0, ENC_BUF_MAX_LEN);
4713       encBufSize = 0;
4714       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\
4715             encBuf);
4716       if(encRetVal.encoded == ENCODE_FAIL)
4717       {
4718          DU_LOG("\nERROR  -->  E2AP : Could not encode reset request structure (at %s)\n",\
4719                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
4720          break;
4721       }
4722       else
4723       {
4724          DU_LOG("\nDEBUG   -->  E2AP : Created APER encoded buffer for reset request\n");
4725 #ifdef DEBUG_ASN_PRINT
4726          for(int i=0; i< encBufSize; i++)
4727          {
4728             printf("%x",encBuf[i]);
4729          }
4730 #endif
4731       }
4732       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duDb->duId) != ROK)
4733       {
4734          DU_LOG("\nERROR  -->  E2AP : Sending reset request failed");
4735          break;
4736       }
4737
4738
4739       ret = ROK;
4740       break;
4741    }while(true);
4742
4743    /* Free all memory */
4744    FreeResetRequest(e2apMsg);
4745    return ret;
4746 }
4747
4748 /******************************************************************
4749  *
4750  * @brief Delete Ric subscription node
4751  *
4752  * @details
4753  *
4754  *    Function : deleteRicSubscriptionNode
4755  *
4756  *    Functionality: Delete Ric subscription node
4757  *
4758  * @params[in] Ric subscription info
4759  *
4760  * @return void
4761  *
4762  * ****************************************************************/
4763 void deleteRicSubscriptionNode(CmLList *subscriptionNode)
4764 {
4765    uint8_t actionIdx=0;
4766    RicSubscription *ricSubscriptionInfo = NULLP;
4767
4768    ricSubscriptionInfo = (RicSubscription*)subscriptionNode->node;
4769
4770    for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++)
4771    {
4772       if(ricSubscriptionInfo->actionSequence[actionIdx].actionId > -1)
4773       {
4774          memset(&ricSubscriptionInfo->actionSequence[actionIdx], 0, sizeof(ActionInfo));
4775       }
4776    }
4777    memset(ricSubscriptionInfo, 0, sizeof(RicSubscription));
4778    RIC_FREE(subscriptionNode->node, sizeof(RicSubscription));
4779    RIC_FREE(subscriptionNode, sizeof(CmLList));
4780 }
4781
4782 /*******************************************************************
4783  *
4784  * @brief Delete RIC subscription List
4785  *
4786  * @details
4787  *
4788  *    Function : deleteRicSubscriptionList 
4789  *
4790  * Functionality: Delete RIC subscription list
4791  *
4792  * @params[in] RIC Subscription list
4793  * @return void
4794
4795  *
4796  ******************************************************************/
4797 void deleteRicSubscriptionList(CmLListCp *subscriptionList)
4798 {
4799    CmLList *subscriptionNode = NULLP;
4800
4801    CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
4802    while(subscriptionNode)
4803    {
4804       cmLListDelFrm(subscriptionList, subscriptionNode);
4805       deleteRicSubscriptionNode(subscriptionNode);
4806       CM_LLIST_FIRST_NODE(subscriptionList, subscriptionNode);
4807    }
4808 }
4809
4810 /*******************************************************************
4811  *
4812  * @brief process the E2 Reset Response
4813  *
4814  * @details
4815  *
4816  *    Function : ProcResetResponse 
4817  *
4818  * Functionality: Process E2 Reset Response 
4819  *
4820  * @params[in] 
4821  *       du Id
4822  *       Pointer to reset response 
4823  * @return void
4824  *
4825  ******************************************************************/
4826
4827 void ProcResetResponse(uint32_t duId, ResetResponseE2_t *resetRsp)
4828 {
4829    uint8_t ieIdx = 0, duIdx =0;
4830    DuDb *duDb = NULLP;
4831    RanFunction *ranFuncDb = NULLP;
4832    uint16_t ranFuncIdx = 0;
4833
4834    SEARCH_DU_DB(duIdx, duId, duDb); 
4835    if(duDb == NULLP)
4836    {
4837       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4838       return;
4839    }
4840    
4841    if(!resetRsp)
4842    {
4843       DU_LOG("\nERROR  -->  E2AP : resetRsp pointer is null"); 
4844       return;
4845    }
4846
4847    if(!resetRsp->protocolIEs.list.array)      
4848    {
4849       DU_LOG("\nERROR  -->  E2AP : resetRsp array pointer is null");
4850       return;
4851    }
4852    
4853    for(ieIdx=0; ieIdx < resetRsp->protocolIEs.list.count; ieIdx++)
4854    {
4855       if(resetRsp->protocolIEs.list.array[ieIdx])
4856       {
4857          switch(resetRsp->protocolIEs.list.array[ieIdx]->id)
4858          {
4859             case ProtocolIE_IDE2_id_TransactionID:
4860                {
4861                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
4862                   {
4863                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
4864                      if(ranFuncDb->id > 0)
4865                      {
4866                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
4867                      }
4868                   }
4869                   break;
4870                }
4871             case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2:
4872                {
4873                   break;
4874                }
4875          }
4876       }
4877    }
4878 }
4879
4880
4881 /*******************************************************************
4882  *
4883  * @brief process the E2 Reset Request
4884  *
4885  * @details
4886  *
4887  *    Function : ProcResetRequest 
4888  *
4889  * Functionality: Process E2 Reset Request 
4890  *
4891  * @params[in] 
4892  *       du Id
4893  *       Pointer to reset response 
4894  * @return void
4895  *
4896  ******************************************************************/
4897
4898 void ProcResetRequest(uint32_t duId, ResetRequestE2_t *resetReq)
4899 {
4900    uint8_t ieIdx = 0, duIdx =0, transId=0;
4901    DuDb *duDb = NULLP;
4902    RanFunction *ranFuncDb = NULLP;
4903    uint16_t ranFuncIdx = 0;
4904
4905    SEARCH_DU_DB(duIdx, duId, duDb); 
4906    if(duDb == NULLP)
4907    {
4908       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
4909       return;
4910    }
4911    
4912    if(!resetReq)
4913    {
4914       DU_LOG("\nERROR  -->  E2AP : resetReq pointer is null"); 
4915       return;
4916    }
4917
4918    if(!resetReq->protocolIEs.list.array)      
4919    {
4920       DU_LOG("\nERROR  -->  E2AP : resetReq array pointer is null");
4921       return;
4922    }
4923    
4924    for(ieIdx=0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++)
4925    {
4926       if(resetReq->protocolIEs.list.array[ieIdx])
4927       {
4928          switch(resetReq->protocolIEs.list.array[ieIdx]->id)
4929          {
4930             case ProtocolIE_IDE2_id_TransactionID:
4931                {
4932                   transId = resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID;
4933                   break;
4934                }
4935             case ProtocolIE_IDE2_id_CauseE2:
4936                {
4937                   for(ranFuncIdx = 0; ranFuncIdx < MAX_RAN_FUNCTION; ranFuncIdx++)
4938                   {
4939                      ranFuncDb = &duDb->ranFunction[ranFuncIdx];
4940                      if(ranFuncDb->id > 0)
4941                      {
4942                         deleteRicSubscriptionList(&ranFuncDb->subscriptionList);
4943                      }
4944                   }
4945                   break;
4946                }
4947          }
4948       }
4949    }
4950
4951    if(BuildAndSendResetResponse(duId, transId) !=ROK)
4952    {
4953       DU_LOG("\nERROR  -->  E2AP : Failed to build and send reset response");
4954    }
4955 }
4956
4957 /*******************************************************************
4958  *
4959  * @brief Free RIC Subscription Delete Request Message
4960  *
4961  * @details
4962  *
4963  *    Function : FreeRicSubscriptionDeleteRequest
4964  *
4965  * Functionality:  Free RIC Subscription Delete Request
4966  *
4967  * @param  E2AP Message PDU
4968  * @return void
4969  *
4970  ******************************************************************/
4971 void FreeRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
4972 {
4973    uint8_t ieIdx = 0, arrIdx = 0;
4974    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
4975
4976    if(e2apMsg)
4977    {
4978       if(e2apMsg->choice.initiatingMessage)
4979       {
4980          ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
4981          if(ricSubsDelReq->protocolIEs.list.array)
4982          {
4983             for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
4984             {
4985                RIC_FREE(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t));
4986             }
4987             RIC_FREE(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
4988          }
4989          RIC_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
4990       }
4991       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));;
4992    }
4993 }
4994
4995 /*******************************************************************
4996  *
4997  * @brief Builds and Send RIC Subscription delete request
4998  *
4999  * @details
5000  *
5001  *    Function : BuildAndSendRicSubscriptionDeleteRequest
5002  *
5003  * Functionality: Build and send RIC subscription delete request.
5004  *
5005  * @params[in] DU ID
5006  *             RIC subscription info to be deleted
5007  * @return ROK     - success
5008  *         RFAILED - failure
5009  *
5010  ******************************************************************/
5011 uint8_t BuildAndSendRicSubscriptionDeleteRequest(uint32_t duId, RicSubscription *ricSubsDb)
5012 {
5013    uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED;
5014    E2AP_PDU_t         *e2apMsg = NULLP;
5015    RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
5016    RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
5017    asn_enc_rval_t     encRetVal;        /* Encoder return value */
5018
5019    while(true)
5020    {
5021       DU_LOG("\nINFO   -->  E2AP : Building RIC Subscription Delete Request Message\n");
5022
5023       RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t));
5024       if(e2apMsg == NULLP)
5025       {
5026          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
5027          break;
5028       }
5029
5030       e2apMsg->present = E2AP_PDU_PR_initiatingMessage;
5031       RIC_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
5032       if(e2apMsg->choice.initiatingMessage == NULLP)
5033       {
5034          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__);
5035          break;
5036       }
5037       e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete;
5038       e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
5039       e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest;
5040
5041       ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
5042
5043       elementCnt = 2;
5044       ricSubsDelReq->protocolIEs.list.count = elementCnt;
5045       ricSubsDelReq->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequest_IEs_t *);
5046
5047       RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array, ricSubsDelReq->protocolIEs.list.size);
5048       if(ricSubsDelReq->protocolIEs.list.array == NULLP)
5049       {
5050          DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__);
5051          break;
5052       }
5053
5054       for(ieIdx = 0; ieIdx < elementCnt; ieIdx++)
5055       {
5056          RIC_ALLOC(ricSubsDelReq->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequest_IEs_t));
5057          if(ricSubsDelReq->protocolIEs.list.array[ieIdx] == NULLP)
5058          {
5059             DU_LOG("\nERROR  -->  E2AP : %s: Memory allocation failed for index [%d] at line %d", \
5060                   __func__, ieIdx, __LINE__);
5061             break;
5062          }
5063       }
5064       if(ieIdx < elementCnt)
5065          break;
5066       
5067       /* RIC Request ID */
5068       ieIdx = 0;
5069       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
5070       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RICrequestID;
5071       ricSubsDelReqIe->criticality = CriticalityE2_reject;
5072       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
5073       ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID = ricSubsDb->requestId.requestorId;
5074       ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID = ricSubsDb->requestId.instanceId;
5075
5076       /* RAN Function ID */
5077       ieIdx++;
5078       ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
5079       ricSubsDelReqIe->id = ProtocolIE_IDE2_id_RANfunctionID;
5080       ricSubsDelReqIe->criticality = CriticalityE2_reject;
5081       ricSubsDelReqIe->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
5082       ricSubsDelReqIe->value.choice.RANfunctionID = ricSubsDb->ranFuncId;
5083
5084       /* Prints the Msg formed */
5085       xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5086       memset(encBuf, 0, ENC_BUF_MAX_LEN);
5087       encBufSize = 0;
5088       encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
5089       if(encRetVal.encoded == ENCODE_FAIL)
5090       {
5091          DU_LOG("\nERROR  -->  E2AP : Could not encode RIC Subscription Delete Request Message (at %s)\n",\
5092                encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
5093          break;
5094       }
5095       else
5096       {
5097          DU_LOG("\nDEBUG  -->  E2AP : Created APER encoded buffer for RIC Subscription Delete Request Message \n");
5098 #ifdef DEBUG_ASN_PRINT
5099          for(int i=0; i< encBufSize; i++)
5100          {
5101             printf("%x",encBuf[i]);
5102          } 
5103 #endif
5104       }
5105
5106       if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK)
5107       {
5108          DU_LOG("\nERROR   -->  E2AP : Failed to send RIC Susbcription Delete Request Message");      
5109          break;
5110       }
5111
5112       ret = ROK;
5113       break;
5114    }
5115
5116    FreeRicSubscriptionDeleteRequest(e2apMsg);  
5117    return ret;
5118 }
5119
5120 /*******************************************************************
5121  *
5122  * @brief Processing of RIC Subscription Delete Required
5123  *
5124  * @details
5125  *
5126  *    Function : ProcRicSubsDeleteReqd
5127  *
5128  * Functionality: Processing of RIC Subscription Delete Required
5129  *    When received, RIC stub will initiate the RIC subscription
5130  *    deletion procedure towards DU
5131  *
5132  * @param  DU ID
5133  *         RIC Subscription Delete Required IEs
5134  * @return ROK-success
5135  *         RFAILED-failure
5136  *
5137  ******************************************************************/
5138 uint8_t ProcRicSubsDeleteReqd(uint32_t duId, RICsubscriptionDeleteRequired_t *ricSubsDelRqd)
5139 {
5140    uint8_t ieIdx = 0, duIdx = 0;
5141    uint16_t arrIdx = 0;
5142    DuDb *duDb = NULLP;
5143    RicRequestId ricReqId;
5144    RanFunction *ranFuncDb = NULLP;
5145    RicSubscription *subsDb = NULLP;
5146    CmLList *ricSubsNode = NULLP;
5147
5148    RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP;
5149    RICsubscription_List_withCause_t *ricSubsList = NULLP;
5150    RICsubscription_withCause_Item_t *subsItem = NULLP;
5151
5152    memset(&ricReqId, 0, sizeof(RicRequestId));
5153
5154    if(!ricSubsDelRqd)
5155    {
5156       DU_LOG("\nERROR  -->  E2AP : %s: Received NULL message", __func__);
5157       return RFAILED;
5158    }
5159
5160    SEARCH_DU_DB(duIdx, duId, duDb);
5161    if(duDb == NULLP)
5162    {
5163       DU_LOG("\nERROR  -->  E2AP : duDb is not present for duId %d",duId);
5164       return RFAILED;
5165    }
5166
5167    for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++)
5168    {
5169       ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx];
5170       switch(ricSubsDelRqdIe->id)
5171       {
5172          case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved:
5173          {
5174             ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause;
5175             for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++)
5176             {
5177                subsItem = &(((RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[arrIdx])->\
5178                   value.choice.RICsubscription_withCause_Item);
5179                ranFuncDb = fetchRanFuncFromRanFuncId(duDb, subsItem->ranFunctionID);
5180                if(!ranFuncDb)
5181                {
5182                   DU_LOG("\nERROR  -->  E2AP : %s: RAN Function ID [%ld] not found", __func__, subsItem->ranFunctionID);
5183                   return RFAILED;
5184                }
5185                
5186                ricReqId.requestorId = subsItem->ricRequestID.ricRequestorID;
5187                ricReqId.instanceId = subsItem->ricRequestID.ricInstanceID;
5188                subsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
5189                if(!subsDb)
5190                {
5191                   DU_LOG("\nERROR  -->  E2AP : %s: RIC Subscription not found for Requestor_ID [%ld] Instance_ID [%ld]", \
5192                      __func__, subsItem->ricRequestID.ricRequestorID, subsItem->ricRequestID.ricInstanceID);
5193                   return RFAILED;
5194                }
5195
5196                /* Delete RIC Subcription from RAN Function */
5197                cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubsNode);
5198                
5199                /* Send RIC Subscription delete request and then free any memory
5200                 * allocated to store subscription info at RIC */
5201                BuildAndSendRicSubscriptionDeleteRequest(duId, (RicSubscription *)ricSubsNode->node);
5202                deleteRicSubscriptionNode(ricSubsNode);
5203             }
5204             
5205             break;
5206          }
5207          default:
5208             break;
5209       }
5210    }  
5211    
5212    return ROK;
5213 }
5214
5215 /*******************************************************************
5216 *
5217 * @brief Handles received E2AP message and sends back response  
5218 *
5219 * @details
5220 *
5221 *    Function : E2APMsgHdlr
5222 *
5223 *    Functionality:
5224 *         - Decodes received E2AP control message
5225 *         - Prepares response message, encodes and sends to SCTP
5226 *
5227 * @params[in] 
5228 * @return ROK     - success
5229 *         RFAILED - failure
5230 *
5231 * ****************************************************************/
5232 void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf)
5233 {
5234    int             i;
5235    char            *recvBuf;
5236    MsgLen          copyCnt;
5237    MsgLen          recvBufLen;
5238    E2AP_PDU_t      *e2apMsg;
5239    asn_dec_rval_t  rval; /* Decoder return value */
5240    E2AP_PDU_t      e2apasnmsg ;
5241  
5242    DU_LOG("\nINFO  -->  E2AP : Received E2AP message buffer");
5243    ODU_PRINT_MSG(mBuf, 0,0);
5244  
5245    /* Copy mBuf into char array to decode it */
5246    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
5247    RIC_ALLOC(recvBuf, (Size)recvBufLen);
5248
5249    if(recvBuf == NULLP)
5250    {
5251       DU_LOG("\nERROR  -->  E2AP : Memory allocation failed");
5252       return;
5253    }
5254    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
5255    {
5256       DU_LOG("\nERROR  -->  E2AP : Failed while copying %d", copyCnt);
5257       return;
5258    }
5259
5260    DU_LOG("\nDEBUG  -->  E2AP : Received flat buffer to be decoded : ");
5261    for(i=0; i< recvBufLen; i++)
5262    {
5263         DU_LOG("%x",recvBuf[i]);
5264    }
5265
5266    /* Decoding flat buffer into E2AP messsage */
5267    e2apMsg = &e2apasnmsg;
5268    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
5269
5270    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
5271    RIC_FREE(recvBuf, (Size)recvBufLen);
5272
5273    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
5274    {
5275       DU_LOG("\nERROR  -->  E2AP : ASN decode failed");
5276       return;
5277    }
5278    DU_LOG("\n");
5279    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
5280
5281    switch(e2apMsg->present)
5282    {
5283       case E2AP_PDU_PR_initiatingMessage:
5284          {
5285             switch(e2apMsg->choice.initiatingMessage->value.present)
5286             {
5287                case InitiatingMessageE2__value_PR_E2setupRequest:
5288                   {
5289                      DU_LOG("\nINFO  -->  E2AP : E2 setup request received");
5290                      ProcE2SetupReq(duId, &e2apMsg->choice.initiatingMessage->value.choice.E2setupRequest);
5291                      break;
5292                   }
5293                case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate:
5294                   {
5295                      DU_LOG("\nINFO  -->  E2AP : E2 node config update received");
5296                      ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate);
5297                      break;
5298                   }
5299                case InitiatingMessageE2__value_PR_ResetRequestE2:
5300                   {
5301                      DU_LOG("\nINFO  -->  E2AP : E2 Reset Request received");
5302                      ProcResetRequest(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2);
5303                      break;
5304                   }
5305                case InitiatingMessageE2__value_PR_RICindication:
5306                   {
5307                      DU_LOG("\nINFO  -->  E2AP : RIC Indication received");
5308                      break;
5309                   }
5310                case InitiatingMessageE2__value_PR_RICserviceUpdate:
5311                   {
5312                      DU_LOG("\nINFO  -->  E2AP : RIC Service update received");
5313                      ProcRicServiceUpdate(*duId,  &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate);
5314                      break;
5315                   }
5316                case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired:
5317                   {
5318                      DU_LOG("\nINFO  -->  E2AP : RIC Subscription Modification Required");
5319                      ProcRicSubsModReqd(*duId, \
5320                            &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired);
5321                      break;
5322                   }
5323                case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired:
5324                   {
5325                       DU_LOG("\nINFO  -->  E2AP : RIC Subscription Delete Required");
5326                       ProcRicSubsDeleteReqd(*duId, \
5327                          &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired);
5328                       break;
5329                   }
5330
5331                case InitiatingMessageE2__value_PR_ErrorIndicationE2:
5332                   {
5333                      DU_LOG("\nINFO  -->  E2AP : Error indication received");
5334                      break;
5335                   }
5336                default:
5337                   {
5338                      DU_LOG("\nERROR  -->  E2AP : Invalid type of intiating message [%d]", \
5339                         e2apMsg->choice.initiatingMessage->value.present);
5340                      return;
5341                   }
5342             }/* End of switch(initiatingMessage) */
5343             break;
5344          }
5345       case E2AP_PDU_PR_successfulOutcome: 
5346          {
5347             switch(e2apMsg->choice.successfulOutcome->value.present)
5348             {
5349                case SuccessfulOutcomeE2__value_PR_ResetResponseE2:
5350                   {
5351                      DU_LOG("\nINFO  -->  E2AP : Reset response received");
5352                      ProcResetResponse(*duId,  &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2);
5353                      break;
5354                   }
5355                case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
5356                   {
5357                      ProcRicSubscriptionResponse(*duId, \
5358                         &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse);
5359                      break;
5360                   }
5361                default:
5362                   {
5363                      DU_LOG("\nERROR  -->  E2AP : Invalid type of successfulOutcome message [%d]", \
5364                         e2apMsg->choice.successfulOutcome->value.present);
5365                      return;
5366                   }
5367                   break;
5368             }
5369             break; 
5370          }
5371          case E2AP_PDU_PR_unsuccessfulOutcome:
5372          {
5373             switch(e2apMsg->choice.successfulOutcome->value.present)
5374             {
5375                case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure:
5376                   {
5377                      ProcRicSubscriptionFailure(*duId, \
5378                         &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure);
5379                      break;
5380                   }
5381                default:
5382                   {
5383                      DU_LOG("\nERROR  -->  E2AP : Invalid type of unsuccessfulOutcome message [%d]", \
5384                         e2apMsg->choice.unsuccessfulOutcome->value.present);
5385                      return;
5386                   }
5387             }
5388             break;
5389          }
5390       default:
5391          {
5392             DU_LOG("\nERROR  -->  E2AP : Invalid type message type ");
5393             return;
5394          }
5395
5396    }/* End of switch(e2apMsg->present) */
5397 } /* End of E2APMsgHdlr */
5398
5399
5400 /**********************************************************************
5401   End of file
5402  **********************************************************************/